@norskvideo/moq-net 0.1.7 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (286) hide show
  1. package/README.md +2 -2
  2. package/announce.d.ts +7 -0
  3. package/announce.d.ts.map +1 -0
  4. package/announce.js +8 -0
  5. package/announce.js.map +1 -0
  6. package/announced.d.ts +49 -91
  7. package/announced.d.ts.map +1 -1
  8. package/announced.js +21 -156
  9. package/announced.js.map +1 -1
  10. package/bandwidth.d.ts +163 -0
  11. package/bandwidth.d.ts.map +1 -0
  12. package/bandwidth.js +304 -0
  13. package/bandwidth.js.map +1 -0
  14. package/bandwidth_api.d.ts +7 -0
  15. package/bandwidth_api.d.ts.map +1 -0
  16. package/bandwidth_api.js +8 -0
  17. package/bandwidth_api.js.map +1 -0
  18. package/broadcast.d.ts +44 -35
  19. package/broadcast.d.ts.map +1 -1
  20. package/broadcast.js +104 -60
  21. package/broadcast.js.map +1 -1
  22. package/connection/accept.d.ts +16 -1
  23. package/connection/accept.d.ts.map +1 -1
  24. package/connection/accept.js +52 -28
  25. package/connection/accept.js.map +1 -1
  26. package/connection/browser.d.ts.map +1 -1
  27. package/connection/browser.js +9 -7
  28. package/connection/browser.js.map +1 -1
  29. package/connection/connect.d.ts +30 -6
  30. package/connection/connect.d.ts.map +1 -1
  31. package/connection/connect.js +110 -54
  32. package/connection/connect.js.map +1 -1
  33. package/connection/established.d.ts +17 -21
  34. package/connection/established.d.ts.map +1 -1
  35. package/connection/established.js.map +1 -1
  36. package/connection/forward.d.ts +2 -0
  37. package/connection/forward.d.ts.map +1 -0
  38. package/connection/forward.js +173 -0
  39. package/connection/forward.js.map +1 -0
  40. package/connection/handshake.d.ts +1 -0
  41. package/connection/handshake.d.ts.map +1 -1
  42. package/connection/handshake.js +5 -2
  43. package/connection/handshake.js.map +1 -1
  44. package/connection/index.d.ts +5 -5
  45. package/connection/index.d.ts.map +1 -1
  46. package/connection/index.js +4 -5
  47. package/connection/index.js.map +1 -1
  48. package/connection/pool.d.ts +186 -0
  49. package/connection/pool.d.ts.map +1 -0
  50. package/connection/pool.js +361 -0
  51. package/connection/pool.js.map +1 -0
  52. package/connection/reload.d.ts +14 -93
  53. package/connection/reload.d.ts.map +1 -1
  54. package/connection/reload.js +217 -81
  55. package/connection/reload.js.map +1 -1
  56. package/connection/stats.d.ts +3 -26
  57. package/connection/stats.d.ts.map +1 -1
  58. package/connection/stats.js.map +1 -1
  59. package/connection/transport.d.ts +0 -7
  60. package/connection/transport.d.ts.map +1 -1
  61. package/consume.d.ts +1 -43
  62. package/consume.d.ts.map +1 -1
  63. package/consume.js +1 -1
  64. package/consume.js.map +1 -1
  65. package/error.d.ts +180 -29
  66. package/error.d.ts.map +1 -1
  67. package/error.js +331 -16
  68. package/error.js.map +1 -1
  69. package/errors.d.ts +7 -0
  70. package/errors.d.ts.map +1 -0
  71. package/errors.js +8 -0
  72. package/errors.js.map +1 -0
  73. package/group.d.ts +9 -43
  74. package/group.d.ts.map +1 -1
  75. package/group.js +284 -69
  76. package/group.js.map +1 -1
  77. package/hop.d.ts +115 -0
  78. package/hop.d.ts.map +1 -0
  79. package/hop.js +119 -0
  80. package/hop.js.map +1 -0
  81. package/ietf/adapter.d.ts +5 -1
  82. package/ietf/adapter.d.ts.map +1 -1
  83. package/ietf/adapter.js +105 -60
  84. package/ietf/adapter.js.map +1 -1
  85. package/ietf/aliases.d.ts +1 -78
  86. package/ietf/aliases.d.ts.map +1 -1
  87. package/ietf/cluster.d.ts +9 -123
  88. package/ietf/cluster.d.ts.map +1 -1
  89. package/ietf/cluster.js +84 -44
  90. package/ietf/cluster.js.map +1 -1
  91. package/ietf/connection.d.ts +6 -72
  92. package/ietf/connection.d.ts.map +1 -1
  93. package/ietf/connection.js +62 -56
  94. package/ietf/connection.js.map +1 -1
  95. package/ietf/error.d.ts +11 -0
  96. package/ietf/error.d.ts.map +1 -0
  97. package/ietf/error.js +193 -0
  98. package/ietf/error.js.map +1 -0
  99. package/ietf/fetch.d.ts +7 -20
  100. package/ietf/fetch.d.ts.map +1 -1
  101. package/ietf/fetch.js +52 -22
  102. package/ietf/fetch.js.map +1 -1
  103. package/ietf/filter.d.ts +2 -0
  104. package/ietf/filter.d.ts.map +1 -1
  105. package/ietf/filter.js +10 -1
  106. package/ietf/filter.js.map +1 -1
  107. package/ietf/goaway.d.ts.map +1 -1
  108. package/ietf/goaway.js +22 -5
  109. package/ietf/goaway.js.map +1 -1
  110. package/ietf/hidden.d.ts +2 -0
  111. package/ietf/hidden.d.ts.map +1 -0
  112. package/ietf/hidden.js +30 -0
  113. package/ietf/hidden.js.map +1 -0
  114. package/ietf/index.d.ts +2 -0
  115. package/ietf/index.d.ts.map +1 -1
  116. package/ietf/index.js +2 -0
  117. package/ietf/index.js.map +1 -1
  118. package/ietf/object.d.ts +15 -8
  119. package/ietf/object.d.ts.map +1 -1
  120. package/ietf/object.js +51 -36
  121. package/ietf/object.js.map +1 -1
  122. package/ietf/parameters.d.ts +14 -2
  123. package/ietf/parameters.d.ts.map +1 -1
  124. package/ietf/parameters.js +97 -29
  125. package/ietf/parameters.js.map +1 -1
  126. package/ietf/properties.d.ts +1 -0
  127. package/ietf/properties.d.ts.map +1 -1
  128. package/ietf/properties.js +14 -0
  129. package/ietf/properties.js.map +1 -1
  130. package/ietf/publish.d.ts +19 -2
  131. package/ietf/publish.d.ts.map +1 -1
  132. package/ietf/publish.js +40 -6
  133. package/ietf/publish.js.map +1 -1
  134. package/ietf/publish_namespace.d.ts +25 -0
  135. package/ietf/publish_namespace.d.ts.map +1 -1
  136. package/ietf/publish_namespace.js +63 -0
  137. package/ietf/publish_namespace.js.map +1 -1
  138. package/ietf/publisher.d.ts +1 -82
  139. package/ietf/publisher.d.ts.map +1 -1
  140. package/ietf/publisher.js +483 -235
  141. package/ietf/publisher.js.map +1 -1
  142. package/ietf/solicit.d.ts +1 -40
  143. package/ietf/solicit.d.ts.map +1 -1
  144. package/ietf/subscribe.d.ts +8 -6
  145. package/ietf/subscribe.d.ts.map +1 -1
  146. package/ietf/subscribe.js +33 -27
  147. package/ietf/subscribe.js.map +1 -1
  148. package/ietf/subscribe_namespace.d.ts +8 -2
  149. package/ietf/subscribe_namespace.d.ts.map +1 -1
  150. package/ietf/subscribe_namespace.js +18 -8
  151. package/ietf/subscribe_namespace.js.map +1 -1
  152. package/ietf/subscriber.d.ts +1 -65
  153. package/ietf/subscriber.d.ts.map +1 -1
  154. package/ietf/subscriber.js +337 -123
  155. package/ietf/subscriber.js.map +1 -1
  156. package/ietf/token.d.ts +2 -0
  157. package/ietf/token.d.ts.map +1 -0
  158. package/ietf/token.js +99 -0
  159. package/ietf/token.js.map +1 -0
  160. package/ietf/track.d.ts +4 -0
  161. package/ietf/track.d.ts.map +1 -1
  162. package/ietf/track.js +6 -20
  163. package/ietf/track.js.map +1 -1
  164. package/ietf/version.d.ts +12 -1
  165. package/ietf/version.d.ts.map +1 -1
  166. package/ietf/version.js +13 -0
  167. package/ietf/version.js.map +1 -1
  168. package/index.d.ts +12 -7
  169. package/index.d.ts.map +1 -1
  170. package/index.js +10 -5
  171. package/index.js.map +1 -1
  172. package/internal.d.ts +115 -1
  173. package/internal.d.ts.map +1 -1
  174. package/internal.js +108 -0
  175. package/internal.js.map +1 -1
  176. package/lite/announce.d.ts +60 -10
  177. package/lite/announce.d.ts.map +1 -1
  178. package/lite/announce.js +176 -31
  179. package/lite/announce.js.map +1 -1
  180. package/lite/connection.d.ts +9 -59
  181. package/lite/connection.d.ts.map +1 -1
  182. package/lite/connection.js +34 -35
  183. package/lite/connection.js.map +1 -1
  184. package/lite/datagram.d.ts +3 -2
  185. package/lite/datagram.d.ts.map +1 -1
  186. package/lite/datagram.js +7 -8
  187. package/lite/datagram.js.map +1 -1
  188. package/lite/fetch.d.ts +15 -1
  189. package/lite/fetch.d.ts.map +1 -1
  190. package/lite/fetch.js +39 -7
  191. package/lite/fetch.js.map +1 -1
  192. package/lite/goaway.d.ts.map +1 -1
  193. package/lite/goaway.js +7 -1
  194. package/lite/goaway.js.map +1 -1
  195. package/lite/group.d.ts +30 -12
  196. package/lite/group.d.ts.map +1 -1
  197. package/lite/group.js +68 -26
  198. package/lite/group.js.map +1 -1
  199. package/lite/message.d.ts +2 -2
  200. package/lite/message.d.ts.map +1 -1
  201. package/lite/message.js +14 -5
  202. package/lite/message.js.map +1 -1
  203. package/lite/priority.d.ts +1 -61
  204. package/lite/priority.d.ts.map +1 -1
  205. package/lite/priority.js +4 -5
  206. package/lite/priority.js.map +1 -1
  207. package/lite/publisher.d.ts +1 -69
  208. package/lite/publisher.d.ts.map +1 -1
  209. package/lite/publisher.js +630 -262
  210. package/lite/publisher.js.map +1 -1
  211. package/lite/setup.d.ts +8 -8
  212. package/lite/setup.d.ts.map +1 -1
  213. package/lite/setup.js +33 -30
  214. package/lite/setup.js.map +1 -1
  215. package/lite/subscribe.d.ts +71 -17
  216. package/lite/subscribe.d.ts.map +1 -1
  217. package/lite/subscribe.js +205 -53
  218. package/lite/subscribe.js.map +1 -1
  219. package/lite/subscriber.d.ts +15 -56
  220. package/lite/subscriber.d.ts.map +1 -1
  221. package/lite/subscriber.js +451 -247
  222. package/lite/subscriber.js.map +1 -1
  223. package/lite/track.d.ts +4 -10
  224. package/lite/track.d.ts.map +1 -1
  225. package/lite/track.js +34 -29
  226. package/lite/track.js.map +1 -1
  227. package/lite/version.d.ts +42 -6
  228. package/lite/version.d.ts.map +1 -1
  229. package/lite/version.js +126 -10
  230. package/lite/version.js.map +1 -1
  231. package/origin.d.ts +256 -29
  232. package/origin.d.ts.map +1 -1
  233. package/origin.js +1427 -37
  234. package/origin.js.map +1 -1
  235. package/package.json +8 -3
  236. package/path.d.ts +25 -7
  237. package/path.d.ts.map +1 -1
  238. package/path.js +5 -3
  239. package/path.js.map +1 -1
  240. package/stream.d.ts +73 -14
  241. package/stream.d.ts.map +1 -1
  242. package/stream.js +372 -141
  243. package/stream.js.map +1 -1
  244. package/tail.d.ts +18 -0
  245. package/tail.d.ts.map +1 -0
  246. package/tail.js +167 -0
  247. package/tail.js.map +1 -0
  248. package/time.d.ts +15 -2
  249. package/time.d.ts.map +1 -1
  250. package/time.js +28 -9
  251. package/time.js.map +1 -1
  252. package/track.d.ts +211 -83
  253. package/track.d.ts.map +1 -1
  254. package/track.js +816 -205
  255. package/track.js.map +1 -1
  256. package/util/abort.d.ts +2 -0
  257. package/util/abort.d.ts.map +1 -0
  258. package/util/abort.js +20 -0
  259. package/util/abort.js.map +1 -0
  260. package/util/log.d.ts +5 -0
  261. package/util/log.d.ts.map +1 -0
  262. package/util/log.js +17 -0
  263. package/util/log.js.map +1 -0
  264. package/util/u64.d.ts +39 -0
  265. package/util/u64.d.ts.map +1 -0
  266. package/util/u64.js +83 -0
  267. package/util/u64.js.map +1 -0
  268. package/util/varint.d.ts +29 -0
  269. package/util/varint.d.ts.map +1 -0
  270. package/util/varint.js +198 -0
  271. package/util/varint.js.map +1 -0
  272. package/varint.d.ts +10 -6
  273. package/varint.d.ts.map +1 -1
  274. package/varint.js +40 -237
  275. package/varint.js.map +1 -1
  276. package/wire.d.ts +80 -0
  277. package/wire.d.ts.map +1 -0
  278. package/wire.js +32 -0
  279. package/wire.js.map +1 -0
  280. package/zod.d.ts +1 -1
  281. package/zod.d.ts.map +1 -1
  282. package/zod.js.map +1 -1
  283. package/mock.d.ts +0 -66
  284. package/mock.d.ts.map +0 -1
  285. package/mock.js +0 -243
  286. package/mock.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"reload.js","sourceRoot":"","sources":["../../src/connection/reload.ts"],"names":[],"mappings":"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","sourcesContent":["import { Effect, type Getter, Signal } from \"@moq/signals\";\nimport * as Announce from \"../announced.ts\";\nimport { error } from \"../error.ts\";\nimport type * as Path from \"../path.ts\";\nimport { empty as emptyPath } from \"../path.ts\";\nimport { type ConnectProps, connect, type WebSocketOptions, type WebTransportProps } from \"./connect.ts\";\nimport type { Established } from \"./established.ts\";\nimport type { Probe, Stats } from \"./stats.ts\";\n\n/**\n * Exponential backoff settings for {@link Reload}'s reconnect loop.\n *\n * The delays carry jitter, so a fleet of tabs knocked offline together doesn't reconnect in\n * lockstep. Every failure is retried; {@link ReloadDelay.timeout} is what stops the loop.\n */\nexport type ReloadDelay = {\n\t/** The delay in milliseconds before reconnecting (default: 1000). */\n\tinitial: DOMHighResTimeStamp;\n\n\t/** The multiplier for the delay (default: 2). */\n\tmultiplier: number;\n\n\t/** The maximum delay in milliseconds (default: 5000). */\n\tmax: DOMHighResTimeStamp;\n\n\t/**\n\t * Maximum total time in milliseconds to spend retrying before giving up (default:\n\t * 10000). Resets after each successful connection. Set to 0 for unlimited retries.\n\t */\n\ttimeout?: DOMHighResTimeStamp;\n};\n\n/** Connection and retry options for {@link Reload}. */\nexport type ReloadProps = Omit<ConnectProps, \"signal\"> & {\n\t/** Whether to reload the connection when it disconnects (default: true). */\n\tenabled?: boolean | Signal<boolean>;\n\n\t/** The URL of the relay server. */\n\turl?: URL | Signal<URL | undefined>;\n\n\t/** Backoff settings for the reconnect loop. */\n\tdelay?: ReloadDelay;\n};\n\n/**\n * How long to keep retrying before giving up, when {@link ReloadDelay.timeout} is unset.\n *\n * Short on purpose: a failure that clears within it was transient, and one that doesn't should\n * surface as an error rather than leave the page silently reconnecting for minutes.\n */\nconst DEFAULT_TIMEOUT = 10000;\n\n/** Current state of a {@link Reload} connection. */\nexport type ReloadStatus = \"connecting\" | \"connected\" | \"disconnected\";\n\n/** Maintains a MoQ connection, reconnecting with exponential backoff when it drops. */\nexport class Reload {\n\t/** Relay URL to connect to; updating it triggers a reconnect. */\n\turl: Signal<URL | undefined>;\n\n\t/** Whether reconnecting is active. */\n\tenabled: Signal<boolean>;\n\n\t/** Current connection status. */\n\tstatus = new Signal<ReloadStatus>(\"disconnected\");\n\n\t/** The currently established session, or undefined while disconnected. */\n\testablished = new Signal<Established | undefined>(undefined);\n\n\t/**\n\t * The current connection's PROBE estimates, spanning reconnects.\n\t *\n\t * Undefined while disconnected: the estimates belong to a single connection.\n\t * See {@link Established.probe}.\n\t */\n\treadonly probe: Getter<Probe | undefined>;\n\n\t/** WebTransport options applied to each connection attempt (not reactive). */\n\twebtransport?: WebTransportProps;\n\n\t/** WebSocket fallback options applied to each connection attempt (not reactive). */\n\twebsocket: WebSocketOptions | undefined;\n\n\t/**\n\t * Whether the relay supports broadcast discovery, applied to each connection attempt (not\n\t * reactive). Undefined defers to the default for the URL. See {@link Established.discovery}.\n\t */\n\tdiscovery?: boolean;\n\n\t/** Backoff settings for the reconnect loop. */\n\tdelay: ReloadDelay;\n\n\t/** The reactive effect scope driving the connect loop; closed by {@link Reload.close}. */\n\t#signals = new Effect();\n\n\t/**\n\t * Resolves when the reconnect loop stops via {@link Reload.close}.\n\t *\n\t * Rejects when the loop gives up instead, carrying the failure that was in flight when the\n\t * retry window expired.\n\t */\n\tclosed: Promise<void>;\n\t#closedResolve!: () => void;\n\t#closedReject!: (err: Error) => void;\n\n\t// The current wait between attempts, doubling per failure, and when the retry window expires.\n\t// Both are undefined between sequences, so a later edit to `delay` applies to the next one.\n\t#delay: DOMHighResTimeStamp | undefined;\n\t#deadline: DOMHighResTimeStamp | undefined;\n\n\t// Increased by 1 each time to trigger a reload.\n\t#tick = new Signal(0);\n\n\t// True after the browser freezes or hides the page until it visibly resumes.\n\t#suspended = new Signal(false);\n\n\t// Use the serialized URL as the reactive connection key. URL objects use identity\n\t// equality, but replacing one with an equivalent instance should not reconnect.\n\t#url: Getter<string | undefined>;\n\tconstructor(props?: ReloadProps) {\n\t\tthis.url = Signal.from(props?.url);\n\t\tthis.enabled = Signal.from(props?.enabled ?? false);\n\t\tthis.delay = props?.delay ?? { initial: 1000, multiplier: 2, max: 5000 };\n\t\tthis.webtransport = props?.webtransport;\n\t\tthis.websocket = props?.websocket;\n\t\tthis.discovery = props?.discovery;\n\n\t\tthis.closed = new Promise((resolve, reject) => {\n\t\t\tthis.#closedResolve = resolve;\n\t\t\tthis.#closedReject = reject;\n\t\t});\n\n\t\t// A caller is free to never await `closed`, and giving up rejects it unprompted. Marking the\n\t\t// rejection handled here keeps that from surfacing as an `unhandledrejection`; a consumer\n\t\t// awaiting the same promise still receives it.\n\t\tthis.closed.catch(() => {});\n\n\t\tif (typeof window !== \"undefined\" && typeof document !== \"undefined\") {\n\t\t\tthis.#signals.event(window, \"pagehide\", () => this.#suspended.set(true));\n\t\t\tthis.#signals.event(window, \"pageshow\", () => this.#suspended.set(false));\n\t\t\tthis.#signals.event(window, \"unload\", () => this.#suspended.set(true));\n\t\t\tthis.#signals.event(document, \"visibilitychange\", () => {\n\t\t\t\tif (!document.hidden) this.#suspended.set(false);\n\t\t\t});\n\t\t}\n\n\t\tthis.probe = this.#signals.computed((effect) => {\n\t\t\tconst connection = effect.get(this.established);\n\t\t\treturn connection && effect.get(connection.probe);\n\t\t});\n\n\t\tthis.#url = this.#signals.computed((effect) => effect.get(this.url)?.href);\n\t\t// Create a reactive root so cleanup is easier.\n\t\tthis.#signals.run(this.#connect.bind(this));\n\t}\n\n\t#connect(effect: Effect): void {\n\t\t// Will retry when the tick changes.\n\t\teffect.get(this.#tick);\n\n\t\tconst suspended = effect.get(this.#suspended);\n\t\tconst enabled = effect.get(this.enabled);\n\t\tif (!enabled || suspended) return;\n\n\t\tconst href = effect.get(this.#url);\n\t\tif (!href) return;\n\t\tconst url = new URL(href);\n\n\t\teffect.set(this.status, \"connecting\", \"disconnected\");\n\n\t\t// This run's teardown, handed to connect() so a rerun cancels the attempt in flight.\n\t\tconst signal = effect.abort;\n\n\t\teffect.spawn(async () => {\n\t\t\t// Set once the session is live, so #retry can tell a healthy session that\n\t\t\t// later dropped from a connect failure or a peer that flaps immediately.\n\t\t\tlet connected: DOMHighResTimeStamp | undefined;\n\n\t\t\ttry {\n\t\t\t\tconst connection = await connect(url, {\n\t\t\t\t\twebsocket: this.websocket,\n\t\t\t\t\twebtransport: this.webtransport,\n\t\t\t\t\tdiscovery: this.discovery,\n\t\t\t\t\tsignal,\n\t\t\t\t});\n\n\t\t\t\t// Hand the connection to the effect, which closes it now if this run is already over.\n\t\t\t\teffect.cleanup(() => connection.close());\n\t\t\t\tif (signal.aborted) return;\n\n\t\t\t\teffect.set(this.established, connection);\n\t\t\t\teffect.set(this.status, \"connected\", \"disconnected\");\n\n\t\t\t\tconnected = performance.now();\n\n\t\t\t\t// A cancelled effect resolves undefined, so the sentinel tells the session\n\t\t\t\t// closing apart from this run being torn down.\n\t\t\t\tconst closed = await Promise.race([effect.cancel, connection.closed.then(() => true)]);\n\t\t\t\tif (!closed) return;\n\n\t\t\t\tconsole.warn(\"connection closed, reconnecting\");\n\t\t\t\tthis.#retry(effect, connected);\n\t\t\t} catch (err) {\n\t\t\t\t// Treat teardown as cancellation, not a connection failure.\n\t\t\t\tif (signal.aborted) return;\n\n\t\t\t\tconsole.warn(\"connection error:\", err);\n\t\t\t\tthis.#retry(effect, connected, err);\n\t\t\t}\n\t\t});\n\t}\n\n\t/**\n\t * Schedule the next connect attempt after the current backoff, or stop once the retry window\n\t * has expired. `connected` is when the dead session was established, if it ever was, and\n\t * `cause` the error that killed it, if it died with one.\n\t */\n\t#retry(effect: Effect, connected: DOMHighResTimeStamp | undefined, cause?: unknown): void {\n\t\t// Any session is dead now: report disconnected during the backoff rather than\n\t\t// when the retry reruns the effect.\n\t\tthis.established.set(undefined);\n\t\tthis.status.set(\"disconnected\");\n\n\t\t// A session that outlived the initial delay was healthy, so clear the backoff and\n\t\t// start a fresh retry window: a one-off drop should reconnect promptly. Anything\n\t\t// shorter is a peer that accepts and immediately severs, which has to keep\n\t\t// escalating or we hammer it forever at the initial delay.\n\t\tif (connected !== undefined && performance.now() - connected >= this.delay.initial) {\n\t\t\tthis.#delay = undefined;\n\t\t\tthis.#deadline = undefined;\n\t\t}\n\n\t\tconst now = performance.now();\n\t\tconst timeout = this.delay.timeout ?? DEFAULT_TIMEOUT;\n\t\tthis.#delay ??= this.delay.initial;\n\t\tthis.#deadline ??= timeout > 0 ? now + timeout : Number.POSITIVE_INFINITY;\n\n\t\tif (now >= this.#deadline) {\n\t\t\tconsole.warn(\"reconnect timed out\");\n\t\t\t// A graceful close has no error, so report the timeout itself.\n\t\t\tthis.#closedReject(cause === undefined ? new Error(\"reconnect timed out\") : error(cause));\n\t\t\treturn;\n\t\t}\n\n\t\t// Equal jitter, so a fleet of tabs knocked offline together doesn't reconnect on the same\n\t\t// tick, and never past the deadline the retry window promised.\n\t\tconst wait = Math.min(this.#delay * (0.5 + Math.random() / 2), this.#deadline - now);\n\t\tthis.#delay = Math.min(this.#delay * this.delay.multiplier, this.delay.max);\n\n\t\tconst tick = this.#tick.peek() + 1;\n\t\teffect.timer(() => this.#tick.update((prev) => Math.max(prev, tick)), wait);\n\t}\n\n\t/**\n\t * Subscribe to broadcast announcements under an optional prefix, spanning reconnects.\n\t *\n\t * The same {@link Announce.Consumer} stream as {@link Established.announced}, but everything active\n\t * is retracted (an `active: false` update) whenever the connection drops and re-announced on\n\t * reconnect, so a consumer draining `next()` never clings to a dead route across a reconnect.\n\t *\n\t * Stays empty while the relay lacks {@link Established.discovery}.\n\t */\n\tannounced(prefix: Path.Valid = emptyPath()): Announce.Consumer {\n\t\tconst producer = new Announce.Producer(prefix);\n\t\tconst consumer = producer.consume();\n\n\t\t// Closing the consumer closes the shared state, so stop appending after that.\n\t\tlet closed = false;\n\t\tvoid consumer.closed.then(() => {\n\t\t\tclosed = true;\n\t\t});\n\n\t\tconst pump = new Effect();\n\t\tpump.run((effect) => {\n\t\t\tconst conn = effect.get(this.established);\n\t\t\tif (!conn) return;\n\n\t\t\t// Without discovery the upstream announce stream never yields, so leave the\n\t\t\t// consumer empty rather than opening a subscription that can't be answered.\n\t\t\tif (!conn.discovery) return;\n\n\t\t\tconst upstream = conn.announced(prefix);\n\t\t\teffect.cleanup(() => upstream.close());\n\n\t\t\t// Track what this connection announced so we can retract it if the connection drops.\n\t\t\tconst active = new Set<Path.Valid>();\n\n\t\t\teffect.spawn(async () => {\n\t\t\t\ttry {\n\t\t\t\t\tfor (;;) {\n\t\t\t\t\t\tconst entry = await Promise.race([effect.cancel, upstream.next()]);\n\t\t\t\t\t\tif (!entry) break;\n\t\t\t\t\t\tif (entry.active) active.add(entry.path);\n\t\t\t\t\t\telse active.delete(entry.path);\n\t\t\t\t\t\tproducer.append(entry);\n\t\t\t\t\t}\n\t\t\t\t} catch {\n\t\t\t\t\t// A dropped connection resets the announce stream; the retractions below cover it.\n\t\t\t\t} finally {\n\t\t\t\t\t// Retract everything from the connection that just went away, so a per-broadcast\n\t\t\t\t\t// watcher tears down instead of clinging to the dead route.\n\t\t\t\t\tif (!closed) {\n\t\t\t\t\t\tfor (const path of active) {\n\t\t\t\t\t\t\tproducer.append({ path, active: false });\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t});\n\n\t\tthis.#signals.cleanup(() => pump.close());\n\t\tvoid consumer.closed.then(() => pump.close());\n\n\t\treturn consumer;\n\t}\n\n\t/**\n\t * A reactive handle to one broadcast, spanning reconnects.\n\t *\n\t * The same {@link Announce.Broadcast} as {@link Established.announcedBroadcast}, but it\n\t * follows the reconnect loop: the broadcast drops to `undefined` when the connection dies\n\t * and resolves again once the new connection announces the path. Use it instead of\n\t * consuming off {@link Reload.established} whenever the broadcast may come online after you\n\t * do, which is exactly the case a blind `consume` loses.\n\t *\n\t * Close the handle when done; {@link Reload.close} only drops it to `undefined`.\n\t */\n\tannouncedBroadcast(path: Path.Valid): Announce.Broadcast {\n\t\treturn new Announce.Broadcast({ connection: this.established, path });\n\t}\n\n\t/**\n\t * Snapshot the live connection's transport counters, or undefined while disconnected.\n\t * See {@link Established.stats}.\n\t */\n\tasync stats(): Promise<Stats | undefined> {\n\t\treturn this.established.peek()?.stats();\n\t}\n\n\t/** Stop reconnecting, close the current connection, and resolve {@link Reload.closed}. */\n\tclose() {\n\t\tthis.#signals.close();\n\t\tthis.#closedResolve();\n\t}\n}\n"]}
1
+ {"version":3,"file":"reload.js","sourceRoot":"","sources":["../../src/connection/reload.ts"],"names":[],"mappings":"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","sourcesContent":["import { Effect, type GetPromise, type Getter, Once, Signal } from \"@moq/signals\";\nimport * as Announce from \"../announced.ts\";\nimport { Allocator } from \"../bandwidth.ts\";\nimport { error, SessionCode, SessionError } from \"../error.ts\";\nimport type { Consumer as OriginConsumer, Producer as OriginProducer } from \"../origin.ts\";\nimport * as Path from \"../path.ts\";\nimport * as Time from \"../time.ts\";\nimport { wireOf } from \"../wire.ts\";\nimport { type ConnectProps, connect, type WebSocketProps, type WebTransportProps } from \"./connect.ts\";\nimport type { Established } from \"./established.ts\";\nimport type { Probe, Stats } from \"./stats.ts\";\n\n/**\n * Exponential backoff settings for the reconnect loop.\n *\n * The delays carry jitter, so a fleet of tabs knocked offline together doesn't reconnect in\n * lockstep. Every failure is retried; {@link ReloadDelay.timeout} is what stops the current\n * URL. A new URL or a disable/re-enable starts another sequence.\n */\nexport type ReloadDelay = {\n\t/** The delay before reconnecting (default: 1000ms). */\n\tinitial?: Time.Milli;\n\n\t/** The multiplier for the delay (default: 2). */\n\tmultiplier?: number;\n\n\t/** The maximum delay (default: 5000ms). */\n\tmax?: Time.Milli;\n\n\t/**\n\t * Maximum total time to spend retrying the current URL before giving up\n\t * (default: 10000ms). Resets after each successful connection, a URL change, or a\n\t * disable/re-enable. Set to 0 for unlimited retries.\n\t */\n\ttimeout?: Time.Milli;\n};\n\n/**\n * Connection and retry options for {@link Reload}.\n *\n * {@link ConnectProps.transport} is excluded: a supplied session is good for exactly one\n * connection, so the reconnect loop has nothing to reuse once that session drops. Call\n * {@link connect} directly when you have a session to hand over.\n *\n * @internal\n */\nexport type ReloadProps = Omit<ConnectProps, \"url\" | \"signal\" | \"transport\"> & {\n\t/** A reload owns the abort signal for each connection attempt. */\n\tsignal?: never;\n\n\t/** A one-shot transport cannot be reused by the reconnect loop. */\n\ttransport?: never;\n\n\t/** Whether to reload the connection when it disconnects (default: true). */\n\tenabled?: boolean | Signal<boolean>;\n\n\t/** The URL of the relay server. */\n\turl?: URL | Signal<URL | undefined>;\n\n\t/** Backoff settings for the reconnect loop; every field falls back to its default. */\n\tdelay?: ReloadDelay;\n};\n\n/**\n * The backoff applied to whichever {@link ReloadDelay} fields a caller leaves out.\n *\n * The timeout is short on purpose: a failure that clears within it was transient, and one that\n * doesn't should surface on {@link Reload.error} rather than leave the page silently\n * reconnecting for minutes. A loop nobody watches wants `timeout: 0` instead, since there is\n * no one to react. Giving up does not dispose the loop: a new URL or a disable/re-enable\n * starts another sequence.\n */\nconst DEFAULT_DELAY: Required<ReloadDelay> = {\n\tinitial: Time.Milli(1000),\n\tmultiplier: 2,\n\tmax: Time.Milli(5000),\n\ttimeout: Time.Milli(10000),\n};\n\n/** How often the send-rate estimate is sampled from the live transport. */\nconst BANDWIDTH_POLL = 100;\n\n/** Current state of a reconnecting connection. */\nexport type ReloadStatus = \"connecting\" | \"connected\" | \"disconnected\";\n\n/**\n * The reconnect loop behind a Connection handle: connects, waits for the session to end, then\n * redials with exponential backoff.\n *\n * @internal\n */\nexport class Reload {\n\t/** Relay URL to connect to; updating it triggers a reconnect. */\n\turl: Signal<URL | undefined>;\n\n\t/** Whether reconnecting is active. */\n\tenabled: Signal<boolean>;\n\n\t/** Current connection status. */\n\tstatus = new Signal<ReloadStatus>(\"disconnected\");\n\n\t/**\n\t * The failure that stopped retrying the current URL, or undefined while the loop is live.\n\t *\n\t * Set on an auth rejection or when the retry window expires. Cleared when a new URL or a\n\t * disable/re-enable starts another sequence, not on a page hide/show. Transient drops\n\t * that are still being retried leave this empty.\n\t */\n\treadonly error: Getter<Error | undefined>;\n\n\t/** The currently established session, or undefined while disconnected. */\n\testablished = new Signal<Established | undefined>(undefined);\n\n\t/**\n\t * The current connection's PROBE estimates, spanning reconnects.\n\t *\n\t * Undefined while disconnected: the estimates belong to a single connection.\n\t * See {@link Established.probe}.\n\t */\n\treadonly probe: Getter<Probe | undefined>;\n\n\t/**\n\t * Divides this connection's send-rate estimate among the tracks sharing it.\n\t *\n\t * The same instance across reconnects, so reservations survive a drop. The\n\t * estimate is `undefined` while disconnected, which tells a sender to hold\n\t * its rate rather than encode at zero.\n\t */\n\treadonly bandwidth: Allocator;\n\n\t/** WebTransport options applied to each connection attempt (not reactive). */\n\twebtransport?: WebTransportProps;\n\n\t/** WebSocket fallback options applied to each connection attempt (not reactive). */\n\twebsocket: WebSocketProps | undefined;\n\n\t/**\n\t * Whether the relay supports broadcast discovery, applied to each connection attempt (not\n\t * reactive). Undefined defers to the default for the URL. See {@link Established.discovery}.\n\t */\n\tdiscovery?: boolean;\n\n\t/**\n\t * The origin whose broadcasts are served, spanning reconnects (not reactive).\n\t *\n\t * Each session announces the origin's table when it attaches, so a broadcast published\n\t * while offline surfaces on the next connection and a reconnect re-announces everything\n\t * still published. See the `publish` connect option.\n\t */\n\tpublish?: OriginConsumer;\n\n\t/**\n\t * The origin fed with the peer's announced broadcasts, spanning reconnects (not\n\t * reactive).\n\t *\n\t * The entries a session fed retract when it dies, and the next session re-populates the\n\t * table, so a consumer watching the origin sees offline/online transitions across a\n\t * reconnect. See the `consume` connect option.\n\t */\n\tconsume?: OriginProducer;\n\n\t/** Backoff settings for the reconnect loop; an unset field uses its default. */\n\tdelay: ReloadDelay;\n\n\t/** The reactive effect scope driving the connect loop; closed by {@link Reload.close}. */\n\t#signals = new Effect();\n\n\t// Sampled from the live session; undefined while disconnected or the transport has none.\n\t#estimate = new Signal<number | undefined>(undefined);\n\n\t/**\n\t * Settles once this loop is disposed via {@link Reload.close}: `null` on a clean close,\n\t * or the abort {@link Error}. Peek it synchronously (`undefined` while open), observe it\n\t * reactively, or `await` it. Attempt failures live on {@link Reload.error} instead.\n\t */\n\tget closed(): GetPromise<Error | null> {\n\t\treturn this.#closed;\n\t}\n\n\t#closed = new Once<Error | null>();\n\t#error = new Signal<Error | undefined>(undefined);\n\n\t// The current wait between attempts, doubling per failure, and when the retry window expires.\n\t// Both are undefined between sequences, so a later edit to `delay` applies to the next one.\n\t#delay: DOMHighResTimeStamp | undefined;\n\t#deadline: DOMHighResTimeStamp | undefined;\n\n\t// The URL the current retry sequence is for. Cleared when disabled, URL-less, or given\n\t// up, so the next attempt starts a fresh backoff window.\n\t#sequenceHref: string | undefined;\n\n\t// The href that exhausted its retry sequence. Survives a page hide/show so resume does\n\t// not redial credentials the peer already refused. Cleared when the URL changes or the\n\t// loop is disabled.\n\t#givenUpHref: string | undefined;\n\n\t// Increased by 1 each time to trigger a reload.\n\t#tick = new Signal(0);\n\n\t// True after the browser freezes or hides the page until it visibly resumes.\n\t#suspended = new Signal(false);\n\n\t// Use the serialized URL as the reactive connection key. URL objects use identity\n\t// equality, but replacing one with an equivalent instance should not reconnect.\n\t#url: Getter<string | undefined>;\n\tconstructor(props?: ReloadProps) {\n\t\tthis.url = Signal.from(props?.url);\n\t\tthis.enabled = Signal.from(props?.enabled ?? true);\n\t\tthis.delay = props?.delay ?? {};\n\t\tthis.webtransport = props?.webtransport;\n\t\tthis.websocket = props?.websocket;\n\t\tthis.discovery = props?.discovery;\n\t\tthis.publish = props?.publish;\n\t\tthis.consume = props?.consume;\n\n\t\t// Requests on the consume origin stay pending across a reconnect, and before the\n\t\t// first session establishes, rather than reading as unroutable the moment no session\n\t\t// is attached. Released only when this loop is disposed: giving up the current URL\n\t\t// is recoverable (a new URL or a disable/re-enable starts another sequence), so a\n\t\t// request must keep waiting rather than go unroutable in the gap.\n\t\tif (this.consume) {\n\t\t\tthis.#signals.cleanup(wireOf(this.consume).expect());\n\t\t}\n\n\t\tthis.error = this.#error;\n\n\t\tconst win = globalThis.window;\n\t\tconst doc = globalThis.document;\n\t\tif (typeof win !== \"undefined\" && typeof doc !== \"undefined\") {\n\t\t\tthis.#signals.event(win, \"pagehide\", () => this.#suspended.set(true));\n\t\t\tthis.#signals.event(win, \"pageshow\", () => this.#suspended.set(false));\n\t\t\tthis.#signals.event(win, \"unload\", () => this.#suspended.set(true));\n\t\t\tthis.#signals.event(doc, \"visibilitychange\", () => {\n\t\t\t\tif (!doc.hidden) this.#suspended.set(false);\n\t\t\t});\n\t\t}\n\n\t\tthis.probe = this.#signals.computed((effect) => {\n\t\t\tconst connection = effect.get(this.established);\n\t\t\treturn connection && effect.get(connection.probe);\n\t\t});\n\n\t\tthis.bandwidth = new Allocator(this.#estimate);\n\t\tthis.#signals.cleanup(() => this.bandwidth.close());\n\n\t\t// The transport has no event for the send-rate estimate, so sample on our\n\t\t// own schedule and skip a tick while the previous snapshot is outstanding.\n\t\tthis.#signals.run((effect) => {\n\t\t\teffect.set(this.#estimate, undefined);\n\t\t\tconst connection = effect.get(this.established);\n\t\t\tif (!connection) return;\n\n\t\t\tlet pending = false;\n\t\t\tconst sample = async () => {\n\t\t\t\tif (pending) return;\n\t\t\t\tpending = true;\n\t\t\t\ttry {\n\t\t\t\t\tconst stats = await effect.race(connection.stats());\n\t\t\t\t\tif (stats) this.#estimate.set(stats.estimatedSendRate);\n\t\t\t\t} finally {\n\t\t\t\t\tpending = false;\n\t\t\t\t}\n\t\t\t};\n\n\t\t\tvoid sample();\n\t\t\teffect.interval(() => void sample(), BANDWIDTH_POLL);\n\t\t});\n\n\t\tthis.#url = this.#signals.computed((effect) => effect.get(this.url)?.href);\n\t\t// Create a reactive root so cleanup is easier.\n\t\tthis.#signals.run(this.#connect.bind(this));\n\t}\n\n\t#connect(effect: Effect): void {\n\t\t// Will retry when the tick changes.\n\t\teffect.get(this.#tick);\n\n\t\tconst enabled = effect.get(this.enabled);\n\t\tif (!enabled) {\n\t\t\tthis.#givenUpHref = undefined;\n\t\t\tthis.#resetSequence();\n\t\t\treturn;\n\t\t}\n\n\t\t// Hide/freeze pauses an in-flight sequence without recovering from give-up.\n\t\tconst suspended = effect.get(this.#suspended);\n\t\tif (suspended) {\n\t\t\tthis.#resetSequence();\n\t\t\treturn;\n\t\t}\n\n\t\tconst href = effect.get(this.#url);\n\t\tif (!href) {\n\t\t\tthis.#givenUpHref = undefined;\n\t\t\tthis.#resetSequence();\n\t\t\treturn;\n\t\t}\n\t\tconst url = new URL(href);\n\n\t\tif (this.#givenUpHref === href) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (this.#sequenceHref !== href) {\n\t\t\tthis.#resetSequence();\n\t\t\tthis.#sequenceHref = href;\n\t\t\tthis.#error.set(undefined);\n\t\t\tthis.#givenUpHref = undefined;\n\t\t}\n\n\t\teffect.set(this.status, \"connecting\", \"disconnected\");\n\n\t\t// This run's teardown, handed to connect() so a rerun cancels the attempt in flight.\n\t\tconst signal = effect.abort;\n\n\t\teffect.spawn(async () => {\n\t\t\t// Set once the session is live, so #retry can tell a healthy session that\n\t\t\t// later dropped from a connect failure or a peer that flaps immediately.\n\t\t\tlet connected: DOMHighResTimeStamp | undefined;\n\n\t\t\ttry {\n\t\t\t\tconst connection = await connect({\n\t\t\t\t\turl,\n\t\t\t\t\twebsocket: this.websocket,\n\t\t\t\t\twebtransport: this.webtransport,\n\t\t\t\t\tdiscovery: this.discovery,\n\t\t\t\t\tpublish: this.publish,\n\t\t\t\t\tconsume: this.consume,\n\t\t\t\t\tsignal,\n\t\t\t\t});\n\n\t\t\t\t// Hand the connection to the effect, which closes it now if this run is already over.\n\t\t\t\teffect.cleanup(() => connection.close());\n\t\t\t\tif (signal.aborted) return;\n\n\t\t\t\teffect.set(this.established, connection);\n\t\t\t\teffect.set(this.status, \"connected\", \"disconnected\");\n\n\t\t\t\tconnected = performance.now();\n\n\t\t\t\t// A cancelled effect resolves undefined, so the sentinel tells the session\n\t\t\t\t// closing (null for clean, an Error otherwise) apart from this run being\n\t\t\t\t// torn down.\n\t\t\t\tconst closed = await effect.race(connection.closed);\n\t\t\t\tif (closed === undefined) return;\n\n\t\t\t\tconsole.warn(\"connection closed, reconnecting\");\n\t\t\t\tthis.#retry(effect, connected, closed ?? undefined);\n\t\t\t} catch (err) {\n\t\t\t\t// Treat teardown as cancellation, not a connection failure.\n\t\t\t\tif (signal.aborted) return;\n\n\t\t\t\tconsole.warn(\"connection error:\", err);\n\t\t\t\tthis.#retry(effect, connected, err);\n\t\t\t}\n\t\t});\n\t}\n\n\t/**\n\t * Schedule the next connect attempt after the current backoff, or stop once the retry window\n\t * has expired. `connected` is when the dead session was established, if it ever was, and\n\t * `cause` the error that killed it, if it died with one.\n\t */\n\t#retry(effect: Effect, connected: DOMHighResTimeStamp | undefined, cause?: unknown): void {\n\t\t// Resolved per sequence rather than at construction, so an edit to `delay` (including\n\t\t// one that drops a field back to its default) applies to the next retry. Field by\n\t\t// field rather than by spread: a caller building `{ initial: maybeInitial }` from an\n\t\t// optional value passes an explicit undefined, which a spread would take as the\n\t\t// answer, turning the backoff into NaN or the window into forever.\n\t\tconst delay = this.delay ?? {};\n\t\tconst initial = delay.initial ?? DEFAULT_DELAY.initial;\n\t\tconst multiplier = delay.multiplier ?? DEFAULT_DELAY.multiplier;\n\t\tconst max = delay.max ?? DEFAULT_DELAY.max;\n\t\tconst timeout = delay.timeout ?? DEFAULT_DELAY.timeout;\n\n\t\t// Any session is dead now: report disconnected during the backoff rather than\n\t\t// when the retry reruns the effect.\n\t\tthis.established.set(undefined);\n\t\tthis.status.set(\"disconnected\");\n\n\t\t// A session that outlived the initial delay was healthy, so clear the backoff and\n\t\t// start a fresh retry window: a one-off drop should reconnect promptly. Anything\n\t\t// shorter is a peer that accepts and immediately severs, which has to keep\n\t\t// escalating or we hammer it forever at the initial delay.\n\t\tif (connected !== undefined && performance.now() - connected >= initial) {\n\t\t\tthis.#delay = undefined;\n\t\t\tthis.#deadline = undefined;\n\t\t}\n\n\t\t// An auth rejection stops this URL however long the session lived. UNAUTHORIZED is a\n\t\t// specified code rather than one we guessed at, so this is the peer saying these\n\t\t// credentials will never work; retrying them just burns the window. Matches\n\t\t// moq-tokio's reconnect loop, which stops on the same close. A new URL or a\n\t\t// disable/re-enable starts another sequence; the handle itself is not disposed.\n\t\t//\n\t\t// Only a session close says that. The stream registry gives 2 to DELIVERY_TIMEOUT,\n\t\t// so a stream reset during the SETUP exchange would otherwise suppress reconnect\n\t\t// for good.\n\t\tif (cause instanceof SessionError && cause.code === SessionCode.Unauthorized) {\n\t\t\tconsole.warn(\"session rejected as unauthorized, not retrying\");\n\t\t\tthis.#giveUp(cause);\n\t\t\treturn;\n\t\t}\n\n\t\tconst now = performance.now();\n\t\tthis.#delay ??= initial;\n\t\tthis.#deadline ??= timeout > 0 ? now + timeout : Number.POSITIVE_INFINITY;\n\n\t\tif (now >= this.#deadline) {\n\t\t\tconsole.warn(\"reconnect timed out\");\n\t\t\t// A graceful close has no error, so report the timeout itself.\n\t\t\tthis.#giveUp(cause === undefined ? new Error(\"reconnect timed out\") : error(cause));\n\t\t\treturn;\n\t\t}\n\n\t\t// Equal jitter, so a fleet of tabs knocked offline together doesn't reconnect on the same\n\t\t// tick, and never past the deadline the retry window promised.\n\t\tconst wait = Math.min(this.#delay * (0.5 + Math.random() / 2), this.#deadline - now);\n\t\tthis.#delay = Math.min(this.#delay * multiplier, max);\n\n\t\tconst tick = this.#tick.peek() + 1;\n\t\teffect.timer(() => this.#tick.update((prev) => Math.max(prev, tick)), wait);\n\t}\n\n\t#giveUp(cause: Error): void {\n\t\tthis.#error.set(cause);\n\t\tthis.#givenUpHref = this.#sequenceHref;\n\t\tthis.#resetSequence();\n\t}\n\n\t#resetSequence(): void {\n\t\tthis.#delay = undefined;\n\t\tthis.#deadline = undefined;\n\t\tthis.#sequenceHref = undefined;\n\t}\n\n\t/**\n\t * Subscribe to broadcast announcements matching `scope`, spanning reconnects.\n\t *\n\t * The same {@link Announce.Consumer} stream as {@link Established.announced}, but everything active\n\t * is retracted (a `retracted` update) whenever the connection drops and re-announced on\n\t * reconnect, so a consumer draining `next()` never clings to a dead route across a reconnect.\n\t *\n\t * Stays empty while the relay lacks {@link Established.discovery}.\n\t */\n\tannounced(scope: Path.Pattern = Path.Pattern.all(), options?: Announce.Options): Announce.Consumer {\n\t\t// With a consume origin the table already spans reconnects (the forwarder retracts\n\t\t// a dead session's entries), so its stream is the same thing with less machinery.\n\t\tif (this.consume) return this.consume.announced(scope, options);\n\n\t\tconst producer = new Announce.Producer();\n\t\tconst consumer = producer.consume();\n\n\t\tconst pump = new Effect();\n\t\tpump.run((effect) => {\n\t\t\tconst conn = effect.get(this.established);\n\t\t\tif (!conn) return;\n\n\t\t\t// Without discovery the upstream announce stream never yields, so leave the\n\t\t\t// consumer empty rather than opening a subscription that can't be answered.\n\t\t\tif (!conn.discovery) return;\n\n\t\t\tconst upstream = conn.announced(scope, options);\n\t\t\teffect.cleanup(() => upstream.close());\n\n\t\t\t// Track what this connection announced so we can retract it if the connection\n\t\t\t// drops; the last event rides along for the retraction.\n\t\t\tconst active = new Map<Path.Valid, Announce.Update>();\n\n\t\t\teffect.spawn(async () => {\n\t\t\t\ttry {\n\t\t\t\t\tfor (;;) {\n\t\t\t\t\t\tconst entry = await effect.race(upstream.next());\n\t\t\t\t\t\tif (!entry) break;\n\t\t\t\t\t\tif (Announce.isActive(entry.kind)) active.set(entry.prefix, entry);\n\t\t\t\t\t\telse active.delete(entry.prefix);\n\t\t\t\t\t\tproducer.append(entry);\n\t\t\t\t\t}\n\t\t\t\t} catch {\n\t\t\t\t\t// A dropped connection resets the announce stream; the retractions below cover it.\n\t\t\t\t} finally {\n\t\t\t\t\t// Retract everything from the connection that just went away, so a per-broadcast\n\t\t\t\t\t// watcher tears down instead of clinging to the dead route.\n\t\t\t\t\tif (consumer.closed.peek() === undefined) {\n\t\t\t\t\t\tfor (const entry of active.values()) {\n\t\t\t\t\t\t\tproducer.append({ ...entry, kind: \"retracted\" });\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t});\n\n\t\tthis.#signals.cleanup(() => pump.close());\n\t\tvoid consumer.closed.then(() => pump.close());\n\n\t\treturn consumer;\n\t}\n\n\t/**\n\t * Snapshot the live connection's transport counters, or undefined while disconnected.\n\t * See {@link Established.stats}.\n\t */\n\tasync stats(): Promise<Stats | undefined> {\n\t\treturn this.established.peek()?.stats();\n\t}\n\n\t/** Stop reconnecting, close the current connection, and settle {@link Reload.closed}. Idempotent. */\n\tclose(abort?: Error) {\n\t\tthis.#signals.close();\n\t\tif (this.#closed.peek() === undefined) this.#closed.set(abort ?? null);\n\t}\n}\n"]}
@@ -14,10 +14,10 @@ import * as Time from "../time";
14
14
  * Every field is optional. The qmux/WebSocket fallback implements no `getStats()` at
15
15
  * all and reports nothing; see {@link Probe} for what the peer measures.
16
16
  *
17
- * The field names match Rust's `moq_net::ConnectionStats` but the counters keep each
17
+ * The field names match Rust's `moq_net::session::Stats` but the counters keep each
18
18
  * stack's own semantics rather than being normalized. Notably W3C excludes
19
- * retransmissions and QUIC overhead from the byte counts where quinn includes them,
20
- * and counts packets where quinn counts datagrams.
19
+ * retransmissions and QUIC overhead from the byte counts where native QUIC includes
20
+ * them, and counts packets where native QUIC counts datagrams.
21
21
  *
22
22
  * @public
23
23
  */
@@ -66,27 +66,4 @@ export interface Probe {
66
66
  /** The peer's estimate of the bitrate it is receiving from us, in bits per second. */
67
67
  estimatedRecvRate?: number;
68
68
  }
69
- /**
70
- * The subset of the W3C `WebTransportConnectionStats` dictionary we consume.
71
- * `getStats()` is not in TypeScript's DOM lib yet, so it is declared here.
72
- *
73
- * @internal
74
- */
75
- export interface TransportStats {
76
- smoothedRtt?: number;
77
- estimatedSendRate?: number | null;
78
- bytesSent?: number;
79
- bytesReceived?: number;
80
- bytesLost?: number;
81
- packetsSent?: number;
82
- packetsReceived?: number;
83
- packetsLost?: number;
84
- }
85
- /**
86
- * Snapshot `quic` via `getStats()`, or an empty snapshot when the transport doesn't
87
- * implement it (the qmux/WebSocket fallback, older browsers) or the call fails.
88
- *
89
- * @internal
90
- */
91
- export declare function transportStats(quic: WebTransport): Promise<Stats>;
92
69
  //# sourceMappingURL=stats.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"stats.d.ts","sourceRoot":"","sources":["../../src/connection/stats.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,KAAK,IAAI,MAAM,YAAY,CAAC;AAEnC;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,WAAW,KAAK;IACrB;;;;;OAKG;IACH,GAAG,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC;IAEjB,mFAAmF;IACnF,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAE3B,8FAA8F;IAC9F,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB,oGAAoG;IACpG,aAAa,CAAC,EAAE,MAAM,CAAC;IAEvB,4FAA4F;IAC5F,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB,qDAAqD;IACrD,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB,oDAAoD;IACpD,eAAe,CAAC,EAAE,MAAM,CAAC;IAEzB,8FAA8F;IAC9F,WAAW,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;;;;;;;;GASG;AACH,MAAM,WAAW,KAAK;IACrB;;;;;;OAMG;IACH,GAAG,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC;IAEjB,sFAAsF;IACtF,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED;;;;;GAKG;AACH,MAAM,WAAW,cAAc;IAC9B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,iBAAiB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,WAAW,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;;;;GAKG;AACH,wBAAsB,cAAc,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,KAAK,CAAC,CAkBvE"}
1
+ {"version":3,"file":"stats.d.ts","sourceRoot":"","sources":["../../src/connection/stats.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,KAAK,IAAI,MAAM,YAAY,CAAC;AAEnC;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,WAAW,KAAK;IACrB;;;;;OAKG;IACH,GAAG,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC;IAEjB,mFAAmF;IACnF,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAE3B,8FAA8F;IAC9F,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB,oGAAoG;IACpG,aAAa,CAAC,EAAE,MAAM,CAAC;IAEvB,4FAA4F;IAC5F,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB,qDAAqD;IACrD,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB,oDAAoD;IACpD,eAAe,CAAC,EAAE,MAAM,CAAC;IAEzB,8FAA8F;IAC9F,WAAW,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;;;;;;;;GASG;AACH,MAAM,WAAW,KAAK;IACrB;;;;;;OAMG;IACH,GAAG,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC;IAEjB,sFAAsF;IACtF,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC3B"}
@@ -1 +1 @@
1
- {"version":3,"file":"stats.js","sourceRoot":"","sources":["../../src/connection/stats.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,KAAK,IAAI,MAAM,YAAY,CAAC;AA2FnC;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,IAAkB;IACtD,MAAM,QAAQ,GAAI,IAAqD,CAAC,QAAQ,CAAC;IACjF,IAAI,OAAO,QAAQ,KAAK,UAAU;QAAE,OAAO,EAAE,CAAC;IAC9C,IAAI,CAAC;QACJ,MAAM,KAAK,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACxC,OAAO;YACN,GAAG,EAAE,KAAK,CAAC,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,SAAS;YAChF,iBAAiB,EAAE,KAAK,CAAC,iBAAiB,IAAI,SAAS;YACvD,SAAS,EAAE,KAAK,CAAC,SAAS;YAC1B,aAAa,EAAE,KAAK,CAAC,aAAa;YAClC,SAAS,EAAE,KAAK,CAAC,SAAS;YAC1B,WAAW,EAAE,KAAK,CAAC,WAAW;YAC9B,eAAe,EAAE,KAAK,CAAC,eAAe;YACtC,WAAW,EAAE,KAAK,CAAC,WAAW;SAC9B,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACR,OAAO,EAAE,CAAC;IACX,CAAC;AACF,CAAC","sourcesContent":["/**\n * Connection statistics: what the local transport counts, and what the peer reports.\n *\n * @module\n */\nimport * as Time from \"../time.ts\";\n\n/**\n * A point-in-time snapshot of the transport's counters, from `WebTransport.getStats()`.\n *\n * Pulled on demand rather than pushed: the transport has no event to subscribe to, and\n * a caller computing a rate wants to choose its own sampling instants. Snapshot twice\n * and divide by the interval you measured.\n *\n * Every field is optional. The qmux/WebSocket fallback implements no `getStats()` at\n * all and reports nothing; see {@link Probe} for what the peer measures.\n *\n * The field names match Rust's `moq_net::ConnectionStats` but the counters keep each\n * stack's own semantics rather than being normalized. Notably W3C excludes\n * retransmissions and QUIC overhead from the byte counts where quinn includes them,\n * and counts packets where quinn counts datagrams.\n *\n * @public\n */\nexport interface Stats {\n\t/**\n\t * Smoothed round-trip time estimate in milliseconds.\n\t *\n\t * Usually absent: browsers don't report an RTT yet even though the W3C dictionary\n\t * has the field. Use {@link Probe.rtt}, which the peer measures.\n\t */\n\trtt?: Time.Milli;\n\n\t/** Estimated send bandwidth from the congestion controller, in bits per second. */\n\testimatedSendRate?: number;\n\n\t/** Total bytes sent on streams and datagrams, excluding retransmissions and QUIC overhead. */\n\tbytesSent?: number;\n\n\t/** Total bytes received on streams and datagrams, including duplicates, excluding QUIC overhead. */\n\tbytesReceived?: number;\n\n\t/** Bytes currently declared lost. The estimate can decrease when a loss proves spurious. */\n\tbytesLost?: number;\n\n\t/** Total packets sent, including retransmissions. */\n\tpacketsSent?: number;\n\n\t/** Total packets received, including duplicates. */\n\tpacketsReceived?: number;\n\n\t/** Packets currently declared lost. The estimate can decrease when a loss proves spurious. */\n\tpacketsLost?: number;\n}\n\n/**\n * Estimates measured by the peer and delivered over the MoQ PROBE stream.\n *\n * Pushed rather than pulled: these arrive when the peer sends them, so they're read\n * from a signal. Empty until the first PROBE message, on versions without PROBE\n * (moq-lite-01/02, moq-transport), and again once the stream ends, so a consumer\n * never holds a stale estimate from a dead stream.\n *\n * @public\n */\nexport interface Probe {\n\t/**\n\t * Round-trip time in milliseconds.\n\t *\n\t * The only RTT available today, since browsers don't populate the transport's.\n\t * Measured through the peer's application layer, so it reads higher than a\n\t * transport-level RTT would.\n\t */\n\trtt?: Time.Milli;\n\n\t/** The peer's estimate of the bitrate it is receiving from us, in bits per second. */\n\testimatedRecvRate?: number;\n}\n\n/**\n * The subset of the W3C `WebTransportConnectionStats` dictionary we consume.\n * `getStats()` is not in TypeScript's DOM lib yet, so it is declared here.\n *\n * @internal\n */\nexport interface TransportStats {\n\tsmoothedRtt?: number;\n\testimatedSendRate?: number | null;\n\tbytesSent?: number;\n\tbytesReceived?: number;\n\tbytesLost?: number;\n\tpacketsSent?: number;\n\tpacketsReceived?: number;\n\tpacketsLost?: number;\n}\n\n/**\n * Snapshot `quic` via `getStats()`, or an empty snapshot when the transport doesn't\n * implement it (the qmux/WebSocket fallback, older browsers) or the call fails.\n *\n * @internal\n */\nexport async function transportStats(quic: WebTransport): Promise<Stats> {\n\tconst getStats = (quic as { getStats?: () => Promise<TransportStats> }).getStats;\n\tif (typeof getStats !== \"function\") return {};\n\ttry {\n\t\tconst stats = await getStats.call(quic);\n\t\treturn {\n\t\t\trtt: stats.smoothedRtt !== undefined ? Time.Milli(stats.smoothedRtt) : undefined,\n\t\t\testimatedSendRate: stats.estimatedSendRate ?? undefined,\n\t\t\tbytesSent: stats.bytesSent,\n\t\t\tbytesReceived: stats.bytesReceived,\n\t\t\tbytesLost: stats.bytesLost,\n\t\t\tpacketsSent: stats.packetsSent,\n\t\t\tpacketsReceived: stats.packetsReceived,\n\t\t\tpacketsLost: stats.packetsLost,\n\t\t};\n\t} catch {\n\t\treturn {};\n\t}\n}\n"]}
1
+ {"version":3,"file":"stats.js","sourceRoot":"","sources":["../../src/connection/stats.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,KAAK,IAAI,MAAM,YAAY,CAAC;AA2FnC;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,IAAkB;IACtD,MAAM,QAAQ,GAAI,IAAqD,CAAC,QAAQ,CAAC;IACjF,IAAI,OAAO,QAAQ,KAAK,UAAU;QAAE,OAAO,EAAE,CAAC;IAC9C,IAAI,CAAC;QACJ,MAAM,KAAK,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACxC,OAAO;YACN,GAAG,EAAE,KAAK,CAAC,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,SAAS;YAChF,iBAAiB,EAAE,KAAK,CAAC,iBAAiB,IAAI,SAAS;YACvD,SAAS,EAAE,KAAK,CAAC,SAAS;YAC1B,aAAa,EAAE,KAAK,CAAC,aAAa;YAClC,SAAS,EAAE,KAAK,CAAC,SAAS;YAC1B,WAAW,EAAE,KAAK,CAAC,WAAW;YAC9B,eAAe,EAAE,KAAK,CAAC,eAAe;YACtC,WAAW,EAAE,KAAK,CAAC,WAAW;SAC9B,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACR,OAAO,EAAE,CAAC;IACX,CAAC;AACF,CAAC","sourcesContent":["/**\n * Connection statistics: what the local transport counts, and what the peer reports.\n *\n * @module\n */\nimport * as Time from \"../time.ts\";\n\n/**\n * A point-in-time snapshot of the transport's counters, from `WebTransport.getStats()`.\n *\n * Pulled on demand rather than pushed: the transport has no event to subscribe to, and\n * a caller computing a rate wants to choose its own sampling instants. Snapshot twice\n * and divide by the interval you measured.\n *\n * Every field is optional. The qmux/WebSocket fallback implements no `getStats()` at\n * all and reports nothing; see {@link Probe} for what the peer measures.\n *\n * The field names match Rust's `moq_net::session::Stats` but the counters keep each\n * stack's own semantics rather than being normalized. Notably W3C excludes\n * retransmissions and QUIC overhead from the byte counts where native QUIC includes\n * them, and counts packets where native QUIC counts datagrams.\n *\n * @public\n */\nexport interface Stats {\n\t/**\n\t * Smoothed round-trip time estimate in milliseconds.\n\t *\n\t * Usually absent: browsers don't report an RTT yet even though the W3C dictionary\n\t * has the field. Use {@link Probe.rtt}, which the peer measures.\n\t */\n\trtt?: Time.Milli;\n\n\t/** Estimated send bandwidth from the congestion controller, in bits per second. */\n\testimatedSendRate?: number;\n\n\t/** Total bytes sent on streams and datagrams, excluding retransmissions and QUIC overhead. */\n\tbytesSent?: number;\n\n\t/** Total bytes received on streams and datagrams, including duplicates, excluding QUIC overhead. */\n\tbytesReceived?: number;\n\n\t/** Bytes currently declared lost. The estimate can decrease when a loss proves spurious. */\n\tbytesLost?: number;\n\n\t/** Total packets sent, including retransmissions. */\n\tpacketsSent?: number;\n\n\t/** Total packets received, including duplicates. */\n\tpacketsReceived?: number;\n\n\t/** Packets currently declared lost. The estimate can decrease when a loss proves spurious. */\n\tpacketsLost?: number;\n}\n\n/**\n * Estimates measured by the peer and delivered over the MoQ PROBE stream.\n *\n * Pushed rather than pulled: these arrive when the peer sends them, so they're read\n * from a signal. Empty until the first PROBE message, on versions without PROBE\n * (moq-lite-01/02, moq-transport), and again once the stream ends, so a consumer\n * never holds a stale estimate from a dead stream.\n *\n * @public\n */\nexport interface Probe {\n\t/**\n\t * Round-trip time in milliseconds.\n\t *\n\t * The only RTT available today, since browsers don't populate the transport's.\n\t * Measured through the peer's application layer, so it reads higher than a\n\t * transport-level RTT would.\n\t */\n\trtt?: Time.Milli;\n\n\t/** The peer's estimate of the bitrate it is receiving from us, in bits per second. */\n\testimatedRecvRate?: number;\n}\n\n/**\n * The subset of the W3C `WebTransportConnectionStats` dictionary we consume.\n * `getStats()` is not in TypeScript's DOM lib yet, so it is declared here.\n *\n * @internal\n */\nexport interface TransportStats {\n\tsmoothedRtt?: number;\n\testimatedSendRate?: number | null;\n\tbytesSent?: number;\n\tbytesReceived?: number;\n\tbytesLost?: number;\n\tpacketsSent?: number;\n\tpacketsReceived?: number;\n\tpacketsLost?: number;\n}\n\n/**\n * Snapshot `quic` via `getStats()`, or an empty snapshot when the transport doesn't\n * implement it (the qmux/WebSocket fallback, older browsers) or the call fails.\n *\n * @internal\n */\nexport async function transportStats(quic: WebTransport): Promise<Stats> {\n\tconst getStats = (quic as { getStats?: () => Promise<TransportStats> }).getStats;\n\tif (typeof getStats !== \"function\") return {};\n\ttry {\n\t\tconst stats = await getStats.call(quic);\n\t\treturn {\n\t\t\trtt: stats.smoothedRtt !== undefined ? Time.Milli(stats.smoothedRtt) : undefined,\n\t\t\testimatedSendRate: stats.estimatedSendRate ?? undefined,\n\t\t\tbytesSent: stats.bytesSent,\n\t\t\tbytesReceived: stats.bytesReceived,\n\t\t\tbytesLost: stats.bytesLost,\n\t\t\tpacketsSent: stats.packetsSent,\n\t\t\tpacketsReceived: stats.packetsReceived,\n\t\t\tpacketsLost: stats.packetsLost,\n\t\t};\n\t} catch {\n\t\treturn {};\n\t}\n}\n"]}
@@ -1,10 +1,3 @@
1
1
  /** The wire transport a session runs over. */
2
2
  export type Transport = "webtransport" | "websocket";
3
- /**
4
- * The transport a live session is actually running over. qmux implements the `WebTransport`
5
- * interface on top of a WebSocket, so the two are indistinguishable by shape.
6
- *
7
- * @internal Not re-exported from the package entrypoint.
8
- */
9
- export declare function transportOf(quic: WebTransport): Transport;
10
3
  //# sourceMappingURL=transport.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"transport.d.ts","sourceRoot":"","sources":["../../src/connection/transport.ts"],"names":[],"mappings":"AAEA,8CAA8C;AAC9C,MAAM,MAAM,SAAS,GAAG,cAAc,GAAG,WAAW,CAAC;AAErD;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,YAAY,GAAG,SAAS,CAEzD"}
1
+ {"version":3,"file":"transport.d.ts","sourceRoot":"","sources":["../../src/connection/transport.ts"],"names":[],"mappings":"AAEA,8CAA8C;AAC9C,MAAM,MAAM,SAAS,GAAG,cAAc,GAAG,WAAW,CAAC"}
package/consume.d.ts CHANGED
@@ -1,44 +1,2 @@
1
- import type * as broadcast from "./broadcast";
2
- import type * as Path from "./path";
3
- /**
4
- * Per-path dedup cache for consumed broadcasts, shared by the moq-lite and moq-ietf
5
- * subscribers.
6
- *
7
- * `Connection.consume(path)` must not mint a fresh subscription per call: repeat requests
8
- * for the same path (e.g. several renditions referencing one `broadcast: "./source"`) should
9
- * share a single upstream subscription. This mirrors the Rust `origin::Consumer` weak-cache:
10
- * a still-live path resolves to a shared {@link broadcast.Consumer.clone}, a closed one is
11
- * re-consumed on the next request. Each handle is reference-counted, so the shared broadcast
12
- * closes once every caller has closed its handle.
13
- *
14
- * @internal
15
- */
16
- export declare class BroadcastCache {
17
- #private;
18
- /** A shared handle to the live broadcast cached for `path`, or `undefined` on a miss. */
19
- get(path: Path.Valid): broadcast.Consumer | undefined;
20
- /**
21
- * Cache `consumer` as the base handle for `path` (evicting it once it closes) and return it.
22
- * Call on a {@link get} miss, after wiring up the fresh consumer's subscribe loop.
23
- */
24
- insert(path: Path.Valid, consumer: broadcast.Consumer): broadcast.Consumer;
25
- /**
26
- * Stop sharing the broadcast cached for `path`, so the next request subscribes fresh.
27
- *
28
- * Call when the path's advertisement goes away. A handle only leaves the cache on its own
29
- * once *every* holder has closed it, so one holder outliving the publisher (a second
30
- * watcher, or a caller consuming the path directly) would otherwise keep the dead
31
- * generation's cached tracks alive and hand them to whoever consumes the path next.
32
- * Existing handles are left alone: they belong to their holders, and the wire resets
33
- * whatever they still have open.
34
- *
35
- * Eviction is unconditional, which costs a dedup miss when two announcement streams watch
36
- * one path: the second stream's retraction can arrive after the first has already seen the
37
- * replacement, dropping the fresh entry so the next request subscribes again instead of
38
- * sharing. Telling that stale retraction from a live one needs a generation id on the
39
- * advertisement (moq-lite's `Epoch`, not yet on the wire), so until then this errs toward a
40
- * duplicate subscription rather than risk handing out a dead one.
41
- */
42
- evict(path: Path.Valid): void;
43
- }
1
+ export {};
44
2
  //# sourceMappingURL=consume.d.ts.map
package/consume.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"consume.d.ts","sourceRoot":"","sources":["../src/consume.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,SAAS,MAAM,gBAAgB,CAAC;AACjD,OAAO,KAAK,KAAK,IAAI,MAAM,WAAW,CAAC;AAEvC;;;;;;;;;;;;GAYG;AACH,qBAAa,cAAc;;IAI1B,yFAAyF;IACzF,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,GAAG,SAAS,CAAC,QAAQ,GAAG,SAAS,CAIpD;IAED;;;OAGG;IACH,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,EAAE,QAAQ,EAAE,SAAS,CAAC,QAAQ,GAAG,SAAS,CAAC,QAAQ,CAUzE;IAED;;;;;;;;;;;;;;;;OAgBG;IACH,KAAK,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,GAAG,IAAI,CAE5B;CACD"}
1
+ {"version":3,"file":"consume.d.ts","sourceRoot":"","sources":["../src/consume.ts"],"names":[],"mappings":""}
package/consume.js CHANGED
@@ -3,7 +3,7 @@
3
3
  * Per-path dedup cache for consumed broadcasts, shared by the moq-lite and moq-ietf
4
4
  * subscribers.
5
5
  *
6
- * `Connection.consume(path)` must not mint a fresh subscription per call: repeat requests
6
+ * Resolving the same path must not mint a fresh subscription per call: repeat requests
7
7
  * for the same path (e.g. several renditions referencing one `broadcast: "./source"`) should
8
8
  * share a single upstream subscription. This mirrors the Rust `origin::Consumer` weak-cache:
9
9
  * a still-live path resolves to a shared {@link broadcast.Consumer.clone}, a closed one is
package/consume.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"consume.js","sourceRoot":"","sources":["../src/consume.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;;GAYG;AACH,MAAM,OAAO,cAAc;IAC1B,wEAAwE;IACxE,MAAM,GAAG,IAAI,GAAG,EAAkC,CAAC;IAEnD,yFAAyF;IACzF,GAAG,CAAC,IAAgB;QACnB,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACnC,IAAI,IAAI,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,SAAS;YAAE,OAAO,IAAI,CAAC,KAAK,EAAE,CAAC;QAClE,OAAO,SAAS,CAAC;IAClB,CAAC;IAED;;;OAGG;IACH,MAAM,CAAC,IAAgB,EAAE,QAA4B;QACpD,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;QAEhC,wFAAwF;QACxF,2FAA2F;QAC3F,KAAK,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE;YAC9B,IAAI,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,QAAQ;gBAAE,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAClE,CAAC,CAAC,CAAC;QAEH,OAAO,QAAQ,CAAC;IACjB,CAAC;IAED;;;;;;;;;;;;;;;;OAgBG;IACH,KAAK,CAAC,IAAgB;QACrB,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAC1B,CAAC;CACD","sourcesContent":["import type * as broadcast from \"./broadcast.ts\";\nimport type * as Path from \"./path.ts\";\n\n/**\n * Per-path dedup cache for consumed broadcasts, shared by the moq-lite and moq-ietf\n * subscribers.\n *\n * `Connection.consume(path)` must not mint a fresh subscription per call: repeat requests\n * for the same path (e.g. several renditions referencing one `broadcast: \"./source\"`) should\n * share a single upstream subscription. This mirrors the Rust `origin::Consumer` weak-cache:\n * a still-live path resolves to a shared {@link broadcast.Consumer.clone}, a closed one is\n * re-consumed on the next request. Each handle is reference-counted, so the shared broadcast\n * closes once every caller has closed its handle.\n *\n * @internal\n */\nexport class BroadcastCache {\n\t// The base handle per path; callers get reference-counted clones of it.\n\t#cache = new Map<Path.Valid, broadcast.Consumer>();\n\n\t/** A shared handle to the live broadcast cached for `path`, or `undefined` on a miss. */\n\tget(path: Path.Valid): broadcast.Consumer | undefined {\n\t\tconst base = this.#cache.get(path);\n\t\tif (base && base.closed.peek() === undefined) return base.clone();\n\t\treturn undefined;\n\t}\n\n\t/**\n\t * Cache `consumer` as the base handle for `path` (evicting it once it closes) and return it.\n\t * Call on a {@link get} miss, after wiring up the fresh consumer's subscribe loop.\n\t */\n\tinsert(path: Path.Valid, consumer: broadcast.Consumer): broadcast.Consumer {\n\t\tthis.#cache.set(path, consumer);\n\n\t\t// Drop the entry once the broadcast closes (every handle released), so the next request\n\t\t// re-consumes rather than cloning a dead handle. Guard against a newer entry for the path.\n\t\tvoid consumer.closed.then(() => {\n\t\t\tif (this.#cache.get(path) === consumer) this.#cache.delete(path);\n\t\t});\n\n\t\treturn consumer;\n\t}\n\n\t/**\n\t * Stop sharing the broadcast cached for `path`, so the next request subscribes fresh.\n\t *\n\t * Call when the path's advertisement goes away. A handle only leaves the cache on its own\n\t * once *every* holder has closed it, so one holder outliving the publisher (a second\n\t * watcher, or a caller consuming the path directly) would otherwise keep the dead\n\t * generation's cached tracks alive and hand them to whoever consumes the path next.\n\t * Existing handles are left alone: they belong to their holders, and the wire resets\n\t * whatever they still have open.\n\t *\n\t * Eviction is unconditional, which costs a dedup miss when two announcement streams watch\n\t * one path: the second stream's retraction can arrive after the first has already seen the\n\t * replacement, dropping the fresh entry so the next request subscribes again instead of\n\t * sharing. Telling that stale retraction from a live one needs a generation id on the\n\t * advertisement (moq-lite's `Epoch`, not yet on the wire), so until then this errs toward a\n\t * duplicate subscription rather than risk handing out a dead one.\n\t */\n\tevict(path: Path.Valid): void {\n\t\tthis.#cache.delete(path);\n\t}\n}\n"]}
1
+ {"version":3,"file":"consume.js","sourceRoot":"","sources":["../src/consume.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;;GAYG;AACH,MAAM,OAAO,cAAc;IAC1B,wEAAwE;IACxE,MAAM,GAAG,IAAI,GAAG,EAAkC,CAAC;IAEnD,yFAAyF;IACzF,GAAG,CAAC,IAAgB;QACnB,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACnC,IAAI,IAAI,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,SAAS;YAAE,OAAO,IAAI,CAAC,KAAK,EAAE,CAAC;QAClE,OAAO,SAAS,CAAC;IAClB,CAAC;IAED;;;OAGG;IACH,MAAM,CAAC,IAAgB,EAAE,QAA4B;QACpD,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;QAEhC,wFAAwF;QACxF,2FAA2F;QAC3F,KAAK,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE;YAC9B,IAAI,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,QAAQ;gBAAE,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAClE,CAAC,CAAC,CAAC;QAEH,OAAO,QAAQ,CAAC;IACjB,CAAC;IAED;;;;;;;;;;;;;;;;OAgBG;IACH,KAAK,CAAC,IAAgB;QACrB,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAC1B,CAAC;CACD","sourcesContent":["import type * as broadcast from \"./broadcast.ts\";\nimport type * as Path from \"./path.ts\";\n\n/**\n * Per-path dedup cache for consumed broadcasts, shared by the moq-lite and moq-ietf\n * subscribers.\n *\n * Resolving the same path must not mint a fresh subscription per call: repeat requests\n * for the same path (e.g. several renditions referencing one `broadcast: \"./source\"`) should\n * share a single upstream subscription. This mirrors the Rust `origin::Consumer` weak-cache:\n * a still-live path resolves to a shared {@link broadcast.Consumer.clone}, a closed one is\n * re-consumed on the next request. Each handle is reference-counted, so the shared broadcast\n * closes once every caller has closed its handle.\n *\n * @internal\n */\nexport class BroadcastCache {\n\t// The base handle per path; callers get reference-counted clones of it.\n\t#cache = new Map<Path.Valid, broadcast.Consumer>();\n\n\t/** A shared handle to the live broadcast cached for `path`, or `undefined` on a miss. */\n\tget(path: Path.Valid): broadcast.Consumer | undefined {\n\t\tconst base = this.#cache.get(path);\n\t\tif (base && base.closed.peek() === undefined) return base.clone();\n\t\treturn undefined;\n\t}\n\n\t/**\n\t * Cache `consumer` as the base handle for `path` (evicting it once it closes) and return it.\n\t * Call on a {@link get} miss, after wiring up the fresh consumer's subscribe loop.\n\t */\n\tinsert(path: Path.Valid, consumer: broadcast.Consumer): broadcast.Consumer {\n\t\tthis.#cache.set(path, consumer);\n\n\t\t// Drop the entry once the broadcast closes (every handle released), so the next request\n\t\t// re-consumes rather than cloning a dead handle. Guard against a newer entry for the path.\n\t\tvoid consumer.closed.then(() => {\n\t\t\tif (this.#cache.get(path) === consumer) this.#cache.delete(path);\n\t\t});\n\n\t\treturn consumer;\n\t}\n\n\t/**\n\t * Stop sharing the broadcast cached for `path`, so the next request subscribes fresh.\n\t *\n\t * Call when the path's advertisement goes away. A handle only leaves the cache on its own\n\t * once *every* holder has closed it, so one holder outliving the publisher (a second\n\t * watcher, or a caller consuming the path directly) would otherwise keep the dead\n\t * generation's cached tracks alive and hand them to whoever consumes the path next.\n\t * Existing handles are left alone: they belong to their holders, and the wire resets\n\t * whatever they still have open.\n\t *\n\t * Eviction is unconditional, which costs a dedup miss when two announcement streams watch\n\t * one path: the second stream's retraction can arrive after the first has already seen the\n\t * replacement, dropping the fresh entry so the next request subscribes again instead of\n\t * sharing. Telling that stale retraction from a live one needs a generation id on the\n\t * advertisement (moq-lite's `Epoch`, not yet on the wire), so until then this errs toward a\n\t * duplicate subscription rather than risk handing out a dead one.\n\t */\n\tevict(path: Path.Valid): void {\n\t\tthis.#cache.delete(path);\n\t}\n}\n"]}
package/error.d.ts CHANGED
@@ -1,69 +1,220 @@
1
1
  /**
2
- * Errors, including the code a peer reports when it resets a stream.
2
+ * Errors, including the code a peer reports when it resets a stream or closes the session.
3
3
  *
4
4
  * @module
5
5
  */
6
+ /** The nominal brand for session termination codes. */
7
+ declare const SESSION_CODE: unique symbol;
8
+ /** A code from the session termination registry. */
9
+ export type SessionCode = number & {
10
+ readonly [SESSION_CODE]: true;
11
+ };
6
12
  /**
7
- * An error the peer reported by resetting a stream, carrying the raw code it sent.
13
+ * Codes a peer sends when terminating the session, mirroring the Rust `Session`.
8
14
  *
9
- * The codes are not standardized, so this deliberately does not translate one into a local
10
- * error: the number means whatever the peer's implementation says it means. A read or write
11
- * rejects with this on every transport, so branch on {@link code} rather than feature-detecting
15
+ * Specified by moq-lite, which reuses moq-transport's codes unchanged. Call `SessionCode(code)`
16
+ * to construct an application code in the 64+ range. {@link StreamCode} is the other registry,
17
+ * and the two are disjoint, so the same integer means different things in each.
18
+ *
19
+ * Codes 32-47 are reserved: nothing is sent there, and the draft gives a received one no
20
+ * meaning, so treat anything not listed below as an unspecified error rather than guessing.
21
+ *
22
+ * @public
23
+ */
24
+ export declare const SessionCode: ((code: number) => SessionCode) & {
25
+ /** Ending the session normally, with no error. */
26
+ readonly Cancel: SessionCode;
27
+ /** Something went wrong that isn't worth a dedicated code. */
28
+ readonly Internal: SessionCode;
29
+ /** The credentials don't grant the requested path or operation. Retrying will fail again. */
30
+ readonly Unauthorized: SessionCode;
31
+ /** A protocol rule was broken; the session is unusable. */
32
+ readonly ProtocolViolation: SessionCode;
33
+ /** A key-value pair was malformed or repeated more than allowed. */
34
+ readonly KeyValueFormatting: SessionCode;
35
+ /** The peer did not close within the GOAWAY drain deadline. */
36
+ readonly GoawayTimeout: SessionCode;
37
+ /** A control message took too long. */
38
+ readonly Timeout: SessionCode;
39
+ /** No version could be negotiated. */
40
+ readonly Version: SessionCode;
41
+ };
42
+ /** The nominal brand for stream reset codes. */
43
+ declare const STREAM_CODE: unique symbol;
44
+ /** A code from the stream reset registry. */
45
+ export type StreamCode = number & {
46
+ readonly [STREAM_CODE]: true;
47
+ };
48
+ /**
49
+ * Codes a peer sends when resetting a stream, mirroring the Rust `Stream`.
50
+ *
51
+ * The counterpart to {@link SessionCode}, and a disjoint space: a stream reset of 0 is
52
+ * {@link StreamCode.Internal}, not a cancellation ({@link StreamCode.Cancel} is 1). Call
53
+ * `StreamCode(code)` to construct an application code in the 64+ range.
54
+ *
55
+ * Conditions the shared codes don't cover are assigned in moq-lite's own 48-63 range, so a
56
+ * received one is the named code. 32 through 47 is reserved: nothing is sent there and a
57
+ * received one is an unspecified error.
58
+ *
59
+ * @public
60
+ */
61
+ export declare const StreamCode: ((code: number) => StreamCode) & {
62
+ /** Something went wrong that isn't worth a dedicated code. */
63
+ readonly Internal: StreamCode;
64
+ /** The sender is done with this stream, not failing. A routine unsubscribe. */
65
+ readonly Cancel: StreamCode;
66
+ /** The content missed its delivery deadline. */
67
+ readonly DeliveryTimeout: StreamCode;
68
+ /** The session ended, taking this stream with it. */
69
+ readonly SessionClosed: StreamCode;
70
+ /** The session is going away (a GOAWAY was received). */
71
+ readonly GoingAway: StreamCode;
72
+ /** The reader fell too far behind and content was dropped to catch up. */
73
+ readonly TooFarBehind: StreamCode;
74
+ /** The track's content could not be parsed. */
75
+ readonly MalformedTrack: StreamCode;
76
+ /** The peer took too long to answer a control request. */
77
+ readonly ControlTimeout: StreamCode;
78
+ /** The requested broadcast or track does not exist at the peer. */
79
+ readonly NotFound: StreamCode;
80
+ /** The group was superseded by a newer one and dropped. */
81
+ readonly Old: StreamCode;
82
+ /** The group was dropped under memory pressure, so it can be re-fetched. */
83
+ readonly Evicted: StreamCode;
84
+ /** A frame declared a payload larger than the receiver accepts. */
85
+ readonly FrameTooLarge: StreamCode;
86
+ /** The publisher could serve this request but has no capacity for it now. */
87
+ readonly NoCapacity: StreamCode;
88
+ /** A group grew past its cache budget and was aborted. */
89
+ readonly GroupTooLarge: StreamCode;
90
+ };
91
+ /**
92
+ * An error the peer reported by closing the session, carrying its {@link SessionCode}.
93
+ *
94
+ * This surfaces on every transport, so catch this type rather than feature-detecting
12
95
  * `WebTransportError`, which a non-browser runtime never defines and the WebSocket fallback
13
96
  * never throws.
14
97
  *
15
- * Code 0 is what a transport sends when a stream is dropped or aborted with no code of its own.
98
+ * ```ts
99
+ * connection.error.subscribe((err) => {
100
+ * if (err instanceof Session && err.code === SessionCode.Unauthorized) {
101
+ * console.warn("server rejected the session");
102
+ * }
103
+ * });
104
+ * ```
105
+ *
106
+ * @public
107
+ */
108
+ export declare class Session extends Error {
109
+ /** The session code the peer sent, verbatim. */
110
+ readonly code: SessionCode;
111
+ constructor(code: SessionCode, options?: {
112
+ cause?: unknown;
113
+ reason?: string;
114
+ });
115
+ }
116
+ /** Options for a {@link Stream}. */
117
+ export interface StreamOptions {
118
+ /** The failure this one wraps. */
119
+ cause?: unknown;
120
+ /** The peer's human-readable reason, appended to the default message. */
121
+ reason?: string;
122
+ /** Replaces the default `remote error: <code>` text, for a condition raised locally. */
123
+ message?: string;
124
+ }
125
+ /**
126
+ * An error carrying a {@link StreamCode}: the code a peer sent when it reset a stream, or the
127
+ * one this side sends when it resets one.
128
+ *
129
+ * This surfaces on every transport, so catch this type rather than feature-detecting
130
+ * `WebTransportError`, which a non-browser runtime never defines and the WebSocket fallback
131
+ * never throws. Local conditions with a code of their own subclass it ({@link TooFarBehind},
132
+ * {@link FrameTooLarge}, {@link GroupTooLarge}, {@link NotFound}), so the same `code` check catches a condition
133
+ * whether it was raised here or reported by the peer.
16
134
  *
17
135
  * ```ts
18
136
  * try {
19
137
  * frame = await group.readFrame();
20
138
  * } catch (err) {
21
- * // Whatever this peer's code 2 means to it.
22
- * if (err instanceof RemoteError && err.code === 2) return;
139
+ * if (err instanceof Stream && err.code === StreamCode.Cancel) return;
23
140
  * throw err;
24
141
  * }
25
142
  * ```
26
143
  *
27
144
  * @public
28
145
  */
29
- export declare class RemoteError extends Error {
30
- /** The code the peer sent, verbatim. */
31
- readonly code: number;
32
- constructor(code: number, options?: {
146
+ export declare class Stream extends Error {
147
+ /** The stream code; moq-lite resets forward it verbatim. */
148
+ readonly code: StreamCode;
149
+ constructor(code: StreamCode, options?: StreamOptions);
150
+ }
151
+ /**
152
+ * The reader asked for a frame the group never held, so the stream has a gap.
153
+ *
154
+ * Raised locally by a frame read, and decoded from a moq-lite peer's `TOO_FAR_BEHIND` reset, since a gap
155
+ * reads the same either way.
156
+ *
157
+ * @public
158
+ */
159
+ export declare class TooFarBehind extends Stream {
160
+ constructor(options?: {
33
161
  cause?: unknown;
34
162
  });
35
163
  }
36
164
  /**
37
- * A peer broke the protocol in a way the spec says must end the session.
165
+ * A frame is larger than a group can cache, so appending it would exceed the budget by itself.
38
166
  *
39
- * Thrown where the violation is detected, rather than handled there: a decoder has no session
40
- * to close. The dispatch that owns the session watches for it and closes, so a nonconforming
41
- * peer cannot repeat the violation on the next stream.
167
+ * Raised locally by a frame write, and decoded from a moq-lite peer's `FRAME_TOO_LARGE` reset.
168
+ * Mirrors the Rust `Error::FrameTooLarge`, which rejects the same frame before touching any state.
42
169
  *
43
- * @internal
170
+ * @public
44
171
  */
45
- export declare class ProtocolViolation extends Error {
46
- constructor(message: string, options?: {
172
+ export declare class FrameTooLarge extends Stream {
173
+ constructor(options?: {
47
174
  cause?: unknown;
48
175
  });
49
176
  }
50
177
  /**
51
- * Decode a transport failure into a {@link RemoteError} error when it carries a stream reset code,
52
- * otherwise pass it through.
178
+ * A write grew the group past its cache budget, so the group is aborted.
53
179
  *
54
- * Native WebTransport rejects with a `WebTransportError`; the WebSocket fallback mints an error
55
- * with the same `source`/`streamErrorCode` fields. Reading the fields rather than the class
56
- * covers both, and works in a runtime with no `WebTransportError` at all.
180
+ * Raised locally by a frame write, and decoded from a moq-lite peer's `GROUP_TOO_LARGE`
181
+ * reset. Mirrors the Rust `Error::GroupTooLarge`.
57
182
  *
58
- * @internal Called at the transport boundary so the raw error never reaches an application.
183
+ * @public
59
184
  */
60
- export declare function fromTransport(err: unknown): Error;
185
+ export declare class GroupTooLarge extends Stream {
186
+ constructor(options?: {
187
+ cause?: unknown;
188
+ });
189
+ }
61
190
  /**
62
- * Coerce an unknown thrown value into an `Error`.
191
+ * The requested broadcast or track is not served here.
63
192
  *
64
- * @internal
193
+ * @public
65
194
  */
66
- export declare function error(err: unknown): Error;
195
+ export declare class NotFound extends Stream {
196
+ constructor(what: string, options?: {
197
+ cause?: unknown;
198
+ });
199
+ }
200
+ /**
201
+ * A peer broke the protocol in a way the spec says must end the session.
202
+ *
203
+ * Thrown where the violation is detected, rather than handled there: a decoder has no session
204
+ * to close. The dispatch that owns the session watches for it and closes, so a nonconforming
205
+ * peer cannot repeat the violation on the next stream.
206
+ *
207
+ * @public
208
+ */
209
+ export declare class ProtocolViolation extends Error {
210
+ constructor(message: string, options?: {
211
+ cause?: unknown;
212
+ });
213
+ }
214
+ /** Package-internal compatibility names used by the wire implementation. */
215
+ export { Session as SessionError, Stream as StreamError, TooFarBehind as Lagged };
216
+ /** Package-internal compatibility name used by the wire implementation. */
217
+ export type StreamErrorOptions = StreamOptions;
67
218
  /**
68
219
  * Format an error into a non-empty, human-readable string for logging.
69
220
  *
package/error.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"error.d.ts","sourceRoot":"","sources":["../src/error.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,qBAAa,WAAY,SAAQ,KAAK;IACrC,wCAAwC;IACxC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAEtB,YAAY,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE,EAItD;CACD;AAED;;;;;;;;GAQG;AACH,qBAAa,iBAAkB,SAAQ,KAAK;IAC3C,YAAY,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE,EAGzD;CACD;AAcD;;;;;;;;;GASG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,OAAO,GAAG,KAAK,CAIjD;AAED;;;;GAIG;AACH,wBAAgB,KAAK,CAAC,GAAG,EAAE,OAAO,GAAG,KAAK,CAEzC;AAED;;;;;;;GAOG;AACH,wBAAgB,MAAM,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,CAa3C"}
1
+ {"version":3,"file":"error.d.ts","sourceRoot":"","sources":["../src/error.ts"],"names":[],"mappings":"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"}