@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.
- package/README.md +2 -2
- package/announce.d.ts +7 -0
- package/announce.d.ts.map +1 -0
- package/announce.js +8 -0
- package/announce.js.map +1 -0
- package/announced.d.ts +49 -91
- package/announced.d.ts.map +1 -1
- package/announced.js +21 -156
- package/announced.js.map +1 -1
- package/bandwidth.d.ts +163 -0
- package/bandwidth.d.ts.map +1 -0
- package/bandwidth.js +304 -0
- package/bandwidth.js.map +1 -0
- package/bandwidth_api.d.ts +7 -0
- package/bandwidth_api.d.ts.map +1 -0
- package/bandwidth_api.js +8 -0
- package/bandwidth_api.js.map +1 -0
- package/broadcast.d.ts +44 -35
- package/broadcast.d.ts.map +1 -1
- package/broadcast.js +104 -60
- package/broadcast.js.map +1 -1
- package/connection/accept.d.ts +16 -1
- package/connection/accept.d.ts.map +1 -1
- package/connection/accept.js +52 -28
- package/connection/accept.js.map +1 -1
- package/connection/browser.d.ts.map +1 -1
- package/connection/browser.js +9 -7
- package/connection/browser.js.map +1 -1
- package/connection/connect.d.ts +30 -6
- package/connection/connect.d.ts.map +1 -1
- package/connection/connect.js +110 -54
- package/connection/connect.js.map +1 -1
- package/connection/established.d.ts +17 -21
- package/connection/established.d.ts.map +1 -1
- package/connection/established.js.map +1 -1
- package/connection/forward.d.ts +2 -0
- package/connection/forward.d.ts.map +1 -0
- package/connection/forward.js +173 -0
- package/connection/forward.js.map +1 -0
- package/connection/handshake.d.ts +1 -0
- package/connection/handshake.d.ts.map +1 -1
- package/connection/handshake.js +5 -2
- package/connection/handshake.js.map +1 -1
- package/connection/index.d.ts +5 -5
- package/connection/index.d.ts.map +1 -1
- package/connection/index.js +4 -5
- package/connection/index.js.map +1 -1
- package/connection/pool.d.ts +186 -0
- package/connection/pool.d.ts.map +1 -0
- package/connection/pool.js +361 -0
- package/connection/pool.js.map +1 -0
- package/connection/reload.d.ts +14 -93
- package/connection/reload.d.ts.map +1 -1
- package/connection/reload.js +217 -81
- package/connection/reload.js.map +1 -1
- package/connection/stats.d.ts +3 -26
- package/connection/stats.d.ts.map +1 -1
- package/connection/stats.js.map +1 -1
- package/connection/transport.d.ts +0 -7
- package/connection/transport.d.ts.map +1 -1
- package/consume.d.ts +1 -43
- package/consume.d.ts.map +1 -1
- package/consume.js +1 -1
- package/consume.js.map +1 -1
- package/error.d.ts +180 -29
- package/error.d.ts.map +1 -1
- package/error.js +331 -16
- package/error.js.map +1 -1
- package/errors.d.ts +7 -0
- package/errors.d.ts.map +1 -0
- package/errors.js +8 -0
- package/errors.js.map +1 -0
- package/group.d.ts +9 -43
- package/group.d.ts.map +1 -1
- package/group.js +284 -69
- package/group.js.map +1 -1
- package/hop.d.ts +115 -0
- package/hop.d.ts.map +1 -0
- package/hop.js +119 -0
- package/hop.js.map +1 -0
- package/ietf/adapter.d.ts +5 -1
- package/ietf/adapter.d.ts.map +1 -1
- package/ietf/adapter.js +105 -60
- package/ietf/adapter.js.map +1 -1
- package/ietf/aliases.d.ts +1 -78
- package/ietf/aliases.d.ts.map +1 -1
- package/ietf/cluster.d.ts +9 -123
- package/ietf/cluster.d.ts.map +1 -1
- package/ietf/cluster.js +84 -44
- package/ietf/cluster.js.map +1 -1
- package/ietf/connection.d.ts +6 -72
- package/ietf/connection.d.ts.map +1 -1
- package/ietf/connection.js +62 -56
- package/ietf/connection.js.map +1 -1
- package/ietf/error.d.ts +11 -0
- package/ietf/error.d.ts.map +1 -0
- package/ietf/error.js +193 -0
- package/ietf/error.js.map +1 -0
- package/ietf/fetch.d.ts +7 -20
- package/ietf/fetch.d.ts.map +1 -1
- package/ietf/fetch.js +52 -22
- package/ietf/fetch.js.map +1 -1
- package/ietf/filter.d.ts +2 -0
- package/ietf/filter.d.ts.map +1 -1
- package/ietf/filter.js +10 -1
- package/ietf/filter.js.map +1 -1
- package/ietf/goaway.d.ts.map +1 -1
- package/ietf/goaway.js +22 -5
- package/ietf/goaway.js.map +1 -1
- package/ietf/hidden.d.ts +2 -0
- package/ietf/hidden.d.ts.map +1 -0
- package/ietf/hidden.js +30 -0
- package/ietf/hidden.js.map +1 -0
- package/ietf/index.d.ts +2 -0
- package/ietf/index.d.ts.map +1 -1
- package/ietf/index.js +2 -0
- package/ietf/index.js.map +1 -1
- package/ietf/object.d.ts +15 -8
- package/ietf/object.d.ts.map +1 -1
- package/ietf/object.js +51 -36
- package/ietf/object.js.map +1 -1
- package/ietf/parameters.d.ts +14 -2
- package/ietf/parameters.d.ts.map +1 -1
- package/ietf/parameters.js +97 -29
- package/ietf/parameters.js.map +1 -1
- package/ietf/properties.d.ts +1 -0
- package/ietf/properties.d.ts.map +1 -1
- package/ietf/properties.js +14 -0
- package/ietf/properties.js.map +1 -1
- package/ietf/publish.d.ts +19 -2
- package/ietf/publish.d.ts.map +1 -1
- package/ietf/publish.js +40 -6
- package/ietf/publish.js.map +1 -1
- package/ietf/publish_namespace.d.ts +25 -0
- package/ietf/publish_namespace.d.ts.map +1 -1
- package/ietf/publish_namespace.js +63 -0
- package/ietf/publish_namespace.js.map +1 -1
- package/ietf/publisher.d.ts +1 -82
- package/ietf/publisher.d.ts.map +1 -1
- package/ietf/publisher.js +483 -235
- package/ietf/publisher.js.map +1 -1
- package/ietf/solicit.d.ts +1 -40
- package/ietf/solicit.d.ts.map +1 -1
- package/ietf/subscribe.d.ts +8 -6
- package/ietf/subscribe.d.ts.map +1 -1
- package/ietf/subscribe.js +33 -27
- package/ietf/subscribe.js.map +1 -1
- package/ietf/subscribe_namespace.d.ts +8 -2
- package/ietf/subscribe_namespace.d.ts.map +1 -1
- package/ietf/subscribe_namespace.js +18 -8
- package/ietf/subscribe_namespace.js.map +1 -1
- package/ietf/subscriber.d.ts +1 -65
- package/ietf/subscriber.d.ts.map +1 -1
- package/ietf/subscriber.js +337 -123
- package/ietf/subscriber.js.map +1 -1
- package/ietf/token.d.ts +2 -0
- package/ietf/token.d.ts.map +1 -0
- package/ietf/token.js +99 -0
- package/ietf/token.js.map +1 -0
- package/ietf/track.d.ts +4 -0
- package/ietf/track.d.ts.map +1 -1
- package/ietf/track.js +6 -20
- package/ietf/track.js.map +1 -1
- package/ietf/version.d.ts +12 -1
- package/ietf/version.d.ts.map +1 -1
- package/ietf/version.js +13 -0
- package/ietf/version.js.map +1 -1
- package/index.d.ts +12 -7
- package/index.d.ts.map +1 -1
- package/index.js +10 -5
- package/index.js.map +1 -1
- package/internal.d.ts +115 -1
- package/internal.d.ts.map +1 -1
- package/internal.js +108 -0
- package/internal.js.map +1 -1
- package/lite/announce.d.ts +60 -10
- package/lite/announce.d.ts.map +1 -1
- package/lite/announce.js +176 -31
- package/lite/announce.js.map +1 -1
- package/lite/connection.d.ts +9 -59
- package/lite/connection.d.ts.map +1 -1
- package/lite/connection.js +34 -35
- package/lite/connection.js.map +1 -1
- package/lite/datagram.d.ts +3 -2
- package/lite/datagram.d.ts.map +1 -1
- package/lite/datagram.js +7 -8
- package/lite/datagram.js.map +1 -1
- package/lite/fetch.d.ts +15 -1
- package/lite/fetch.d.ts.map +1 -1
- package/lite/fetch.js +39 -7
- package/lite/fetch.js.map +1 -1
- package/lite/goaway.d.ts.map +1 -1
- package/lite/goaway.js +7 -1
- package/lite/goaway.js.map +1 -1
- package/lite/group.d.ts +30 -12
- package/lite/group.d.ts.map +1 -1
- package/lite/group.js +68 -26
- package/lite/group.js.map +1 -1
- package/lite/message.d.ts +2 -2
- package/lite/message.d.ts.map +1 -1
- package/lite/message.js +14 -5
- package/lite/message.js.map +1 -1
- package/lite/priority.d.ts +1 -61
- package/lite/priority.d.ts.map +1 -1
- package/lite/priority.js +4 -5
- package/lite/priority.js.map +1 -1
- package/lite/publisher.d.ts +1 -69
- package/lite/publisher.d.ts.map +1 -1
- package/lite/publisher.js +630 -262
- package/lite/publisher.js.map +1 -1
- package/lite/setup.d.ts +8 -8
- package/lite/setup.d.ts.map +1 -1
- package/lite/setup.js +33 -30
- package/lite/setup.js.map +1 -1
- package/lite/subscribe.d.ts +71 -17
- package/lite/subscribe.d.ts.map +1 -1
- package/lite/subscribe.js +205 -53
- package/lite/subscribe.js.map +1 -1
- package/lite/subscriber.d.ts +15 -56
- package/lite/subscriber.d.ts.map +1 -1
- package/lite/subscriber.js +451 -247
- package/lite/subscriber.js.map +1 -1
- package/lite/track.d.ts +4 -10
- package/lite/track.d.ts.map +1 -1
- package/lite/track.js +34 -29
- package/lite/track.js.map +1 -1
- package/lite/version.d.ts +42 -6
- package/lite/version.d.ts.map +1 -1
- package/lite/version.js +126 -10
- package/lite/version.js.map +1 -1
- package/origin.d.ts +256 -29
- package/origin.d.ts.map +1 -1
- package/origin.js +1427 -37
- package/origin.js.map +1 -1
- package/package.json +8 -3
- package/path.d.ts +25 -7
- package/path.d.ts.map +1 -1
- package/path.js +5 -3
- package/path.js.map +1 -1
- package/stream.d.ts +73 -14
- package/stream.d.ts.map +1 -1
- package/stream.js +372 -141
- package/stream.js.map +1 -1
- package/tail.d.ts +18 -0
- package/tail.d.ts.map +1 -0
- package/tail.js +167 -0
- package/tail.js.map +1 -0
- package/time.d.ts +15 -2
- package/time.d.ts.map +1 -1
- package/time.js +28 -9
- package/time.js.map +1 -1
- package/track.d.ts +211 -83
- package/track.d.ts.map +1 -1
- package/track.js +816 -205
- package/track.js.map +1 -1
- package/util/abort.d.ts +2 -0
- package/util/abort.d.ts.map +1 -0
- package/util/abort.js +20 -0
- package/util/abort.js.map +1 -0
- package/util/log.d.ts +5 -0
- package/util/log.d.ts.map +1 -0
- package/util/log.js +17 -0
- package/util/log.js.map +1 -0
- package/util/u64.d.ts +39 -0
- package/util/u64.d.ts.map +1 -0
- package/util/u64.js +83 -0
- package/util/u64.js.map +1 -0
- package/util/varint.d.ts +29 -0
- package/util/varint.d.ts.map +1 -0
- package/util/varint.js +198 -0
- package/util/varint.js.map +1 -0
- package/varint.d.ts +10 -6
- package/varint.d.ts.map +1 -1
- package/varint.js +40 -237
- package/varint.js.map +1 -1
- package/wire.d.ts +80 -0
- package/wire.d.ts.map +1 -0
- package/wire.js +32 -0
- package/wire.js.map +1 -0
- package/zod.d.ts +1 -1
- package/zod.d.ts.map +1 -1
- package/zod.js.map +1 -1
- package/mock.d.ts +0 -66
- package/mock.d.ts.map +0 -1
- package/mock.js +0 -243
- package/mock.js.map +0 -1
package/lite/connection.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
/* @ts-self-types="./connection.d.ts" */
|
|
2
2
|
import { Signal } from "@norskvideo/moq-signals";
|
|
3
|
-
import * as announce from "../announced.js";
|
|
4
3
|
import { transportStats } from "../connection/stats.js";
|
|
5
4
|
import { transportOf } from "../connection/transport.js";
|
|
6
|
-
import {
|
|
7
|
-
import
|
|
5
|
+
import { closeError, error, fromClose, StreamCode, StreamError, sessionCause } from "../error.js";
|
|
6
|
+
import { randomHop } from "../hop.js";
|
|
8
7
|
import { Readers, Stream, Writer } from "../stream.js";
|
|
8
|
+
import { registerWire } from "../wire.js";
|
|
9
9
|
import { AnnounceRequest } from "./announce.js";
|
|
10
10
|
import { Fetch } from "./fetch.js";
|
|
11
11
|
import { Goaway } from "./goaway.js";
|
|
@@ -44,9 +44,9 @@ export class Connection {
|
|
|
44
44
|
#subscriber;
|
|
45
45
|
/** The peer's PROBE estimates; see {@link Established.probe}. */
|
|
46
46
|
probe;
|
|
47
|
-
/** Random per-connection
|
|
47
|
+
/** Random per-connection Hop ID. Shared by Publisher (for outbound hop
|
|
48
48
|
* chains) and Subscriber (available for optional self-filtering on announces). */
|
|
49
|
-
|
|
49
|
+
hop;
|
|
50
50
|
// The peer's SETUP, recorded once its Setup stream is read (lite-05+). Streams whose
|
|
51
51
|
// encoding depends on a negotiated capability (e.g. PROBE) wait on this. undefined
|
|
52
52
|
// until the peer's SETUP arrives; stays undefined forever on older drafts.
|
|
@@ -73,18 +73,24 @@ export class Connection {
|
|
|
73
73
|
*
|
|
74
74
|
* @internal
|
|
75
75
|
*/
|
|
76
|
-
constructor({ url, quic, version, session, discovery = true }) {
|
|
76
|
+
constructor({ url, quic, version, session, discovery = true, publish }) {
|
|
77
77
|
this.url = url;
|
|
78
78
|
this.#quic = quic;
|
|
79
79
|
this.#session = session;
|
|
80
|
+
// The session stream was opened at the SETUP exchange's version; the rest of it speaks this one.
|
|
81
|
+
if (session) {
|
|
82
|
+
session.reader.version = version;
|
|
83
|
+
session.writer.version = version;
|
|
84
|
+
}
|
|
80
85
|
this.version = versionName(version);
|
|
81
86
|
this.#version = version;
|
|
82
87
|
this.transport = transportOf(quic);
|
|
83
88
|
this.discovery = discovery;
|
|
84
89
|
this.probe = this.#probe;
|
|
85
|
-
this.
|
|
86
|
-
this.#publisher = new Publisher(this.#quic, this.#version, this.
|
|
87
|
-
this.#subscriber = new Subscriber(this.#quic, this.#version, this.
|
|
90
|
+
this.hop = randomHop();
|
|
91
|
+
this.#publisher = new Publisher(this.#quic, this.#version, this.hop, publish);
|
|
92
|
+
this.#subscriber = new Subscriber(this.#quic, this.#version, this.hop, this.#probe, this.#peerSetup);
|
|
93
|
+
registerWire(this, { consume: (path) => this.#subscriber.consume(path) });
|
|
88
94
|
void this.#run();
|
|
89
95
|
}
|
|
90
96
|
/**
|
|
@@ -112,33 +118,24 @@ export class Connection {
|
|
|
112
118
|
if (hasDatagrams(this.#version)) {
|
|
113
119
|
tasks.push(this.#subscriber.runDatagrams());
|
|
114
120
|
}
|
|
121
|
+
let fatal;
|
|
115
122
|
try {
|
|
116
123
|
await Promise.all(tasks);
|
|
117
124
|
}
|
|
118
125
|
catch (err) {
|
|
119
126
|
console.error("fatal error running connection", err);
|
|
127
|
+
// A session-sourced failure is the peer's close, not the raw transport error.
|
|
128
|
+
fatal = await sessionCause(this.#quic, err);
|
|
120
129
|
}
|
|
121
130
|
finally {
|
|
131
|
+
// The session died under every track it was receiving, so they end with its
|
|
132
|
+
// error. A deliberate close() already ended them cleanly, which makes this a no-op.
|
|
133
|
+
this.#subscriber.close(fatal ?? (await closeError(this.#quic)));
|
|
122
134
|
this.close();
|
|
123
135
|
}
|
|
124
136
|
}
|
|
125
|
-
|
|
126
|
-
this.#
|
|
127
|
-
}
|
|
128
|
-
announced(prefix = Path.empty()) {
|
|
129
|
-
return this.#subscriber.announced(prefix);
|
|
130
|
-
}
|
|
131
|
-
consume(path) {
|
|
132
|
-
return this.#subscriber.consume(path);
|
|
133
|
-
}
|
|
134
|
-
/**
|
|
135
|
-
* Watches a broadcast, live only while it is announced.
|
|
136
|
-
*
|
|
137
|
-
* @param path - The path of the broadcast to watch
|
|
138
|
-
* @returns A reactive handle to the broadcast
|
|
139
|
-
*/
|
|
140
|
-
announcedBroadcast(path) {
|
|
141
|
-
return new announce.Broadcast({ connection: this, path });
|
|
137
|
+
announced(scope, options) {
|
|
138
|
+
return this.#subscriber.announced(scope, options);
|
|
142
139
|
}
|
|
143
140
|
async #runSession() {
|
|
144
141
|
if (!this.#session) {
|
|
@@ -159,15 +156,16 @@ export class Connection {
|
|
|
159
156
|
// The browser uses WebTransport, which carries the request URI, so we advertise no
|
|
160
157
|
// path and leave routing to the URL. The probe level reflects what this transport
|
|
161
158
|
// can actually measure; we never pad, so we never advertise Increase.
|
|
162
|
-
// Role stays Both: publish
|
|
163
|
-
//
|
|
159
|
+
// Role stays Both: the publish origin starts empty and fills later, and consume is
|
|
160
|
+
// called after this point, so there is nothing to narrow yet. The origin declares
|
|
161
|
+
// our session identity so the peer can filter
|
|
164
162
|
// reflected announcements (lite-06 removed ANNOUNCE_REQUEST's exclude_hop for it).
|
|
165
163
|
async #sendSetup() {
|
|
166
|
-
const writer = await Writer.open(this.#quic);
|
|
164
|
+
const writer = await Writer.open(this.#quic, { version: this.#version });
|
|
167
165
|
try {
|
|
168
166
|
await writer.u53(DataType.Setup);
|
|
169
167
|
const probe = await probeLevel(this.#quic, this.#version);
|
|
170
|
-
await new Setup({ probe,
|
|
168
|
+
await new Setup({ probe, hop: this.hop }).encode(writer, this.#version);
|
|
171
169
|
writer.close();
|
|
172
170
|
}
|
|
173
171
|
catch (err) {
|
|
@@ -177,7 +175,7 @@ export class Connection {
|
|
|
177
175
|
}
|
|
178
176
|
async #runBidis() {
|
|
179
177
|
for (;;) {
|
|
180
|
-
const stream = await Stream.accept(this.#quic);
|
|
178
|
+
const stream = await Stream.accept(this.#quic, this.#version);
|
|
181
179
|
if (!stream)
|
|
182
180
|
break;
|
|
183
181
|
this.#runBidi(stream)
|
|
@@ -222,14 +220,14 @@ export class Connection {
|
|
|
222
220
|
}
|
|
223
221
|
}
|
|
224
222
|
async #runUnis() {
|
|
225
|
-
const readers = new Readers(this.#quic);
|
|
223
|
+
const readers = new Readers(this.#quic, this.#version);
|
|
226
224
|
for (;;) {
|
|
227
225
|
const stream = await readers.next();
|
|
228
226
|
if (!stream)
|
|
229
227
|
break;
|
|
230
228
|
this.#runUni(stream)
|
|
231
229
|
.then(() => {
|
|
232
|
-
stream.stop(new
|
|
230
|
+
stream.stop(new StreamError(StreamCode.Cancel, { message: "cancel" }));
|
|
233
231
|
})
|
|
234
232
|
.catch((err) => {
|
|
235
233
|
stream.stop(err);
|
|
@@ -239,7 +237,7 @@ export class Connection {
|
|
|
239
237
|
async #runUni(stream) {
|
|
240
238
|
const typ = await stream.u53();
|
|
241
239
|
if (typ === DataType.Group) {
|
|
242
|
-
const msg = await Group.decode(stream);
|
|
240
|
+
const msg = await Group.decode(stream, this.#version);
|
|
243
241
|
await this.#subscriber.runGroup(msg, stream);
|
|
244
242
|
}
|
|
245
243
|
else if (typ === DataType.Setup) {
|
|
@@ -257,8 +255,9 @@ export class Connection {
|
|
|
257
255
|
async stats() {
|
|
258
256
|
return transportStats(this.#quic);
|
|
259
257
|
}
|
|
258
|
+
/** Resolves when the session closes, decoding the peer's close code; see {@link Established.closed}. */
|
|
260
259
|
get closed() {
|
|
261
|
-
return this.#quic.closed.then(() =>
|
|
260
|
+
return this.#quic.closed.then(fromClose, (err) => error(err));
|
|
262
261
|
}
|
|
263
262
|
}
|
|
264
263
|
/**
|
package/lite/connection.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"connection.js","sourceRoot":"","sources":["../../src/lite/connection.ts"],"names":[],"mappings":"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","sourcesContent":["import { type Getter, Signal } from \"@moq/signals\";\nimport * as announce from \"../announced.ts\";\nimport type * as broadcast from \"../broadcast.ts\";\nimport type { Established } from \"../connection/established.ts\";\nimport { type Probe, type Stats, transportStats } from \"../connection/stats.ts\";\nimport { type Transport, transportOf } from \"../connection/transport.ts\";\nimport { type Origin, randomOrigin } from \"../origin.ts\";\nimport * as Path from \"../path.ts\";\nimport { type Reader, Readers, Stream, Writer } from \"../stream.ts\";\nimport { AnnounceRequest } from \"./announce.ts\";\nimport { Fetch } from \"./fetch.ts\";\nimport { Goaway } from \"./goaway.ts\";\nimport { Group } from \"./group.ts\";\nimport { Publisher } from \"./publisher.ts\";\nimport { SessionInfo } from \"./session.ts\";\nimport { ProbeLevel, type Role, Setup } from \"./setup.ts\";\nimport { DataType, StreamId } from \"./stream.ts\";\nimport { Subscribe } from \"./subscribe.ts\";\nimport { Subscriber } from \"./subscriber.ts\";\nimport { Track as TrackMessage } from \"./track.ts\";\nimport { hasDatagrams, hasProbeRtt, hasSetupStream, type Version, versionName } from \"./version.ts\";\n\n/**\n * Constructor options for {@link Connection}.\n *\n * @internal\n */\nexport interface ConnectionProps {\n\t/** The URL of the connection. */\n\turl: URL;\n\t/** The established WebTransport session. */\n\tquic: WebTransport;\n\t/** The negotiated wire version. */\n\tversion: Version;\n\t/** The session stream, absent on drafts that have none. */\n\tsession?: Stream;\n\t/** Whether the relay supports broadcast discovery. Defaults to true. */\n\tdiscovery?: boolean;\n}\n\n/**\n * Represents a connection to a MoQ server.\n *\n * @public\n */\nexport class Connection implements Established {\n\t// The URL of the connection.\n\treadonly url: URL;\n\n\t// The version of the connection as a human-readable string.\n\treadonly version: string;\n\n\t// The wire transport this session runs over.\n\treadonly transport: Transport;\n\n\t/** Whether the relay supports broadcast discovery; see {@link Established.discovery}. */\n\treadonly discovery: boolean;\n\n\t// The version used for encoding/decoding.\n\t#version: Version;\n\n\t// The established WebTransport session.\n\t#quic: WebTransport;\n\n\t// Use to receive/send session messages.\n\t#session?: Stream;\n\n\t// Module for contributing tracks.\n\t#publisher: Publisher;\n\n\t// Module for distributing tracks.\n\t#subscriber: Subscriber;\n\n\t/** The peer's PROBE estimates; see {@link Established.probe}. */\n\treadonly probe: Getter<Probe>;\n\n\t/** Random per-connection origin id. Shared by Publisher (for outbound hop\n\t * chains) and Subscriber (available for optional self-filtering on announces). */\n\treadonly origin: Origin;\n\n\t// The peer's SETUP, recorded once its Setup stream is read (lite-05+). Streams whose\n\t// encoding depends on a negotiated capability (e.g. PROBE) wait on this. undefined\n\t// until the peer's SETUP arrives; stays undefined forever on older drafts.\n\t#peerSetup = new Signal<Setup | undefined>(undefined);\n\n\t// Mirrors the role out of #peerSetup, so the public surface exposes the peer's declared\n\t// direction without handing out the whole SETUP (whose probe level gates our own streams).\n\t#peerRole = new Signal<Role | undefined>(undefined);\n\n\t// Written by the Subscriber as PROBE messages arrive.\n\t#probe = new Signal<Probe>({});\n\n\t/**\n\t * The {@link Role} the peer advertised in its SETUP, for a server deciding whether the\n\t * peer's authorization grants the direction it intends to use.\n\t *\n\t * `undefined` until the peer's SETUP arrives, and forever on pre-lite-05 versions, which\n\t * carry no in-band role. {@link Role.Both} is the absence of the parameter, so it is what\n\t * a peer reports when it declines to declare a direction, sends a value we don't\n\t * recognize, or is a server (which never sends one).\n\t */\n\tget peerRole(): Getter<Role | undefined> {\n\t\treturn this.#peerRole;\n\t}\n\n\t/**\n\t * Creates a new Connection instance.\n\t *\n\t * @internal\n\t */\n\tconstructor({ url, quic, version, session, discovery = true }: ConnectionProps) {\n\t\tthis.url = url;\n\t\tthis.#quic = quic;\n\t\tthis.#session = session;\n\t\tthis.version = versionName(version);\n\t\tthis.#version = version;\n\t\tthis.transport = transportOf(quic);\n\t\tthis.discovery = discovery;\n\n\t\tthis.probe = this.#probe;\n\n\t\tthis.origin = randomOrigin();\n\t\tthis.#publisher = new Publisher(this.#quic, this.#version, this.origin);\n\t\tthis.#subscriber = new Subscriber(this.#quic, this.#version, this.origin, this.#probe, this.#peerSetup);\n\n\t\tvoid this.#run();\n\t}\n\n\t/**\n\t * Closes the connection.\n\t */\n\tclose() {\n\t\tthis.#publisher.close();\n\t\tthis.#subscriber.close();\n\n\t\ttry {\n\t\t\t// TODO: For whatever reason, this try/catch doesn't seem to work..?\n\t\t\tthis.#quic.close();\n\t\t} catch {\n\t\t\t// ignore\n\t\t}\n\t}\n\n\tasync #run(): Promise<void> {\n\t\tconst tasks: Promise<void>[] = [this.#runSession(), this.#runBidis(), this.#runUnis()];\n\n\t\tif (hasSetupStream(this.#version)) {\n\t\t\ttasks.push(this.#sendSetup());\n\t\t}\n\n\t\ttasks.push(this.#subscriber.runProbe());\n\n\t\t// Route incoming QUIC datagrams into their subscriptions (lite-05+; runDatagrams\n\t\t// no-ops on a transport that doesn't carry them).\n\t\tif (hasDatagrams(this.#version)) {\n\t\t\ttasks.push(this.#subscriber.runDatagrams());\n\t\t}\n\n\t\ttry {\n\t\t\tawait Promise.all(tasks);\n\t\t} catch (err) {\n\t\t\tconsole.error(\"fatal error running connection\", err);\n\t\t} finally {\n\t\t\tthis.close();\n\t\t}\n\t}\n\n\tpublish(path: Path.Valid, producer: broadcast.Producer) {\n\t\tthis.#publisher.publish(path, producer);\n\t}\n\n\tannounced(prefix = Path.empty()): announce.Consumer {\n\t\treturn this.#subscriber.announced(prefix);\n\t}\n\n\tconsume(path: Path.Valid): broadcast.Consumer {\n\t\treturn this.#subscriber.consume(path);\n\t}\n\n\t/**\n\t * Watches a broadcast, live only while it is announced.\n\t *\n\t * @param path - The path of the broadcast to watch\n\t * @returns A reactive handle to the broadcast\n\t */\n\tannouncedBroadcast(path: Path.Valid): announce.Broadcast {\n\t\treturn new announce.Broadcast({ connection: this, path });\n\t}\n\n\tasync #runSession() {\n\t\tif (!this.#session) {\n\t\t\treturn;\n\t\t}\n\n\t\ttry {\n\t\t\tfor (;;) {\n\t\t\t\tconst msg = await SessionInfo.decodeMaybe(this.#session.reader, this.#version);\n\t\t\t\tif (!msg) break;\n\t\t\t}\n\t\t} finally {\n\t\t\tconsole.debug(\"session stream closed\");\n\t\t}\n\t}\n\n\t// Open the unidirectional Setup Stream, send our single SETUP, and FIN (lite-05+).\n\t// The browser uses WebTransport, which carries the request URI, so we advertise no\n\t// path and leave routing to the URL. The probe level reflects what this transport\n\t// can actually measure; we never pad, so we never advertise Increase.\n\t// Role stays Both: publish/consume are called after this point, so there is nothing\n\t// to narrow yet. The origin declares our session identity so the peer can filter\n\t// reflected announcements (lite-06 removed ANNOUNCE_REQUEST's exclude_hop for it).\n\tasync #sendSetup(): Promise<void> {\n\t\tconst writer = await Writer.open(this.#quic);\n\t\ttry {\n\t\t\tawait writer.u53(DataType.Setup);\n\t\t\tconst probe = await probeLevel(this.#quic, this.#version);\n\t\t\tawait new Setup({ probe, origin: this.origin }).encode(writer, this.#version);\n\t\t\twriter.close();\n\t\t} catch (err: unknown) {\n\t\t\twriter.reset(err);\n\t\t\tthrow err;\n\t\t}\n\t}\n\n\tasync #runBidis() {\n\t\tfor (;;) {\n\t\t\tconst stream = await Stream.accept(this.#quic);\n\t\t\tif (!stream) break;\n\n\t\t\tthis.#runBidi(stream)\n\t\t\t\t.catch((err: unknown) => {\n\t\t\t\t\tstream.writer.reset(err);\n\t\t\t\t})\n\t\t\t\t.finally(() => {\n\t\t\t\t\tstream.writer.close();\n\t\t\t\t});\n\t\t}\n\t}\n\n\tasync #runBidi(stream: Stream) {\n\t\tconst typ = await stream.reader.u53();\n\n\t\tif (typ === StreamId.Session) {\n\t\t\tthrow new Error(\"duplicate session stream\");\n\t\t} else if (typ === StreamId.Announce) {\n\t\t\tconst msg = await AnnounceRequest.decode(stream.reader, this.#version);\n\t\t\tawait this.#publisher.runAnnounce(msg, stream);\n\t\t} else if (typ === StreamId.Subscribe) {\n\t\t\tconst msg = await Subscribe.decode(stream.reader, this.#version);\n\t\t\tawait this.#publisher.runSubscribe(msg, stream);\n\t\t} else if (typ === StreamId.Fetch) {\n\t\t\tconst msg = await Fetch.decode(stream.reader, this.#version);\n\t\t\tawait this.#publisher.runFetch(msg, stream);\n\t\t} else if (typ === StreamId.Track) {\n\t\t\tconst msg = await TrackMessage.decode(stream.reader, this.#version);\n\t\t\tawait this.#publisher.runTrackInfo(msg, stream);\n\t\t} else if (typ === StreamId.Probe) {\n\t\t\tawait this.#publisher.runProbe(stream);\n\t\t} else if (typ === StreamId.Goaway) {\n\t\t\tconst msg = await Goaway.decode(stream.reader, this.#version);\n\t\t\tconsole.info(\"received goaway:\", msg.uri);\n\t\t} else {\n\t\t\tthrow new Error(`unknown stream type: ${typ.toString()}`);\n\t\t}\n\t}\n\n\tasync #runUnis() {\n\t\tconst readers = new Readers(this.#quic);\n\n\t\tfor (;;) {\n\t\t\tconst stream = await readers.next();\n\t\t\tif (!stream) break;\n\n\t\t\tthis.#runUni(stream)\n\t\t\t\t.then(() => {\n\t\t\t\t\tstream.stop(new Error(\"cancel\"));\n\t\t\t\t})\n\t\t\t\t.catch((err: unknown) => {\n\t\t\t\t\tstream.stop(err);\n\t\t\t\t});\n\t\t}\n\t}\n\n\tasync #runUni(stream: Reader) {\n\t\tconst typ = await stream.u53();\n\t\tif (typ === DataType.Group) {\n\t\t\tconst msg = await Group.decode(stream);\n\t\t\tawait this.#subscriber.runGroup(msg, stream);\n\t\t} else if (typ === DataType.Setup) {\n\t\t\t// The peer sends exactly one SETUP, then FINs. Record it so capability-gated\n\t\t\t// streams (e.g. PROBE) can react, then drain to the FIN.\n\t\t\tconst setup = await Setup.decode(stream, this.#version);\n\t\t\tthis.#peerSetup.set(setup);\n\t\t\tthis.#peerRole.set(setup.role);\n\t\t} else {\n\t\t\tthrow new Error(`unknown stream type: ${typ.toString()}`);\n\t\t}\n\t}\n\n\t/** Snapshot the transport's counters; see {@link Established.stats}. */\n\tasync stats(): Promise<Stats> {\n\t\treturn transportStats(this.#quic);\n\t}\n\n\tget closed(): Promise<void> {\n\t\treturn this.#quic.closed.then(() => undefined);\n\t}\n}\n\n/**\n * The probe level to advertise in SETUP, from what the transport can measure.\n *\n * `Report` claims we can measure and periodically report, so it is only truthful\n * when a metric this version can carry actually exists. The qmux/WebSocket fallback\n * implements no `getStats()` at all, and even a transport that has one may report\n * neither figure. Advertising `Report` and then holding the subscriber's PROBE\n * stream open with nothing to send is the state this avoids; the subscriber's own\n * gate then skips a stream it could not use.\n *\n * Mirrors `ProbeLevel::detect` in `moq-net`, including its limitation: a metric\n * that only appears after SETUP reads as unsupported here.\n *\n * @internal\n */\nexport async function probeLevel(quic: WebTransport, version: Version): Promise<ProbeLevel> {\n\tconst getStats = (\n\t\tquic as unknown as {\n\t\t\tgetStats?: () => Promise<{ estimatedSendRate: number | null; smoothedRtt?: number | null }>;\n\t\t}\n\t).getStats;\n\tif (typeof getStats !== \"function\") return ProbeLevel.None;\n\n\t// A transport that can't answer tells us nothing, which is itself an answer.\n\tlet stats: { estimatedSendRate: number | null; smoothedRtt?: number | null };\n\ttry {\n\t\tstats = await getStats.call(quic);\n\t} catch {\n\t\treturn ProbeLevel.None;\n\t}\n\n\tconst rtt = hasProbeRtt(version) ? stats.smoothedRtt : undefined;\n\treturn stats.estimatedSendRate != null || rtt != null ? ProbeLevel.Report : ProbeLevel.None;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"connection.js","sourceRoot":"","sources":["../../src/lite/connection.ts"],"names":[],"mappings":"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","sourcesContent":["import { type Getter, Signal } from \"@moq/signals\";\nimport type * as announce from \"../announced.ts\";\nimport type { Established } from \"../connection/established.ts\";\nimport { type Probe, type Stats, transportStats } from \"../connection/stats.ts\";\nimport { type Transport, transportOf } from \"../connection/transport.ts\";\nimport { closeError, error, fromClose, StreamCode, StreamError, sessionCause } from \"../error.ts\";\nimport { type Hop, randomHop } from \"../hop.ts\";\nimport type { Consumer as OriginConsumer } from \"../origin.ts\";\nimport type * as Path from \"../path.ts\";\nimport { type Reader, Readers, Stream, Writer } from \"../stream.ts\";\nimport { registerWire } from \"../wire.ts\";\nimport { AnnounceRequest } from \"./announce.ts\";\nimport { Fetch } from \"./fetch.ts\";\nimport { Goaway } from \"./goaway.ts\";\nimport { Group } from \"./group.ts\";\nimport { Publisher } from \"./publisher.ts\";\nimport { SessionInfo } from \"./session.ts\";\nimport { ProbeLevel, type Role, Setup } from \"./setup.ts\";\nimport { DataType, StreamId } from \"./stream.ts\";\nimport { Subscribe } from \"./subscribe.ts\";\nimport { Subscriber } from \"./subscriber.ts\";\nimport { Track as TrackMessage } from \"./track.ts\";\nimport { hasDatagrams, hasProbeRtt, hasSetupStream, type Version, versionName } from \"./version.ts\";\n\n/**\n * Constructor options for {@link Connection}.\n *\n * @internal\n */\nexport interface ConnectionProps {\n\t/** The URL of the connection. */\n\turl: URL;\n\t/** The established WebTransport session. */\n\tquic: WebTransport;\n\t/** The negotiated wire version. */\n\tversion: Version;\n\t/** The session stream, absent on drafts that have none. */\n\tsession?: Stream;\n\t/** Whether the relay supports broadcast discovery. Defaults to true. */\n\tdiscovery?: boolean;\n\t/** The origin whose broadcasts are served to the peer. Omit to publish nothing. */\n\tpublish?: OriginConsumer;\n}\n\n/**\n * Represents a connection to a MoQ server.\n *\n * @public\n */\nexport class Connection implements Established {\n\t// The URL of the connection.\n\treadonly url: URL;\n\n\t// The version of the connection as a human-readable string.\n\treadonly version: string;\n\n\t// The wire transport this session runs over.\n\treadonly transport: Transport;\n\n\t/** Whether the relay supports broadcast discovery; see {@link Established.discovery}. */\n\treadonly discovery: boolean;\n\n\t// The version used for encoding/decoding.\n\t#version: Version;\n\n\t// The established WebTransport session.\n\t#quic: WebTransport;\n\n\t// Use to receive/send session messages.\n\t#session?: Stream;\n\n\t// Module for contributing tracks.\n\t#publisher: Publisher;\n\n\t// Module for distributing tracks.\n\t#subscriber: Subscriber;\n\n\t/** The peer's PROBE estimates; see {@link Established.probe}. */\n\treadonly probe: Getter<Probe>;\n\n\t/** Random per-connection Hop ID. Shared by Publisher (for outbound hop\n\t * chains) and Subscriber (available for optional self-filtering on announces). */\n\treadonly hop: Hop;\n\n\t// The peer's SETUP, recorded once its Setup stream is read (lite-05+). Streams whose\n\t// encoding depends on a negotiated capability (e.g. PROBE) wait on this. undefined\n\t// until the peer's SETUP arrives; stays undefined forever on older drafts.\n\t#peerSetup = new Signal<Setup | undefined>(undefined);\n\n\t// Mirrors the role out of #peerSetup, so the public surface exposes the peer's declared\n\t// direction without handing out the whole SETUP (whose probe level gates our own streams).\n\t#peerRole = new Signal<Role | undefined>(undefined);\n\n\t// Written by the Subscriber as PROBE messages arrive.\n\t#probe = new Signal<Probe>({});\n\n\t/**\n\t * The {@link Role} the peer advertised in its SETUP, for a server deciding whether the\n\t * peer's authorization grants the direction it intends to use.\n\t *\n\t * `undefined` until the peer's SETUP arrives, and forever on pre-lite-05 versions, which\n\t * carry no in-band role. {@link Role.Both} is the absence of the parameter, so it is what\n\t * a peer reports when it declines to declare a direction, sends a value we don't\n\t * recognize, or is a server (which never sends one).\n\t */\n\tget peerRole(): Getter<Role | undefined> {\n\t\treturn this.#peerRole;\n\t}\n\n\t/**\n\t * Creates a new Connection instance.\n\t *\n\t * @internal\n\t */\n\tconstructor({ url, quic, version, session, discovery = true, publish }: ConnectionProps) {\n\t\tthis.url = url;\n\t\tthis.#quic = quic;\n\t\tthis.#session = session;\n\t\t// The session stream was opened at the SETUP exchange's version; the rest of it speaks this one.\n\t\tif (session) {\n\t\t\tsession.reader.version = version;\n\t\t\tsession.writer.version = version;\n\t\t}\n\t\tthis.version = versionName(version);\n\t\tthis.#version = version;\n\t\tthis.transport = transportOf(quic);\n\t\tthis.discovery = discovery;\n\n\t\tthis.probe = this.#probe;\n\n\t\tthis.hop = randomHop();\n\t\tthis.#publisher = new Publisher(this.#quic, this.#version, this.hop, publish);\n\t\tthis.#subscriber = new Subscriber(this.#quic, this.#version, this.hop, this.#probe, this.#peerSetup);\n\t\tregisterWire(this, { consume: (path) => this.#subscriber.consume(path) });\n\n\t\tvoid this.#run();\n\t}\n\n\t/**\n\t * Closes the connection.\n\t */\n\tclose() {\n\t\tthis.#publisher.close();\n\t\tthis.#subscriber.close();\n\n\t\ttry {\n\t\t\t// TODO: For whatever reason, this try/catch doesn't seem to work..?\n\t\t\tthis.#quic.close();\n\t\t} catch {\n\t\t\t// ignore\n\t\t}\n\t}\n\n\tasync #run(): Promise<void> {\n\t\tconst tasks: Promise<void>[] = [this.#runSession(), this.#runBidis(), this.#runUnis()];\n\n\t\tif (hasSetupStream(this.#version)) {\n\t\t\ttasks.push(this.#sendSetup());\n\t\t}\n\n\t\ttasks.push(this.#subscriber.runProbe());\n\n\t\t// Route incoming QUIC datagrams into their subscriptions (lite-05+; runDatagrams\n\t\t// no-ops on a transport that doesn't carry them).\n\t\tif (hasDatagrams(this.#version)) {\n\t\t\ttasks.push(this.#subscriber.runDatagrams());\n\t\t}\n\n\t\tlet fatal: Error | undefined;\n\t\ttry {\n\t\t\tawait Promise.all(tasks);\n\t\t} catch (err) {\n\t\t\tconsole.error(\"fatal error running connection\", err);\n\t\t\t// A session-sourced failure is the peer's close, not the raw transport error.\n\t\t\tfatal = await sessionCause(this.#quic, err);\n\t\t} finally {\n\t\t\t// The session died under every track it was receiving, so they end with its\n\t\t\t// error. A deliberate close() already ended them cleanly, which makes this a no-op.\n\t\t\tthis.#subscriber.close(fatal ?? (await closeError(this.#quic)));\n\t\t\tthis.close();\n\t\t}\n\t}\n\n\tannounced(scope?: Path.Pattern, options?: announce.Options): announce.Consumer {\n\t\treturn this.#subscriber.announced(scope, options);\n\t}\n\n\tasync #runSession() {\n\t\tif (!this.#session) {\n\t\t\treturn;\n\t\t}\n\n\t\ttry {\n\t\t\tfor (;;) {\n\t\t\t\tconst msg = await SessionInfo.decodeMaybe(this.#session.reader, this.#version);\n\t\t\t\tif (!msg) break;\n\t\t\t}\n\t\t} finally {\n\t\t\tconsole.debug(\"session stream closed\");\n\t\t}\n\t}\n\n\t// Open the unidirectional Setup Stream, send our single SETUP, and FIN (lite-05+).\n\t// The browser uses WebTransport, which carries the request URI, so we advertise no\n\t// path and leave routing to the URL. The probe level reflects what this transport\n\t// can actually measure; we never pad, so we never advertise Increase.\n\t// Role stays Both: the publish origin starts empty and fills later, and consume is\n\t// called after this point, so there is nothing to narrow yet. The origin declares\n\t// our session identity so the peer can filter\n\t// reflected announcements (lite-06 removed ANNOUNCE_REQUEST's exclude_hop for it).\n\tasync #sendSetup(): Promise<void> {\n\t\tconst writer = await Writer.open(this.#quic, { version: this.#version });\n\t\ttry {\n\t\t\tawait writer.u53(DataType.Setup);\n\t\t\tconst probe = await probeLevel(this.#quic, this.#version);\n\t\t\tawait new Setup({ probe, hop: this.hop }).encode(writer, this.#version);\n\t\t\twriter.close();\n\t\t} catch (err: unknown) {\n\t\t\twriter.reset(err);\n\t\t\tthrow err;\n\t\t}\n\t}\n\n\tasync #runBidis() {\n\t\tfor (;;) {\n\t\t\tconst stream = await Stream.accept(this.#quic, this.#version);\n\t\t\tif (!stream) break;\n\n\t\t\tthis.#runBidi(stream)\n\t\t\t\t.catch((err: unknown) => {\n\t\t\t\t\tstream.writer.reset(err);\n\t\t\t\t})\n\t\t\t\t.finally(() => {\n\t\t\t\t\tstream.writer.close();\n\t\t\t\t});\n\t\t}\n\t}\n\n\tasync #runBidi(stream: Stream) {\n\t\tconst typ = await stream.reader.u53();\n\n\t\tif (typ === StreamId.Session) {\n\t\t\tthrow new Error(\"duplicate session stream\");\n\t\t} else if (typ === StreamId.Announce) {\n\t\t\tconst msg = await AnnounceRequest.decode(stream.reader, this.#version);\n\t\t\tawait this.#publisher.runAnnounce(msg, stream);\n\t\t} else if (typ === StreamId.Subscribe) {\n\t\t\tconst msg = await Subscribe.decode(stream.reader, this.#version);\n\t\t\tawait this.#publisher.runSubscribe(msg, stream);\n\t\t} else if (typ === StreamId.Fetch) {\n\t\t\tconst msg = await Fetch.decode(stream.reader, this.#version);\n\t\t\tawait this.#publisher.runFetch(msg, stream);\n\t\t} else if (typ === StreamId.Track) {\n\t\t\tconst msg = await TrackMessage.decode(stream.reader, this.#version);\n\t\t\tawait this.#publisher.runTrackInfo(msg, stream);\n\t\t} else if (typ === StreamId.Probe) {\n\t\t\tawait this.#publisher.runProbe(stream);\n\t\t} else if (typ === StreamId.Goaway) {\n\t\t\tconst msg = await Goaway.decode(stream.reader, this.#version);\n\t\t\tconsole.info(\"received goaway:\", msg.uri);\n\t\t} else {\n\t\t\tthrow new Error(`unknown stream type: ${typ.toString()}`);\n\t\t}\n\t}\n\n\tasync #runUnis() {\n\t\tconst readers = new Readers(this.#quic, this.#version);\n\n\t\tfor (;;) {\n\t\t\tconst stream = await readers.next();\n\t\t\tif (!stream) break;\n\n\t\t\tthis.#runUni(stream)\n\t\t\t\t.then(() => {\n\t\t\t\t\tstream.stop(new StreamError(StreamCode.Cancel, { message: \"cancel\" }));\n\t\t\t\t})\n\t\t\t\t.catch((err: unknown) => {\n\t\t\t\t\tstream.stop(err);\n\t\t\t\t});\n\t\t}\n\t}\n\n\tasync #runUni(stream: Reader) {\n\t\tconst typ = await stream.u53();\n\t\tif (typ === DataType.Group) {\n\t\t\tconst msg = await Group.decode(stream, this.#version);\n\t\t\tawait this.#subscriber.runGroup(msg, stream);\n\t\t} else if (typ === DataType.Setup) {\n\t\t\t// The peer sends exactly one SETUP, then FINs. Record it so capability-gated\n\t\t\t// streams (e.g. PROBE) can react, then drain to the FIN.\n\t\t\tconst setup = await Setup.decode(stream, this.#version);\n\t\t\tthis.#peerSetup.set(setup);\n\t\t\tthis.#peerRole.set(setup.role);\n\t\t} else {\n\t\t\tthrow new Error(`unknown stream type: ${typ.toString()}`);\n\t\t}\n\t}\n\n\t/** Snapshot the transport's counters; see {@link Established.stats}. */\n\tasync stats(): Promise<Stats> {\n\t\treturn transportStats(this.#quic);\n\t}\n\n\t/** Resolves when the session closes, decoding the peer's close code; see {@link Established.closed}. */\n\tget closed(): Promise<Error | null> {\n\t\treturn this.#quic.closed.then(fromClose, (err: unknown) => error(err));\n\t}\n}\n\n/**\n * The probe level to advertise in SETUP, from what the transport can measure.\n *\n * `Report` claims we can measure and periodically report, so it is only truthful\n * when a metric this version can carry actually exists. The qmux/WebSocket fallback\n * implements no `getStats()` at all, and even a transport that has one may report\n * neither figure. Advertising `Report` and then holding the subscriber's PROBE\n * stream open with nothing to send is the state this avoids; the subscriber's own\n * gate then skips a stream it could not use.\n *\n * Mirrors `ProbeLevel::detect` in `moq-net`, including its limitation: a metric\n * that only appears after SETUP reads as unsupported here.\n *\n * @internal\n */\nexport async function probeLevel(quic: WebTransport, version: Version): Promise<ProbeLevel> {\n\tconst getStats = (\n\t\tquic as unknown as {\n\t\t\tgetStats?: () => Promise<{ estimatedSendRate: number | null; smoothedRtt?: number | null }>;\n\t\t}\n\t).getStats;\n\tif (typeof getStats !== \"function\") return ProbeLevel.None;\n\n\t// A transport that can't answer tells us nothing, which is itself an answer.\n\tlet stats: { estimatedSendRate: number | null; smoothedRtt?: number | null };\n\ttry {\n\t\tstats = await getStats.call(quic);\n\t} catch {\n\t\treturn ProbeLevel.None;\n\t}\n\n\tconst rtt = hasProbeRtt(version) ? stats.smoothedRtt : undefined;\n\treturn stats.estimatedSendRate != null || rtt != null ? ProbeLevel.Report : ProbeLevel.None;\n}\n"]}
|
package/lite/datagram.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { Version } from "./version";
|
|
1
2
|
/**
|
|
2
3
|
* A QUIC datagram body: `subscribe (i) | sequence (i) | timestamp (i) | payload (b)`.
|
|
3
4
|
*
|
|
@@ -16,8 +17,8 @@ export declare class Datagram {
|
|
|
16
17
|
payload: Uint8Array;
|
|
17
18
|
constructor(subscribe: bigint, sequence: number, timestamp: number, payload: Uint8Array);
|
|
18
19
|
/** Encode the body to a single `Uint8Array` (no length prefix; the datagram boundary delimits it). */
|
|
19
|
-
encode(): Uint8Array;
|
|
20
|
+
encode(version: Version): Uint8Array;
|
|
20
21
|
/** Decode a datagram body from the raw bytes of one QUIC datagram. */
|
|
21
|
-
static decode(data: Uint8Array): Promise<Datagram>;
|
|
22
|
+
static decode(data: Uint8Array, version: Version): Promise<Datagram>;
|
|
22
23
|
}
|
|
23
24
|
//# sourceMappingURL=datagram.d.ts.map
|
package/lite/datagram.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"datagram.d.ts","sourceRoot":"","sources":["../../src/lite/datagram.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"datagram.d.ts","sourceRoot":"","sources":["../../src/lite/datagram.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAE5C;;;;;;GAMG;AACH,qBAAa,QAAQ;IACpB,kDAAkD;IAClD,SAAS,EAAE,MAAM,CAAC;IAClB,uEAAuE;IACvE,QAAQ,EAAE,MAAM,CAAC;IACjB,4EAA4E;IAC5E,SAAS,EAAE,MAAM,CAAC;IAClB,6DAA6D;IAC7D,OAAO,EAAE,UAAU,CAAC;IAEpB,YAAY,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,EAKtF;IAED,sGAAsG;IACtG,MAAM,CAAC,OAAO,EAAE,OAAO,GAAG,UAAU,CAiBnC;IAED,sEAAsE;IACtE,OAAa,MAAM,CAAC,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC,CAOzE;CACD"}
|
package/lite/datagram.js
CHANGED
|
@@ -4,8 +4,7 @@
|
|
|
4
4
|
*
|
|
5
5
|
* @module
|
|
6
6
|
*/
|
|
7
|
-
import { Reader } from "../stream.js";
|
|
8
|
-
import * as Varint from "../varint.js";
|
|
7
|
+
import { encodeVarint, Reader } from "../stream.js";
|
|
9
8
|
/**
|
|
10
9
|
* A QUIC datagram body: `subscribe (i) | sequence (i) | timestamp (i) | payload (b)`.
|
|
11
10
|
*
|
|
@@ -29,10 +28,10 @@ export class Datagram {
|
|
|
29
28
|
this.payload = payload;
|
|
30
29
|
}
|
|
31
30
|
/** Encode the body to a single `Uint8Array` (no length prefix; the datagram boundary delimits it). */
|
|
32
|
-
encode() {
|
|
33
|
-
const subscribe =
|
|
34
|
-
const sequence =
|
|
35
|
-
const timestamp =
|
|
31
|
+
encode(version) {
|
|
32
|
+
const subscribe = encodeVarint(this.subscribe, version);
|
|
33
|
+
const sequence = encodeVarint(this.sequence, version);
|
|
34
|
+
const timestamp = encodeVarint(this.timestamp, version);
|
|
36
35
|
const out = new Uint8Array(subscribe.byteLength + sequence.byteLength + timestamp.byteLength + this.payload.byteLength);
|
|
37
36
|
let offset = 0;
|
|
38
37
|
out.set(subscribe, offset);
|
|
@@ -45,8 +44,8 @@ export class Datagram {
|
|
|
45
44
|
return out;
|
|
46
45
|
}
|
|
47
46
|
/** Decode a datagram body from the raw bytes of one QUIC datagram. */
|
|
48
|
-
static async decode(data) {
|
|
49
|
-
const r = new Reader(undefined, data);
|
|
47
|
+
static async decode(data, version) {
|
|
48
|
+
const r = new Reader(undefined, data, version);
|
|
50
49
|
const subscribe = await r.u62();
|
|
51
50
|
const sequence = await r.u53();
|
|
52
51
|
const timestamp = await r.u53();
|
package/lite/datagram.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"datagram.js","sourceRoot":"","sources":["../../src/lite/datagram.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"datagram.js","sourceRoot":"","sources":["../../src/lite/datagram.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAGpD;;;;;;GAMG;AACH,MAAM,OAAO,QAAQ;IACpB,kDAAkD;IAClD,SAAS,CAAS;IAClB,uEAAuE;IACvE,QAAQ,CAAS;IACjB,4EAA4E;IAC5E,SAAS,CAAS;IAClB,6DAA6D;IAC7D,OAAO,CAAa;IAEpB,YAAY,SAAiB,EAAE,QAAgB,EAAE,SAAiB,EAAE,OAAmB;QACtF,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;QAC3B,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;QAC3B,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IACxB,CAAC;IAED,sGAAsG;IACtG,MAAM,CAAC,OAAgB;QACtB,MAAM,SAAS,GAAG,YAAY,CAAC,IAAI,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;QACxD,MAAM,QAAQ,GAAG,YAAY,CAAC,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QACtD,MAAM,SAAS,GAAG,YAAY,CAAC,IAAI,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;QAExD,MAAM,GAAG,GAAG,IAAI,UAAU,CACzB,SAAS,CAAC,UAAU,GAAG,QAAQ,CAAC,UAAU,GAAG,SAAS,CAAC,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAC3F,CAAC;QACF,IAAI,MAAM,GAAG,CAAC,CAAC;QACf,GAAG,CAAC,GAAG,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;QAC3B,MAAM,IAAI,SAAS,CAAC,UAAU,CAAC;QAC/B,GAAG,CAAC,GAAG,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;QAC1B,MAAM,IAAI,QAAQ,CAAC,UAAU,CAAC;QAC9B,GAAG,CAAC,GAAG,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;QAC3B,MAAM,IAAI,SAAS,CAAC,UAAU,CAAC;QAC/B,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QAC9B,OAAO,GAAG,CAAC;IACZ,CAAC;IAED,sEAAsE;IACtE,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,IAAgB,EAAE,OAAgB;QACrD,MAAM,CAAC,GAAG,IAAI,MAAM,CAAC,SAAS,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;QAC/C,MAAM,SAAS,GAAG,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC;QAChC,MAAM,QAAQ,GAAG,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC;QAC/B,MAAM,SAAS,GAAG,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC;QAChC,MAAM,OAAO,GAAG,MAAM,CAAC,CAAC,OAAO,EAAE,CAAC;QAClC,OAAO,IAAI,QAAQ,CAAC,SAAS,EAAE,QAAQ,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;IAC9D,CAAC;CACD","sourcesContent":["/**\n * Wire-level QUIC datagram body for moq-lite-05 (§6.4).\n *\n * @module\n */\nimport { encodeVarint, Reader } from \"../stream.ts\";\nimport type { Version } from \"./version.ts\";\n\n/**\n * A QUIC datagram body: `subscribe (i) | sequence (i) | timestamp (i) | payload (b)`.\n *\n * The payload runs to the datagram boundary, so unlike a size-prefixed lite message there is no\n * inner length prefix. Mirrors the Rust `lite::Datagram`; the model counterpart is\n * {@link Datagram} in `../datagram.ts`.\n */\nexport class Datagram {\n\t/** Subscribe ID this datagram is delivered on. */\n\tsubscribe: bigint;\n\t/** Group sequence number (shared with the track's group namespace). */\n\tsequence: number;\n\t/** Absolute presentation timestamp, in the track's negotiated timescale. */\n\ttimestamp: number;\n\t/** The frame payload, delimited by the datagram boundary. */\n\tpayload: Uint8Array;\n\n\tconstructor(subscribe: bigint, sequence: number, timestamp: number, payload: Uint8Array) {\n\t\tthis.subscribe = subscribe;\n\t\tthis.sequence = sequence;\n\t\tthis.timestamp = timestamp;\n\t\tthis.payload = payload;\n\t}\n\n\t/** Encode the body to a single `Uint8Array` (no length prefix; the datagram boundary delimits it). */\n\tencode(version: Version): Uint8Array {\n\t\tconst subscribe = encodeVarint(this.subscribe, version);\n\t\tconst sequence = encodeVarint(this.sequence, version);\n\t\tconst timestamp = encodeVarint(this.timestamp, version);\n\n\t\tconst out = new Uint8Array(\n\t\t\tsubscribe.byteLength + sequence.byteLength + timestamp.byteLength + this.payload.byteLength,\n\t\t);\n\t\tlet offset = 0;\n\t\tout.set(subscribe, offset);\n\t\toffset += subscribe.byteLength;\n\t\tout.set(sequence, offset);\n\t\toffset += sequence.byteLength;\n\t\tout.set(timestamp, offset);\n\t\toffset += timestamp.byteLength;\n\t\tout.set(this.payload, offset);\n\t\treturn out;\n\t}\n\n\t/** Decode a datagram body from the raw bytes of one QUIC datagram. */\n\tstatic async decode(data: Uint8Array, version: Version): Promise<Datagram> {\n\t\tconst r = new Reader(undefined, data, version);\n\t\tconst subscribe = await r.u62();\n\t\tconst sequence = await r.u53();\n\t\tconst timestamp = await r.u53();\n\t\tconst payload = await r.readAll();\n\t\treturn new Datagram(subscribe, sequence, timestamp, payload);\n\t}\n}\n"]}
|
package/lite/fetch.d.ts
CHANGED
|
@@ -7,7 +7,21 @@ export declare class Fetch {
|
|
|
7
7
|
track: string;
|
|
8
8
|
priority: number;
|
|
9
9
|
group: number;
|
|
10
|
-
|
|
10
|
+
/** Index of the first frame to return; 0 is the start of the group. Lite-06+. */
|
|
11
|
+
startFrame: number;
|
|
12
|
+
/**
|
|
13
|
+
* Index of the last frame to return (inclusive), or undefined for through the end
|
|
14
|
+
* of the group. Lite-06+.
|
|
15
|
+
*/
|
|
16
|
+
endFrame?: number;
|
|
17
|
+
constructor({ broadcast, track, priority, group, startFrame, endFrame, }: {
|
|
18
|
+
broadcast: Path.Valid;
|
|
19
|
+
track: string;
|
|
20
|
+
priority: number;
|
|
21
|
+
group: number;
|
|
22
|
+
startFrame?: number;
|
|
23
|
+
endFrame?: number;
|
|
24
|
+
});
|
|
11
25
|
encode(w: Writer, version: Version): Promise<void>;
|
|
12
26
|
static decode(r: Reader, version: Version): Promise<Fetch>;
|
|
13
27
|
}
|
package/lite/fetch.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fetch.d.ts","sourceRoot":"","sources":["../../src/lite/fetch.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,IAAI,MAAM,YAAY,CAAC;AACnC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAEnD,OAAO,
|
|
1
|
+
{"version":3,"file":"fetch.d.ts","sourceRoot":"","sources":["../../src/lite/fetch.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,IAAI,MAAM,YAAY,CAAC;AACnC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAEnD,OAAO,EAAkB,OAAO,EAAE,MAAM,cAAc,CAAC;AAYvD,qBAAa,KAAK;;IACjB,SAAS,EAAE,IAAI,CAAC,KAAK,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IAEd,iFAAiF;IACjF,UAAU,EAAE,MAAM,CAAC;IAEnB;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB,YAAY,EACX,SAAS,EACT,KAAK,EACL,QAAQ,EACR,KAAK,EACL,UAAc,EACd,QAAQ,GACR,EAAE;QACF,SAAS,EAAE,IAAI,CAAC,KAAK,CAAC;QACtB,KAAK,EAAE,MAAM,CAAC;QACd,QAAQ,EAAE,MAAM,CAAC;QACjB,KAAK,EAAE,MAAM,CAAC;QACd,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;KAClB,EAOA;IA2CK,MAAM,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAGvD;IAED,OAAa,MAAM,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,CAG/D;CACD"}
|
package/lite/fetch.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/* @ts-self-types="./fetch.d.ts" */
|
|
2
2
|
import * as Path from "../path.js";
|
|
3
3
|
import * as Message from "./message.js";
|
|
4
|
-
import { Version } from "./version.js";
|
|
4
|
+
import { hasFrameBounds, Version } from "./version.js";
|
|
5
5
|
function guardFetch(version) {
|
|
6
6
|
switch (version) {
|
|
7
7
|
case Version.DRAFT_01:
|
|
@@ -16,32 +16,64 @@ export class Fetch {
|
|
|
16
16
|
track;
|
|
17
17
|
priority;
|
|
18
18
|
group;
|
|
19
|
-
|
|
19
|
+
/** Index of the first frame to return; 0 is the start of the group. Lite-06+. */
|
|
20
|
+
startFrame;
|
|
21
|
+
/**
|
|
22
|
+
* Index of the last frame to return (inclusive), or undefined for through the end
|
|
23
|
+
* of the group. Lite-06+.
|
|
24
|
+
*/
|
|
25
|
+
endFrame;
|
|
26
|
+
constructor({ broadcast, track, priority, group, startFrame = 0, endFrame, }) {
|
|
20
27
|
this.broadcast = broadcast;
|
|
21
28
|
this.track = track;
|
|
22
29
|
this.priority = priority;
|
|
23
30
|
this.group = group;
|
|
31
|
+
this.startFrame = startFrame;
|
|
32
|
+
this.endFrame = endFrame;
|
|
24
33
|
}
|
|
25
|
-
async #encode(w) {
|
|
34
|
+
async #encode(w, version) {
|
|
26
35
|
await w.string(Path.encode(this.broadcast));
|
|
27
36
|
await w.string(this.track);
|
|
28
37
|
await w.u8(this.priority);
|
|
29
38
|
await w.u53(this.group);
|
|
39
|
+
if (hasFrameBounds(version)) {
|
|
40
|
+
await w.u53(this.startFrame);
|
|
41
|
+
await w.u53(this.endFrame !== undefined ? this.endFrame + 1 : 0);
|
|
42
|
+
}
|
|
43
|
+
else if (this.startFrame !== 0 || this.endFrame !== undefined) {
|
|
44
|
+
// The peer would serve the whole group, including frames we excluded.
|
|
45
|
+
throw new Error("frame bounds not supported for this version");
|
|
46
|
+
}
|
|
30
47
|
}
|
|
31
|
-
static async #decode(r) {
|
|
48
|
+
static async #decode(r, version) {
|
|
32
49
|
const broadcast = Path.decode(await r.string());
|
|
33
50
|
const track = await r.string();
|
|
34
51
|
const priority = await r.u8();
|
|
35
52
|
const group = await r.u53();
|
|
36
|
-
|
|
53
|
+
if (!hasFrameBounds(version)) {
|
|
54
|
+
return new Fetch({ broadcast, track, priority, group });
|
|
55
|
+
}
|
|
56
|
+
const startFrame = await r.u53();
|
|
57
|
+
const endFrame = await r.u53();
|
|
58
|
+
if (endFrame > 0 && endFrame - 1 < startFrame) {
|
|
59
|
+
throw new Error("fetch frame range ends before it starts");
|
|
60
|
+
}
|
|
61
|
+
return new Fetch({
|
|
62
|
+
broadcast,
|
|
63
|
+
track,
|
|
64
|
+
priority,
|
|
65
|
+
group,
|
|
66
|
+
startFrame,
|
|
67
|
+
endFrame: endFrame > 0 ? endFrame - 1 : undefined,
|
|
68
|
+
});
|
|
37
69
|
}
|
|
38
70
|
async encode(w, version) {
|
|
39
71
|
guardFetch(version);
|
|
40
|
-
return Message.encode(w, (w) => this.#encode(w));
|
|
72
|
+
return Message.encode(w, (w) => this.#encode(w, version));
|
|
41
73
|
}
|
|
42
74
|
static async decode(r, version) {
|
|
43
75
|
guardFetch(version);
|
|
44
|
-
return Message.decode(r, (r) => Fetch.#decode(r));
|
|
76
|
+
return Message.decode(r, (r) => Fetch.#decode(r, version));
|
|
45
77
|
}
|
|
46
78
|
}
|
|
47
79
|
//# sourceMappingURL=fetch.js.map
|
package/lite/fetch.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fetch.js","sourceRoot":"","sources":["../../src/lite/fetch.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,IAAI,MAAM,YAAY,CAAC;AAEnC,OAAO,KAAK,OAAO,MAAM,cAAc,CAAC;AACxC,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"fetch.js","sourceRoot":"","sources":["../../src/lite/fetch.ts"],"names":[],"mappings":"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","sourcesContent":["import * as Path from \"../path.ts\";\nimport type { Reader, Writer } from \"../stream.ts\";\nimport * as Message from \"./message.ts\";\nimport { hasFrameBounds, Version } from \"./version.ts\";\n\nfunction guardFetch(version: Version) {\n\tswitch (version) {\n\t\tcase Version.DRAFT_01:\n\t\tcase Version.DRAFT_02:\n\t\t\tthrow new Error(\"fetch not supported for this version\");\n\t\tdefault:\n\t\t\tbreak;\n\t}\n}\n\nexport class Fetch {\n\tbroadcast: Path.Valid;\n\ttrack: string;\n\tpriority: number;\n\tgroup: number;\n\n\t/** Index of the first frame to return; 0 is the start of the group. Lite-06+. */\n\tstartFrame: number;\n\n\t/**\n\t * Index of the last frame to return (inclusive), or undefined for through the end\n\t * of the group. Lite-06+.\n\t */\n\tendFrame?: number;\n\n\tconstructor({\n\t\tbroadcast,\n\t\ttrack,\n\t\tpriority,\n\t\tgroup,\n\t\tstartFrame = 0,\n\t\tendFrame,\n\t}: {\n\t\tbroadcast: Path.Valid;\n\t\ttrack: string;\n\t\tpriority: number;\n\t\tgroup: number;\n\t\tstartFrame?: number;\n\t\tendFrame?: number;\n\t}) {\n\t\tthis.broadcast = broadcast;\n\t\tthis.track = track;\n\t\tthis.priority = priority;\n\t\tthis.group = group;\n\t\tthis.startFrame = startFrame;\n\t\tthis.endFrame = endFrame;\n\t}\n\n\tasync #encode(w: Writer, version: Version) {\n\t\tawait w.string(Path.encode(this.broadcast));\n\t\tawait w.string(this.track);\n\t\tawait w.u8(this.priority);\n\t\tawait w.u53(this.group);\n\n\t\tif (hasFrameBounds(version)) {\n\t\t\tawait w.u53(this.startFrame);\n\t\t\tawait w.u53(this.endFrame !== undefined ? this.endFrame + 1 : 0);\n\t\t} else if (this.startFrame !== 0 || this.endFrame !== undefined) {\n\t\t\t// The peer would serve the whole group, including frames we excluded.\n\t\t\tthrow new Error(\"frame bounds not supported for this version\");\n\t\t}\n\t}\n\n\tstatic async #decode(r: Reader, version: Version): Promise<Fetch> {\n\t\tconst broadcast = Path.decode(await r.string());\n\t\tconst track = await r.string();\n\t\tconst priority = await r.u8();\n\t\tconst group = await r.u53();\n\n\t\tif (!hasFrameBounds(version)) {\n\t\t\treturn new Fetch({ broadcast, track, priority, group });\n\t\t}\n\n\t\tconst startFrame = await r.u53();\n\t\tconst endFrame = await r.u53();\n\t\tif (endFrame > 0 && endFrame - 1 < startFrame) {\n\t\t\tthrow new Error(\"fetch frame range ends before it starts\");\n\t\t}\n\n\t\treturn new Fetch({\n\t\t\tbroadcast,\n\t\t\ttrack,\n\t\t\tpriority,\n\t\t\tgroup,\n\t\t\tstartFrame,\n\t\t\tendFrame: endFrame > 0 ? endFrame - 1 : undefined,\n\t\t});\n\t}\n\n\tasync encode(w: Writer, version: Version): Promise<void> {\n\t\tguardFetch(version);\n\t\treturn Message.encode(w, (w) => this.#encode(w, version));\n\t}\n\n\tstatic async decode(r: Reader, version: Version): Promise<Fetch> {\n\t\tguardFetch(version);\n\t\treturn Message.decode(r, (r) => Fetch.#decode(r, version));\n\t}\n}\n"]}
|
package/lite/goaway.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"goaway.d.ts","sourceRoot":"","sources":["../../src/lite/goaway.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAEnD,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAgBvC,qBAAa,MAAM;;IAClB,GAAG,EAAE,MAAM,CAAC;IAEZ,YAAY,GAAG,EAAE,MAAM,EAEtB;
|
|
1
|
+
{"version":3,"file":"goaway.d.ts","sourceRoot":"","sources":["../../src/lite/goaway.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAEnD,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAgBvC,qBAAa,MAAM;;IAClB,GAAG,EAAE,MAAM,CAAC;IAEZ,YAAY,GAAG,EAAE,MAAM,EAEtB;IAgBK,MAAM,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAGvD;IAED,OAAa,MAAM,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAGhE;CACD"}
|
package/lite/goaway.js
CHANGED
|
@@ -23,7 +23,13 @@ export class Goaway {
|
|
|
23
23
|
await w.string(this.uri);
|
|
24
24
|
}
|
|
25
25
|
static async #decode(r) {
|
|
26
|
-
|
|
26
|
+
const uri = await r.string();
|
|
27
|
+
// The URI is capped at 8,192 bytes, matching the IETF wire and the Rust
|
|
28
|
+
// decoder; a longer one is a protocol violation.
|
|
29
|
+
if (new TextEncoder().encode(uri).byteLength > 8192) {
|
|
30
|
+
throw new Error("GOAWAY URI exceeds 8,192 bytes");
|
|
31
|
+
}
|
|
32
|
+
return new Goaway(uri);
|
|
27
33
|
}
|
|
28
34
|
async encode(w, version) {
|
|
29
35
|
guardGoaway(version);
|
package/lite/goaway.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"goaway.js","sourceRoot":"","sources":["../../src/lite/goaway.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,OAAO,MAAM,cAAc,CAAC;AACxC,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAEvC,SAAS,WAAW,CAAC,OAAgB;IACpC,QAAQ,OAAO,EAAE,CAAC;QACjB,KAAK,OAAO,CAAC,QAAQ,CAAC;QACtB,KAAK,OAAO,CAAC,QAAQ,CAAC;QACtB,KAAK,OAAO,CAAC,QAAQ;YACpB,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAC;QAC1D;YACC,MAAM;IACR,CAAC;AACF,CAAC;AAED,gFAAgF;AAChF,GAAG;AACH,iBAAiB;AACjB,MAAM,OAAO,MAAM;IAClB,GAAG,CAAS;IAEZ,YAAY,GAAW;QACtB,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC;IAChB,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,CAAS;QACtB,MAAM,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC1B,CAAC;IAED,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAS;QAC7B,
|
|
1
|
+
{"version":3,"file":"goaway.js","sourceRoot":"","sources":["../../src/lite/goaway.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,OAAO,MAAM,cAAc,CAAC;AACxC,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAEvC,SAAS,WAAW,CAAC,OAAgB;IACpC,QAAQ,OAAO,EAAE,CAAC;QACjB,KAAK,OAAO,CAAC,QAAQ,CAAC;QACtB,KAAK,OAAO,CAAC,QAAQ,CAAC;QACtB,KAAK,OAAO,CAAC,QAAQ;YACpB,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAC;QAC1D;YACC,MAAM;IACR,CAAC;AACF,CAAC;AAED,gFAAgF;AAChF,GAAG;AACH,iBAAiB;AACjB,MAAM,OAAO,MAAM;IAClB,GAAG,CAAS;IAEZ,YAAY,GAAW;QACtB,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC;IAChB,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,CAAS;QACtB,MAAM,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC1B,CAAC;IAED,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAS;QAC7B,MAAM,GAAG,GAAG,MAAM,CAAC,CAAC,MAAM,EAAE,CAAC;QAC7B,wEAAwE;QACxE,iDAAiD;QACjD,IAAI,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,UAAU,GAAG,IAAI,EAAE,CAAC;YACrD,MAAM,IAAI,KAAK,CAAC,gCAAgC,CAAC,CAAC;QACnD,CAAC;QACD,OAAO,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC;IACxB,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,CAAS,EAAE,OAAgB;QACvC,WAAW,CAAC,OAAO,CAAC,CAAC;QACrB,OAAO,OAAO,CAAC,MAAM,CAAC,CAAC,EAAE,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IACnD,CAAC;IAED,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAS,EAAE,OAAgB;QAC9C,WAAW,CAAC,OAAO,CAAC,CAAC;QACrB,OAAO,OAAO,CAAC,MAAM,CAAC,CAAC,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;IAC1C,CAAC;CACD","sourcesContent":["import type { Reader, Writer } from \"../stream.ts\";\nimport * as Message from \"./message.ts\";\nimport { Version } from \"./version.ts\";\n\nfunction guardGoaway(version: Version) {\n\tswitch (version) {\n\t\tcase Version.DRAFT_01:\n\t\tcase Version.DRAFT_02:\n\t\tcase Version.DRAFT_03:\n\t\t\tthrow new Error(\"goaway not supported for this version\");\n\t\tdefault:\n\t\t\tbreak;\n\t}\n}\n\n/// Sent to gracefully shut down a session and optionally redirect to a new URI.\n///\n/// Lite04+ only.\nexport class Goaway {\n\turi: string;\n\n\tconstructor(uri: string) {\n\t\tthis.uri = uri;\n\t}\n\n\tasync #encode(w: Writer) {\n\t\tawait w.string(this.uri);\n\t}\n\n\tstatic async #decode(r: Reader): Promise<Goaway> {\n\t\tconst uri = await r.string();\n\t\t// The URI is capped at 8,192 bytes, matching the IETF wire and the Rust\n\t\t// decoder; a longer one is a protocol violation.\n\t\tif (new TextEncoder().encode(uri).byteLength > 8192) {\n\t\t\tthrow new Error(\"GOAWAY URI exceeds 8,192 bytes\");\n\t\t}\n\t\treturn new Goaway(uri);\n\t}\n\n\tasync encode(w: Writer, version: Version): Promise<void> {\n\t\tguardGoaway(version);\n\t\treturn Message.encode(w, this.#encode.bind(this));\n\t}\n\n\tstatic async decode(r: Reader, version: Version): Promise<Goaway> {\n\t\tguardGoaway(version);\n\t\treturn Message.decode(r, Goaway.#decode);\n\t}\n}\n"]}
|
package/lite/group.d.ts
CHANGED
|
@@ -1,18 +1,36 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import type * as netGroup from "../group";
|
|
2
|
+
import type { Cursor, Reader, Writer } from "../stream";
|
|
3
|
+
import { type Version } from "./version";
|
|
2
4
|
export declare class Group {
|
|
3
5
|
#private;
|
|
4
6
|
subscribe: bigint;
|
|
5
7
|
sequence: number;
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
8
|
+
/**
|
|
9
|
+
* The index of the first frame on this stream within the group.
|
|
10
|
+
*
|
|
11
|
+
* 0 (the common case) means the stream carries the group from its beginning. A
|
|
12
|
+
* higher value means the leading frames are not here, either because the
|
|
13
|
+
* subscription started partway into the group or because the publisher only holds
|
|
14
|
+
* the tail. Lite-06+; older versions always start at 0.
|
|
15
|
+
*/
|
|
16
|
+
frameStart: number;
|
|
17
|
+
constructor({ subscribe, sequence, frameStart, }: {
|
|
18
|
+
subscribe: bigint;
|
|
19
|
+
sequence: number;
|
|
20
|
+
frameStart?: number;
|
|
21
|
+
});
|
|
22
|
+
encode(w: Writer, version: Version): Promise<void>;
|
|
23
|
+
static decode(r: Reader, version: Version): Promise<Group>;
|
|
24
|
+
static decodeMaybe(r: Reader, version: Version): Promise<Group | undefined>;
|
|
17
25
|
}
|
|
26
|
+
/**
|
|
27
|
+
* A synchronous decode for one frame of a group or FETCH response stream.
|
|
28
|
+
*
|
|
29
|
+
* A non-zero `scale` means every frame is prefixed with a zigzag-delta timestamp (the lite-05
|
|
30
|
+
* FRAME format), decoded into a Timestamp at that scale. Scale 0 (pre-lite-05) carries no
|
|
31
|
+
* timestamp, so frames are wall-clock stamped on arrival.
|
|
32
|
+
*/
|
|
33
|
+
export declare function frameDecoder(scale: number): (c: Cursor) => netGroup.Frame;
|
|
34
|
+
/** Write a group stream's frames into `producer` until the stream ends or the producer closes. */
|
|
35
|
+
export declare function readFrames(stream: Reader, producer: netGroup.Producer, scale: number): Promise<void>;
|
|
18
36
|
//# sourceMappingURL=group.d.ts.map
|
package/lite/group.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"group.d.ts","sourceRoot":"","sources":["../../src/lite/group.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"group.d.ts","sourceRoot":"","sources":["../../src/lite/group.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,KAAK,QAAQ,MAAM,aAAa,CAAC;AAC7C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAG3D,OAAO,EAAkB,KAAK,OAAO,EAAE,MAAM,cAAc,CAAC;AAE5D,qBAAa,KAAK;;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IAEjB;;;;;;;OAOG;IACH,UAAU,EAAE,MAAM,CAAC;IAEnB,YAAY,EACX,SAAS,EACT,QAAQ,EACR,UAAc,GACd,EAAE;QACF,SAAS,EAAE,MAAM,CAAC;QAClB,QAAQ,EAAE,MAAM,CAAC;QACjB,UAAU,CAAC,EAAE,MAAM,CAAC;KACpB,EAIA;IAoBK,MAAM,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAEvD;IAED,OAAa,MAAM,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,CAE/D;IAED,OAAa,WAAW,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,KAAK,GAAG,SAAS,CAAC,CAEhF;CACD;AAOD;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,CAAC,CAAC,EAAE,MAAM,KAAK,QAAQ,CAAC,KAAK,CAczE;AAED,kGAAkG;AAClG,wBAAsB,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,CAAC,QAAQ,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAW1G"}
|