@norskvideo/moq-net 0.1.2 → 0.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (310) hide show
  1. package/README.md +1 -0
  2. package/announced.d.ts +111 -21
  3. package/announced.d.ts.map +1 -1
  4. package/announced.js +213 -40
  5. package/announced.js.map +1 -1
  6. package/broadcast.d.ts +80 -25
  7. package/broadcast.d.ts.map +1 -1
  8. package/broadcast.js +270 -49
  9. package/broadcast.js.map +1 -1
  10. package/connection/accept.d.ts +6 -0
  11. package/connection/accept.d.ts.map +1 -1
  12. package/connection/accept.js +42 -13
  13. package/connection/accept.js.map +1 -1
  14. package/connection/browser.d.ts +5 -0
  15. package/connection/browser.d.ts.map +1 -0
  16. package/connection/browser.js +31 -0
  17. package/connection/browser.js.map +1 -0
  18. package/connection/connect.d.ts +43 -1
  19. package/connection/connect.d.ts.map +1 -1
  20. package/connection/connect.js +118 -123
  21. package/connection/connect.js.map +1 -1
  22. package/connection/established.d.ts +43 -16
  23. package/connection/established.d.ts.map +1 -1
  24. package/connection/established.js.map +1 -1
  25. package/connection/handshake.d.ts +12 -1
  26. package/connection/handshake.d.ts.map +1 -1
  27. package/connection/handshake.js +30 -14
  28. package/connection/handshake.js.map +1 -1
  29. package/connection/index.d.ts +8 -0
  30. package/connection/index.d.ts.map +1 -1
  31. package/connection/index.js +6 -0
  32. package/connection/index.js.map +1 -1
  33. package/connection/reload.d.ts +66 -9
  34. package/connection/reload.d.ts.map +1 -1
  35. package/connection/reload.js +192 -66
  36. package/connection/reload.js.map +1 -1
  37. package/connection/stats.d.ts +92 -0
  38. package/connection/stats.d.ts.map +1 -0
  39. package/connection/stats.js +35 -0
  40. package/connection/stats.js.map +1 -0
  41. package/connection/transport.d.ts +10 -0
  42. package/connection/transport.d.ts.map +1 -0
  43. package/connection/transport.js +12 -0
  44. package/connection/transport.js.map +1 -0
  45. package/consume.d.ts +44 -0
  46. package/consume.d.ts.map +1 -0
  47. package/consume.js +60 -0
  48. package/consume.js.map +1 -0
  49. package/datagram.d.ts +23 -0
  50. package/datagram.d.ts.map +1 -0
  51. package/datagram.js +3 -0
  52. package/datagram.js.map +1 -0
  53. package/error.d.ts +76 -0
  54. package/error.d.ts.map +1 -0
  55. package/error.js +107 -0
  56. package/error.js.map +1 -0
  57. package/group.d.ts +143 -38
  58. package/group.d.ts.map +1 -1
  59. package/group.js +270 -68
  60. package/group.js.map +1 -1
  61. package/ietf/adapter.d.ts +2 -2
  62. package/ietf/adapter.d.ts.map +1 -1
  63. package/ietf/adapter.js +20 -10
  64. package/ietf/adapter.js.map +1 -1
  65. package/ietf/aliases.d.ts +73 -5
  66. package/ietf/aliases.d.ts.map +1 -1
  67. package/ietf/aliases.js +121 -14
  68. package/ietf/aliases.js.map +1 -1
  69. package/ietf/cluster.d.ts +141 -0
  70. package/ietf/cluster.d.ts.map +1 -0
  71. package/ietf/cluster.js +204 -0
  72. package/ietf/cluster.js.map +1 -0
  73. package/ietf/connection.d.ts +39 -6
  74. package/ietf/connection.d.ts.map +1 -1
  75. package/ietf/connection.js +73 -12
  76. package/ietf/connection.js.map +1 -1
  77. package/ietf/fetch.d.ts +17 -0
  78. package/ietf/fetch.d.ts.map +1 -1
  79. package/ietf/fetch.js +21 -0
  80. package/ietf/fetch.js.map +1 -1
  81. package/ietf/filter.d.ts +87 -0
  82. package/ietf/filter.d.ts.map +1 -0
  83. package/ietf/filter.js +292 -0
  84. package/ietf/filter.js.map +1 -0
  85. package/ietf/index.d.ts +2 -0
  86. package/ietf/index.d.ts.map +1 -1
  87. package/ietf/index.js +3 -0
  88. package/ietf/index.js.map +1 -1
  89. package/ietf/namespace.d.ts +6 -0
  90. package/ietf/namespace.d.ts.map +1 -1
  91. package/ietf/namespace.js +27 -2
  92. package/ietf/namespace.js.map +1 -1
  93. package/ietf/object.d.ts +54 -6
  94. package/ietf/object.d.ts.map +1 -1
  95. package/ietf/object.js +178 -25
  96. package/ietf/object.js.map +1 -1
  97. package/ietf/parameters.d.ts +35 -10
  98. package/ietf/parameters.d.ts.map +1 -1
  99. package/ietf/parameters.js +236 -45
  100. package/ietf/parameters.js.map +1 -1
  101. package/ietf/priority.d.ts +5 -0
  102. package/ietf/priority.d.ts.map +1 -0
  103. package/ietf/priority.js +10 -0
  104. package/ietf/priority.js.map +1 -0
  105. package/ietf/properties.d.ts +13 -2
  106. package/ietf/properties.d.ts.map +1 -1
  107. package/ietf/properties.js +65 -8
  108. package/ietf/properties.js.map +1 -1
  109. package/ietf/publish.d.ts.map +1 -1
  110. package/ietf/publish.js +13 -3
  111. package/ietf/publish.js.map +1 -1
  112. package/ietf/publish_namespace.d.ts +16 -2
  113. package/ietf/publish_namespace.d.ts.map +1 -1
  114. package/ietf/publish_namespace.js +25 -6
  115. package/ietf/publish_namespace.js.map +1 -1
  116. package/ietf/publisher.d.ts +40 -7
  117. package/ietf/publisher.d.ts.map +1 -1
  118. package/ietf/publisher.js +751 -134
  119. package/ietf/publisher.js.map +1 -1
  120. package/ietf/request.js +1 -1
  121. package/ietf/request.js.map +1 -1
  122. package/ietf/solicit.d.ts +41 -0
  123. package/ietf/solicit.d.ts.map +1 -0
  124. package/ietf/solicit.js +47 -0
  125. package/ietf/solicit.js.map +1 -0
  126. package/ietf/subscribe.d.ts +41 -2
  127. package/ietf/subscribe.d.ts.map +1 -1
  128. package/ietf/subscribe.js +103 -22
  129. package/ietf/subscribe.js.map +1 -1
  130. package/ietf/subscribe_namespace.d.ts +21 -7
  131. package/ietf/subscribe_namespace.d.ts.map +1 -1
  132. package/ietf/subscribe_namespace.js +31 -14
  133. package/ietf/subscribe_namespace.js.map +1 -1
  134. package/ietf/subscriber.d.ts +20 -7
  135. package/ietf/subscriber.d.ts.map +1 -1
  136. package/ietf/subscriber.js +512 -142
  137. package/ietf/subscriber.js.map +1 -1
  138. package/ietf/version.d.ts +7 -1
  139. package/ietf/version.d.ts.map +1 -1
  140. package/ietf/version.js +7 -0
  141. package/ietf/version.js.map +1 -1
  142. package/index.d.ts +10 -5
  143. package/index.d.ts.map +1 -1
  144. package/index.js +10 -5
  145. package/index.js.map +1 -1
  146. package/internal.d.ts +29 -0
  147. package/internal.d.ts.map +1 -0
  148. package/internal.js +8 -0
  149. package/internal.js.map +1 -0
  150. package/lite/announce.d.ts +62 -15
  151. package/lite/announce.d.ts.map +1 -1
  152. package/lite/announce.js +230 -94
  153. package/lite/announce.js.map +1 -1
  154. package/lite/connection.d.ts +69 -20
  155. package/lite/connection.d.ts.map +1 -1
  156. package/lite/connection.js +128 -81
  157. package/lite/connection.js.map +1 -1
  158. package/lite/datagram.d.ts +23 -0
  159. package/lite/datagram.d.ts.map +1 -0
  160. package/lite/datagram.js +57 -0
  161. package/lite/datagram.js.map +1 -0
  162. package/lite/datagram_stream.d.ts +8 -0
  163. package/lite/datagram_stream.d.ts.map +1 -0
  164. package/lite/datagram_stream.js +44 -0
  165. package/lite/datagram_stream.js.map +1 -0
  166. package/lite/fetch.d.ts.map +1 -1
  167. package/lite/fetch.js +2 -2
  168. package/lite/fetch.js.map +1 -1
  169. package/lite/index.d.ts +3 -0
  170. package/lite/index.d.ts.map +1 -1
  171. package/lite/index.js +3 -0
  172. package/lite/index.js.map +1 -1
  173. package/lite/priority.d.ts +67 -0
  174. package/lite/priority.d.ts.map +1 -0
  175. package/lite/priority.js +114 -0
  176. package/lite/priority.js.map +1 -0
  177. package/lite/probe.d.ts +18 -2
  178. package/lite/probe.d.ts.map +1 -1
  179. package/lite/probe.js +24 -22
  180. package/lite/probe.js.map +1 -1
  181. package/lite/publisher.d.ts +14 -7
  182. package/lite/publisher.d.ts.map +1 -1
  183. package/lite/publisher.js +406 -84
  184. package/lite/publisher.js.map +1 -1
  185. package/lite/setup.d.ts +83 -6
  186. package/lite/setup.d.ts.map +1 -1
  187. package/lite/setup.js +203 -31
  188. package/lite/setup.js.map +1 -1
  189. package/lite/stream.d.ts +12 -3
  190. package/lite/stream.d.ts.map +1 -1
  191. package/lite/stream.js +7 -4
  192. package/lite/stream.js.map +1 -1
  193. package/lite/subscribe.d.ts +37 -23
  194. package/lite/subscribe.d.ts.map +1 -1
  195. package/lite/subscribe.js +70 -55
  196. package/lite/subscribe.js.map +1 -1
  197. package/lite/subscriber.d.ts +29 -23
  198. package/lite/subscriber.d.ts.map +1 -1
  199. package/lite/subscriber.js +689 -112
  200. package/lite/subscriber.js.map +1 -1
  201. package/lite/track.d.ts +25 -13
  202. package/lite/track.d.ts.map +1 -1
  203. package/lite/track.js +60 -35
  204. package/lite/track.js.map +1 -1
  205. package/lite/version.d.ts +39 -4
  206. package/lite/version.d.ts.map +1 -1
  207. package/lite/version.js +139 -17
  208. package/lite/version.js.map +1 -1
  209. package/mock.d.ts +53 -3
  210. package/mock.d.ts.map +1 -1
  211. package/mock.js +110 -21
  212. package/mock.js.map +1 -1
  213. package/{lite/origin.d.ts → origin.d.ts} +25 -1
  214. package/origin.d.ts.map +1 -0
  215. package/{lite/origin.js → origin.js} +25 -1
  216. package/origin.js.map +1 -0
  217. package/package.json +6 -4
  218. package/path.d.ts +67 -0
  219. package/path.d.ts.map +1 -1
  220. package/path.js +128 -0
  221. package/path.js.map +1 -1
  222. package/stream.d.ts +94 -4
  223. package/stream.d.ts.map +1 -1
  224. package/stream.js +128 -17
  225. package/stream.js.map +1 -1
  226. package/time.d.ts +109 -86
  227. package/time.d.ts.map +1 -1
  228. package/time.js +80 -30
  229. package/time.js.map +1 -1
  230. package/track.d.ts +298 -47
  231. package/track.d.ts.map +1 -1
  232. package/track.js +721 -109
  233. package/track.js.map +1 -1
  234. package/util/timeout.d.ts +5 -0
  235. package/util/timeout.d.ts.map +1 -0
  236. package/util/timeout.js +18 -0
  237. package/util/timeout.js.map +1 -0
  238. package/util/utf8.d.ts +3 -0
  239. package/util/utf8.d.ts.map +1 -0
  240. package/util/utf8.js +7 -0
  241. package/util/utf8.js.map +1 -0
  242. package/varint.d.ts +14 -3
  243. package/varint.d.ts.map +1 -1
  244. package/varint.js +23 -12
  245. package/varint.js.map +1 -1
  246. package/zod.d.ts +5 -5
  247. package/zod.d.ts.map +1 -1
  248. package/zod.js.map +1 -1
  249. package/bandwidth.d.ts +0 -11
  250. package/bandwidth.d.ts.map +0 -1
  251. package/bandwidth.js +0 -7
  252. package/bandwidth.js.map +0 -1
  253. package/connection/cert.test.d.ts +0 -2
  254. package/connection/cert.test.d.ts.map +0 -1
  255. package/connection/cert.test.js +0 -26
  256. package/connection/cert.test.js.map +0 -1
  257. package/connection/reload.test.d.ts +0 -2
  258. package/connection/reload.test.d.ts.map +0 -1
  259. package/connection/reload.test.js +0 -39
  260. package/connection/reload.test.js.map +0 -1
  261. package/group.test.d.ts +0 -2
  262. package/group.test.d.ts.map +0 -1
  263. package/group.test.js +0 -66
  264. package/group.test.js.map +0 -1
  265. package/ietf/aliases.test.d.ts +0 -2
  266. package/ietf/aliases.test.d.ts.map +0 -1
  267. package/ietf/aliases.test.js +0 -30
  268. package/ietf/aliases.test.js.map +0 -1
  269. package/ietf/ietf.test.d.ts +0 -2
  270. package/ietf/ietf.test.d.ts.map +0 -1
  271. package/ietf/ietf.test.js +0 -873
  272. package/ietf/ietf.test.js.map +0 -1
  273. package/integration.test.d.ts +0 -2
  274. package/integration.test.d.ts.map +0 -1
  275. package/integration.test.js +0 -90
  276. package/integration.test.js.map +0 -1
  277. package/lite/origin.d.ts.map +0 -1
  278. package/lite/origin.js.map +0 -1
  279. package/lite/subscriber.test.d.ts +0 -2
  280. package/lite/subscriber.test.d.ts.map +0 -1
  281. package/lite/subscriber.test.js +0 -30
  282. package/lite/subscriber.test.js.map +0 -1
  283. package/lite/track.test.d.ts +0 -2
  284. package/lite/track.test.d.ts.map +0 -1
  285. package/lite/track.test.js +0 -53
  286. package/lite/track.test.js.map +0 -1
  287. package/path.test.d.ts +0 -2
  288. package/path.test.d.ts.map +0 -1
  289. package/path.test.js +0 -169
  290. package/path.test.js.map +0 -1
  291. package/stream.test.d.ts +0 -2
  292. package/stream.test.d.ts.map +0 -1
  293. package/stream.test.js +0 -210
  294. package/stream.test.js.map +0 -1
  295. package/track.test.d.ts +0 -2
  296. package/track.test.d.ts.map +0 -1
  297. package/track.test.js +0 -56
  298. package/track.test.js.map +0 -1
  299. package/util/error.d.ts +0 -3
  300. package/util/error.d.ts.map +0 -1
  301. package/util/error.js +0 -9
  302. package/util/error.js.map +0 -1
  303. package/util/index.d.ts +0 -2
  304. package/util/index.d.ts.map +0 -1
  305. package/util/index.js +0 -3
  306. package/util/index.js.map +0 -1
  307. package/varint.test.d.ts +0 -2
  308. package/varint.test.d.ts.map +0 -1
  309. package/varint.test.js +0 -106
  310. package/varint.test.js.map +0 -1
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@norskvideo/moq-net",
3
3
  "type": "module",
4
- "version": "0.1.2",
4
+ "version": "0.1.4",
5
5
  "description": "The networking layer for Media over QUIC: real-time pub/sub with built-in caching, fan-out, and prioritization.",
6
6
  "license": "(MIT OR Apache-2.0)",
7
7
  "repository": "github:moq-dev/moq",
@@ -17,11 +17,13 @@
17
17
  }
18
18
  },
19
19
  "dependencies": {
20
- "@moq/qmux": "^0.1.3",
20
+ "@moq/qmux": "^0.3.3",
21
21
  "async-mutex": "^0.5.0",
22
- "@norskvideo/moq-signals": "^0.1.2"
22
+ "bowser": "^2.14.1",
23
+ "@norskvideo/moq-signals": "^0.1.4"
23
24
  },
24
25
  "peerDependencies": {
25
- "zod": "^4.0.0"
26
+ "@zod/mini": "^4.5.0",
27
+ "zod": "^4.5.0"
26
28
  }
27
29
  }
package/path.d.ts CHANGED
@@ -108,4 +108,71 @@ export declare function stripPrefix(prefix: Valid, path: Valid): Valid | null;
108
108
  export declare function join(path: Valid, other: Valid): Valid;
109
109
  /** The empty path, which is a prefix of every path. */
110
110
  export declare function empty(): Valid;
111
+ /**
112
+ * Normalize a relative path reference: trim leading/trailing slashes, drop empty
113
+ * segments, and drop redundant `.` segments. A reference made only of `.` segments
114
+ * normalizes to `.` because it names the base's parent, while empty names the base.
115
+ * `..` is preserved and only interpreted by {@link resolve}.
116
+ *
117
+ * Mirrors the Rust `PathRelative::new` normalization, so JS and Rust agree
118
+ * byte-for-byte on the stored form. Two callers comparing normalized strings can
119
+ * detect equivalent references while preserving the distinction between `""` and `"."`.
120
+ */
121
+ export declare function normalizeRelative(rel: string): string;
122
+ /**
123
+ * Resolve a relative path reference against a base path.
124
+ *
125
+ * A non-empty reference replaces the last segment of the base, matching relative URL
126
+ * resolution. `..` segments then pop another segment; other segments are appended.
127
+ * `.` and empty segments are no-ops. Excess `..` once the base is empty is also a no-op
128
+ * (subsequent named segments still append). An empty `rel` returns the base unchanged.
129
+ *
130
+ * Mirrors the Rust `Path::resolve`, used by hang catalogs to express
131
+ * cross-broadcast track references (a rendition's `broadcast` field).
132
+ *
133
+ * @example
134
+ * ```typescript
135
+ * Path.resolve(Path.from("a/b/c"), "./source"); // "a/b/source"
136
+ * Path.resolve(Path.from("a/b"), "."); // "a"
137
+ * Path.resolve(Path.from("a/b/c"), "../source"); // "a/source"
138
+ * ```
139
+ */
140
+ export declare function resolve(base: Valid, rel: string): Valid;
141
+ /**
142
+ * Resolve a relative path, returning `undefined` if it escapes above the root.
143
+ *
144
+ * Unlike {@link resolve}, this distinguishes a valid reference to the empty root
145
+ * path from excess `..` segments. Use it for untrusted catalog references that
146
+ * must not be clamped to the root.
147
+ */
148
+ export declare function tryResolve(base: Valid, rel: string): Valid | undefined;
149
+ /**
150
+ * Express `target` relative to `base`: the inverse of {@link resolve}.
151
+ *
152
+ * The result round-trips (`resolve(base, relative(target, base)) === target`) and never
153
+ * walks above the root, so {@link tryResolve} accepts it too.
154
+ *
155
+ * A relative reference replaces the last segment of the base, matching relative URL
156
+ * resolution, so a target nested under the base repeats the base's own last segment.
157
+ *
158
+ * The empty reference names the base itself, so that is what a self-reference returns.
159
+ *
160
+ * Returns `undefined` for a target no reference can name: a path segment may literally be
161
+ * `.` or `..`, which resolution reads as navigation instead of as a name. Only the segments
162
+ * past the shared prefix matter, since the rest are never emitted.
163
+ *
164
+ * Mirrors the Rust `Path::relative`, used to author the cross-broadcast track
165
+ * references a hang catalog carries. Note the argument order: the target comes first,
166
+ * the opposite of Node's `path.relative(from, to)`.
167
+ *
168
+ * @example
169
+ * ```typescript
170
+ * Path.relative(Path.from("a/b/c"), Path.from("a/b")); // "b/c"
171
+ * Path.relative(Path.from("a/c"), Path.from("a/b")); // "c"
172
+ * Path.relative(Path.from("a"), Path.from("a/b")); // "."
173
+ * Path.relative(Path.from("a/b"), Path.from("a/b")); // ""
174
+ * Path.relative(Path.from("a/.."), Path.from("a/b")); // undefined
175
+ * ```
176
+ */
177
+ export declare function relative(target: Valid, base: Valid): string | undefined;
111
178
  //# sourceMappingURL=path.d.ts.map
package/path.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"path.d.ts","sourceRoot":"","sources":["../src/path.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,MAAM,MAAM,KAAK,GAAG,MAAM,GAAG;IAAE,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAEjD;;;;;GAKG;AACH,eAAO,MAAM,SAAS,KAAK,CAAC;AAE5B,iGAAiG;AACjG,wBAAgB,IAAI,CAAC,GAAG,KAAK,EAAE,MAAM,EAAE,GAAG,KAAK,CAI9C;AAED,gFAAgF;AAChF,wBAAgB,KAAK,CAAC,IAAI,EAAE,KAAK,GAAG,MAAM,EAAE,CAE3C;AAED;;;;GAIG;AACH,wBAAgB,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,KAAK,CAGzC;AAED;;;;;GAKG;AACH,wBAAgB,MAAM,CAAC,IAAI,EAAE,KAAK,GAAG,KAAK,CAKzC;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,SAAS,CAAC,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,GAAG,OAAO,CAgB7D;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,GAAG,KAAK,GAAG,IAAI,CAiBpE;AAED;;;;;;;;;GASG;AACH,wBAAgB,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,GAAG,KAAK,CASrD;AAED,uDAAuD;AACvD,wBAAgB,KAAK,IAAI,KAAK,CAE7B"}
1
+ {"version":3,"file":"path.d.ts","sourceRoot":"","sources":["../src/path.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,MAAM,MAAM,KAAK,GAAG,MAAM,GAAG;IAAE,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAEjD;;;;;GAKG;AACH,eAAO,MAAM,SAAS,KAAK,CAAC;AAE5B,iGAAiG;AACjG,wBAAgB,IAAI,CAAC,GAAG,KAAK,EAAE,MAAM,EAAE,GAAG,KAAK,CAI9C;AAED,gFAAgF;AAChF,wBAAgB,KAAK,CAAC,IAAI,EAAE,KAAK,GAAG,MAAM,EAAE,CAE3C;AAED;;;;GAIG;AACH,wBAAgB,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,KAAK,CAGzC;AAED;;;;;GAKG;AACH,wBAAgB,MAAM,CAAC,IAAI,EAAE,KAAK,GAAG,KAAK,CAKzC;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,SAAS,CAAC,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,GAAG,OAAO,CAgB7D;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,GAAG,KAAK,GAAG,IAAI,CAiBpE;AAED;;;;;;;;;GASG;AACH,wBAAgB,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,GAAG,KAAK,CASrD;AAED,uDAAuD;AACvD,wBAAgB,KAAK,IAAI,KAAK,CAE7B;AAED;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAKrD;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,OAAO,CAAC,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,GAAG,KAAK,CAkBvD;AAED;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,GAAG,KAAK,GAAG,SAAS,CAkBtE;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAgB,QAAQ,CAAC,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,GAAG,MAAM,GAAG,SAAS,CA0BvE"}
package/path.js CHANGED
@@ -130,4 +130,132 @@ export function join(path, other) {
130
130
  export function empty() {
131
131
  return "";
132
132
  }
133
+ /**
134
+ * Normalize a relative path reference: trim leading/trailing slashes, drop empty
135
+ * segments, and drop redundant `.` segments. A reference made only of `.` segments
136
+ * normalizes to `.` because it names the base's parent, while empty names the base.
137
+ * `..` is preserved and only interpreted by {@link resolve}.
138
+ *
139
+ * Mirrors the Rust `PathRelative::new` normalization, so JS and Rust agree
140
+ * byte-for-byte on the stored form. Two callers comparing normalized strings can
141
+ * detect equivalent references while preserving the distinction between `""` and `"."`.
142
+ */
143
+ export function normalizeRelative(rel) {
144
+ const raw = rel.split("/");
145
+ const normalized = raw.filter((s) => s !== "" && s !== ".").join("/");
146
+ return normalized === "" && raw.includes(".") ? "." : normalized;
147
+ }
148
+ /**
149
+ * Resolve a relative path reference against a base path.
150
+ *
151
+ * A non-empty reference replaces the last segment of the base, matching relative URL
152
+ * resolution. `..` segments then pop another segment; other segments are appended.
153
+ * `.` and empty segments are no-ops. Excess `..` once the base is empty is also a no-op
154
+ * (subsequent named segments still append). An empty `rel` returns the base unchanged.
155
+ *
156
+ * Mirrors the Rust `Path::resolve`, used by hang catalogs to express
157
+ * cross-broadcast track references (a rendition's `broadcast` field).
158
+ *
159
+ * @example
160
+ * ```typescript
161
+ * Path.resolve(Path.from("a/b/c"), "./source"); // "a/b/source"
162
+ * Path.resolve(Path.from("a/b"), "."); // "a"
163
+ * Path.resolve(Path.from("a/b/c"), "../source"); // "a/source"
164
+ * ```
165
+ */
166
+ export function resolve(base, rel) {
167
+ if (rel === "")
168
+ return base;
169
+ const segments = base === "" ? [] : base.split("/");
170
+ segments.pop();
171
+ for (const seg of rel.split("/")) {
172
+ if (seg === "" || seg === ".") {
173
+ continue;
174
+ }
175
+ if (seg === "..") {
176
+ segments.pop();
177
+ }
178
+ else {
179
+ segments.push(seg);
180
+ }
181
+ }
182
+ return segments.join("/");
183
+ }
184
+ /**
185
+ * Resolve a relative path, returning `undefined` if it escapes above the root.
186
+ *
187
+ * Unlike {@link resolve}, this distinguishes a valid reference to the empty root
188
+ * path from excess `..` segments. Use it for untrusted catalog references that
189
+ * must not be clamped to the root.
190
+ */
191
+ export function tryResolve(base, rel) {
192
+ if (rel === "")
193
+ return base;
194
+ const segments = base === "" ? [] : base.split("/");
195
+ segments.pop();
196
+ for (const seg of rel.split("/")) {
197
+ if (seg === "" || seg === ".") {
198
+ continue;
199
+ }
200
+ if (seg === "..") {
201
+ if (segments.pop() === undefined)
202
+ return undefined;
203
+ }
204
+ else {
205
+ segments.push(seg);
206
+ }
207
+ }
208
+ return segments.join("/");
209
+ }
210
+ /**
211
+ * Express `target` relative to `base`: the inverse of {@link resolve}.
212
+ *
213
+ * The result round-trips (`resolve(base, relative(target, base)) === target`) and never
214
+ * walks above the root, so {@link tryResolve} accepts it too.
215
+ *
216
+ * A relative reference replaces the last segment of the base, matching relative URL
217
+ * resolution, so a target nested under the base repeats the base's own last segment.
218
+ *
219
+ * The empty reference names the base itself, so that is what a self-reference returns.
220
+ *
221
+ * Returns `undefined` for a target no reference can name: a path segment may literally be
222
+ * `.` or `..`, which resolution reads as navigation instead of as a name. Only the segments
223
+ * past the shared prefix matter, since the rest are never emitted.
224
+ *
225
+ * Mirrors the Rust `Path::relative`, used to author the cross-broadcast track
226
+ * references a hang catalog carries. Note the argument order: the target comes first,
227
+ * the opposite of Node's `path.relative(from, to)`.
228
+ *
229
+ * @example
230
+ * ```typescript
231
+ * Path.relative(Path.from("a/b/c"), Path.from("a/b")); // "b/c"
232
+ * Path.relative(Path.from("a/c"), Path.from("a/b")); // "c"
233
+ * Path.relative(Path.from("a"), Path.from("a/b")); // "."
234
+ * Path.relative(Path.from("a/b"), Path.from("a/b")); // ""
235
+ * Path.relative(Path.from("a/.."), Path.from("a/b")); // undefined
236
+ * ```
237
+ */
238
+ export function relative(target, base) {
239
+ // Only the empty reference can name a base whose last segment is itself `.` or `..`,
240
+ // since resolution replaces that segment rather than emitting it.
241
+ if (target === base)
242
+ return "";
243
+ // Resolution replaces the base's last segment, so walk from its parent.
244
+ const dir = base === "" ? [] : base.split("/");
245
+ dir.pop();
246
+ const parts = target === "" ? [] : target.split("/");
247
+ let common = 0;
248
+ while (common < dir.length && common < parts.length && dir[common] === parts[common]) {
249
+ common += 1;
250
+ }
251
+ const down = parts.slice(common);
252
+ // Resolution would walk on these instead of naming them.
253
+ if (down.some((part) => part === "." || part === ".."))
254
+ return undefined;
255
+ const rel = Array(dir.length - common)
256
+ .fill("..")
257
+ .concat(down);
258
+ // An empty reference resolves to the base itself, so name the parent explicitly.
259
+ return rel.length === 0 ? "." : rel.join("/");
260
+ }
133
261
  //# sourceMappingURL=path.js.map
package/path.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"path.js","sourceRoot":"","sources":["../src/path.ts"],"names":[],"mappings":"AAgCA;;;;;GAKG;AACH,MAAM,CAAC,MAAM,SAAS,GAAG,EAAE,CAAC;AAE5B,iGAAiG;AACjG,MAAM,UAAU,IAAI,CAAC,GAAG,KAAe;IACtC,4GAA4G;IAC5G,MAAM,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC/B,OAAO,MAAM,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAU,CAAC;AACrF,CAAC;AAED,gFAAgF;AAChF,MAAM,UAAU,KAAK,CAAC,IAAW;IAChC,OAAO,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;AAC3C,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,MAAM,CAAC,GAAW;IACjC,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC;IACvB,OAAO,MAAM,CAAC,IAAI,CAAC,CAAC;AACrB,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,MAAM,CAAC,IAAW;IACjC,IAAI,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,GAAG,SAAS,EAAE,CAAC;QACpC,MAAM,IAAI,KAAK,CAAC,gBAAgB,SAAS,QAAQ,CAAC,CAAC;IACpD,CAAC;IACD,OAAO,IAAI,CAAC;AACb,CAAC;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,UAAU,SAAS,CAAC,MAAa,EAAE,IAAW;IACnD,IAAI,MAAM,KAAK,EAAE,EAAE,CAAC;QACnB,OAAO,IAAI,CAAC;IACb,CAAC;IAED,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;QAC9B,OAAO,KAAK,CAAC;IACd,CAAC;IAED,yCAAyC;IACzC,IAAI,IAAI,CAAC,MAAM,KAAK,MAAM,CAAC,MAAM,EAAE,CAAC;QACnC,OAAO,IAAI,CAAC;IACb,CAAC;IAED,kEAAkE;IAClE,OAAO,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,GAAG,CAAC;AACpC,CAAC;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,UAAU,WAAW,CAAC,MAAa,EAAE,IAAW;IACrD,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,CAAC,EAAE,CAAC;QAC9B,OAAO,IAAI,CAAC;IACb,CAAC;IAED,2BAA2B;IAC3B,IAAI,MAAM,KAAK,EAAE,EAAE,CAAC;QACnB,OAAO,IAAI,CAAC;IACb,CAAC;IAED,0CAA0C;IAC1C,IAAI,IAAI,CAAC,MAAM,KAAK,MAAM,CAAC,MAAM,EAAE,CAAC;QACnC,OAAO,EAAW,CAAC;IACpB,CAAC;IAED,+EAA+E;IAC/E,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAU,CAAC;AAC/C,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,IAAI,CAAC,IAAW,EAAE,KAAY;IAC7C,IAAI,IAAI,KAAK,EAAE,EAAE,CAAC;QACjB,OAAO,KAAK,CAAC;IACd,CAAC;SAAM,IAAI,KAAK,KAAK,EAAE,EAAE,CAAC;QACzB,OAAO,IAAI,CAAC;IACb,CAAC;SAAM,CAAC;QACP,yDAAyD;QACzD,OAAO,GAAG,IAAI,IAAI,KAAK,EAAW,CAAC;IACpC,CAAC;AACF,CAAC;AAED,uDAAuD;AACvD,MAAM,UAAU,KAAK;IACpB,OAAO,EAAW,CAAC;AACpB,CAAC","sourcesContent":["/**\n * A broadcast path that provides safe prefix matching operations.\n *\n * This module provides path-aware operations that respect delimiter boundaries,\n * preventing issues like \"foo\" matching \"foobar\".\n *\n * Paths are automatically trimmed of leading and trailing slashes on creation,\n * making all slashes implicit at boundaries.\n * All paths are RELATIVE; you cannot join with a leading slash to make an absolute path.\n *\n * @example\n * ```typescript\n * // Creation automatically trims slashes\n * const path1 = Path.from(\"/foo/bar/\");\n * const path2 = Path.from(\"foo/bar\");\n * console.log(path1 === path2); // true\n *\n * // Multiple arguments are joined with \"/\"\n * const path3 = Path.from(\"api\", \"v1\", \"users\");\n * console.log(path3); // \"api/v1/users\"\n *\n * // Safe prefix matching\n * const base = Path.from(\"api/v1\");\n * console.log(Path.hasPrefix(Path.from(\"api\"), base)); // true\n * console.log(Path.hasPrefix(Path.from(\"api/v1\"), base)); // true\n *\n * const joined = Path.join(base, Path.from(\"users\"));\n * console.log(joined); // \"api/v1/users\"\n * ```\n */\nexport type Valid = string & { __brand: \"Name\" };\n\n/**\n * Maximum number of slash-separated parts in a path.\n *\n * Matches the IETF moq-transport limit of 32 fields in a namespace tuple.\n * moq-lite enforces the same bound when decoding paths off the wire.\n */\nexport const MAX_PARTS = 32;\n\n/** Build a path from one or more components, joining with \"/\" and trimming redundant slashes. */\nexport function from(...paths: string[]): Valid {\n\t// Join paths with \"/\" and then remove leading and trailing slashes, and collapse multiple slashes into one.\n\tconst joined = paths.join(\"/\");\n\treturn joined.replace(/\\/+/g, \"/\").replace(/^\\/+/, \"\").replace(/\\/+$/, \"\") as Valid;\n}\n\n/** Split a path into its slash-separated parts. The empty path has no parts. */\nexport function parts(path: Valid): string[] {\n\treturn path === \"\" ? [] : path.split(\"/\");\n}\n\n/**\n * Validate an untrusted wire string as a path, enforcing {@link MAX_PARTS}.\n *\n * Throws when the path has too many parts; use at wire decode sites.\n */\nexport function decode(raw: string): Valid {\n\tconst path = from(raw);\n\treturn encode(path);\n}\n\n/**\n * Validate a path before writing it to the wire, enforcing {@link MAX_PARTS}.\n *\n * Throws when the path has too many parts; use at wire encode sites so we never\n * emit a path the remote side is required to reject.\n */\nexport function encode(path: Valid): Valid {\n\tif (parts(path).length > MAX_PARTS) {\n\t\tthrow new Error(`path exceeds ${MAX_PARTS} parts`);\n\t}\n\treturn path;\n}\n\n/**\n * Check if a path has the given prefix, respecting path boundaries.\n *\n * Unlike String.startsWith, this ensures that \"foo\" does not match \"foobar\".\n * The prefix must either:\n * - Be exactly equal to the path\n * - Be followed by a '/' delimiter in the original path\n * - Be empty (matches everything)\n *\n * @example\n * ```typescript\n * const path = Path.from(\"foo/bar\");\n * console.log(Path.hasPrefix(Path.from(\"foo\"), path)); // true\n * console.log(Path.hasPrefix(Path.from(\"foo/\"), path)); // true (trailing slash ignored)\n * console.log(Path.hasPrefix(Path.from(\"fo\"), path)); // false\n *\n * const path2 = Path.from(\"foobar\");\n * console.log(Path.hasPrefix(Path.from(\"foo\"), path2)); // false\n * ```\n */\nexport function hasPrefix(prefix: Valid, path: Valid): boolean {\n\tif (prefix === \"\") {\n\t\treturn true;\n\t}\n\n\tif (!path.startsWith(prefix)) {\n\t\treturn false;\n\t}\n\n\t// Check if the prefix is the exact match\n\tif (path.length === prefix.length) {\n\t\treturn true;\n\t}\n\n\t// Otherwise, ensure the character after the prefix is a delimiter\n\treturn path[prefix.length] === \"/\";\n}\n\n/**\n * Strip the given prefix from a path, returning the suffix.\n *\n * Returns null if the prefix doesn't match according to hasPrefix rules.\n *\n * @example\n * ```typescript\n * const path = Path.from(\"foo/bar/baz\");\n * const suffix = Path.stripPrefix(Path.from(\"foo\"), path);\n * console.log(suffix); // \"bar/baz\"\n *\n * const suffix2 = Path.stripPrefix(Path.from(\"foo/\"), path);\n * console.log(suffix2); // \"bar/baz\"\n *\n * const noMatch = Path.stripPrefix(Path.from(\"notfound\"), path);\n * console.log(noMatch); // null\n * ```\n */\nexport function stripPrefix(prefix: Valid, path: Valid): Valid | null {\n\tif (!hasPrefix(prefix, path)) {\n\t\treturn null;\n\t}\n\n\t// Handle empty prefix case\n\tif (prefix === \"\") {\n\t\treturn path;\n\t}\n\n\t// If prefix matches exactly, return empty\n\tif (path.length === prefix.length) {\n\t\treturn \"\" as Valid;\n\t}\n\n\t// For non-empty prefix that's shorter, skip the prefix and the following slash\n\treturn path.slice(prefix.length + 1) as Valid;\n}\n\n/**\n * Join two path components together.\n *\n * @example\n * ```typescript\n * const base = Path.from(\"foo\");\n * const joined = Path.join(base, Path.from(\"bar\"));\n * console.log(joined); // \"foo/bar\"\n * ```\n */\nexport function join(path: Valid, other: Valid): Valid {\n\tif (path === \"\") {\n\t\treturn other;\n\t} else if (other === \"\") {\n\t\treturn path;\n\t} else {\n\t\t// Since paths are trimmed, we always need to add a slash\n\t\treturn `${path}/${other}` as Valid;\n\t}\n}\n\n/** The empty path, which is a prefix of every path. */\nexport function empty(): Valid {\n\treturn \"\" as Valid;\n}\n"]}
1
+ {"version":3,"file":"path.js","sourceRoot":"","sources":["../src/path.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * A broadcast path that provides safe prefix matching operations.\n *\n * This module provides path-aware operations that respect delimiter boundaries,\n * preventing issues like \"foo\" matching \"foobar\".\n *\n * Paths are automatically trimmed of leading and trailing slashes on creation,\n * making all slashes implicit at boundaries.\n * All paths are RELATIVE; you cannot join with a leading slash to make an absolute path.\n *\n * @example\n * ```typescript\n * // Creation automatically trims slashes\n * const path1 = Path.from(\"/foo/bar/\");\n * const path2 = Path.from(\"foo/bar\");\n * console.log(path1 === path2); // true\n *\n * // Multiple arguments are joined with \"/\"\n * const path3 = Path.from(\"api\", \"v1\", \"users\");\n * console.log(path3); // \"api/v1/users\"\n *\n * // Safe prefix matching\n * const base = Path.from(\"api/v1\");\n * console.log(Path.hasPrefix(Path.from(\"api\"), base)); // true\n * console.log(Path.hasPrefix(Path.from(\"api/v1\"), base)); // true\n *\n * const joined = Path.join(base, Path.from(\"users\"));\n * console.log(joined); // \"api/v1/users\"\n * ```\n */\nexport type Valid = string & { __brand: \"Name\" };\n\n/**\n * Maximum number of slash-separated parts in a path.\n *\n * Matches the IETF moq-transport limit of 32 fields in a namespace tuple.\n * moq-lite enforces the same bound when decoding paths off the wire.\n */\nexport const MAX_PARTS = 32;\n\n/** Build a path from one or more components, joining with \"/\" and trimming redundant slashes. */\nexport function from(...paths: string[]): Valid {\n\t// Join paths with \"/\" and then remove leading and trailing slashes, and collapse multiple slashes into one.\n\tconst joined = paths.join(\"/\");\n\treturn joined.replace(/\\/+/g, \"/\").replace(/^\\/+/, \"\").replace(/\\/+$/, \"\") as Valid;\n}\n\n/** Split a path into its slash-separated parts. The empty path has no parts. */\nexport function parts(path: Valid): string[] {\n\treturn path === \"\" ? [] : path.split(\"/\");\n}\n\n/**\n * Validate an untrusted wire string as a path, enforcing {@link MAX_PARTS}.\n *\n * Throws when the path has too many parts; use at wire decode sites.\n */\nexport function decode(raw: string): Valid {\n\tconst path = from(raw);\n\treturn encode(path);\n}\n\n/**\n * Validate a path before writing it to the wire, enforcing {@link MAX_PARTS}.\n *\n * Throws when the path has too many parts; use at wire encode sites so we never\n * emit a path the remote side is required to reject.\n */\nexport function encode(path: Valid): Valid {\n\tif (parts(path).length > MAX_PARTS) {\n\t\tthrow new Error(`path exceeds ${MAX_PARTS} parts`);\n\t}\n\treturn path;\n}\n\n/**\n * Check if a path has the given prefix, respecting path boundaries.\n *\n * Unlike String.startsWith, this ensures that \"foo\" does not match \"foobar\".\n * The prefix must either:\n * - Be exactly equal to the path\n * - Be followed by a '/' delimiter in the original path\n * - Be empty (matches everything)\n *\n * @example\n * ```typescript\n * const path = Path.from(\"foo/bar\");\n * console.log(Path.hasPrefix(Path.from(\"foo\"), path)); // true\n * console.log(Path.hasPrefix(Path.from(\"foo/\"), path)); // true (trailing slash ignored)\n * console.log(Path.hasPrefix(Path.from(\"fo\"), path)); // false\n *\n * const path2 = Path.from(\"foobar\");\n * console.log(Path.hasPrefix(Path.from(\"foo\"), path2)); // false\n * ```\n */\nexport function hasPrefix(prefix: Valid, path: Valid): boolean {\n\tif (prefix === \"\") {\n\t\treturn true;\n\t}\n\n\tif (!path.startsWith(prefix)) {\n\t\treturn false;\n\t}\n\n\t// Check if the prefix is the exact match\n\tif (path.length === prefix.length) {\n\t\treturn true;\n\t}\n\n\t// Otherwise, ensure the character after the prefix is a delimiter\n\treturn path[prefix.length] === \"/\";\n}\n\n/**\n * Strip the given prefix from a path, returning the suffix.\n *\n * Returns null if the prefix doesn't match according to hasPrefix rules.\n *\n * @example\n * ```typescript\n * const path = Path.from(\"foo/bar/baz\");\n * const suffix = Path.stripPrefix(Path.from(\"foo\"), path);\n * console.log(suffix); // \"bar/baz\"\n *\n * const suffix2 = Path.stripPrefix(Path.from(\"foo/\"), path);\n * console.log(suffix2); // \"bar/baz\"\n *\n * const noMatch = Path.stripPrefix(Path.from(\"notfound\"), path);\n * console.log(noMatch); // null\n * ```\n */\nexport function stripPrefix(prefix: Valid, path: Valid): Valid | null {\n\tif (!hasPrefix(prefix, path)) {\n\t\treturn null;\n\t}\n\n\t// Handle empty prefix case\n\tif (prefix === \"\") {\n\t\treturn path;\n\t}\n\n\t// If prefix matches exactly, return empty\n\tif (path.length === prefix.length) {\n\t\treturn \"\" as Valid;\n\t}\n\n\t// For non-empty prefix that's shorter, skip the prefix and the following slash\n\treturn path.slice(prefix.length + 1) as Valid;\n}\n\n/**\n * Join two path components together.\n *\n * @example\n * ```typescript\n * const base = Path.from(\"foo\");\n * const joined = Path.join(base, Path.from(\"bar\"));\n * console.log(joined); // \"foo/bar\"\n * ```\n */\nexport function join(path: Valid, other: Valid): Valid {\n\tif (path === \"\") {\n\t\treturn other;\n\t} else if (other === \"\") {\n\t\treturn path;\n\t} else {\n\t\t// Since paths are trimmed, we always need to add a slash\n\t\treturn `${path}/${other}` as Valid;\n\t}\n}\n\n/** The empty path, which is a prefix of every path. */\nexport function empty(): Valid {\n\treturn \"\" as Valid;\n}\n\n/**\n * Normalize a relative path reference: trim leading/trailing slashes, drop empty\n * segments, and drop redundant `.` segments. A reference made only of `.` segments\n * normalizes to `.` because it names the base's parent, while empty names the base.\n * `..` is preserved and only interpreted by {@link resolve}.\n *\n * Mirrors the Rust `PathRelative::new` normalization, so JS and Rust agree\n * byte-for-byte on the stored form. Two callers comparing normalized strings can\n * detect equivalent references while preserving the distinction between `\"\"` and `\".\"`.\n */\nexport function normalizeRelative(rel: string): string {\n\tconst raw = rel.split(\"/\");\n\tconst normalized = raw.filter((s) => s !== \"\" && s !== \".\").join(\"/\");\n\n\treturn normalized === \"\" && raw.includes(\".\") ? \".\" : normalized;\n}\n\n/**\n * Resolve a relative path reference against a base path.\n *\n * A non-empty reference replaces the last segment of the base, matching relative URL\n * resolution. `..` segments then pop another segment; other segments are appended.\n * `.` and empty segments are no-ops. Excess `..` once the base is empty is also a no-op\n * (subsequent named segments still append). An empty `rel` returns the base unchanged.\n *\n * Mirrors the Rust `Path::resolve`, used by hang catalogs to express\n * cross-broadcast track references (a rendition's `broadcast` field).\n *\n * @example\n * ```typescript\n * Path.resolve(Path.from(\"a/b/c\"), \"./source\"); // \"a/b/source\"\n * Path.resolve(Path.from(\"a/b\"), \".\"); // \"a\"\n * Path.resolve(Path.from(\"a/b/c\"), \"../source\"); // \"a/source\"\n * ```\n */\nexport function resolve(base: Valid, rel: string): Valid {\n\tif (rel === \"\") return base;\n\n\tconst segments = base === \"\" ? [] : base.split(\"/\");\n\tsegments.pop();\n\n\tfor (const seg of rel.split(\"/\")) {\n\t\tif (seg === \"\" || seg === \".\") {\n\t\t\tcontinue;\n\t\t}\n\t\tif (seg === \"..\") {\n\t\t\tsegments.pop();\n\t\t} else {\n\t\t\tsegments.push(seg);\n\t\t}\n\t}\n\n\treturn segments.join(\"/\") as Valid;\n}\n\n/**\n * Resolve a relative path, returning `undefined` if it escapes above the root.\n *\n * Unlike {@link resolve}, this distinguishes a valid reference to the empty root\n * path from excess `..` segments. Use it for untrusted catalog references that\n * must not be clamped to the root.\n */\nexport function tryResolve(base: Valid, rel: string): Valid | undefined {\n\tif (rel === \"\") return base;\n\n\tconst segments = base === \"\" ? [] : base.split(\"/\");\n\tsegments.pop();\n\n\tfor (const seg of rel.split(\"/\")) {\n\t\tif (seg === \"\" || seg === \".\") {\n\t\t\tcontinue;\n\t\t}\n\t\tif (seg === \"..\") {\n\t\t\tif (segments.pop() === undefined) return undefined;\n\t\t} else {\n\t\t\tsegments.push(seg);\n\t\t}\n\t}\n\n\treturn segments.join(\"/\") as Valid;\n}\n\n/**\n * Express `target` relative to `base`: the inverse of {@link resolve}.\n *\n * The result round-trips (`resolve(base, relative(target, base)) === target`) and never\n * walks above the root, so {@link tryResolve} accepts it too.\n *\n * A relative reference replaces the last segment of the base, matching relative URL\n * resolution, so a target nested under the base repeats the base's own last segment.\n *\n * The empty reference names the base itself, so that is what a self-reference returns.\n *\n * Returns `undefined` for a target no reference can name: a path segment may literally be\n * `.` or `..`, which resolution reads as navigation instead of as a name. Only the segments\n * past the shared prefix matter, since the rest are never emitted.\n *\n * Mirrors the Rust `Path::relative`, used to author the cross-broadcast track\n * references a hang catalog carries. Note the argument order: the target comes first,\n * the opposite of Node's `path.relative(from, to)`.\n *\n * @example\n * ```typescript\n * Path.relative(Path.from(\"a/b/c\"), Path.from(\"a/b\")); // \"b/c\"\n * Path.relative(Path.from(\"a/c\"), Path.from(\"a/b\")); // \"c\"\n * Path.relative(Path.from(\"a\"), Path.from(\"a/b\")); // \".\"\n * Path.relative(Path.from(\"a/b\"), Path.from(\"a/b\")); // \"\"\n * Path.relative(Path.from(\"a/..\"), Path.from(\"a/b\")); // undefined\n * ```\n */\nexport function relative(target: Valid, base: Valid): string | undefined {\n\t// Only the empty reference can name a base whose last segment is itself `.` or `..`,\n\t// since resolution replaces that segment rather than emitting it.\n\tif (target === base) return \"\";\n\n\t// Resolution replaces the base's last segment, so walk from its parent.\n\tconst dir = base === \"\" ? [] : base.split(\"/\");\n\tdir.pop();\n\n\tconst parts = target === \"\" ? [] : target.split(\"/\");\n\n\tlet common = 0;\n\twhile (common < dir.length && common < parts.length && dir[common] === parts[common]) {\n\t\tcommon += 1;\n\t}\n\n\tconst down = parts.slice(common);\n\t// Resolution would walk on these instead of naming them.\n\tif (down.some((part) => part === \".\" || part === \"..\")) return undefined;\n\n\tconst rel = Array(dir.length - common)\n\t\t.fill(\"..\")\n\t\t.concat(down);\n\n\t// An empty reference resolves to the base itself, so name the parent explicitly.\n\treturn rel.length === 0 ? \".\" : rel.join(\"/\");\n}\n"]}
package/stream.d.ts CHANGED
@@ -1,16 +1,80 @@
1
1
  import type { IetfVersion } from "./ietf/version";
2
+ /**
3
+ * Options handed to the transport for one outgoing stream.
4
+ *
5
+ * `waitUntilAvailable` waits for the peer's concurrent stream limit to free a slot instead
6
+ * of rejecting with a `QuotaExceededError`, which is what we want for the streams a session
7
+ * opens occasionally. `@types/web` doesn't declare it yet, hence the intersection.
8
+ */
9
+ export declare function sendOptions(options?: OpenOptions): WebTransportSendStreamOptions & {
10
+ waitUntilAvailable?: boolean;
11
+ };
12
+ /**
13
+ * The `WebTransportSendStream` that every outgoing stream is, narrowed to the one attribute
14
+ * this package uses. The DOM types available here still describe them as plain
15
+ * `WritableStream`s, so the interface has to be named structurally.
16
+ *
17
+ * `sendOrder` is optional because it is absent until set, and stays absent on an
18
+ * implementation that doesn't carry the interface at all.
19
+ *
20
+ * @see https://www.w3.org/TR/webtransport/#webtransportsendstream
21
+ */
22
+ export type SendStream = WritableStream<Uint8Array> & {
23
+ sendOrder?: number;
24
+ };
25
+ /** Options for opening an outgoing stream. */
26
+ export interface OpenOptions {
27
+ /** The negotiated IETF version, which selects the varint encoding. */
28
+ version?: IetfVersion;
29
+ /**
30
+ * The transport send order, where HIGHER values are transmitted first.
31
+ * Left to the transport's default when unset.
32
+ */
33
+ sendOrder?: number;
34
+ /**
35
+ * Reject if the peer hasn't freed a stream slot within this many milliseconds. Defaults
36
+ * to 10s. There is no way to wait indefinitely: a peer can advertise a stream limit of
37
+ * zero and never raise it, so every open needs a way out.
38
+ */
39
+ timeout?: number;
40
+ /**
41
+ * Ask the transport to wait for a stream slot rather than failing when the peer's
42
+ * concurrent stream limit is exhausted. Defaults to true.
43
+ *
44
+ * Set it false on a path that opens streams faster than the peer can retire them. The
45
+ * transport queues the opens it can't satisfy and serves them in order, with no way to
46
+ * cancel one, so waiting there spends returning credit on whatever was requested first
47
+ * rather than on what matters now.
48
+ */
49
+ waitUntilAvailable?: boolean;
50
+ }
51
+ /** Options for {@link Writer.tryOpen}. */
52
+ export interface TryOpenOptions extends OpenOptions {
53
+ /** Give up once this settles, however it settles. */
54
+ cancel: Promise<unknown>;
55
+ }
2
56
  export declare class Stream {
3
57
  reader: Reader;
4
58
  writer: Writer;
59
+ /** Wrap the two halves of a transport stream. */
5
60
  constructor(props: {
6
61
  writable: WritableStream<Uint8Array>;
7
62
  readable: ReadableStream<Uint8Array>;
8
- writer?: Writer;
9
- reader?: Reader;
10
63
  version?: IetfVersion;
11
64
  });
65
+ /** Pair halves that were opened separately, as the SETUP exchange does. */
66
+ constructor(props: {
67
+ writer: Writer;
68
+ reader: Reader;
69
+ });
12
70
  static accept(quic: WebTransport, version?: IetfVersion): Promise<Stream | undefined>;
13
- static open(quic: WebTransport, version?: IetfVersion, priority?: number): Promise<Stream>;
71
+ /**
72
+ * Open an outgoing bidirectional stream.
73
+ * @param quic - The session to open it on
74
+ * @param options - The version its varints encode with, and the send order ranking it
75
+ * against the session's other streams
76
+ */
77
+ static open(quic: WebTransport, options?: OpenOptions): Promise<Stream>;
14
78
  close(): void;
15
79
  abort(reason: Error): void;
16
80
  }
@@ -35,6 +99,17 @@ export declare class Writer {
35
99
  #private;
36
100
  version?: IetfVersion;
37
101
  constructor(stream: WritableStream<Uint8Array>, version?: IetfVersion);
102
+ /**
103
+ * Rank this stream against the session's others, where HIGHER values are sent first.
104
+ *
105
+ * A send order only schedules the local end, so a stream the peer opened has to be ranked
106
+ * here rather than at the peer's {@link open}.
107
+ *
108
+ * The spec makes `sendOrder` a settable attribute on every {@link SendStream}. Where the
109
+ * interface isn't implemented (Chrome as of writing, a mock, a polyfill) this just sets an
110
+ * ignored property, the same way an ignored `sendOrder` option does at {@link open}.
111
+ */
112
+ setPriority(sendOrder: number): void;
38
113
  bool(v: boolean): Promise<void>;
39
114
  u8(v: number): Promise<void>;
40
115
  u16(v: number): Promise<void>;
@@ -46,7 +121,22 @@ export declare class Writer {
46
121
  close(): void;
47
122
  get closed(): Promise<void>;
48
123
  reset(reason: unknown): void;
49
- static open(quic: WebTransport, version?: IetfVersion): Promise<Writer>;
124
+ /**
125
+ * Open an outgoing unidirectional stream.
126
+ * @param quic - The session to open it on
127
+ * @param options - The version its varints encode with, and the send order ranking it
128
+ * against the session's other streams
129
+ */
130
+ static open(quic: WebTransport, options?: OpenOptions): Promise<Writer>;
131
+ /**
132
+ * Like {@link Writer.open}, but gives up when `cancel` settles or `timeout` elapses,
133
+ * returning undefined so the caller can drop whatever it meant to send. A stream that
134
+ * opens after that is reset rather than leaked. A real transport failure still throws.
135
+ *
136
+ * Worth using even with `waitUntilAvailable: false`, since an implementation may park
137
+ * an over-limit open instead of rejecting it.
138
+ */
139
+ static tryOpen(quic: WebTransport, options: TryOpenOptions): Promise<Writer | undefined>;
50
140
  }
51
141
  export declare class Readers {
52
142
  #private;
package/stream.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"stream.d.ts","sourceRoot":"","sources":["../src/stream.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"stream.d.ts","sourceRoot":"","sources":["../src/stream.ts"],"names":[],"mappings":"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"}