@norskvideo/moq-net 0.1.8 → 0.2.1

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
package/track.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"track.js","sourceRoot":"","sources":["../src/track.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Track role handles: a live stream of groups (and best-effort datagrams) within a broadcast.\n *\n * @module\n */\nimport { type GetPromise, type Getter, Once, Signal } from \"@moq/signals\";\nimport type { Datagram } from \"./datagram.ts\";\nimport { type Frame, type Consumer as GroupConsumer, Producer as GroupProducer, Lagged } from \"./group.ts\";\nimport { hooks, type TrackRequestOptions, type TrackSequence, type TrackSequences } from \"./internal.ts\";\nimport { Timescale, type Timestamp } from \"./time.ts\";\n\nexport type { Datagram } from \"./datagram.ts\";\n\n/** Default {@link Info.latencyMax} window (milliseconds) when the publisher does not set one. */\nexport const DEFAULT_LATENCY_MAX_MS = 5000;\n\n/**\n * How long (milliseconds) a datagram stays in the per-subscriber buffer before it is dropped.\n *\n * Datagrams are a best-effort send buffer, not a replay cache (unlike groups): only the last few\n * tens of milliseconds are kept, so a consumer that stalls loses stale datagrams instead of\n * replaying them. Mirrors the Rust `MAX_DATAGRAM_AGE`.\n */\nconst MAX_DATAGRAM_AGE_MS = 50;\n\n/** A datagram buffered with its arrival time, so the send buffer can evict by age. */\ntype BufferedDatagram = { datagram: Datagram; time: number };\n\n/**\n * Sanity cap on a datagram payload: the QUIC DATAGRAM frame ceiling. The real limit is\n * per-hop (the negotiated transport datagram size minus a small header) and oversize\n * datagrams are dropped there; a payload above this cap could never fit anywhere.\n */\nconst MAX_DATAGRAM_BYTES = 65535;\n\n/** A position within a track: a group's sequence and a frame's index inside it. */\nexport interface Location {\n\t/** The group's sequence number within the track. */\n\tgroup: number;\n\t/** The frame's index within that group. */\n\tframe: number;\n}\n\n/**\n * A track's immutable publisher properties, fixed for the lifetime of the track.\n *\n * A producer declares these once (via {@link Request.accept} or\n * {@link Producer.accept}); a consumer awaits them via {@link Subscriber.info}\n * (resolved from the wire TRACK_INFO on lite-05+). They map 1:1 onto TRACK_INFO.\n */\nexport interface Info {\n\t/**\n\t * Units per second for this track's frame timestamps (reported in TRACK_INFO on\n\t * Lite05+). Defaults to milliseconds; set it finer (e.g. {@link Timescale.MICRO})\n\t * for media that needs sub-millisecond timing.\n\t */\n\ttimescale: Timescale;\n\t/**\n\t * Publisher Max Latency: the maximum age (milliseconds) of a non-latest group before\n\t * the publisher evicts it. Reported in TRACK_INFO (Lite05+) so relays re-serve with the\n\t * same bound. The publisher-side half of the budget a subscriber sets for itself.\n\t */\n\tlatencyMax: number;\n\t/** Tie-break priority between subscriptions of equal subscriber priority. */\n\tpriority: number;\n\t/**\n\t * Whether groups are prioritized in sequence order. Groups may always arrive\n\t * out-of-order (or not at all) over the network. Defaults to `false` (newest-first).\n\t */\n\tordered: boolean;\n}\n\n/** Fill in any unset {@link Info} fields with their defaults. */\nexport function infoDefaults(info: Partial<Info> = {}): Info {\n\treturn {\n\t\ttimescale: info.timescale ?? Timescale.MILLI,\n\t\tlatencyMax: info.latencyMax ?? DEFAULT_LATENCY_MAX_MS,\n\t\tpriority: info.priority ?? 0,\n\t\tordered: info.ordered ?? false,\n\t};\n}\n\n/**\n * Per-subscription options, requested when a subscription opens and adjustable later via\n * {@link Subscriber.update}. Mirrors the Rust `Subscription`.\n */\nexport interface Subscription {\n\t/** Delivery priority relative to this session's other subscriptions. Defaults to `0`. */\n\tpriority?: number;\n\t/** Whether groups are prioritized in sequence order. Defaults to `false` (newest-first). */\n\tordered?: boolean;\n\t/** Maximum age (milliseconds) of a non-latest group before it is skipped. Defaults to `0`. */\n\tlatencyMax?: number;\n\t/** First group the publisher should deliver, or omit to start at the latest group. */\n\tstartGroup?: number;\n\t/** Last group the publisher should deliver (inclusive), or omit for no end. */\n\tendGroup?: number;\n}\n\n// Materialize the defaults at the model boundary so every layer observes a complete\n// subscription rather than interpreting an omitted field differently.\nfunction subscriptionDefaults(subscription: Subscription = {}): Subscription {\n\treturn {\n\t\tpriority: subscription.priority ?? 0,\n\t\tordered: subscription.ordered ?? false,\n\t\tlatencyMax: subscription.latencyMax ?? 0,\n\t\tstartGroup: subscription.startGroup,\n\t\tendGroup: subscription.endGroup,\n\t};\n}\n\n// Aggregate the preferences of every live subscriber, matching Rust's Subscription::poll_combined.\nfunction combineSubscriptions(states: Iterable<TrackState>): Subscription | undefined {\n\tlet combined: Subscription | undefined;\n\tfor (const state of states) {\n\t\tconst subscription = state.update.peek();\n\t\tif (!subscription) continue;\n\t\tif (!combined) {\n\t\t\tcombined = { ...subscription };\n\t\t\tcontinue;\n\t\t}\n\n\t\tcombined.priority = Math.max(combined.priority ?? 0, subscription.priority ?? 0);\n\t\tcombined.ordered = (combined.ordered ?? false) && (subscription.ordered ?? false);\n\t\tcombined.latencyMax = Math.max(combined.latencyMax ?? 0, subscription.latencyMax ?? 0);\n\n\t\tif (subscription.startGroup !== undefined) {\n\t\t\tcombined.startGroup =\n\t\t\t\tcombined.startGroup === undefined\n\t\t\t\t\t? subscription.startGroup\n\t\t\t\t\t: Math.min(combined.startGroup, subscription.startGroup);\n\t\t}\n\n\t\tif (combined.endGroup === undefined || subscription.endGroup === undefined) {\n\t\t\tcombined.endGroup = undefined;\n\t\t} else {\n\t\t\tcombined.endGroup = Math.max(combined.endGroup, subscription.endGroup);\n\t\t}\n\t}\n\treturn combined;\n}\n\n/**\n * A request for a track the peer wants, yielded by `Broadcast.Producer.requested`.\n *\n * Created internally by the broadcast when a subscription (or info lookup) needs a track\n * served; answer it with {@link accept} or {@link reject}.\n *\n * @public\n */\nexport class Request {\n\t/** The requested track name. */\n\treadonly name: string;\n\n\t#producer: Producer;\n\t#sequences: TrackSequences;\n\n\tprivate constructor(options: TrackRequestOptions) {\n\t\tthis.name = options.name;\n\t\tthis.#producer = options.producer;\n\t\tthis.#sequences = options.sequences;\n\t}\n\n\tstatic {\n\t\thooks.makeRequest = (options) => new Request(options);\n\t}\n\n\t/** The aggregate subscription requested for this track. */\n\tget subscription(): Readonly<Subscription> {\n\t\treturn this.#producer.subscription.peek() ?? subscriptionDefaults();\n\t}\n\n\t/** The subscriber's priority for this track. */\n\tget priority(): number {\n\t\treturn this.subscription.priority ?? 0;\n\t}\n\n\t/** Accept the request, committing the track's immutable {@link Info}. */\n\taccept(info: Partial<Info> = {}): Producer {\n\t\tbindProducer(this.name, this.#producer, this.#sequences);\n\t\treturn this.#producer.accept(info);\n\t}\n\n\t/** Reject the request, closing the track optionally with an error. */\n\treject(err?: Error): void {\n\t\tthis.#producer.close(err);\n\t}\n}\n\n/** Options for {@link Consumer.fetchGroup}. */\nexport interface FetchGroupOptions {\n\t/** Delivery priority for the fetch stream. Defaults to `0`. */\n\tpriority?: number;\n}\n\n/**\n * The per-track operations a lazy {@link Consumer} delegates to the broadcast it came from.\n *\n * Implemented by `broadcast.Producer` / `broadcast.Consumer` (and the wire-layer subclasses\n * that resolve them over the network), so a track handle holds a reference to its broadcast\n * and calls methods on it rather than capturing a bag of callbacks.\n */\nexport interface Broadcast {\n\t/** Open a live subscription to the named track. */\n\tsubscribe(name: string, options?: Subscription): Subscriber;\n\t/** Resolve the named track's immutable info. */\n\tresolveTrackInfo(name: string): Promise<Info>;\n\t/** Fetch a single group of the named track by sequence. */\n\tfetchGroup(name: string, sequence: number, options?: FetchGroupOptions): Promise<GroupConsumer>;\n}\n\n/**\n * A lazy handle to a track on a consumed broadcast.\n *\n * @public\n */\nexport class Consumer {\n\t/** The track name. */\n\treadonly name: string;\n\n\t#broadcast: Broadcast;\n\n\tconstructor(name: string, broadcast: Broadcast) {\n\t\tthis.name = name;\n\t\tthis.#broadcast = broadcast;\n\t}\n\n\t/** Open a live subscription to the track. */\n\tsubscribe(options?: Subscription): Subscriber {\n\t\treturn this.#broadcast.subscribe(this.name, options);\n\t}\n\n\t/** Fetch the track's immutable publisher properties without subscribing. */\n\tinfo(): Promise<Info> {\n\t\treturn this.#broadcast.resolveTrackInfo(this.name);\n\t}\n\n\t/** Fetch a single group by sequence without holding a live subscription. */\n\tfetchGroup(sequence: number, options?: FetchGroupOptions): Promise<GroupConsumer> {\n\t\treturn this.#broadcast.fetchGroup(this.name, sequence, options);\n\t}\n}\n\n// The shared state behind a Producer / Subscriber pair. Package-internal\n// wiring, unexported so it never appears in the published type declarations.\nclass TrackState {\n\t/** The producer fanning into this sink, so a subscriber can mint a sibling of itself. */\n\tproducer?: Producer;\n\tgroups = new Signal<GroupConsumer[]>([]);\n\t/** Best-effort datagram channel, parallel to {@link groups}; an age-evicted send buffer per subscriber. */\n\tdatagrams = new Signal<BufferedDatagram[]>([]);\n\tlatest?: number;\n\tclosed = new Once<Error | null>();\n\tupdate: Signal<Subscription | undefined>;\n\t/** Resolved once the producer commits the immutable properties. */\n\tinfo = new Signal<Info | undefined>(undefined);\n\n\tconstructor(subscription?: Subscription) {\n\t\tthis.update = new Signal(subscription === undefined ? undefined : subscriptionDefaults(subscription));\n\t}\n}\n\n// Settle a track state's closed Once. Idempotent: Once.set throws on a second settle, and a\n// Producer closing its sinks races the Subscriber closing itself (the sink is only removed from\n// #sinks a microtask later, via the closed subscription below).\nfunction closeTrackState(state: TrackState, abort?: Error): boolean {\n\tif (state.closed.peek() !== undefined) return false;\n\tstate.closed.set(abort ?? null);\n\treturn true;\n}\n\n// Resolve the track's immutable publisher properties, or reject if it closes first.\n// On a producer this resolves once info is committed (at accept time); on a consumer\n// once the wire layer commits the TRACK_INFO it received (lite-05+) or defaults (older\n// drafts), so awaiting it never yields a placeholder.\nasync function resolveInfo(state: TrackState): Promise<Info> {\n\tfor (;;) {\n\t\tconst info = state.info.peek();\n\t\tif (info) return info;\n\n\t\tconst closed = state.closed.peek();\n\t\tif (closed instanceof Error) throw closed;\n\t\tif (closed !== undefined) throw new Error(\"track closed before info was known\");\n\n\t\tawait Signal.race(state.info, state.closed);\n\t}\n}\n\n// A source group retained in the producer cache, with the mirror handed to each sink\n// so eviction can drop them together.\ntype CachedGroup = { group: GroupProducer; time: number; mirrors: Map<TrackState, GroupConsumer> };\n\nfunction bindProducer(name: string, producer: Producer, sequences: TrackSequences): void {\n\tlet shared = sequences.get(name);\n\tif (!shared) {\n\t\tshared = { next: 0 };\n\t\tsequences.set(name, shared);\n\t}\n\tbindProducerSequence(producer, shared);\n}\n\nlet bindProducerSequence: (producer: Producer, sequence: TrackSequence) => void;\n\n// Constructs a Subscriber from within this module without exposing a public\n// constructor that would leak the unexported TrackState. Assigned in the class's\n// static block.\nlet makeSubscriber: (name: string, state: TrackState) => Subscriber;\n\n/**\n * The write side of a track, mirroring the Rust `Producer`.\n *\n * A producer is a fan-out source: every {@link subscribe} (including each wire\n * subscription the publisher serves from it) gets an independent\n * {@link Subscriber} that receives a full copy of the groups, each with its own\n * read cursor. Groups are mirrored into every live subscriber and retained for the\n * track's `latencyMax` window so a late subscriber replays the recent groups.\n *\n * Obtained from {@link Request.accept} (the wire asks the application for a track to\n * serve) or constructed directly for an in-process track.\n */\nexport class Producer {\n\t/** The track name. */\n\treadonly name: string;\n\n\t// The producer's own state is the source of truth (info/closed); subscribers\n\t// read mirrored sinks, never this state directly.\n\t#state = new TrackState();\n\t#sequence: TrackSequence = { next: 0 };\n\n\t// Recently written source groups, retained for replay to late subscribers and\n\t// pruned once closed and older than the cache window. Each entry tracks the mirror\n\t// it handed to every sink so eviction can drop them too: otherwise a slow consumer\n\t// that never reads would pin old groups (and their frame bytes) forever.\n\t#cache: CachedGroup[] = [];\n\n\t// One independent downstream state per live subscriber.\n\t#sinks = new Set<TrackState>();\n\n\t// Whether any subscriber is currently attached. Exposed as {@link used}; the consumer wire\n\t// watches it to tear down an idle upstream, and a publisher can watch it for on-demand capture.\n\t#used = new Signal<boolean>(false);\n\n\tconstructor(name: string) {\n\t\tthis.name = name;\n\t}\n\n\tstatic {\n\t\tbindProducerSequence = (producer, sequence) => {\n\t\t\tproducer.#sequence = sequence;\n\t\t};\n\t}\n\n\t/**\n\t * Resolve this track's immutable publisher properties, committed at accept time.\n\t * Rejects if the track is closed before the properties are known.\n\t */\n\tinfo(): Promise<Info> {\n\t\treturn resolveInfo(this.#state);\n\t}\n\n\t/**\n\t * Settles once the track closes: `null` on a clean close, or the abort {@link Error}.\n\t * Peek it synchronously (`undefined` while open), observe it reactively, or `await` it.\n\t */\n\tget closed(): GetPromise<Error | null> {\n\t\treturn this.#state.closed;\n\t}\n\n\t/**\n\t * The aggregate subscription across live subscribers, or `undefined` when there are none.\n\t * The wire layer watches this to emit SUBSCRIBE_UPDATE.\n\t */\n\tget subscription(): Getter<Subscription | undefined> {\n\t\treturn this.#state.update;\n\t}\n\n\t/** Commit the immutable publisher properties, resolving {@link info}. Returns `this`. */\n\taccept(info: Partial<Info> = {}): this {\n\t\tconst resolved = infoDefaults(info);\n\t\tthis.#state.info.set(resolved);\n\t\t// Propagate to any sink handed out before accept (the on-demand path).\n\t\tfor (const sink of this.#sinks) sink.info.set(resolved);\n\t\treturn this;\n\t}\n\n\t/** An independent {@link Subscriber} receiving a full copy of this track's groups. */\n\tsubscribe(options: Subscription = {}): Subscriber {\n\t\tconst sink = new TrackState(options);\n\t\tthis.#addSink(sink);\n\t\treturn makeSubscriber(this.name, sink);\n\t}\n\n\t/**\n\t * Whether the track currently has any subscribers.\n\t *\n\t * Watch it (`effect.get` / `.peek()`) to drive on-demand work: a publisher can start and stop\n\t * capture with demand, and the consumer wire watches it to tear an idle upstream subscription\n\t * down instead of downloading to nobody. Pairs with {@link unused}. Mirrors the Rust `Demand`.\n\t */\n\tget used(): Getter<boolean> {\n\t\treturn this.#used;\n\t}\n\n\t/** Resolves once the track has no subscribers (or has closed). Await it to react to demand ending. */\n\tasync unused(): Promise<void> {\n\t\twhile (this.#used.peek() && this.#state.closed.peek() === undefined) {\n\t\t\tawait Signal.race(this.#used, this.#state.closed);\n\t\t}\n\t}\n\n\t// Register a downstream sink: seed its info, replay the retained window, and (while\n\t// the track is open) mirror future groups into it. A late subscriber to a closed\n\t// track still drains the buffered groups before seeing the end.\n\t#addSink(sink: TrackState): void {\n\t\tsink.producer = this;\n\t\tconst info = this.#state.info.peek();\n\t\tif (info) sink.info.set(info);\n\n\t\tconst closed = this.#state.closed.peek();\n\t\tif (closed === undefined) {\n\t\t\tthis.#sinks.add(sink);\n\t\t\tthis.#used.set(true);\n\n\t\t\t// Forward subscription updates from the sink's Subscriber to the producer's own\n\t\t\t// state, which the wire layer (or the serving application) watches.\n\t\t\tconst forward = sink.update.subscribe(() => this.#updateSubscription());\n\t\t\tthis.#updateSubscription();\n\n\t\t\t// Drop the sink once its consumer goes away, closing its mirrors so source\n\t\t\t// groups stop teeing into them, so a long-lived producer doesn't leak. This\n\t\t\t// covers mirrors already handed out via recvGroup (no longer in sink.groups)\n\t\t\t// by closing them through the cache's per-sink tracking.\n\t\t\tconst dispose = sink.closed.subscribe((c) => {\n\t\t\t\tif (c === undefined) return;\n\t\t\t\tconst abort = c instanceof Error ? c : undefined;\n\t\t\t\tforward();\n\t\t\t\tthis.#sinks.delete(sink);\n\t\t\t\tthis.#updateSubscription();\n\t\t\t\tfor (const entry of this.#cache) {\n\t\t\t\t\tconst mirror = entry.mirrors.get(sink);\n\t\t\t\t\tif (mirror) {\n\t\t\t\t\t\tmirror.close(abort);\n\t\t\t\t\t\tentry.mirrors.delete(sink);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tfor (const group of sink.groups.peek()) group.close(abort);\n\t\t\t\tdispose();\n\n\t\t\t\t// Update demand: once the last subscriber leaves, the consumer wire (watching\n\t\t\t\t// {@link unused}) tears the upstream down instead of downloading to nobody.\n\t\t\t\tthis.#used.set(this.#sinks.size > 0);\n\t\t\t});\n\t\t}\n\n\t\tthis.#prune();\n\t\tfor (const entry of this.#cache) this.#mirror(entry, sink);\n\n\t\tif (closed !== undefined) closeTrackState(sink, closed instanceof Error ? closed : undefined);\n\t}\n\n\t// Recompute from every live sink because an update or close can narrow as well as widen\n\t// the aggregate. The wire layer observes this signal and emits SUBSCRIBE_UPDATE.\n\t#updateSubscription(): void {\n\t\tthis.#state.update.set(combineSubscriptions(this.#sinks));\n\t}\n\n\t// Mirror a cached source group into a sink. The mirror fills synchronously as the\n\t// source is written and keeps its own read cursor; frame bytes are shared by\n\t// reference. Tracked on the entry so eviction can drop it from the sink.\n\t#mirror(entry: CachedGroup, sink: TrackState): void {\n\t\tconst dst = entry.group.mirror();\n\t\tentry.mirrors.set(sink, dst);\n\t\tsink.latest = Math.max(sink.latest ?? 0, dst.sequence);\n\t\tsink.groups.mutate((groups) => {\n\t\t\tgroups.push(dst);\n\t\t\tgroups.sort((a, b) => a.sequence - b.sequence);\n\t\t});\n\t}\n\n\t// Drop a cached group's mirror from every sink so no consumer can pin it.\n\t#evict(entry: CachedGroup): void {\n\t\tfor (const [sink, mirror] of entry.mirrors) {\n\t\t\tsink.groups.mutate((groups) => {\n\t\t\t\tconst i = groups.indexOf(mirror);\n\t\t\t\tif (i >= 0) groups.splice(i, 1);\n\t\t\t});\n\t\t\tmirror.close();\n\t\t}\n\t\tentry.mirrors.clear();\n\t}\n\n\t// Evict cached groups that are closed and older than the cache window.\n\t#prune(): void {\n\t\tconst latencyMaxMs = this.#state.info.peek()?.latencyMax ?? DEFAULT_LATENCY_MAX_MS;\n\t\tconst cutoff = Date.now() - latencyMaxMs;\n\n\t\tconst retained: CachedGroup[] = [];\n\t\tfor (const entry of this.#cache) {\n\t\t\tif (entry.time > cutoff || entry.group.closed.peek() === undefined) {\n\t\t\t\tretained.push(entry);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tthis.#evict(entry);\n\t\t}\n\t\tthis.#cache = retained;\n\t}\n\n\t// Retain a source group and fan it out to every live sink.\n\t#publish(group: GroupProducer): void {\n\t\tconst entry: CachedGroup = { group, time: Date.now(), mirrors: new Map<TrackState, GroupConsumer>() };\n\t\tthis.#cache.push(entry);\n\t\tthis.#prune();\n\t\tfor (const sink of this.#sinks) this.#mirror(entry, sink);\n\t}\n\n\t/** Append a new group with the next sequence number. */\n\tappendGroup(): GroupProducer {\n\t\tif (this.#state.closed.peek() !== undefined) throw new Error(\"track is closed\");\n\n\t\tconst sequence = this.#sequence;\n\t\tconst group = new GroupProducer(sequence.next);\n\t\tsequence.next = group.sequence + 1;\n\t\tthis.#publish(group);\n\n\t\treturn group;\n\t}\n\n\t/**\n\t * Insert an existing group into the track.\n\t *\n\t * Throws on a sequence that is still cached: a live duplicate would fan out to every\n\t * subscriber twice. An aborted incarnation is evicted so a fresh group can serve the\n\t * sequence again. Best effort (mirrors Rust): nothing remembers a sequence whose cache\n\t * entry is already gone, so a long-evicted sequence is accepted as new.\n\t */\n\twriteGroup(group: GroupProducer) {\n\t\tif (this.#state.closed.peek() !== undefined) throw new Error(\"track is closed\");\n\n\t\tconst existing = this.#cache.findIndex((entry) => entry.group.sequence === group.sequence);\n\t\tif (existing >= 0) {\n\t\t\tconst entry = this.#cache[existing];\n\t\t\tif (!(entry.group.closed.peek() instanceof Error)) {\n\t\t\t\tthrow new Error(`duplicate group: sequence=${group.sequence}`);\n\t\t\t}\n\t\t\tthis.#evict(entry);\n\t\t\tthis.#cache.splice(existing, 1);\n\t\t}\n\n\t\t// Only advance the shared counter upward (for appendGroup auto-increment).\n\t\tconst sequence = this.#sequence;\n\t\tif (group.sequence >= sequence.next) {\n\t\t\tsequence.next = group.sequence + 1;\n\t\t}\n\n\t\tthis.#publish(group);\n\t}\n\n\t// Fan a datagram out to every live subscriber, dropping the oldest once the ring is full.\n\t// Late subscribers do NOT replay old datagrams (best-effort, unlike the group cache).\n\t#publishDatagram(datagram: Datagram): void {\n\t\tconst now = performance.now();\n\t\tfor (const sink of this.#sinks) {\n\t\t\tsink.datagrams.mutate((list) => {\n\t\t\t\tlist.push({ datagram, time: now });\n\t\t\t\t// Drop anything older than the send-buffer window.\n\t\t\t\twhile (list.length > 0 && now - list[0].time > MAX_DATAGRAM_AGE_MS) list.shift();\n\t\t\t});\n\t\t}\n\t}\n\n\t/**\n\t * Append a datagram with the next sequence number, returning the assigned sequence.\n\t *\n\t * A datagram is delivered best-effort over a single QUIC datagram, parallel to the track's\n\t * groups but drawing from the same sequence namespace (interleaving with {@link appendGroup}\n\t * never reuses a number). The payload must fit the negotiated transport datagram size minus\n\t * a small header; an oversize payload is dropped at each hop (there is no group fallback), so\n\t * keep datagram payloads small (e.g. a single audio frame). Datagrams are never delivered\n\t * over IETF moq-transport or stream-only transports (the WebSocket fallback). A payload over\n\t * 65535 bytes (the QUIC datagram frame ceiling) throws. An origin publisher uses this; a\n\t * relay preserving upstream numbering uses {@link writeDatagram}.\n\t */\n\tappendDatagram(timestamp: Timestamp, payload: Uint8Array): number {\n\t\tif (this.#state.closed.peek() !== undefined) throw new Error(\"track is closed\");\n\t\tif (payload.byteLength > MAX_DATAGRAM_BYTES) throw new Error(\"datagram payload too large\");\n\n\t\tconst counter = this.#sequence;\n\t\tconst sequence = counter.next;\n\t\tcounter.next = sequence + 1;\n\t\tthis.#publishDatagram({ sequence, timestamp, payload });\n\t\treturn sequence;\n\t}\n\n\t/**\n\t * Write a datagram with an explicit sequence number.\n\t *\n\t * Preserves the supplied sequence (advancing the shared counter if needed) so a relay can\n\t * forward a datagram without renumbering it. The size limits of {@link appendDatagram}\n\t * apply. Most origin publishers want {@link appendDatagram} instead.\n\t */\n\twriteDatagram(datagram: Datagram) {\n\t\tif (this.#state.closed.peek() !== undefined) throw new Error(\"track is closed\");\n\t\tif (datagram.payload.byteLength > MAX_DATAGRAM_BYTES) throw new Error(\"datagram payload too large\");\n\n\t\tconst sequence = this.#sequence;\n\t\tif (datagram.sequence >= sequence.next) {\n\t\t\tsequence.next = datagram.sequence + 1;\n\t\t}\n\t\tthis.#publishDatagram(datagram);\n\t}\n\n\t/** Close the track and every subscriber, mirroring the abort to their groups. Idempotent. */\n\tclose(abort?: Error) {\n\t\tcloseTrackState(this.#state, abort);\n\t\tfor (const { group } of this.#cache) group.close(abort);\n\t\tfor (const sink of this.#sinks) {\n\t\t\tfor (const group of sink.groups.peek()) group.close(abort);\n\t\t\tcloseTrackState(sink, abort);\n\t\t}\n\t\tthis.#sinks.clear();\n\t}\n\n\t/** Append a frame as its own single-frame group. */\n\twriteFrame(frame: Frame) {\n\t\tconst group = this.appendGroup();\n\t\tgroup.writeFrame(frame);\n\t\tgroup.close();\n\t}\n\n\t/** Appends a string to the track as its own single-frame group. */\n\twriteString(str: string) {\n\t\tconst group = this.appendGroup();\n\t\tgroup.writeString(str);\n\t\tgroup.close();\n\t}\n\n\t/** Appends a JSON value to the track as its own single-frame group. */\n\twriteJson(json: unknown) {\n\t\tconst group = this.appendGroup();\n\t\tgroup.writeJson(json);\n\t\tgroup.close();\n\t}\n\n\t/** Appends a boolean to the track as its own single-frame group. */\n\twriteBool(bool: boolean) {\n\t\tconst group = this.appendGroup();\n\t\tgroup.writeBool(bool);\n\t\tgroup.close();\n\t}\n}\n\n/**\n * The read side of a live track subscription, mirroring the Rust `Subscriber`.\n *\n * Obtained from `Broadcast.Consumer.subscribe` / `Track.Consumer.subscribe`, or from\n * {@link Producer.subscribe} for an in-process track. Reads the groups a\n * {@link Producer} on the same underlying state writes.\n */\nexport class Subscriber {\n\t/** The track name. */\n\treadonly name: string;\n\n\t#state: TrackState;\n\t#nextSequence = 0;\n\t#cursor = new Signal<{ start: number; end?: number }>({ start: 0 });\n\n\tprivate constructor(name: string, state: TrackState) {\n\t\tthis.name = name;\n\t\tthis.#state = state;\n\t}\n\n\tstatic {\n\t\tmakeSubscriber = (name, state) => new Subscriber(name, state);\n\t}\n\n\t/**\n\t * Resolve this track's immutable publisher properties.\n\t *\n\t * Resolves once the wire layer commits the TRACK_INFO it received (lite-05+) or\n\t * defaults (older drafts), so awaiting it never yields a placeholder. Rejects if\n\t * the track is closed before the properties are known (e.g. a rejected subscription).\n\t */\n\tinfo(): Promise<Info> {\n\t\treturn resolveInfo(this.#state);\n\t}\n\n\t/** Settles once the track closes; see {@link Producer.closed}. */\n\tget closed(): GetPromise<Error | null> {\n\t\treturn this.#state.closed;\n\t}\n\n\t/** This subscriber's current options, including defaults and the last {@link update}. */\n\tget subscription(): Getter<Subscription | undefined> {\n\t\treturn this.#state.update;\n\t}\n\n\t/** Return the latest group sequence observed on this track, if any. */\n\tlatest(): number | undefined {\n\t\treturn this.#state.latest;\n\t}\n\n\t/**\n\t * The newest frame this track has produced, or `undefined` while it has none.\n\t *\n\t * Read from the groups buffered for this subscriber, so nothing is consumed. A newest\n\t * group that has no frames yet falls back to the newest older group that does. It\n\t * reads as `undefined` once the newest group has been evicted or received: what is\n\t * left can no longer say where the edge is.\n\t */\n\tlargest(): Location | undefined {\n\t\tconst latest = this.#state.latest;\n\t\tif (latest === undefined) return undefined;\n\n\t\tconst groups = this.#state.groups.peek();\n\t\tconst newest = groups[groups.length - 1];\n\t\tif (!newest || newest.sequence !== latest) return undefined;\n\n\t\tfor (let i = groups.length - 1; i >= 0; i--) {\n\t\t\tconst count = groups[i].frameCount;\n\t\t\tif (count > 0) return { group: groups[i].sequence, frame: count - 1 };\n\t\t}\n\t\treturn undefined;\n\t}\n\n\t/**\n\t * An independent subscriber to the same track, with its own cursor and its own replay of\n\t * the retained window.\n\t *\n\t * Reads here do not consume anything this one would deliver, which is what lets a\n\t * publisher read the cache alongside the cursor it is serving from. Resolving the track\n\t * again through the broadcast would not do: a dynamic serve is one request per peer\n\t * subscription, so that mints a second producer the application has to answer separately.\n\t *\n\t * @internal Wire layers only.\n\t */\n\tfork(options?: Subscription): Subscriber {\n\t\tconst producer = this.#state.producer;\n\t\tif (!producer) throw new Error(\"track has no producer to fork from\");\n\t\treturn producer.subscribe(options);\n\t}\n\n\t/** Start this subscriber's local read cursor at `sequence`, without changing its wire request. */\n\tstartAt(sequence: number): void {\n\t\tthis.#cursor.update((cursor) => ({ ...cursor, start: sequence }));\n\t}\n\n\t/**\n\t * Cap {@link nextGroup} and {@link recvGroup} at `sequence` inclusively, or omit it to\n\t * remove the cap. Groups above the cap remain buffered and become readable if the cap\n\t * is raised. This local cursor does not change the subscription's wire request.\n\t */\n\tendAt(sequence?: number): void {\n\t\tthis.#cursor.update((cursor) => ({ ...cursor, end: sequence }));\n\t}\n\n\t/** Close the track (optionally with an error), closing any pending groups. Idempotent. */\n\tclose(abort?: Error) {\n\t\t// Settle if we're first (the producer may already have); either way drop anything\n\t\t// still buffered. Groups parked at the endAt cap deliberately outlive a clean\n\t\t// producer close, so the subscriber leaving is what must release them: closing\n\t\t// and clearing wakes a pending read to observe the end instead of hanging.\n\t\tcloseTrackState(this.#state, abort);\n\t\tthis.#state.groups.mutate((groups) => {\n\t\t\tfor (const group of groups) group.close(abort);\n\t\t\tgroups.length = 0;\n\t\t});\n\t}\n\n\t/**\n\t * Receive every group on this track exactly once, as it becomes available.\n\t *\n\t * Groups may arrive out of order or with gaps due to network conditions; unlike\n\t * {@link nextGroup}, one that arrives after a newer group was already returned is\n\t * still delivered. When several groups are buffered, the lowest sequence is\n\t * returned first.\n\t *\n\t * Honors the floor set by {@link startAt} and the cap set by {@link endAt}: a group\n\t * beyond the cap stays buffered (not dropped) and is offered once the cap rises, even\n\t * after a clean close, without blocking in-range groups that arrive behind it.\n\t */\n\tasync recvGroup(): Promise<GroupConsumer | undefined> {\n\t\tfor (;;) {\n\t\t\tconst group = this.tryRecvGroup();\n\t\t\tif (group) return group;\n\n\t\t\tconst closed = this.#state.closed.peek();\n\t\t\tif (closed instanceof Error) throw closed;\n\t\t\t// A group beyond the cap outlives a clean close: it becomes deliverable if\n\t\t\t// the cap rises, so the track isn't over while any are held.\n\t\t\tif (closed !== undefined && !this.#state.groups.peek()[0]) return undefined;\n\n\t\t\tawait Signal.race(this.#state.groups, this.#cursor, this.#state.closed);\n\t\t}\n\t}\n\n\t/**\n\t * Take the next buffered group without blocking, honoring the same cursor bounds as\n\t * {@link recvGroup}.\n\t *\n\t * Returns `undefined` when nothing is deliverable right now, which is not by itself the\n\t * end of the track: a group may still arrive, or one may be parked beyond the\n\t * {@link endAt} cap. Use it to drain what the retained window already holds, where\n\t * waiting for a sequence nothing will republish would park forever.\n\t */\n\ttryRecvGroup(): GroupConsumer | undefined {\n\t\tconst groups = this.#state.groups.peek();\n\t\tconst { start, end } = this.#cursor.peek();\n\t\twhile (groups.length > 0 && groups[0].sequence < start) groups.shift()?.close();\n\n\t\t// The buffer is sequence-sorted, so an in-range group that arrives behind a\n\t\t// beyond-cap one sorts in front of it and is never blocked by it.\n\t\tconst group = groups[0];\n\t\tif (group && (end === undefined || group.sequence <= end)) {\n\t\t\tgroups.shift();\n\t\t\treturn group;\n\t\t}\n\n\t\treturn undefined;\n\t}\n\n\t/**\n\t * Receive the next datagram in arrival order.\n\t *\n\t * Datagrams are a separate best-effort channel from groups (see\n\t * {@link Producer.appendDatagram}); they share only the sequence namespace. A consumer\n\t * that falls too far behind silently loses the oldest datagrams. Read this alongside\n\t * {@link recvGroup} (e.g. in a separate loop) to receive both channels concurrently. Returning\n\t * a datagram advances {@link nextGroup} past that sequence.\n\t */\n\tasync recvDatagram(): Promise<Datagram | undefined> {\n\t\tfor (;;) {\n\t\t\tconst datagrams = this.#state.datagrams.peek();\n\n\t\t\t// Evict datagrams older than the send-buffer window (also enforced on write), so a\n\t\t\t// reader that stalled skips stale datagrams instead of replaying them.\n\t\t\tconst cutoff = performance.now() - MAX_DATAGRAM_AGE_MS;\n\t\t\twhile (datagrams.length > 0 && datagrams[0].time < cutoff) datagrams.shift();\n\n\t\t\tif (datagrams.length > 0) {\n\t\t\t\tconst datagram = datagrams.shift()?.datagram;\n\t\t\t\tif (datagram) {\n\t\t\t\t\tthis.#nextSequence = Math.max(this.#nextSequence, datagram.sequence + 1);\n\t\t\t\t}\n\t\t\t\treturn datagram;\n\t\t\t}\n\n\t\t\tconst closed = this.#state.closed.peek();\n\t\t\tif (closed instanceof Error) throw closed;\n\t\t\tif (closed !== undefined) return undefined;\n\n\t\t\tawait Signal.race(this.#state.datagrams, this.#state.closed);\n\t\t}\n\t}\n\n\t/**\n\t * Return the next group with a strictly-greater sequence number than the last returned.\n\t *\n\t * Late arrivals (sequence at or below the last returned) are silently skipped.\n\t * Use {@link recvGroup} to see every group in arrival order instead.\n\t */\n\tasync nextGroup(): Promise<GroupConsumer | undefined> {\n\t\tfor (;;) {\n\t\t\tconst groups = this.#state.groups.peek();\n\t\t\tconst cursor = this.#cursor.peek();\n\t\t\tconst start = Math.max(cursor.start, this.#nextSequence);\n\t\t\twhile (groups.length > 0 && groups[0].sequence < start) groups.shift()?.close();\n\n\t\t\tconst group = groups[0];\n\t\t\tif (group && (cursor.end === undefined || group.sequence <= cursor.end)) {\n\t\t\t\tgroups.shift();\n\t\t\t\tthis.#nextSequence = group.sequence + 1;\n\t\t\t\treturn group;\n\t\t\t}\n\n\t\t\tconst closed = this.#state.closed.peek();\n\t\t\tif (closed instanceof Error) throw closed;\n\t\t\tif (closed !== undefined && !group) return undefined;\n\n\t\t\tawait Signal.race(this.#state.groups, this.#cursor, this.#state.closed);\n\t\t}\n\t}\n\n\t/**\n\t * Reads the next frame across all groups, discarding older groups.\n\t * Treat the returned frame bytes as read-only; they are shared with other consumers.\n\t */\n\tasync readFrame(): Promise<Frame | undefined> {\n\t\tconst next = await this.readFrameSequence();\n\t\treturn next ? { payload: next.payload, timestamp: next.timestamp } : undefined;\n\t}\n\n\t/**\n\t * Reads the next frame along with its group and frame sequence numbers.\n\t * Treat the returned frame bytes as read-only; they are shared with other consumers.\n\t */\n\tasync readFrameSequence(): Promise<({ group: number; frame: number } & Frame) | undefined> {\n\t\tfor (;;) {\n\t\t\tconst groups = this.#state.groups.peek();\n\t\t\tconst { start } = this.#cursor.peek();\n\t\t\twhile (groups.length > 0 && groups[0].sequence < start) groups.shift()?.close();\n\n\t\t\t// Drain older groups first, dropping each once empty.\n\t\t\twhile (groups.length > 1) {\n\t\t\t\tif (groups[0].skipped) {\n\t\t\t\t\t// The reader fell behind this group's eviction window. Drop it and\n\t\t\t\t\t// signal the gap; the next read resyncs from the following group.\n\t\t\t\t\tgroups.shift()?.close();\n\t\t\t\t\tthrow new Lagged();\n\t\t\t\t}\n\t\t\t\tconst next = groups[0].tryReadFrameSequence();\n\t\t\t\tif (next) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tgroup: groups[0].sequence,\n\t\t\t\t\t\tframe: next.sequence,\n\t\t\t\t\t\tpayload: next.payload,\n\t\t\t\t\t\ttimestamp: next.timestamp,\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t\tgroups.shift()?.close();\n\t\t\t}\n\n\t\t\tif (groups.length === 0) {\n\t\t\t\tconst closed = this.#state.closed.peek();\n\t\t\t\tif (closed instanceof Error) throw closed;\n\t\t\t\tif (closed !== undefined) return undefined;\n\t\t\t\tawait Signal.race(this.#state.groups, this.#cursor, this.#state.closed);\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tconst group = groups[0];\n\t\t\tif (group.skipped) {\n\t\t\t\t// Fell behind this group's eviction window. Drop it and signal the gap;\n\t\t\t\t// the next read resyncs from the following group.\n\t\t\t\tgroups.shift()?.close();\n\t\t\t\tthrow new Lagged();\n\t\t\t}\n\t\t\tconst next = group.tryReadFrameSequence();\n\t\t\tif (next)\n\t\t\t\treturn {\n\t\t\t\t\tgroup: group.sequence,\n\t\t\t\t\tframe: next.sequence,\n\t\t\t\t\tpayload: next.payload,\n\t\t\t\t\ttimestamp: next.timestamp,\n\t\t\t\t};\n\n\t\t\tconst closed = this.#state.closed.peek();\n\t\t\tif (closed instanceof Error) throw closed;\n\t\t\tif (closed !== undefined) return undefined;\n\n\t\t\t// A finished (drained + closed) group has nothing left: drop it and loop, rather than\n\t\t\t// busy-waiting on its already-resolved readable() (which would livelock and starve the\n\t\t\t// macrotask that delivers the next group).\n\t\t\tif (group.done) {\n\t\t\t\tgroups.shift()?.close();\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// Lone open group with nothing buffered yet: wait for a frame on it, a new group, or\n\t\t\t// the track closing.\n\t\t\tawait Promise.race([Signal.race(this.#state.groups, this.#cursor, this.#state.closed), group.readable()]);\n\t\t}\n\t}\n\n\t/** Reads the next frame and decodes it as a UTF-8 string. */\n\tasync readString(): Promise<string | undefined> {\n\t\tconst next = await this.readFrame();\n\t\tif (!next) return undefined;\n\t\treturn new TextDecoder().decode(next.payload);\n\t}\n\n\t/** Reads the next frame and parses it as JSON. */\n\tasync readJson(): Promise<unknown | undefined> {\n\t\tconst next = await this.readString();\n\t\tif (!next) return undefined;\n\t\treturn JSON.parse(next);\n\t}\n\n\t/** Reads the next frame and decodes it as a one-byte boolean, throwing on a malformed frame. */\n\tasync readBool(): Promise<boolean | undefined> {\n\t\tconst next = await this.readFrame();\n\t\tif (!next) return undefined;\n\t\tconst payload = next.payload;\n\t\tif (payload.byteLength !== 1 || !(payload[0] === 0 || payload[0] === 1)) throw new Error(\"invalid bool frame\");\n\t\treturn payload[0] === 1;\n\t}\n\n\t/**\n\t * Update this subscription's options (e.g. priority), triggering a SUBSCRIBE_UPDATE to the\n\t * publisher. Mirrors the Rust `Subscriber::update`.\n\t */\n\tupdate(options: Subscription) {\n\t\tthis.#state.update.set(subscriptionDefaults(options));\n\t}\n}\n"]}
1
+ {"version":3,"file":"track.js","sourceRoot":"","sources":["../src/track.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Track role handles: a live stream of groups (and best-effort datagrams) within a broadcast.\n *\n * @module\n */\nimport { type Dispose, type GetPromise, type Getter, Once, Signal } from \"@moq/signals\";\nimport type { Datagram } from \"./datagram.ts\";\nimport { GroupTooLarge, TooFarBehind } from \"./error.ts\";\nimport { type Frame, type Consumer as GroupConsumer, Producer as GroupProducer } from \"./group.ts\";\nimport {\n\tgroupBounds,\n\thooks,\n\ttype Recv,\n\ttype TrackRequestOptions,\n\ttype TrackSequence,\n\ttype TrackSequences,\n} from \"./internal.ts\";\nimport { Milli, Timescale, type Timestamp } from \"./time.ts\";\nimport { type Broadcast as BroadcastWire, registerTrackConsumer } from \"./wire.ts\";\n\nexport type { Datagram } from \"./datagram.ts\";\n\n// The largest delay setTimeout keeps: anything more truncates to a signed 32-bit int\n// and fires right away.\nconst MAX_TIMEOUT_MS = 2 ** 31 - 1;\n\n// The cache scans at most this many times per retention window.\nconst PRUNE_SLICES = 8;\n\n/** Default {@link Info.maxAge} window (milliseconds) when the publisher does not set one. */\nexport const DEFAULT_MAX_AGE_MS = Milli(5000);\n\n// The higher-first midpoint. IETF flips priority (lower first), so this goes out as 128, the\n// draft's usual publisher priority, while moq-lite carries 127 as written: one urgency on both.\nconst DEFAULT_PRIORITY = 127;\n\n/** Maximum buffered datagrams per subscriber; mirrors Rust's bounded send buffer. */\nconst MAX_DATAGRAMS = 64;\n\n/**\n * Sanity cap on a datagram payload: the QUIC DATAGRAM frame ceiling. The real limit is\n * per-hop (the negotiated transport datagram size minus a small header) and oversize\n * datagrams are dropped there; a payload above this cap could never fit anywhere.\n */\nconst MAX_DATAGRAM_BYTES = 65535;\n\n/** A position within a track: a group's sequence and a frame's index inside it. */\nexport interface Location {\n\t/** The group's sequence number within the track. */\n\tgroup: number;\n\t/** The frame's index within that group. */\n\tframe: number;\n}\n\n/**\n * A track's immutable publisher properties, fixed for the lifetime of the track.\n *\n * A producer declares these once (via {@link Request.accept} or\n * {@link Producer.accept}); a consumer awaits them via {@link Subscriber.info}\n * (resolved from the wire TRACK_INFO on lite-05+). They map 1:1 onto TRACK_INFO.\n */\nexport interface Info {\n\t/**\n\t * Units per second for this track's frame timestamps (reported in TRACK_INFO on\n\t * Lite05+). Defaults to milliseconds; set it finer (e.g. {@link Timescale.MICRO})\n\t * for media that needs sub-millisecond timing.\n\t */\n\ttimescale: Timescale;\n\t/**\n\t * Publisher Max Age: the maximum age (milliseconds) of a non-latest group before\n\t * the publisher evicts it. Reported in TRACK_INFO (Lite05+) so relays re-serve with the\n\t * same bound. The publisher-side half of the budget a subscriber sets for itself.\n\t * Rounded up to a whole millisecond by {@link infoDefaults}, which refuses a negative\n\t * or non-finite value and a result past `Number.MAX_SAFE_INTEGER`.\n\t */\n\tmaxAge: Milli;\n\t/** Tie-break priority between subscriptions of equal subscriber priority (`0..=255`, higher first). Defaults to `127`. */\n\tpriority: number;\n}\n\n// Normalize a latency budget for the wire, which carries it as an unsigned varint.\n//\n// Callers derive it from measurements (a jitter estimate scaled off RTT), so a fractional\n// millisecond is expected; ceil rather than round, because a budget shortened by rounding\n// skips a group the subscriber still wants. Anything that is not a duration is refused\n// here, where the field is named, rather than deep in the encoder.\nfunction maxAgeMillis(value: Milli): Milli {\n\tif (!Number.isFinite(value) || value < 0) {\n\t\tthrow new RangeError(`maxAge must be a non-negative number of milliseconds: ${value}`);\n\t}\n\tconst millis = Math.ceil(value);\n\tif (!Number.isSafeInteger(millis)) {\n\t\tthrow new RangeError(`maxAge exceeds the safe integer millisecond range: ${value}`);\n\t}\n\treturn Milli(millis);\n}\n\nfunction priorityByte(value: number): number {\n\tif (!Number.isInteger(value) || value < 0 || value > 255) {\n\t\tthrow new RangeError(`priority must be an integer in 0..=255: ${value}`);\n\t}\n\treturn value;\n}\n\n/** Fill in any unset {@link Info} fields with their defaults. */\nexport function infoDefaults(info: Partial<Info> = {}): Info {\n\treturn {\n\t\ttimescale: Timescale(info.timescale ?? Timescale.MILLI),\n\t\tmaxAge: maxAgeMillis(info.maxAge ?? DEFAULT_MAX_AGE_MS),\n\t\tpriority: priorityByte(info.priority ?? DEFAULT_PRIORITY),\n\t};\n}\n\n/** An explicitly included or excluded group sequence. */\nexport type Bound = { included: number; excluded?: never } | { excluded: number; included?: never };\n\n/** Group limits; an omitted endpoint is unbounded. */\nexport interface Groups {\n\t/** The first group boundary. */\n\tstart?: Bound;\n\t/** The last group boundary. */\n\tend?: Bound;\n}\n\n/**\n * Per-subscription options, requested when a subscription opens and adjustable later via\n * {@link Subscriber.update}. Mirrors the Rust `Subscription`.\n */\nexport interface Subscription {\n\t/** Delivery priority relative to this session's other subscriptions (`0..=255`). Defaults to `0`. */\n\tpriority?: number;\n\t/**\n\t * Maximum age (milliseconds) of a non-latest group before it is skipped. Defaults to `0`.\n\t * Rounded up to a whole millisecond, so a value derived from a measurement is never\n\t * shortened. A negative or non-finite value, or one past `Number.MAX_SAFE_INTEGER`\n\t * after rounding, is refused.\n\t */\n\tmaxAge?: Milli;\n\t/**\n\t * The lowest group the publisher may deliver (a floor), or omit for none.\n\t *\n\t * A floor, not a request: only {@link maxAge} asks for data, and the floor bounds how\n\t * far back it may reach. Omitting it and a floor of 0 mean the same thing, and a floor\n\t * above the live edge simply waits there (a resumed subscription naming where it left\n\t * off).\n\t */\n\tgroups?: Groups;\n}\n\n// Materialize the defaults at the model boundary so every layer observes a complete\n// subscription rather than interpreting an omitted field differently.\nfunction subscriptionDefaults(subscription: Subscription = {}): Subscription {\n\tconst bounds = groupBounds(subscription.groups ?? {});\n\treturn {\n\t\tpriority: priorityByte(subscription.priority ?? 0),\n\t\tmaxAge: maxAgeMillis(subscription.maxAge ?? Milli.zero),\n\t\tgroups: {\n\t\t\tstart: subscription.groups?.start === undefined ? undefined : { included: bounds.start },\n\t\t\tend: bounds.end === undefined ? undefined : { excluded: bounds.end },\n\t\t},\n\t};\n}\n\n// Aggregate the preferences of every live subscriber, matching Rust's Subscription::poll_combined.\nfunction combineSubscriptions(states: Iterable<TrackState>): Subscription | undefined {\n\tlet combined: Subscription | undefined;\n\tfor (const state of states) {\n\t\tconst subscription = state.update.peek();\n\t\tif (!subscription) continue;\n\t\tif (!combined) {\n\t\t\tcombined = { ...subscription };\n\t\t\tcontinue;\n\t\t}\n\n\t\tcombined.priority = Math.max(combined.priority ?? 0, subscription.priority ?? 0);\n\t\tcombined.maxAge = Milli(Math.max(combined.maxAge ?? Milli.zero, subscription.maxAge ?? Milli.zero));\n\n\t\t// A floor only restricts, so a subscriber without one clears the aggregate:\n\t\t// its budget may reach below any floor the others set.\n\t\tconst a = groupBounds(combined.groups ?? {});\n\t\tconst b = groupBounds(subscription.groups ?? {});\n\t\tcombined.groups = {\n\t\t\tstart:\n\t\t\t\tcombined.groups?.start === undefined || subscription.groups?.start === undefined\n\t\t\t\t\t? undefined\n\t\t\t\t\t: { included: Math.min(a.start, b.start) },\n\t\t\tend: a.end === undefined || b.end === undefined ? undefined : { excluded: Math.max(a.end, b.end) },\n\t\t};\n\t}\n\treturn combined;\n}\n\n/**\n * A request for a track the peer wants, delivered to the publishing wire layer.\n *\n * Created internally by the broadcast when a subscription (or info lookup) needs a track\n * served; answer it with {@link accept} or {@link reject}.\n *\n * @public\n */\nexport class Request {\n\t/** The requested track name. */\n\treadonly name: string;\n\n\t#producer: Producer;\n\t#sequences: TrackSequences;\n\t#pending: Set<Request>;\n\n\tprivate constructor(options: TrackRequestOptions) {\n\t\tthis.name = options.name;\n\t\tthis.#producer = options.producer;\n\t\tthis.#sequences = options.sequences;\n\t\tthis.#pending = options.pending;\n\t\tthis.#pending.add(this);\n\t}\n\n\tstatic {\n\t\thooks.makeRequest = (options) => new Request(options);\n\t\thooks.pendingTrackProducer = (request) => request.#producer;\n\t}\n\n\t/** The aggregate subscription requested for this track. */\n\tget subscription(): Readonly<Subscription> {\n\t\treturn this.#producer.subscription.peek() ?? subscriptionDefaults();\n\t}\n\n\t/** The subscriber's priority for this track. */\n\tget priority(): number {\n\t\treturn this.subscription.priority ?? 0;\n\t}\n\n\t/** Accept the request, committing the track's immutable {@link Info}. */\n\taccept(info: Partial<Info> = {}): Producer {\n\t\tthis.#pending.delete(this);\n\t\tbindProducer(this.name, this.#producer, this.#sequences);\n\t\treturn this.#producer.accept(info);\n\t}\n\n\t/** Reject the request, closing the track optionally with an error. */\n\treject(err?: Error): void {\n\t\tthis.#pending.delete(this);\n\t\tthis.#producer.close(err);\n\t}\n}\n\n/** Options for {@link Consumer.fetchGroup}. */\nexport interface FetchGroupOptions {\n\t/** Delivery priority for the fetch stream. Defaults to `0`. */\n\tpriority?: number;\n\n\t/**\n\t * Abandons this fetch, rejecting with the signal's reason. Concurrent fetches of the same\n\t * group share one stream, cancelled only once every caller has left. An already-aborted\n\t * signal rejects before anything is sent, and aborting after the group resolves has no\n\t * effect; close the group instead.\n\t */\n\tsignal?: AbortSignal;\n}\n\n/**\n * A lazy handle to a track on a consumed broadcast.\n *\n * @public\n */\nexport class Consumer {\n\t/** The track name. */\n\treadonly name: string;\n\n\t#broadcast: BroadcastWire;\n\n\tprivate constructor(name: string, broadcast: BroadcastWire) {\n\t\tthis.name = name;\n\t\tthis.#broadcast = broadcast;\n\t}\n\n\tstatic {\n\t\tregisterTrackConsumer((name, broadcast) => new Consumer(name, broadcast));\n\t}\n\n\t/**\n\t * Open a live subscription to the track.\n\t *\n\t * The cursor starts at the group the subscription named (its floor), or 0.\n\t * {@link Subscription.maxAge} is what asks for data: delivery skips everything above\n\t * the floor that the budget convicts, so the default budget of zero delivers only the\n\t * latest group and a larger one reaches back over what it can still use.\n\t */\n\tsubscribe(options?: Subscription): Subscriber {\n\t\treturn this.#broadcast.subscribe(this.name, options);\n\t}\n\n\t/** Fetch the track's immutable publisher properties without subscribing. */\n\tinfo(): Promise<Info> {\n\t\treturn this.#broadcast.resolveTrackInfo(this.name);\n\t}\n\n\t/** Fetch a single group by sequence without holding a live subscription. */\n\tfetchGroup(sequence: number, options?: FetchGroupOptions): Promise<GroupConsumer> {\n\t\treturn this.#broadcast.fetchGroup(this.name, sequence, options);\n\t}\n}\n\n// The index of the first timeline group at or after `sequence`.\nfunction timelineIndex(timeline: GroupConsumer[], sequence: number): number {\n\tlet lo = 0;\n\tlet hi = timeline.length;\n\twhile (lo < hi) {\n\t\tconst mid = (lo + hi) >>> 1;\n\t\tif (timeline[mid].sequence < sequence) lo = mid + 1;\n\t\telse hi = mid;\n\t}\n\treturn lo;\n}\n\n// Add a group to a sorted timeline, replacing any group with the same sequence. Groups\n// usually arrive in order, so the append is checked first.\nfunction timelineInsert(timeline: GroupConsumer[], group: GroupConsumer): void {\n\tconst last = timeline.at(-1);\n\tif (!last || last.sequence < group.sequence) {\n\t\ttimeline.push(group);\n\t\treturn;\n\t}\n\tconst index = timelineIndex(timeline, group.sequence);\n\tif (timeline[index]?.sequence === group.sequence) timeline[index] = group;\n\telse timeline.splice(index, 0, group);\n}\n\n// The shared state behind a Producer / Subscriber pair. Package-internal\n// wiring, unexported so it never appears in the published type declarations.\nclass TrackState {\n\t/** The producer fanning into this sink, so a subscriber can mint a sibling of itself. */\n\tproducer?: Producer;\n\tgroups = new Signal<GroupConsumer[]>([]);\n\t// Every group still in the producer's replay cache, including groups this\n\t// subscriber already consumed, sorted by sequence. Drift anchors have the same\n\t// lifetime as content. Sorted so the latency guard, evaluated per group and per\n\t// arrival, searches it instead of scanning the whole retained window.\n\ttimeline: GroupConsumer[] = [];\n\t// First timestamps mutate group state rather than track state, so held groups\n\t// watch this revision as well as arrivals when enforcing latency after handoff.\n\ttimelineChanged = new Signal(0);\n\t/** Best-effort datagram channel, parallel to {@link groups}; a bounded send buffer per subscriber. */\n\tdatagrams = new Signal<Datagram[]>([]);\n\tlatest?: number;\n\t/**\n\t * The exclusive final boundary, declared by {@link Producer.finishAt} or stamped by a\n\t * clean close as one past the highest sequence produced. Groups and datagrams share the\n\t * namespace, so this can exceed `latest + 1` (which only tracks groups). Mirrors the\n\t * Rust `final_sequence`.\n\t */\n\tfinal = new Signal<number | undefined>(undefined);\n\tclosed = new Once<Error | null>();\n\tupdate: Signal<Subscription | undefined>;\n\t/** Resolved once the producer commits the immutable properties. */\n\tinfo = new Signal<Info | undefined>(undefined);\n\n\tconstructor(subscription?: Subscription) {\n\t\tthis.update = new Signal(subscription === undefined ? undefined : subscriptionDefaults(subscription));\n\t}\n}\n\n// Settle a track state's closed Once. Idempotent: Once.set throws on a second settle, and a\n// Producer closing its sinks races the Subscriber closing itself (the sink is only removed from\n// #sinks a microtask later, via the closed subscription below).\nfunction closeTrackState(state: TrackState, abort?: Error): boolean {\n\tif (state.closed.peek() !== undefined) return false;\n\tstate.closed.set(abort ?? null);\n\treturn true;\n}\n\n// Resolve the track's immutable publisher properties, or reject if it closes first.\n// On a producer this resolves once info is committed (at accept time); on a consumer\n// once the wire layer commits the TRACK_INFO it received (lite-05+) or defaults (older\n// drafts), so awaiting it never yields a placeholder.\nasync function resolveInfo(state: TrackState): Promise<Info> {\n\tfor (;;) {\n\t\tconst info = state.info.peek();\n\t\tif (info) return info;\n\n\t\tconst closed = state.closed.peek();\n\t\tif (closed instanceof Error) throw closed;\n\t\tif (closed !== undefined) throw new Error(\"track closed before info was known\");\n\n\t\tawait Signal.race(state.info, state.closed);\n\t}\n}\n\n// A source group retained in the producer cache, with the mirror handed to each sink\n// so eviction can drop them together.\ntype CachedGroup = { group: GroupProducer; mirrors: Map<TrackState, GroupConsumer> };\n\nfunction bindProducer(name: string, producer: Producer, sequences: TrackSequences): void {\n\tlet shared = sequences.get(name);\n\tif (!shared) {\n\t\tshared = { next: 0 };\n\t\tsequences.set(name, shared);\n\t}\n\tbindProducerSequence(producer, shared);\n}\n\nlet bindProducerSequence: (producer: Producer, sequence: TrackSequence) => void;\n\n// The sequence-order cursor lives inside `Subscriber` (it shares the group buffer and the\n// drift anchor with the arrival cursor), so `Ordered` reaches it through this bridge,\n// assigned in the class's static block.\nlet makeOrdered: (subscriber: Subscriber) => Ordered;\nlet ordered_: {\n\tnextGroup(subscriber: Subscriber): Promise<GroupConsumer | undefined>;\n\treadFrame(subscriber: Subscriber): Promise<({ group: number; frame: number } & Frame) | undefined>;\n\treadString(subscriber: Subscriber): Promise<string | undefined>;\n\treadJson(subscriber: Subscriber): Promise<unknown | undefined>;\n\treadBool(subscriber: Subscriber): Promise<boolean | undefined>;\n\trecvDatagram(subscriber: Subscriber): Promise<Datagram | undefined>;\n};\n\n// Constructs a Subscriber from within this module without exposing a public\n// constructor that would leak the unexported TrackState. Assigned in the class's\n// static block.\nlet makeSubscriber: (name: string, state: TrackState) => Subscriber;\n\n/**\n * The write side of a track, mirroring the Rust `Producer`.\n *\n * A producer is a fan-out source: every {@link subscribe} (including each wire\n * subscription the publisher serves from it) gets an independent\n * {@link Subscriber} that receives a full copy of the groups, each with its own\n * read cursor. Groups are mirrored into every live subscriber and retained for the\n * track's `maxAge` window so a late subscriber replays the recent groups.\n *\n * Obtained from {@link Request.accept} (the wire asks the application for a track to\n * serve) or constructed directly for an in-process track.\n */\nexport class Producer {\n\t/** The track name. */\n\treadonly name: string;\n\n\t// The producer's own state is the source of truth (info/closed); subscribers\n\t// read mirrored sinks, never this state directly.\n\t#state = new TrackState();\n\t#sequence: TrackSequence = { next: 0 };\n\t// One past the highest group or datagram this producer received, like the Rust\n\t// `max_sequence`. The shared counter above can run ahead of it: sibling producers of\n\t// the same track advance it too.\n\t#received = 0;\n\n\t// Recently written source groups, retained for replay to late subscribers and\n\t// pruned once idle for longer than the cache window. Each entry tracks the mirror\n\t// it handed to every sink so eviction can drop them too: otherwise a slow consumer\n\t// that never reads would pin old groups (and their frame bytes) forever.\n\t#cache: CachedGroup[] = [];\n\t// The same entries by sequence, so a write finds a duplicate without a scan.\n\t#cached = new Map<number, CachedGroup>();\n\t// When the cache was last scanned. See #prune.\n\t#pruned = Number.NEGATIVE_INFINITY;\n\n\t// Wakeup for the next entry due to age out. Writes settle retention inline, but a\n\t// publisher that stalls stops writing, so without this an abandoned group (and any\n\t// reader parked in it) would wait for a write that never comes.\n\t#pruneTimer?: ReturnType<typeof setTimeout>;\n\t#pruneTimerAt = 0;\n\n\t// One independent downstream state per live subscriber.\n\t#sinks = new Set<TrackState>();\n\n\t// Whether any subscriber is currently attached. Exposed as {@link used}; the consumer wire\n\t// watches it to tear down an idle upstream, and a publisher can watch it for on-demand capture.\n\t#used = new Signal<boolean>(false);\n\n\tconstructor(name: string) {\n\t\tthis.name = name;\n\t}\n\n\tstatic {\n\t\tbindProducerSequence = (producer, sequence) => {\n\t\t\tproducer.#sequence = sequence;\n\t\t};\n\t}\n\n\t/**\n\t * Resolve this track's immutable publisher properties, committed at accept time.\n\t * Rejects if the track is closed before the properties are known.\n\t */\n\tinfo(): Promise<Info> {\n\t\treturn resolveInfo(this.#state);\n\t}\n\n\t/**\n\t * Publisher priority from the committed {@link Info}, or the default before {@link accept}.\n\t *\n\t * Higher is served first. Hang publishers set this from `Catalog.PRIORITY` so\n\t * audio outranks video on the wire and in the bandwidth allocator.\n\t */\n\tget priority(): number {\n\t\treturn this.#state.info.peek()?.priority ?? DEFAULT_PRIORITY;\n\t}\n\n\t/**\n\t * Settles once the track closes: `null` on a clean close, or the abort {@link Error}.\n\t * Peek it synchronously (`undefined` while open), observe it reactively, or `await` it.\n\t */\n\tget closed(): GetPromise<Error | null> {\n\t\treturn this.#state.closed;\n\t}\n\n\t/**\n\t * The aggregate subscription across live subscribers, or `undefined` when there are none.\n\t * The wire layer watches this to emit SUBSCRIBE_UPDATE.\n\t */\n\tget subscription(): Getter<Subscription | undefined> {\n\t\treturn this.#state.update;\n\t}\n\n\t/** Commit the immutable publisher properties, resolving {@link info}. Returns `this`. */\n\taccept(info: Partial<Info> = {}): this {\n\t\tif (this.#state.closed.peek() !== undefined) return this;\n\t\tconst resolved = infoDefaults(info);\n\t\tthis.#state.info.set(resolved);\n\t\t// Propagate to any sink handed out before accept (the on-demand path).\n\t\tfor (const sink of this.#sinks) sink.info.set(resolved);\n\t\tthis.#updateSubscription();\n\t\treturn this;\n\t}\n\n\t/**\n\t * An independent {@link Subscriber} reading this track's groups.\n\t *\n\t * Its cursor starts at the group the subscription named (its floor), or 0.\n\t * {@link Subscription.maxAge} is what asks for data: delivery skips everything above\n\t * the floor that the budget convicts, so the default budget of zero delivers only the\n\t * latest group and a larger one reaches back over what it can still use.\n\t */\n\tsubscribe(options: Subscription = {}): Subscriber {\n\t\tconst sink = new TrackState(options);\n\t\tthis.#addSink(sink);\n\t\treturn makeSubscriber(this.name, sink);\n\t}\n\n\t/**\n\t * Whether the track currently has any subscribers.\n\t *\n\t * Watch it (`effect.get` / `.peek()`) to drive on-demand work: a publisher can start and stop\n\t * capture with demand, and the consumer wire watches it to tear an idle upstream subscription\n\t * down instead of downloading to nobody. Pairs with {@link unused}. Mirrors the Rust `Demand`.\n\t */\n\tget used(): Getter<boolean> {\n\t\treturn this.#used;\n\t}\n\n\t/** Resolves once the track has no subscribers (or has closed). Await it to react to demand ending. */\n\tasync unused(): Promise<void> {\n\t\twhile (this.#used.peek() && this.#state.closed.peek() === undefined) {\n\t\t\tawait Signal.race(this.#used, this.#state.closed);\n\t\t}\n\t}\n\n\t// Register a downstream sink: seed its info, replay the retained window, and (while\n\t// the track is open) mirror future groups into it. A late subscriber to a closed\n\t// track still drains the buffered groups before seeing the end.\n\t#addSink(sink: TrackState): void {\n\t\tsink.producer = this;\n\t\tconst info = this.#state.info.peek();\n\t\tif (info) sink.info.set(info);\n\n\t\tconst closed = this.#state.closed.peek();\n\t\tif (closed === undefined) {\n\t\t\tthis.#sinks.add(sink);\n\t\t\tthis.#used.set(true);\n\n\t\t\t// Forward subscription updates from the sink's Subscriber to the producer's own\n\t\t\t// state, which the wire layer (or the serving application) watches.\n\t\t\tconst forward = sink.update.subscribe(() => this.#updateSubscription());\n\t\t\tthis.#updateSubscription();\n\n\t\t\t// Drop the sink once its consumer goes away, closing its mirrors so source\n\t\t\t// groups stop teeing into them, so a long-lived producer doesn't leak. This\n\t\t\t// covers mirrors already handed out via recvGroup (no longer in sink.groups)\n\t\t\t// by closing them through the cache's per-sink tracking.\n\t\t\tconst dispose = sink.closed.subscribe((c) => {\n\t\t\t\tif (c === undefined) return;\n\t\t\t\tconst abort = c instanceof Error ? c : undefined;\n\t\t\t\tforward();\n\t\t\t\tthis.#sinks.delete(sink);\n\t\t\t\tthis.#updateSubscription();\n\t\t\t\t// Update demand: once the last subscriber leaves, the consumer wire (watching\n\t\t\t\t// {@link unused}) tears the upstream down instead of downloading to nobody.\n\t\t\t\tthis.#used.set(this.#sinks.size > 0);\n\t\t\t\t// The producer closing every sink keeps its mirrors tracked, so what the sink\n\t\t\t\t// still buffers ages out with the cache instead of staying pinned.\n\t\t\t\tif (this.#state.closed.peek() !== undefined) {\n\t\t\t\t\tdispose();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tfor (const entry of this.#cache) {\n\t\t\t\t\tconst mirror = entry.mirrors.get(sink);\n\t\t\t\t\tif (mirror) {\n\t\t\t\t\t\tmirror.close(abort);\n\t\t\t\t\t\tentry.mirrors.delete(sink);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tfor (const group of sink.groups.peek()) group.close(abort);\n\t\t\t\tdispose();\n\t\t\t});\n\t\t}\n\n\t\tthis.#prune();\n\t\tfor (const entry of this.#cache) this.#mirror(entry, sink);\n\n\t\tsink.final.set(this.#state.final.peek());\n\t\tif (closed !== undefined) closeTrackState(sink, closed instanceof Error ? closed : undefined);\n\t}\n\n\t// Recompute from every live sink because an update or close can narrow as well as widen\n\t// the aggregate. The wire layer observes this signal and emits SUBSCRIBE_UPDATE.\n\t#updateSubscription(): void {\n\t\tconst combined = combineSubscriptions(this.#sinks);\n\t\tconst retained = this.#state.info.peek()?.maxAge;\n\t\tif (combined && retained !== undefined) combined.maxAge = Milli.min(combined.maxAge ?? Milli.zero, retained);\n\t\tthis.#state.update.set(combined);\n\t}\n\n\t// Mirror a cached source group into a sink. The mirror fills synchronously as the\n\t// source is written and keeps its own read cursor; frame bytes are shared by\n\t// reference. Tracked on the entry so eviction can drop it from the sink.\n\t#mirror(entry: CachedGroup, sink: TrackState): void {\n\t\tconst dst = entry.group.mirror();\n\t\tentry.mirrors.set(sink, dst);\n\t\ttimelineInsert(sink.timeline, dst);\n\t\tvoid dst.readable().then(() => sink.timelineChanged.update((revision) => revision + 1));\n\t\tsink.latest = Math.max(sink.latest ?? 0, dst.sequence);\n\t\tsink.groups.mutate((groups) => {\n\t\t\tgroups.push(dst);\n\t\t\tgroups.sort((a, b) => a.sequence - b.sequence);\n\t\t});\n\t}\n\n\t// Drop a cached group's mirror from every sink so no consumer can pin it.\n\t#evict(entry: CachedGroup): void {\n\t\t// Reclaiming a group the publisher never closed ends it as the gap it is, before\n\t\t// the mirrors below would otherwise report a clean finish to a reader that had\n\t\t// drained it. The usual case, an already-closed group aging out, keeps its own\n\t\t// terminal state.\n\t\tif (!entry.group.isClosed) entry.group.close(new TooFarBehind());\n\t\tconst mirrors = [...entry.mirrors.values()];\n\t\tfor (const mirror of mirrors) hooks.evictGroup(mirror);\n\t\tthis.#unlink(entry);\n\t\tfor (const mirror of mirrors) mirror.close();\n\t}\n\n\t// Take a cached group's mirrors out of every sink, so a subscriber can no longer\n\t// receive them. A reader already holding one keeps it as is.\n\t#unlink(entry: CachedGroup): void {\n\t\tfor (const [sink, mirror] of entry.mirrors) {\n\t\t\tsink.groups.mutate((groups) => {\n\t\t\t\tconst i = groups.indexOf(mirror);\n\t\t\t\tif (i >= 0) groups.splice(i, 1);\n\t\t\t});\n\t\t\tconst index = timelineIndex(sink.timeline, mirror.sequence);\n\t\t\tif (sink.timeline[index] === mirror) sink.timeline.splice(index, 1);\n\t\t}\n\t\tentry.mirrors.clear();\n\t}\n\n\t// Take a cached group out of the cache lookups.\n\t#uncache(entry: CachedGroup): void {\n\t\tthis.#cache.splice(this.#cache.indexOf(entry), 1);\n\t\tthis.#cached.delete(entry.group.sequence);\n\t}\n\n\t// The one group retention never takes: the newest, while it is still open. That is\n\t// the live edge a publisher is appending to, and a track may legitimately keep it\n\t// open across a long quiet stretch (a catalog snapshot, a JSON stream). Every other\n\t// open group is an abandoned one, and ages out like a closed one.\n\t#liveEdge(): GroupProducer | undefined {\n\t\tconst latest = this.#cache.at(-1)?.group;\n\t\treturn latest?.closed.peek() === undefined ? latest : undefined;\n\t}\n\n\t// Evict cached groups idle for longer than the cache window. Idle means nothing\n\t// written, so an abandoned open group ages out instead of pinning its buffer (and\n\t// any reader parked in it) forever.\n\t//\n\t// Scans at most once per slice of the window, so a track publishing faster than that\n\t// evicts a run of groups per scan instead of scanning everything to evict one per\n\t// write. A group can outlive the window by up to one slice.\n\t#prune(): void {\n\t\tconst maxAgeMs = this.#state.info.peek()?.maxAge ?? DEFAULT_MAX_AGE_MS;\n\t\tconst now = performance.now();\n\t\tconst slice = maxAgeMs / PRUNE_SLICES;\n\t\tif (now < this.#pruned + slice) {\n\t\t\t// Something may have come due since the last scan, so make sure another follows.\n\t\t\tthis.#wake(this.#pruned + slice);\n\t\t\treturn;\n\t\t}\n\t\tthis.#pruned = now;\n\n\t\tconst cutoff = now - maxAgeMs;\n\t\tconst live = this.#liveEdge();\n\n\t\tlet oldest: number | undefined;\n\t\tconst retained: CachedGroup[] = [];\n\t\tfor (const entry of this.#cache) {\n\t\t\tif (entry.group === live) {\n\t\t\t\tretained.push(entry);\n\t\t\t} else if (entry.group.activity >= cutoff) {\n\t\t\t\tretained.push(entry);\n\t\t\t\tif (oldest === undefined || entry.group.activity < oldest) oldest = entry.group.activity;\n\t\t\t} else {\n\t\t\t\tthis.#cached.delete(entry.group.sequence);\n\t\t\t\tthis.#evict(entry);\n\t\t\t}\n\t\t}\n\t\tthis.#cache = retained;\n\n\t\t// Replace the wakeup with one for the next entry due to age out. Writes settle\n\t\t// retention inline, so this only has to cover the case no write follows. Cheap to\n\t\t// over-arm: an entry written since is retained and re-armed.\n\t\tclearTimeout(this.#pruneTimer);\n\t\tthis.#pruneTimer = undefined;\n\t\tif (oldest !== undefined) this.#wake(Math.max(oldest + maxAgeMs, now + slice));\n\t}\n\n\t// Arm the prune wakeup for `at`, unless one is already armed sooner. Kept after a close,\n\t// until the cache empties, so what the track left behind still ages out.\n\t#wake(at: number): void {\n\t\tif (this.#pruneTimer !== undefined && this.#pruneTimerAt <= at) return;\n\t\tclearTimeout(this.#pruneTimer);\n\n\t\t// setTimeout truncates its delay to a signed 32-bit int, so a longer window\n\t\t// would fire immediately and spin. Wake at the cap instead and re-arm: #prune\n\t\t// retains anything still fresh, so the extra wakeups are the only cost.\n\t\tconst delay = Math.min(MAX_TIMEOUT_MS, Math.max(0, at - performance.now()));\n\t\tconst timer = setTimeout(() => {\n\t\t\tthis.#pruneTimer = undefined;\n\t\t\tthis.#prune();\n\t\t}, delay);\n\t\t// A cache prune is never a reason to hold a Node/Bun process open.\n\t\t(timer as unknown as { unref?: () => void }).unref?.();\n\t\tthis.#pruneTimer = timer;\n\t\tthis.#pruneTimerAt = at;\n\t}\n\n\t// Retain a source group and fan it out to every live sink.\n\t#publish(group: GroupProducer): void {\n\t\tconst entry: CachedGroup = { group, mirrors: new Map<TrackState, GroupConsumer>() };\n\t\tthis.#cache.push(entry);\n\t\tthis.#cached.set(group.sequence, entry);\n\t\tthis.#received = Math.max(this.#received, group.sequence + 1);\n\t\tfor (const sink of this.#sinks) this.#mirror(entry, sink);\n\t\t// Give held mirrors the new live edge before pruning their timeline entry,\n\t\t// so their latency guard can preserve a terminal expiry verdict.\n\t\tthis.#prune();\n\t}\n\n\t// Refuse a write once the track is closed, or at or past its declared end.\n\t#writable(sequence: number): void {\n\t\tif (this.#state.closed.peek() !== undefined) throw new Error(\"track is closed\");\n\t\tconst final = this.#state.final.peek();\n\t\tif (final !== undefined && sequence >= final) {\n\t\t\tthrow new Error(`sequence ${sequence} is at or past the track's end ${final}`);\n\t\t}\n\t}\n\n\t/** Append a new group with the next sequence number. */\n\tappendGroup(): GroupProducer {\n\t\tconst sequence = this.#sequence;\n\t\tthis.#writable(sequence.next);\n\t\tconst group = new GroupProducer(sequence.next);\n\t\tsequence.next = group.sequence + 1;\n\t\tthis.#publish(group);\n\n\t\treturn group;\n\t}\n\n\t/**\n\t * Insert an existing group into the track.\n\t *\n\t * Throws on a sequence that is still cached: a live duplicate would fan out to every\n\t * subscriber twice. An aborted incarnation is evicted so a fresh group can serve the\n\t * sequence again. Best effort (mirrors Rust): nothing remembers a sequence whose cache\n\t * entry is already gone, so a long-evicted sequence is accepted as new.\n\t */\n\twriteGroup(group: GroupProducer) {\n\t\tthis.#writable(group.sequence);\n\n\t\tconst existing = this.#cached.get(group.sequence);\n\t\tif (existing) {\n\t\t\tif (!(existing.group.closed.peek() instanceof Error)) {\n\t\t\t\tthrow new Error(`duplicate group: sequence=${group.sequence}`);\n\t\t\t}\n\t\t\tthis.#evict(existing);\n\t\t\tthis.#uncache(existing);\n\t\t}\n\n\t\t// Only advance the shared counter upward (for appendGroup auto-increment).\n\t\tconst sequence = this.#sequence;\n\t\tif (group.sequence >= sequence.next) {\n\t\t\tsequence.next = group.sequence + 1;\n\t\t}\n\n\t\tthis.#publish(group);\n\t}\n\n\t// Fan a datagram out to every live subscriber, dropping the oldest once the ring is full.\n\t// Late subscribers do NOT replay old datagrams (best-effort, unlike the group cache).\n\t#publishDatagram(datagram: Datagram): void {\n\t\tthis.#received = Math.max(this.#received, datagram.sequence + 1);\n\t\tfor (const sink of this.#sinks) {\n\t\t\tsink.datagrams.mutate((list) => {\n\t\t\t\tif (list.length === MAX_DATAGRAMS) list.shift();\n\t\t\t\tlist.push(datagram);\n\t\t\t});\n\t\t}\n\t}\n\n\t/**\n\t * Append a datagram with the next sequence number, returning the assigned sequence.\n\t *\n\t * A datagram is delivered best-effort over a single QUIC datagram, parallel to the track's\n\t * groups but drawing from the same sequence namespace (interleaving with {@link appendGroup}\n\t * never reuses a number). The payload must fit the negotiated transport datagram size minus\n\t * a small header; an oversize payload is dropped at each hop (there is no group fallback), so\n\t * keep datagram payloads small (e.g. a single audio frame). Datagrams are never delivered\n\t * over IETF moq-transport or stream-only transports (the WebSocket fallback). A payload over\n\t * 65535 bytes (the QUIC datagram frame ceiling) throws. An origin publisher uses this; a\n\t * relay preserving upstream numbering uses {@link insertDatagram}.\n\t */\n\tappendDatagram(timestamp: Timestamp, payload: Uint8Array): number {\n\t\tconst counter = this.#sequence;\n\t\tconst sequence = counter.next;\n\t\tthis.#writable(sequence);\n\t\tif (payload.byteLength > MAX_DATAGRAM_BYTES) throw new Error(\"datagram payload too large\");\n\n\t\tcounter.next = sequence + 1;\n\t\tthis.#publishDatagram({ sequence, timestamp, payload });\n\t\treturn sequence;\n\t}\n\n\t/**\n\t * Insert a datagram with an explicit sequence number.\n\t *\n\t * Preserves the supplied sequence (advancing the shared counter if needed) so a relay can\n\t * forward a datagram without renumbering it. The size limits of {@link appendDatagram}\n\t * apply. Most origin publishers want {@link appendDatagram} instead.\n\t */\n\tinsertDatagram(sequence: number, timestamp: Timestamp, payload: Uint8Array) {\n\t\tthis.#writable(sequence);\n\t\tif (payload.byteLength > MAX_DATAGRAM_BYTES) throw new Error(\"datagram payload too large\");\n\n\t\tconst counter = this.#sequence;\n\t\tif (sequence >= counter.next) {\n\t\t\tcounter.next = sequence + 1;\n\t\t}\n\t\tthis.#publishDatagram({ sequence, timestamp, payload });\n\t}\n\n\t/**\n\t * Declare the track's exclusive end, possibly ahead of the live edge, mirroring the Rust\n\t * `finish_at`.\n\t *\n\t * `final` is the first sequence that will never be produced, so a track whose last group\n\t * is 89 finishes at 90. Groups and datagrams below it are still accepted; anything at or\n\t * above it is refused. Unlike {@link close} it is not terminal: call `close()` once the\n\t * remaining groups are written. Throws if the track is closed, already has an end, or\n\t * `final` is at or below a sequence already produced.\n\t */\n\tfinishAt(final: number): void {\n\t\tif (this.#state.closed.peek() !== undefined) throw new Error(\"track is closed\");\n\t\tif (!Number.isSafeInteger(final) || final < 0) throw new RangeError(`invalid track end: ${final}`);\n\t\tconst declared = this.#state.final.peek();\n\t\tif (declared !== undefined) throw new Error(`track already ends at ${declared}`);\n\t\tif (final < this.#received) {\n\t\t\tthrow new Error(`track end ${final} is below the next sequence ${this.#received}`);\n\t\t}\n\t\tthis.#declareFinal(final);\n\t}\n\n\t#declareFinal(final: number): void {\n\t\tthis.#state.final.set(final);\n\t\tfor (const sink of this.#sinks) sink.final.set(final);\n\t}\n\n\t/**\n\t * Close the track and every subscriber, mirroring the abort to their groups. Idempotent.\n\t *\n\t * A clean close keeps the end {@link finishAt} declared, or declares one past the highest\n\t * sequence produced; an abort ends without one. Subscribers still draining get the\n\t * finished groups first, then the end or the abort. An abort after the declared end\n\t * settled (reached, with every group below it finished) is a clean close. The groups\n\t * left behind still age out after the track's `maxAge`, so a stale subscriber can't pin\n\t * them.\n\t */\n\tclose(abort?: Error) {\n\t\tif (this.#state.closed.peek() !== undefined) return;\n\t\tif (abort && this.#settled()) abort = undefined;\n\t\tif (abort === undefined && this.#state.final.peek() === undefined) {\n\t\t\tthis.#declareFinal(this.#received);\n\t\t}\n\t\t// Nobody will finish these, so a subscriber that has not taken one yet never sees it.\n\t\t// Not evicted: a reader already holding one keeps its frames and sees the abort.\n\t\tconst open = abort ? this.#cache.filter((entry) => entry.group.closed.peek() === undefined) : [];\n\t\tcloseTrackState(this.#state, abort);\n\t\tfor (const { group } of this.#cache) group.close(abort);\n\t\tfor (const entry of open) {\n\t\t\tthis.#unlink(entry);\n\t\t\tthis.#uncache(entry);\n\t\t}\n\t\tfor (const sink of this.#sinks) {\n\t\t\tfor (const group of sink.groups.peek()) group.close(abort);\n\t\t\tcloseTrackState(sink, abort);\n\t\t}\n\t\tthis.#sinks.clear();\n\t\tthis.#prune();\n\t}\n\n\t// Whether the declared end was reached and every cached group below it finished, so\n\t// the track already holds everything it promised. Mirrors the Rust `is_settled`.\n\t#settled(): boolean {\n\t\tconst final = this.#state.final.peek();\n\t\tif (final === undefined || this.#received < final) return false;\n\t\treturn this.#cache.every(({ group }) => group.sequence >= final || group.closed.peek() === null);\n\t}\n\n\t/** Append a frame as its own single-frame group. */\n\twriteFrame(frame: Frame) {\n\t\tconst group = this.appendGroup();\n\t\tgroup.writeFrame(frame);\n\t\tgroup.close();\n\t}\n\n\t/** Appends a string to the track as its own single-frame group. */\n\twriteString(str: string) {\n\t\tconst group = this.appendGroup();\n\t\tgroup.writeString(str);\n\t\tgroup.close();\n\t}\n\n\t/** Appends a JSON value to the track as its own single-frame group. */\n\twriteJson(json: unknown) {\n\t\tconst group = this.appendGroup();\n\t\tgroup.writeJson(json);\n\t\tgroup.close();\n\t}\n\n\t/** Appends a boolean to the track as its own single-frame group. */\n\twriteBool(bool: boolean) {\n\t\tconst group = this.appendGroup();\n\t\tgroup.writeBool(bool);\n\t\tgroup.close();\n\t}\n}\n\n/**\n * The read side of a live track subscription, mirroring the Rust `Subscriber`.\n *\n * Obtained from `Broadcast.Consumer.subscribe` / `Track.Consumer.subscribe`, or from\n * {@link Producer.subscribe} for an in-process track. Reads the groups a\n * {@link Producer} on the same underlying state writes.\n */\nexport class Subscriber {\n\t/** The track name. */\n\treadonly name: string;\n\n\t#state: TrackState;\n\t#nextSequence = 0;\n\t#cursor = new Signal<{ start: number; end?: number }>({ start: 0 });\n\t#enforceLatency = true;\n\t// Which cursor owns this subscription. Both cursors draw from one buffer, so the\n\t// first group read commits the track to arrival order and {@link ordered} commits\n\t// it to sequence order; whichever wins is the only one allowed from here on.\n\t// Datagrams are a separate cursor and never commit.\n\t#mode?: \"arrival\" | \"ordered\";\n\t// The group the frame-level helpers are currently draining, acquired through the\n\t// sequence cursor so frame reads and {@link Ordered.nextGroup} share one floor.\n\t#frameGroup?: GroupConsumer;\n\n\t#drift(): {\n\t\tbudget: number;\n\t\tpresentation?: { sequence: number; timestamp: Timestamp };\n\t\tend?: number;\n\t} {\n\t\tconst { end } = this.#cursor.peek();\n\t\tconst timeline = this.#state.timeline;\n\t\tlet presentation: { sequence: number; timestamp: Timestamp } | undefined;\n\t\t// The edge wants the newest content that exists, so it takes the newest\n\t\t// stamped group's latest frame: walk back from the cap to the first one.\n\t\tfor (let i = (end === undefined ? timeline.length : timelineIndex(timeline, end)) - 1; i >= 0; i--) {\n\t\t\tconst group = timeline[i];\n\t\t\tif (group.closed.peek() instanceof Error) continue;\n\t\t\tconst timestamp = hooks.groupTimestamp(group);\n\t\t\tif (timestamp === undefined) continue;\n\t\t\tpresentation = { sequence: group.sequence, timestamp: hooks.groupLatest(group) ?? timestamp };\n\t\t\tbreak;\n\t\t}\n\n\t\tconst requested = this.#state.update.peek()?.maxAge ?? 0;\n\t\tconst retained = this.#state.info.peek()?.maxAge;\n\t\treturn {\n\t\t\tbudget: this.#enforceLatency\n\t\t\t\t? retained === undefined\n\t\t\t\t\t? requested\n\t\t\t\t\t: Math.min(requested, retained)\n\t\t\t\t: Number.POSITIVE_INFINITY,\n\t\t\tpresentation,\n\t\t\tend,\n\t\t};\n\t}\n\n\t// The furthest presentation time the group at `sequence` could still reach: where its\n\t// immediate servable successor begins, or undefined when nothing proves where it\n\t// stops. An upper bound, deliberately: a frame's duration is not on the wire, so a\n\t// group's own last timestamp says where it starts presenting, not where it ends.\n\t// Only the *immediate* successor counts: timestamps need not rise with sequence (a\n\t// rewind reorders them), so a later stamped group proves nothing about where an\n\t// unstamped successor will begin, and shrinking the bound is the unsafe direction.\n\t// An unstamped successor leaves the reach unbounded until it presents a frame.\n\t#reach(sequence: number, end?: number): number | undefined {\n\t\tconst timeline = this.#state.timeline;\n\t\tfor (let i = timelineIndex(timeline, sequence + 1); i < timeline.length; i++) {\n\t\t\tconst successor = timeline[i];\n\t\t\tif (end !== undefined && successor.sequence >= end) break;\n\t\t\tif (successor.closed.peek() instanceof Error) continue;\n\t\t\treturn hooks.groupTimestamp(successor)?.asMillis();\n\t\t}\n\t\treturn undefined;\n\t}\n\n\t// Whether the drift budget says to give up on `group`.\n\t//\n\t// Presentation time measures a group by how far it could still reach, not by how far\n\t// behind it started. Being behind is survivable: priority transmits newer groups first,\n\t// so a backlog bursts at whatever rate is left over and closes the gap faster than the\n\t// live edge advances. A group is abandoned only once everything it could still present\n\t// falls outside the budget.\n\t//\n\t// A group's reach is bounded by its nearest successor: it cannot present past where the\n\t// next group begins. Its own frames say nothing, since a frame's duration is not on the\n\t// wire, and the candidate needs no timestamp of its own: an empty group is bounded by\n\t// its stamped successor the same way. The bound is exclusive, so the comparison is `>=`:\n\t// the freshest frame a group could still hold sits just below its reach, so an age equal\n\t// to the budget already puts every frame in it strictly past the budget. A zero budget\n\t// falls out for free. Only timestamps drive expiry; wall-clock reclamation of idle\n\t// content is the cache's own policy, not the budget's.\n\t#isStale(\n\t\tgroup: GroupConsumer,\n\t\tdrift: {\n\t\t\tbudget: number;\n\t\t\tpresentation?: { sequence: number; timestamp: Timestamp };\n\t\t\tend?: number;\n\t\t},\n\t): boolean {\n\t\tif (this.#state.timeline[timelineIndex(this.#state.timeline, group.sequence)] !== group) return false;\n\n\t\tconst reach = this.#reach(group.sequence, drift.end);\n\t\treturn (\n\t\t\tdrift.presentation !== undefined &&\n\t\t\tdrift.presentation.sequence > group.sequence &&\n\t\t\treach !== undefined &&\n\t\t\tdrift.presentation.timestamp.asMillis() - reach >= drift.budget\n\t\t);\n\t}\n\n\t#guard(group: GroupConsumer): GroupConsumer {\n\t\tif (!this.#enforceLatency) return group;\n\t\thooks.expireGroup(group, {\n\t\t\texpired: () => this.#isStale(group, this.#drift()),\n\t\t\tchanged: [\n\t\t\t\tthis.#state.groups,\n\t\t\t\tthis.#state.timelineChanged,\n\t\t\t\tthis.#state.update,\n\t\t\t\tthis.#state.info,\n\t\t\t\tthis.#cursor,\n\t\t\t\tthis.#state.closed,\n\t\t\t],\n\t\t});\n\t\treturn group;\n\t}\n\n\tprivate constructor(name: string, state: TrackState) {\n\t\tthis.name = name;\n\t\tthis.#state = state;\n\t\t// The cursor's floor is the group the subscription named, or 0. A floor is the\n\t\t// only thing a start contributes; {@link Subscription.maxAge} is what asks for\n\t\t// data, and delivery skips everything above the floor that the budget convicts.\n\t\tthis.#cursor.set({ start: groupBounds(state.update.peek()?.groups ?? {}).start });\n\t}\n\n\tstatic {\n\t\tmakeSubscriber = (name, state) => new Subscriber(name, state);\n\t\thooks.tryRecvGroup = (subscriber) => subscriber.#tryRecvGroup();\n\t\thooks.groupChanged = (subscriber, fn) => subscriber.#groupChanged(fn);\n\t\thooks.exemptFetch = (subscriber) => {\n\t\t\tsubscriber.#enforceLatency = false;\n\t\t};\n\t\thooks.replaceGroups = (subscriber, groups) => subscriber.#replaceGroups(groups);\n\t\t// The sequence cursor lives here (it shares the buffer and the drift anchor with\n\t\t// the arrival cursor); `Ordered` is the handle that reaches it.\n\t\tordered_ = {\n\t\t\tnextGroup: (subscriber) => subscriber.#nextGroup(),\n\t\t\treadFrame: (subscriber) => subscriber.#readFrame(),\n\t\t\treadString: (subscriber) => subscriber.#readString(),\n\t\t\treadJson: (subscriber) => subscriber.#readJson(),\n\t\t\treadBool: (subscriber) => subscriber.#readBool(),\n\t\t\t// Unordered either way, so both handles reach the same cursor.\n\t\t\trecvDatagram: (subscriber) => subscriber.#recvDatagram(),\n\t\t};\n\t}\n\n\t// Refuse a read on this handle once `ordered()` has taken the subscription.\n\t#live() {\n\t\tif (this.#mode === \"ordered\") throw new Error(\"track is read in sequence order; use the Ordered handle\");\n\t}\n\n\t/**\n\t * Resolve this track's immutable publisher properties.\n\t *\n\t * Resolves once the wire layer commits the TRACK_INFO it received (lite-05+) or\n\t * defaults (older drafts), so awaiting it never yields a placeholder. Rejects if\n\t * the track is closed before the properties are known (e.g. a rejected subscription).\n\t */\n\tinfo(): Promise<Info> {\n\t\treturn resolveInfo(this.#state);\n\t}\n\n\t/** Settles once the track closes; see {@link Producer.closed}. */\n\tget closed(): GetPromise<Error | null> {\n\t\treturn this.#state.closed;\n\t}\n\n\t/** This subscriber's current options, including defaults and the last {@link update}. */\n\tget subscription(): Getter<Subscription | undefined> {\n\t\treturn this.#state.update;\n\t}\n\n\t/** Return the latest group sequence observed on this track, if any. */\n\tlatest(): number | undefined {\n\t\treturn this.#state.latest;\n\t}\n\n\t/**\n\t * The track's exclusive final boundary: the end {@link Producer.finishAt} declared, which\n\t * can be ahead of the live edge, or one past the highest sequence produced once the\n\t * producer closes cleanly (0 for a track that produced none). Groups and datagrams share\n\t * the sequence namespace, so this can exceed `latest() + 1`. Undefined until declared,\n\t * and after an abort that declared none.\n\t */\n\tfinal(): number | undefined {\n\t\treturn this.#state.final.peek();\n\t}\n\n\t/**\n\t * Resolve with the track's exclusive final boundary once it is known, mirroring the Rust\n\t * `finished`.\n\t *\n\t * Resolves as soon as the end is declared, which may be ahead of the live edge, so it\n\t * says nothing about every group having arrived: read until the cursor returns\n\t * `undefined` for that. Rejects with the abort, or if the track closes without an end.\n\t */\n\tasync finished(): Promise<number> {\n\t\tfor (;;) {\n\t\t\tconst final = this.#state.final.peek();\n\t\t\tif (final !== undefined) return final;\n\n\t\t\tconst closed = this.#state.closed.peek();\n\t\t\tif (closed instanceof Error) throw closed;\n\t\t\tif (closed !== undefined) throw new Error(\"track closed before its end was known\");\n\n\t\t\tawait Signal.race(this.#state.final, this.#state.closed);\n\t\t}\n\t}\n\n\t/**\n\t * The newest frame this track has produced, or `undefined` while it has none.\n\t *\n\t * Read from the groups buffered for this subscriber, so nothing is consumed. A newest\n\t * group that has no frames yet falls back to the newest older group that does. It\n\t * reads as `undefined` once the newest group has been evicted or received: what is\n\t * left can no longer say where the edge is.\n\t */\n\tlargest(): Location | undefined {\n\t\tconst latest = this.#state.latest;\n\t\tif (latest === undefined) return undefined;\n\n\t\tconst groups = this.#state.groups.peek();\n\t\tconst newest = groups[groups.length - 1];\n\t\tif (!newest || newest.sequence !== latest) return undefined;\n\n\t\tfor (let i = groups.length - 1; i >= 0; i--) {\n\t\t\tconst count = groups[i].frameCount;\n\t\t\tif (count > 0) return { group: groups[i].sequence, frame: count - 1 };\n\t\t}\n\t\treturn undefined;\n\t}\n\n\t/**\n\t * An independent subscriber to the same track, with its own cursor and its own replay of\n\t * the retained window.\n\t *\n\t * Reads here do not consume anything this one would deliver, which is what lets a\n\t * publisher read the cache alongside the cursor it is serving from. Resolving the track\n\t * again through the broadcast would not do: a dynamic serve is one request per peer\n\t * subscription, so that mints a second producer the application has to answer separately.\n\t *\n\t * @internal Wire layers only.\n\t */\n\tfork(options?: Subscription): Subscriber {\n\t\tconst producer = this.#state.producer;\n\t\tif (!producer) throw new Error(\"track has no producer to fork from\");\n\t\treturn producer.subscribe(options);\n\t}\n\n\t/** Limit subsequent reads to these groups and return this reader for chaining. */\n\twithGroups(groups: Groups): this {\n\t\tthis.setGroups(groups);\n\t\treturn this;\n\t}\n\n\t/**\n\t * Limit subsequent reads without rewinding read progress or changing the wire request.\n\t * An omitted start preserves the current floor; an omitted end removes the cap.\n\t * Raising the end makes unread buffered groups available again.\n\t */\n\tsetGroups(groups: Groups): void {\n\t\tconst { start, end } = groupBounds(groups);\n\t\tthis.#cursor.update((cursor) => ({ start: Math.max(cursor.start, start), end }));\n\t}\n\n\t// Serving counterpart of setGroups: a named start replaces the floor, matching\n\t// Rust `start_at`. Local readers stay monotonic; only the wire publisher lowers.\n\t#replaceGroups(groups: Groups): void {\n\t\tconst { start, end } = groupBounds(groups);\n\t\tthis.#cursor.update((cursor) => ({\n\t\t\tstart: groups.start === undefined ? cursor.start : start,\n\t\t\tend,\n\t\t}));\n\t}\n\n\t/** Close the track (optionally with an error), closing any pending groups. Idempotent. */\n\tclose(abort?: Error) {\n\t\t// Settle if we're first (the producer may already have); either way drop anything\n\t\t// still buffered. Groups parked at the setGroups cap deliberately outlive a clean\n\t\t// producer close, so the subscriber leaving is what must release them: closing\n\t\t// and clearing wakes a pending read to observe the end instead of hanging.\n\t\tcloseTrackState(this.#state, abort);\n\t\tthis.#state.groups.mutate((groups) => {\n\t\t\tfor (const group of groups) group.close(abort);\n\t\t\tgroups.length = 0;\n\t\t});\n\t\tthis.#frameGroup?.close(abort);\n\t\tthis.#frameGroup = undefined;\n\t\tthis.#state.timeline.length = 0;\n\t}\n\n\t/**\n\t * Receive every group on this track exactly once, as it becomes available.\n\t *\n\t * Groups may arrive out of order or with gaps due to network conditions; unlike\n\t * {@link Ordered.nextGroup}, one that arrives after a newer group was already returned\n\t * is still delivered. When several groups are buffered, the lowest sequence is\n\t * returned first.\n\t *\n\t * Honors the range set by {@link setGroups}: a group\n\t * beyond the cap stays buffered (not dropped) and is offered once the cap rises, even\n\t * after a clean close, without blocking in-range groups that arrive behind it.\n\t * A group whose presentation time is further behind the live edge than this\n\t * subscriber's `maxAge` is skipped. The default of zero takes the live edge.\n\t * The budget remains attached after return, so a pending frame read rejects if a stalled\n\t * group becomes stale while newer data advances.\n\t *\n\t * The first call commits this track to arrival order: {@link ordered} throws afterwards.\n\t */\n\tasync recvGroup(): Promise<GroupConsumer | undefined> {\n\t\tthis.#live();\n\t\tthis.#mode = \"arrival\";\n\t\tfor (;;) {\n\t\t\tconst recv = this.#tryRecvGroup();\n\t\t\tswitch (recv.kind) {\n\t\t\t\tcase \"group\":\n\t\t\t\t\treturn recv.group;\n\t\t\t\tcase \"done\":\n\t\t\t\t\treturn undefined;\n\t\t\t\tcase \"error\":\n\t\t\t\t\tthrow recv.error;\n\t\t\t}\n\n\t\t\t// Idle, or parked at the boundary waiting for the cap to rise.\n\t\t\tawait Signal.race(this.#state.groups, this.#cursor, this.#state.closed);\n\t\t}\n\t}\n\n\t// Package-internal synchronous half of recvGroup. The lite publisher uses this so applying\n\t// control state, popping the group, and positioning its frames are one JavaScript turn.\n\t#tryRecvGroup(): Recv {\n\t\tconst groups = this.#state.groups.peek();\n\t\tconst { start, end } = this.#cursor.peek();\n\t\twhile (groups.length > 0 && groups[0].sequence < start) groups.shift()?.close();\n\t\tconst drift = this.#drift();\n\n\t\tfor (;;) {\n\t\t\t// The buffer is sequence-sorted, so an in-range group that arrives behind a\n\t\t\t// beyond-cap one sorts in front of it and is never blocked by it.\n\t\t\tconst group = groups[0];\n\t\t\tif (!group || (end !== undefined && group.sequence >= end)) break;\n\t\t\tgroups.shift();\n\t\t\tif (this.#isStale(group, drift)) {\n\t\t\t\tgroup.close();\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\treturn { kind: \"group\", group: this.#guard(group) };\n\t\t}\n\n\t\tconst group = groups[0];\n\t\tconst closed = this.#state.closed.peek();\n\t\tif (closed instanceof Error) return { kind: \"error\", error: closed };\n\t\tif (closed === undefined) return { kind: \"idle\" };\n\t\t// A group beyond the cap outlives a clean close: it becomes deliverable if\n\t\t// the cap rises, so the track isn't over while any are held.\n\t\treturn group ? { kind: \"boundary\" } : { kind: \"done\" };\n\t}\n\n\t// Package-internal readiness half of recvGroup. Each registration fires at most once, and\n\t// the caller disposes the losers after whichever source wakes it. A declared end wakes it\n\t// too, so a publisher can forward the end before the live edge reaches it.\n\t#groupChanged(fn: () => void): Dispose {\n\t\tconst dispose = [\n\t\t\tthis.#state.groups.changed(fn),\n\t\t\tthis.#cursor.changed(fn),\n\t\t\tthis.#state.closed.changed(fn),\n\t\t\tthis.#state.final.changed(fn),\n\t\t];\n\t\treturn () => {\n\t\t\tfor (const close of dispose) close();\n\t\t};\n\t}\n\n\t/**\n\t * Take the next buffered group without blocking, honoring the same cursor bounds as\n\t * {@link recvGroup}.\n\t *\n\t * Returns `undefined` when nothing is deliverable right now, which is not by itself the\n\t * end of the track: a group may still arrive, or one may be parked beyond the\n\t * {@link setGroups} cap. Use it to drain what the retained window already holds, where\n\t * waiting for a sequence nothing will republish would park forever.\n\t */\n\ttryRecvGroup(): GroupConsumer | undefined {\n\t\tthis.#live();\n\t\tthis.#mode = \"arrival\";\n\t\tconst recv = this.#tryRecvGroup();\n\t\tif (recv.kind === \"group\") return recv.group;\n\t\tif (recv.kind === \"error\") throw recv.error;\n\t\treturn undefined;\n\t}\n\n\t/**\n\t * Receive the next datagram in arrival order.\n\t *\n\t * Datagrams are a separate best-effort channel from groups (see\n\t * {@link Producer.appendDatagram}); they share only the sequence namespace. A consumer\n\t * that falls too far behind silently loses the oldest datagrams. Read this alongside\n\t * {@link recvGroup} (e.g. in a separate loop) to receive both channels concurrently.\n\t * The two cursors are independent: a datagram never moves the group cursor.\n\t */\n\tasync recvDatagram(): Promise<Datagram | undefined> {\n\t\tthis.#live();\n\t\treturn this.#recvDatagram();\n\t}\n\n\t// The datagram cursor, reachable from either handle: unordered by construction, so the\n\t// choice of group order says nothing about it.\n\tasync #recvDatagram(): Promise<Datagram | undefined> {\n\t\tfor (;;) {\n\t\t\tconst datagrams = this.#state.datagrams.peek();\n\n\t\t\tif (datagrams.length > 0) {\n\t\t\t\treturn datagrams.shift();\n\t\t\t}\n\n\t\t\tconst closed = this.#state.closed.peek();\n\t\t\tif (closed instanceof Error) throw closed;\n\t\t\tif (closed !== undefined) return undefined;\n\n\t\t\tawait Signal.race(this.#state.datagrams, this.#state.closed);\n\t\t}\n\t}\n\n\t// The sequence cursor behind {@link Ordered}, which owns the only public door to it.\n\tasync #nextGroup(): Promise<GroupConsumer | undefined> {\n\t\tfor (;;) {\n\t\t\tconst groups = this.#state.groups.peek();\n\t\t\tconst cursor = this.#cursor.peek();\n\t\t\tconst start = Math.max(cursor.start, this.#nextSequence);\n\t\t\twhile (groups.length > 0 && groups[0].sequence < start) groups.shift()?.close();\n\t\t\t// One anchor for the whole pass, so walking a backlog off stays linear.\n\t\t\tconst drift = this.#drift();\n\n\t\t\tfor (;;) {\n\t\t\t\tconst group = groups[0];\n\t\t\t\tif (!group || (cursor.end !== undefined && group.sequence >= cursor.end)) break;\n\t\t\t\tgroups.shift();\n\t\t\t\tthis.#nextSequence = group.sequence + 1;\n\t\t\t\t// Every frame this group could still hold is past the budget, so keep\n\t\t\t\t// scanning: one pass walks a whole backlog off rather than replaying it.\n\t\t\t\tif (this.#isStale(group, drift)) {\n\t\t\t\t\tgroup.close();\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\t// One cursor: the frame helpers must not keep draining a group this\n\t\t\t\t// read just moved past, or interleaved reads would run backwards.\n\t\t\t\tif (this.#frameGroup && this.#frameGroup.sequence < group.sequence) {\n\t\t\t\t\tthis.#frameGroup.close();\n\t\t\t\t\tthis.#frameGroup = undefined;\n\t\t\t\t}\n\t\t\t\treturn this.#guard(group);\n\t\t\t}\n\n\t\t\tconst closed = this.#state.closed.peek();\n\t\t\tif (closed instanceof Error) throw closed;\n\t\t\t// A group parked above the cap stays deliverable even after a clean close\n\t\t\t// (its frames remain buffered), so keep waiting for a cap raise. Only a\n\t\t\t// drained track reports finished.\n\t\t\tif (closed !== undefined && !groups[0]) return undefined;\n\n\t\t\tawait Signal.race(this.#state.groups, this.#cursor, this.#state.closed);\n\t\t}\n\t}\n\n\t/**\n\t * Reads the next frame across groups, in sequence order, with its group and frame numbers.\n\t * Treat the returned frame bytes as read-only; they are shared with other consumers.\n\t *\n\t * Groups are acquired through the same sequence cursor as {@link Ordered.nextGroup},\n\t * so frames never run backwards: a late lower-sequence group is skipped, and so is\n\t * one every frame of which `maxAge` proves is too old. A group the budget abandons\n\t * mid-stall ends cleanly and the cursor resyncs from the next group; a gap inside a\n\t * group still surfaces as {@link TooFarBehind} or {@link GroupTooLarge}.\n\t */\n\tasync #readFrame(): Promise<({ group: number; frame: number } & Frame) | undefined> {\n\t\tfor (;;) {\n\t\t\tif (!this.#frameGroup) {\n\t\t\t\tthis.#frameGroup = await this.#nextGroup();\n\t\t\t\tif (!this.#frameGroup) return undefined;\n\t\t\t}\n\t\t\tconst group = this.#frameGroup;\n\n\t\t\tlet next: ({ sequence: number } & Frame) | undefined;\n\t\t\ttry {\n\t\t\t\tnext = await group.readFrameSequence();\n\t\t\t} catch (err) {\n\t\t\t\t// The group failed underneath us: resync from the next one, surfacing\n\t\t\t\t// only what the caller can act on (a gap, or the track's own abort).\n\t\t\t\tthis.#frameGroup = undefined;\n\t\t\t\tgroup.close();\n\t\t\t\tif (err instanceof TooFarBehind || err instanceof GroupTooLarge) throw err;\n\t\t\t\tconst closed = this.#state.closed.peek();\n\t\t\t\tif (closed instanceof Error) throw closed;\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif (next) {\n\t\t\t\treturn {\n\t\t\t\t\tgroup: group.sequence,\n\t\t\t\t\tframe: next.sequence,\n\t\t\t\t\tpayload: next.payload,\n\t\t\t\t\ttimestamp: next.timestamp,\n\t\t\t\t};\n\t\t\t}\n\n\t\t\t// The group is exhausted (or the budget abandoned its stall); move on.\n\t\t\tthis.#frameGroup = undefined;\n\t\t\tgroup.close();\n\t\t}\n\t}\n\n\t/** Reads the next frame and decodes it as a UTF-8 string. */\n\tasync #readString(): Promise<string | undefined> {\n\t\tconst next = await this.#readFrame();\n\t\tif (!next) return undefined;\n\t\treturn new TextDecoder().decode(next.payload);\n\t}\n\n\t/** Reads the next frame and parses it as JSON. */\n\tasync #readJson(): Promise<unknown | undefined> {\n\t\tconst next = await this.#readString();\n\t\tif (!next) return undefined;\n\t\treturn JSON.parse(next);\n\t}\n\n\t/** Reads the next frame and decodes it as a one-byte boolean, throwing on a malformed frame. */\n\tasync #readBool(): Promise<boolean | undefined> {\n\t\tconst next = await this.#readFrame();\n\t\tif (!next) return undefined;\n\t\tconst payload = next.payload;\n\t\tif (payload.byteLength !== 1 || !(payload[0] === 0 || payload[0] === 1)) throw new Error(\"invalid bool frame\");\n\t\treturn payload[0] === 1;\n\t}\n\n\t/**\n\t * Read this track's groups in sequence order instead of arrival order.\n\t *\n\t * Both cursors draw from the same buffer, so a track is read one way or the other: this\n\t * hands the subscription to the returned {@link Ordered} and leaves this handle inert.\n\t * {@link recvGroup} and {@link recvDatagram} throw afterwards. Throws once a\n\t * {@link recvGroup} call has already committed the track to arrival order.\n\t *\n\t * Datagrams come along: they are a separate cursor either way, so the choice of group\n\t * order says nothing about them, and reading them commits nothing.\n\t */\n\tordered(): Ordered {\n\t\tif (this.#mode === \"ordered\") throw new Error(\"track is already read in sequence order\");\n\t\tif (this.#mode === \"arrival\") throw new Error(\"track is already read in arrival order\");\n\t\tthis.#mode = \"ordered\";\n\t\treturn makeOrdered(this);\n\t}\n\n\t/**\n\t * Update this subscription's options (e.g. priority), triggering a SUBSCRIBE_UPDATE to the\n\t * publisher. Mirrors the Rust `Subscriber::update`.\n\t */\n\tupdate(options: Subscription) {\n\t\tthis.#state.update.set(subscriptionDefaults(options));\n\t}\n}\n\n/**\n * A {@link Subscriber} that reads groups in sequence order.\n *\n * Created by {@link Subscriber.ordered}, which takes the subscription over: the two\n * cursors draw from one buffer, so a track is read one way or the other and never both.\n * Every group this returns has a higher sequence than the last, so a late arrival is\n * skipped rather than delivered out of turn.\n *\n * `maxAge` applies as this cursor reads, exactly as it does on the arrival cursor: a\n * group is skipped once its reach, where its immediate successor begins, is that far\n * behind the newest frame on the track. Nothing weaker convicts it, since the reach is\n * the only proof that every frame it could still hold is past the budget, so a backlog\n * inside the budget is still delivered whole, as a burst in order. The budget follows a\n * group already handed out too: a stalled group's pending frame read rejects once newer\n * content has pulled that far ahead.\n */\nexport class Ordered {\n\t/** The track name. */\n\treadonly name: string;\n\n\t#subscriber: Subscriber;\n\n\tprivate constructor(subscriber: Subscriber) {\n\t\tthis.name = subscriber.name;\n\t\tthis.#subscriber = subscriber;\n\t}\n\n\tstatic {\n\t\tmakeOrdered = (subscriber) => new Ordered(subscriber);\n\t}\n\n\t/** Resolve this track's immutable publisher properties; see {@link Subscriber.info}. */\n\tinfo(): Promise<Info> {\n\t\treturn this.#subscriber.info();\n\t}\n\n\t/** Settles once the track closes; see {@link Producer.closed}. */\n\tget closed(): GetPromise<Error | null> {\n\t\treturn this.#subscriber.closed;\n\t}\n\n\t/** This subscriber's current options, including defaults and the last {@link update}. */\n\tget subscription(): Getter<Subscription | undefined> {\n\t\treturn this.#subscriber.subscription;\n\t}\n\n\t/** The latest group sequence observed on this track, if any. */\n\tlatest(): number | undefined {\n\t\treturn this.#subscriber.latest();\n\t}\n\n\t/** The track's exclusive final boundary; see {@link Subscriber.final}. */\n\tfinal(): number | undefined {\n\t\treturn this.#subscriber.final();\n\t}\n\n\t/** Resolve with the track's exclusive final boundary once known; see {@link Subscriber.finished}. */\n\tfinished(): Promise<number> {\n\t\treturn this.#subscriber.finished();\n\t}\n\n\t/** Limit subsequent reads to these groups and return this reader for chaining. */\n\twithGroups(groups: Groups): this {\n\t\tthis.setGroups(groups);\n\t\treturn this;\n\t}\n\n\t/** Limit subsequent reads to these groups; see {@link Subscriber.setGroups}. */\n\tsetGroups(groups: Groups): void {\n\t\tthis.#subscriber.setGroups(groups);\n\t}\n\n\t/** Update this subscription's options; see {@link Subscriber.update}. */\n\tupdate(options: Subscription) {\n\t\tthis.#subscriber.update(options);\n\t}\n\n\t/** Close the track (optionally with an error), closing any pending groups. Idempotent. */\n\tclose(abort?: Error) {\n\t\tthis.#subscriber.close(abort);\n\t}\n\n\t/**\n\t * Return the next group with a strictly-greater sequence number than the last returned.\n\t *\n\t * Late arrivals (sequence at or below the last returned) are silently skipped, as is a\n\t * group whose every frame is further behind the live edge than `maxAge` (the default of\n\t * zero keeps only what nothing newer has superseded). Honors the bounds set by\n\t * {@link setGroups}.\n\t */\n\tnextGroup(): Promise<GroupConsumer | undefined> {\n\t\treturn ordered_.nextGroup(this.#subscriber);\n\t}\n\n\t/**\n\t * Read the next frame across groups, in sequence order, with its group and frame numbers.\n\t *\n\t * Rides the same cursor as {@link nextGroup} and shares this handle's contract: a\n\t * buffered backlog is drained in full up to the point `maxAge` proves it useless.\n\t * Treat the returned frame bytes as read-only; they are shared with other consumers.\n\t */\n\treadFrame(): Promise<({ group: number; frame: number } & Frame) | undefined> {\n\t\treturn ordered_.readFrame(this.#subscriber);\n\t}\n\n\t/** Read the next frame and decode it as a UTF-8 string. */\n\treadString(): Promise<string | undefined> {\n\t\treturn ordered_.readString(this.#subscriber);\n\t}\n\n\t/** Read the next frame and parse it as JSON. */\n\treadJson(): Promise<unknown | undefined> {\n\t\treturn ordered_.readJson(this.#subscriber);\n\t}\n\n\t/** Read the next frame and decode it as a one-byte boolean, throwing on a malformed frame. */\n\treadBool(): Promise<boolean | undefined> {\n\t\treturn ordered_.readBool(this.#subscriber);\n\t}\n\n\t/**\n\t * Receive the next datagram in arrival order.\n\t *\n\t * Datagrams are a separate best-effort channel from groups (see\n\t * {@link Producer.appendDatagram}); they share only the sequence namespace, and\n\t * neither cursor moves the other. Unordered by construction, so this behaves\n\t * identically on either handle; it is here so a track carrying both channels needs\n\t * one subscription rather than two.\n\t */\n\trecvDatagram(): Promise<Datagram | undefined> {\n\t\treturn ordered_.recvDatagram(this.#subscriber);\n\t}\n}\n"]}
@@ -0,0 +1,2 @@
1
+ export declare function untilAborted<T>(promise: Promise<T>, signal?: AbortSignal): Promise<T>;
2
+ //# sourceMappingURL=abort.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"abort.d.ts","sourceRoot":"","sources":["../../src/util/abort.ts"],"names":[],"mappings":"AAKA,wBAAsB,YAAY,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,CAAC,CAAC,CAY3F"}
package/util/abort.js ADDED
@@ -0,0 +1,20 @@
1
+ /* @ts-self-types="./abort.d.ts" */
2
+ import { race } from "@norskvideo/moq-signals";
3
+ // Settle with `promise`, or reject with the signal's reason once it aborts. An already-aborted
4
+ // signal rejects at once. There's no cancellation of `promise` itself; the caller releases
5
+ // whatever it holds when this rejects.
6
+ export async function untilAborted(promise, signal) {
7
+ if (!signal)
8
+ return promise;
9
+ signal.throwIfAborted();
10
+ const { promise: aborted, reject } = Promise.withResolvers();
11
+ const onAbort = () => reject(signal.reason);
12
+ signal.addEventListener("abort", onAbort, { once: true });
13
+ try {
14
+ return await race([promise, aborted]);
15
+ }
16
+ finally {
17
+ signal.removeEventListener("abort", onAbort);
18
+ }
19
+ }
20
+ //# sourceMappingURL=abort.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"abort.js","sourceRoot":"","sources":["../../src/util/abort.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAEpC,+FAA+F;AAC/F,2FAA2F;AAC3F,uCAAuC;AACvC,MAAM,CAAC,KAAK,UAAU,YAAY,CAAI,OAAmB,EAAE,MAAoB;IAC9E,IAAI,CAAC,MAAM;QAAE,OAAO,OAAO,CAAC;IAC5B,MAAM,CAAC,cAAc,EAAE,CAAC;IAExB,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,aAAa,EAAS,CAAC;IACpE,MAAM,OAAO,GAAG,GAAG,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAC5C,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;IAC1D,IAAI,CAAC;QACJ,OAAO,MAAM,IAAI,CAAC,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC;IACvC,CAAC;YAAS,CAAC;QACV,MAAM,CAAC,mBAAmB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IAC9C,CAAC;AACF,CAAC","sourcesContent":["import { race } from \"@moq/signals\";\n\n// Settle with `promise`, or reject with the signal's reason once it aborts. An already-aborted\n// signal rejects at once. There's no cancellation of `promise` itself; the caller releases\n// whatever it holds when this rejects.\nexport async function untilAborted<T>(promise: Promise<T>, signal?: AbortSignal): Promise<T> {\n\tif (!signal) return promise;\n\tsignal.throwIfAborted();\n\n\tconst { promise: aborted, reject } = Promise.withResolvers<never>();\n\tconst onAbort = () => reject(signal.reason);\n\tsignal.addEventListener(\"abort\", onAbort, { once: true });\n\ttry {\n\t\treturn await race([promise, aborted]);\n\t} finally {\n\t\tsignal.removeEventListener(\"abort\", onAbort);\n\t}\n}\n"]}
package/util/log.d.ts ADDED
@@ -0,0 +1,5 @@
1
+ /** Renders a relay URL without user credentials, query parameters, or fragment. */
2
+ export declare function redact(url: URL): string;
3
+ /** Whether the consumer environment enables development diagnostics. */
4
+ export declare function dev(): boolean;
5
+ //# sourceMappingURL=log.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"log.d.ts","sourceRoot":"","sources":["../../src/util/log.ts"],"names":[],"mappings":"AAAA,mFAAmF;AACnF,wBAAgB,MAAM,CAAC,GAAG,EAAE,GAAG,GAAG,MAAM,CAEvC;AAED,wEAAwE;AACxE,wBAAgB,GAAG,IAAI,OAAO,CAO7B"}
package/util/log.js ADDED
@@ -0,0 +1,17 @@
1
+ /* @ts-self-types="./log.d.ts" */
2
+ /** Renders a relay URL without user credentials, query parameters, or fragment. */
3
+ export function redact(url) {
4
+ return `${url.origin}${url.pathname}`;
5
+ }
6
+ /** Whether the consumer environment enables development diagnostics. */
7
+ export function dev() {
8
+ // Bundlers expose a boolean DEV; Bun exposes environment variables as strings.
9
+ // @ts-ignore - Some environments don't recognize import.meta.env
10
+ const env = import.meta.env;
11
+ if (typeof env === "undefined")
12
+ return false;
13
+ if (typeof env.DEV === "boolean")
14
+ return env.DEV;
15
+ return env.NODE_ENV !== "production" && env.MODE !== "production";
16
+ }
17
+ //# sourceMappingURL=log.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"log.js","sourceRoot":"","sources":["../../src/util/log.ts"],"names":[],"mappings":"AAAA,mFAAmF;AACnF,MAAM,UAAU,MAAM,CAAC,GAAQ;IAC9B,OAAO,GAAG,GAAG,CAAC,MAAM,GAAG,GAAG,CAAC,QAAQ,EAAE,CAAC;AACvC,CAAC;AAED,wEAAwE;AACxE,MAAM,UAAU,GAAG;IAClB,+EAA+E;IAC/E,iEAAiE;IACjE,MAAM,GAAG,GAAG,OAAO,IAAI,CAAC,GAAG,CAAC;IAC5B,IAAI,OAAO,GAAG,KAAK,WAAW;QAAE,OAAO,KAAK,CAAC;IAC7C,IAAI,OAAO,GAAG,CAAC,GAAG,KAAK,SAAS;QAAE,OAAO,GAAG,CAAC,GAAG,CAAC;IACjD,OAAO,GAAG,CAAC,QAAQ,KAAK,YAAY,IAAI,GAAG,CAAC,IAAI,KAAK,YAAY,CAAC;AACnE,CAAC","sourcesContent":["/** Renders a relay URL without user credentials, query parameters, or fragment. */\nexport function redact(url: URL): string {\n\treturn `${url.origin}${url.pathname}`;\n}\n\n/** Whether the consumer environment enables development diagnostics. */\nexport function dev(): boolean {\n\t// Bundlers expose a boolean DEV; Bun exposes environment variables as strings.\n\t// @ts-ignore - Some environments don't recognize import.meta.env\n\tconst env = import.meta.env;\n\tif (typeof env === \"undefined\") return false;\n\tif (typeof env.DEV === \"boolean\") return env.DEV;\n\treturn env.NODE_ENV !== \"production\" && env.MODE !== \"production\";\n}\n"]}
package/util/u64.d.ts ADDED
@@ -0,0 +1,39 @@
1
+ /** 2^32, the weight of the upper half. */
2
+ export declare const POW32 = 4294967296;
3
+ /** Join two halves into a `number`, throwing if it is above `Number.MAX_SAFE_INTEGER` rather than rounding. */
4
+ export declare function toNumber(hi: number, lo: number): number;
5
+ /** Join two halves into a bigint, exact up to 64 bits. */
6
+ export declare function toBigInt(hi: number, lo: number): bigint;
7
+ /**
8
+ * An unsigned 64-bit integer, held as two 32-bit halves so it encodes and decodes without a BigInt.
9
+ * Converting to a `number` throws past 2^53 rather than rounding.
10
+ */
11
+ export declare class U64 {
12
+ /** The value 0. */
13
+ static readonly ZERO: U64;
14
+ /** The largest value, 2^64 - 1. */
15
+ static readonly MAX: U64;
16
+ /** The upper 32 bits. */
17
+ readonly hi: number;
18
+ /** The lower 32 bits. */
19
+ readonly lo: number;
20
+ /** Join the upper and lower 32 bits, throwing if either is not a u32. */
21
+ constructor(hi: number, lo: number);
22
+ /** Convert a non-negative safe integer, throwing on anything else. */
23
+ static fromNumber(v: number): U64;
24
+ /** Convert a bigint, throwing unless it is in [0, 2^64). */
25
+ static fromBigInt(v: bigint): U64;
26
+ /** Convert to a `number`, throwing if it is above `Number.MAX_SAFE_INTEGER`. */
27
+ toNumber(): number;
28
+ /** Convert to a bigint, exactly. */
29
+ toBigInt(): bigint;
30
+ /** The value in decimal. */
31
+ toString(): string;
32
+ /** Negative if this is less than `other`, zero if equal, positive if greater. */
33
+ compare(other: U64): number;
34
+ /** Whether this equals `other`. */
35
+ equals(other: U64): boolean;
36
+ /** This plus a non-negative safe integer, throwing if the sum reaches 2^64. */
37
+ add(delta: number): U64;
38
+ }
39
+ //# sourceMappingURL=u64.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"u64.d.ts","sourceRoot":"","sources":["../../src/util/u64.ts"],"names":[],"mappings":"AAGA,0CAA0C;AAC1C,eAAO,MAAM,KAAK,aAAgB,CAAC;AAInC,+GAA+G;AAC/G,wBAAgB,QAAQ,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,MAAM,CAGvD;AAED,0DAA0D;AAC1D,wBAAgB,QAAQ,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,MAAM,CAEvD;AAED;;;GAGG;AACH,qBAAa,GAAG;IACf,mBAAmB;IACnB,MAAM,CAAC,QAAQ,CAAC,IAAI,MAAiB;IACrC,mCAAmC;IACnC,MAAM,CAAC,QAAQ,CAAC,GAAG,MAAiC;IAEpD,yBAAyB;IACzB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,yBAAyB;IACzB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IAEpB,yEAAyE;IACzE,YAAY,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAKjC;IAED,sEAAsE;IACtE,MAAM,CAAC,UAAU,CAAC,CAAC,EAAE,MAAM,GAAG,GAAG,CAGhC;IAED,4DAA4D;IAC5D,MAAM,CAAC,UAAU,CAAC,CAAC,EAAE,MAAM,GAAG,GAAG,CAGhC;IAED,gFAAgF;IAChF,QAAQ,IAAI,MAAM,CAEjB;IAED,oCAAoC;IACpC,QAAQ,IAAI,MAAM,CAEjB;IAED,4BAA4B;IAC5B,QAAQ,IAAI,MAAM,CAEjB;IAED,iFAAiF;IACjF,OAAO,CAAC,KAAK,EAAE,GAAG,GAAG,MAAM,CAE1B;IAED,mCAAmC;IACnC,MAAM,CAAC,KAAK,EAAE,GAAG,GAAG,OAAO,CAE1B;IAED,+EAA+E;IAC/E,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,GAAG,CAMtB;CACD"}
package/util/u64.js ADDED
@@ -0,0 +1,83 @@
1
+ /* @ts-self-types="./u64.d.ts" */
2
+ // An unsigned 64-bit integer as two u32 halves, so nothing on the hot path needs a BigInt.
3
+ // Package-internal. Varints are only its wire encoding; see ./varint.ts.
4
+ /** 2^32, the weight of the upper half. */
5
+ export const POW32 = 0x1_0000_0000;
6
+ // An upper half at or above this is past `Number.MAX_SAFE_INTEGER`.
7
+ const SAFE_HI = 2 ** 21;
8
+ /** Join two halves into a `number`, throwing if it is above `Number.MAX_SAFE_INTEGER` rather than rounding. */
9
+ export function toNumber(hi, lo) {
10
+ if (hi >= SAFE_HI)
11
+ throw new RangeError(`value larger than 53-bits: ${toBigInt(hi, lo)}`);
12
+ return hi * POW32 + lo;
13
+ }
14
+ /** Join two halves into a bigint, exact up to 64 bits. */
15
+ export function toBigInt(hi, lo) {
16
+ return hi === 0 ? BigInt(lo) : (BigInt(hi) << 32n) | BigInt(lo);
17
+ }
18
+ /**
19
+ * An unsigned 64-bit integer, held as two 32-bit halves so it encodes and decodes without a BigInt.
20
+ * Converting to a `number` throws past 2^53 rather than rounding.
21
+ */
22
+ export class U64 {
23
+ /** The value 0. */
24
+ static ZERO = new U64(0, 0);
25
+ /** The largest value, 2^64 - 1. */
26
+ static MAX = new U64(POW32 - 1, POW32 - 1);
27
+ /** The upper 32 bits. */
28
+ hi;
29
+ /** The lower 32 bits. */
30
+ lo;
31
+ /** Join the upper and lower 32 bits, throwing if either is not a u32. */
32
+ constructor(hi, lo) {
33
+ if (!Number.isInteger(hi) || hi < 0 || hi >= POW32)
34
+ throw new RangeError(`invalid upper half: ${hi}`);
35
+ if (!Number.isInteger(lo) || lo < 0 || lo >= POW32)
36
+ throw new RangeError(`invalid lower half: ${lo}`);
37
+ this.hi = hi;
38
+ this.lo = lo;
39
+ }
40
+ /** Convert a non-negative safe integer, throwing on anything else. */
41
+ static fromNumber(v) {
42
+ if (!Number.isSafeInteger(v) || v < 0)
43
+ throw new RangeError(`invalid u64: ${v}`);
44
+ return new U64(Math.floor(v / POW32), v >>> 0);
45
+ }
46
+ /** Convert a bigint, throwing unless it is in [0, 2^64). */
47
+ static fromBigInt(v) {
48
+ if (v < 0n || v >> 64n)
49
+ throw new RangeError(`invalid u64: ${v}`);
50
+ return new U64(Number(v >> 32n), Number(v & 0xffffffffn));
51
+ }
52
+ /** Convert to a `number`, throwing if it is above `Number.MAX_SAFE_INTEGER`. */
53
+ toNumber() {
54
+ return toNumber(this.hi, this.lo);
55
+ }
56
+ /** Convert to a bigint, exactly. */
57
+ toBigInt() {
58
+ return toBigInt(this.hi, this.lo);
59
+ }
60
+ /** The value in decimal. */
61
+ toString() {
62
+ return this.hi < SAFE_HI ? String(this.hi * POW32 + this.lo) : this.toBigInt().toString();
63
+ }
64
+ /** Negative if this is less than `other`, zero if equal, positive if greater. */
65
+ compare(other) {
66
+ return this.hi - other.hi || this.lo - other.lo;
67
+ }
68
+ /** Whether this equals `other`. */
69
+ equals(other) {
70
+ return this.hi === other.hi && this.lo === other.lo;
71
+ }
72
+ /** This plus a non-negative safe integer, throwing if the sum reaches 2^64. */
73
+ add(delta) {
74
+ if (!Number.isSafeInteger(delta) || delta < 0)
75
+ throw new RangeError(`invalid delta: ${delta}`);
76
+ const lo = this.lo + (delta >>> 0);
77
+ const hi = this.hi + Math.floor(delta / POW32) + (lo >= POW32 ? 1 : 0);
78
+ if (hi >= POW32)
79
+ throw new RangeError(`overflow, ${this} + ${delta} exceeds 64 bits`);
80
+ return new U64(hi, lo >>> 0);
81
+ }
82
+ }
83
+ //# sourceMappingURL=u64.js.map