@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.
- package/README.md +1 -0
- package/announced.d.ts +111 -21
- package/announced.d.ts.map +1 -1
- package/announced.js +213 -40
- package/announced.js.map +1 -1
- package/broadcast.d.ts +80 -25
- package/broadcast.d.ts.map +1 -1
- package/broadcast.js +270 -49
- package/broadcast.js.map +1 -1
- package/connection/accept.d.ts +6 -0
- package/connection/accept.d.ts.map +1 -1
- package/connection/accept.js +42 -13
- package/connection/accept.js.map +1 -1
- package/connection/browser.d.ts +5 -0
- package/connection/browser.d.ts.map +1 -0
- package/connection/browser.js +31 -0
- package/connection/browser.js.map +1 -0
- package/connection/connect.d.ts +43 -1
- package/connection/connect.d.ts.map +1 -1
- package/connection/connect.js +118 -123
- package/connection/connect.js.map +1 -1
- package/connection/established.d.ts +43 -16
- package/connection/established.d.ts.map +1 -1
- package/connection/established.js.map +1 -1
- package/connection/handshake.d.ts +12 -1
- package/connection/handshake.d.ts.map +1 -1
- package/connection/handshake.js +30 -14
- package/connection/handshake.js.map +1 -1
- package/connection/index.d.ts +8 -0
- package/connection/index.d.ts.map +1 -1
- package/connection/index.js +6 -0
- package/connection/index.js.map +1 -1
- package/connection/reload.d.ts +66 -9
- package/connection/reload.d.ts.map +1 -1
- package/connection/reload.js +192 -66
- package/connection/reload.js.map +1 -1
- package/connection/stats.d.ts +92 -0
- package/connection/stats.d.ts.map +1 -0
- package/connection/stats.js +35 -0
- package/connection/stats.js.map +1 -0
- package/connection/transport.d.ts +10 -0
- package/connection/transport.d.ts.map +1 -0
- package/connection/transport.js +12 -0
- package/connection/transport.js.map +1 -0
- package/consume.d.ts +44 -0
- package/consume.d.ts.map +1 -0
- package/consume.js +60 -0
- package/consume.js.map +1 -0
- package/datagram.d.ts +23 -0
- package/datagram.d.ts.map +1 -0
- package/datagram.js +3 -0
- package/datagram.js.map +1 -0
- package/error.d.ts +76 -0
- package/error.d.ts.map +1 -0
- package/error.js +107 -0
- package/error.js.map +1 -0
- package/group.d.ts +143 -38
- package/group.d.ts.map +1 -1
- package/group.js +270 -68
- package/group.js.map +1 -1
- package/ietf/adapter.d.ts +2 -2
- package/ietf/adapter.d.ts.map +1 -1
- package/ietf/adapter.js +20 -10
- package/ietf/adapter.js.map +1 -1
- package/ietf/aliases.d.ts +73 -5
- package/ietf/aliases.d.ts.map +1 -1
- package/ietf/aliases.js +121 -14
- package/ietf/aliases.js.map +1 -1
- package/ietf/cluster.d.ts +141 -0
- package/ietf/cluster.d.ts.map +1 -0
- package/ietf/cluster.js +204 -0
- package/ietf/cluster.js.map +1 -0
- package/ietf/connection.d.ts +39 -6
- package/ietf/connection.d.ts.map +1 -1
- package/ietf/connection.js +73 -12
- package/ietf/connection.js.map +1 -1
- package/ietf/fetch.d.ts +17 -0
- package/ietf/fetch.d.ts.map +1 -1
- package/ietf/fetch.js +21 -0
- package/ietf/fetch.js.map +1 -1
- package/ietf/filter.d.ts +87 -0
- package/ietf/filter.d.ts.map +1 -0
- package/ietf/filter.js +292 -0
- package/ietf/filter.js.map +1 -0
- package/ietf/index.d.ts +2 -0
- package/ietf/index.d.ts.map +1 -1
- package/ietf/index.js +3 -0
- package/ietf/index.js.map +1 -1
- package/ietf/namespace.d.ts +6 -0
- package/ietf/namespace.d.ts.map +1 -1
- package/ietf/namespace.js +27 -2
- package/ietf/namespace.js.map +1 -1
- package/ietf/object.d.ts +54 -6
- package/ietf/object.d.ts.map +1 -1
- package/ietf/object.js +178 -25
- package/ietf/object.js.map +1 -1
- package/ietf/parameters.d.ts +35 -10
- package/ietf/parameters.d.ts.map +1 -1
- package/ietf/parameters.js +236 -45
- package/ietf/parameters.js.map +1 -1
- package/ietf/priority.d.ts +5 -0
- package/ietf/priority.d.ts.map +1 -0
- package/ietf/priority.js +10 -0
- package/ietf/priority.js.map +1 -0
- package/ietf/properties.d.ts +13 -2
- package/ietf/properties.d.ts.map +1 -1
- package/ietf/properties.js +65 -8
- package/ietf/properties.js.map +1 -1
- package/ietf/publish.d.ts.map +1 -1
- package/ietf/publish.js +13 -3
- package/ietf/publish.js.map +1 -1
- package/ietf/publish_namespace.d.ts +16 -2
- package/ietf/publish_namespace.d.ts.map +1 -1
- package/ietf/publish_namespace.js +25 -6
- package/ietf/publish_namespace.js.map +1 -1
- package/ietf/publisher.d.ts +40 -7
- package/ietf/publisher.d.ts.map +1 -1
- package/ietf/publisher.js +751 -134
- package/ietf/publisher.js.map +1 -1
- package/ietf/request.js +1 -1
- package/ietf/request.js.map +1 -1
- package/ietf/solicit.d.ts +41 -0
- package/ietf/solicit.d.ts.map +1 -0
- package/ietf/solicit.js +47 -0
- package/ietf/solicit.js.map +1 -0
- package/ietf/subscribe.d.ts +41 -2
- package/ietf/subscribe.d.ts.map +1 -1
- package/ietf/subscribe.js +103 -22
- package/ietf/subscribe.js.map +1 -1
- package/ietf/subscribe_namespace.d.ts +21 -7
- package/ietf/subscribe_namespace.d.ts.map +1 -1
- package/ietf/subscribe_namespace.js +31 -14
- package/ietf/subscribe_namespace.js.map +1 -1
- package/ietf/subscriber.d.ts +20 -7
- package/ietf/subscriber.d.ts.map +1 -1
- package/ietf/subscriber.js +512 -142
- package/ietf/subscriber.js.map +1 -1
- package/ietf/version.d.ts +7 -1
- package/ietf/version.d.ts.map +1 -1
- package/ietf/version.js +7 -0
- package/ietf/version.js.map +1 -1
- package/index.d.ts +10 -5
- package/index.d.ts.map +1 -1
- package/index.js +10 -5
- package/index.js.map +1 -1
- package/internal.d.ts +29 -0
- package/internal.d.ts.map +1 -0
- package/internal.js +8 -0
- package/internal.js.map +1 -0
- package/lite/announce.d.ts +62 -15
- package/lite/announce.d.ts.map +1 -1
- package/lite/announce.js +230 -94
- package/lite/announce.js.map +1 -1
- package/lite/connection.d.ts +69 -20
- package/lite/connection.d.ts.map +1 -1
- package/lite/connection.js +128 -81
- package/lite/connection.js.map +1 -1
- package/lite/datagram.d.ts +23 -0
- package/lite/datagram.d.ts.map +1 -0
- package/lite/datagram.js +57 -0
- package/lite/datagram.js.map +1 -0
- package/lite/datagram_stream.d.ts +8 -0
- package/lite/datagram_stream.d.ts.map +1 -0
- package/lite/datagram_stream.js +44 -0
- package/lite/datagram_stream.js.map +1 -0
- package/lite/fetch.d.ts.map +1 -1
- package/lite/fetch.js +2 -2
- package/lite/fetch.js.map +1 -1
- package/lite/index.d.ts +3 -0
- package/lite/index.d.ts.map +1 -1
- package/lite/index.js +3 -0
- package/lite/index.js.map +1 -1
- package/lite/priority.d.ts +67 -0
- package/lite/priority.d.ts.map +1 -0
- package/lite/priority.js +114 -0
- package/lite/priority.js.map +1 -0
- package/lite/probe.d.ts +18 -2
- package/lite/probe.d.ts.map +1 -1
- package/lite/probe.js +24 -22
- package/lite/probe.js.map +1 -1
- package/lite/publisher.d.ts +14 -7
- package/lite/publisher.d.ts.map +1 -1
- package/lite/publisher.js +406 -84
- package/lite/publisher.js.map +1 -1
- package/lite/setup.d.ts +83 -6
- package/lite/setup.d.ts.map +1 -1
- package/lite/setup.js +203 -31
- package/lite/setup.js.map +1 -1
- package/lite/stream.d.ts +12 -3
- package/lite/stream.d.ts.map +1 -1
- package/lite/stream.js +7 -4
- package/lite/stream.js.map +1 -1
- package/lite/subscribe.d.ts +37 -23
- package/lite/subscribe.d.ts.map +1 -1
- package/lite/subscribe.js +70 -55
- package/lite/subscribe.js.map +1 -1
- package/lite/subscriber.d.ts +29 -23
- package/lite/subscriber.d.ts.map +1 -1
- package/lite/subscriber.js +689 -112
- package/lite/subscriber.js.map +1 -1
- package/lite/track.d.ts +25 -13
- package/lite/track.d.ts.map +1 -1
- package/lite/track.js +60 -35
- package/lite/track.js.map +1 -1
- package/lite/version.d.ts +39 -4
- package/lite/version.d.ts.map +1 -1
- package/lite/version.js +139 -17
- package/lite/version.js.map +1 -1
- package/mock.d.ts +53 -3
- package/mock.d.ts.map +1 -1
- package/mock.js +110 -21
- package/mock.js.map +1 -1
- package/{lite/origin.d.ts → origin.d.ts} +25 -1
- package/origin.d.ts.map +1 -0
- package/{lite/origin.js → origin.js} +25 -1
- package/origin.js.map +1 -0
- package/package.json +6 -4
- package/path.d.ts +67 -0
- package/path.d.ts.map +1 -1
- package/path.js +128 -0
- package/path.js.map +1 -1
- package/stream.d.ts +94 -4
- package/stream.d.ts.map +1 -1
- package/stream.js +128 -17
- package/stream.js.map +1 -1
- package/time.d.ts +109 -86
- package/time.d.ts.map +1 -1
- package/time.js +80 -30
- package/time.js.map +1 -1
- package/track.d.ts +298 -47
- package/track.d.ts.map +1 -1
- package/track.js +721 -109
- package/track.js.map +1 -1
- package/util/timeout.d.ts +5 -0
- package/util/timeout.d.ts.map +1 -0
- package/util/timeout.js +18 -0
- package/util/timeout.js.map +1 -0
- package/util/utf8.d.ts +3 -0
- package/util/utf8.d.ts.map +1 -0
- package/util/utf8.js +7 -0
- package/util/utf8.js.map +1 -0
- package/varint.d.ts +14 -3
- package/varint.d.ts.map +1 -1
- package/varint.js +23 -12
- package/varint.js.map +1 -1
- package/zod.d.ts +5 -5
- package/zod.d.ts.map +1 -1
- package/zod.js.map +1 -1
- package/bandwidth.d.ts +0 -11
- package/bandwidth.d.ts.map +0 -1
- package/bandwidth.js +0 -7
- package/bandwidth.js.map +0 -1
- package/connection/cert.test.d.ts +0 -2
- package/connection/cert.test.d.ts.map +0 -1
- package/connection/cert.test.js +0 -26
- package/connection/cert.test.js.map +0 -1
- package/connection/reload.test.d.ts +0 -2
- package/connection/reload.test.d.ts.map +0 -1
- package/connection/reload.test.js +0 -39
- package/connection/reload.test.js.map +0 -1
- package/group.test.d.ts +0 -2
- package/group.test.d.ts.map +0 -1
- package/group.test.js +0 -66
- package/group.test.js.map +0 -1
- package/ietf/aliases.test.d.ts +0 -2
- package/ietf/aliases.test.d.ts.map +0 -1
- package/ietf/aliases.test.js +0 -30
- package/ietf/aliases.test.js.map +0 -1
- package/ietf/ietf.test.d.ts +0 -2
- package/ietf/ietf.test.d.ts.map +0 -1
- package/ietf/ietf.test.js +0 -873
- package/ietf/ietf.test.js.map +0 -1
- package/integration.test.d.ts +0 -2
- package/integration.test.d.ts.map +0 -1
- package/integration.test.js +0 -90
- package/integration.test.js.map +0 -1
- package/lite/origin.d.ts.map +0 -1
- package/lite/origin.js.map +0 -1
- package/lite/subscriber.test.d.ts +0 -2
- package/lite/subscriber.test.d.ts.map +0 -1
- package/lite/subscriber.test.js +0 -30
- package/lite/subscriber.test.js.map +0 -1
- package/lite/track.test.d.ts +0 -2
- package/lite/track.test.d.ts.map +0 -1
- package/lite/track.test.js +0 -53
- package/lite/track.test.js.map +0 -1
- package/path.test.d.ts +0 -2
- package/path.test.d.ts.map +0 -1
- package/path.test.js +0 -169
- package/path.test.js.map +0 -1
- package/stream.test.d.ts +0 -2
- package/stream.test.d.ts.map +0 -1
- package/stream.test.js +0 -210
- package/stream.test.js.map +0 -1
- package/track.test.d.ts +0 -2
- package/track.test.d.ts.map +0 -1
- package/track.test.js +0 -56
- package/track.test.js.map +0 -1
- package/util/error.d.ts +0 -3
- package/util/error.d.ts.map +0 -1
- package/util/error.js +0 -9
- package/util/error.js.map +0 -1
- package/util/index.d.ts +0 -2
- package/util/index.d.ts.map +0 -1
- package/util/index.js +0 -3
- package/util/index.js.map +0 -1
- package/varint.test.d.ts +0 -2
- package/varint.test.d.ts.map +0 -1
- package/varint.test.js +0 -106
- package/varint.test.js.map +0 -1
package/lite/connection.js
CHANGED
|
@@ -1,21 +1,23 @@
|
|
|
1
1
|
/* @ts-self-types="./connection.d.ts" */
|
|
2
2
|
import { Signal } from "@norskvideo/moq-signals";
|
|
3
|
-
import
|
|
3
|
+
import * as announce from "../announced.js";
|
|
4
|
+
import { transportStats } from "../connection/stats.js";
|
|
5
|
+
import { transportOf } from "../connection/transport.js";
|
|
6
|
+
import { randomOrigin } from "../origin.js";
|
|
4
7
|
import * as Path from "../path.js";
|
|
5
8
|
import { Readers, Stream, Writer } from "../stream.js";
|
|
6
|
-
import {
|
|
9
|
+
import { AnnounceRequest } from "./announce.js";
|
|
10
|
+
import { Fetch } from "./fetch.js";
|
|
7
11
|
import { Goaway } from "./goaway.js";
|
|
8
12
|
import { Group } from "./group.js";
|
|
9
|
-
import { randomOrigin } from "./origin.js";
|
|
10
13
|
import { Publisher } from "./publisher.js";
|
|
11
14
|
import { SessionInfo } from "./session.js";
|
|
12
|
-
import { Setup } from "./setup.js";
|
|
13
|
-
import {
|
|
15
|
+
import { ProbeLevel, Setup } from "./setup.js";
|
|
16
|
+
import { DataType, StreamId } from "./stream.js";
|
|
14
17
|
import { Subscribe } from "./subscribe.js";
|
|
15
18
|
import { Subscriber } from "./subscriber.js";
|
|
16
|
-
import { Track } from "./track.js";
|
|
17
|
-
import {
|
|
18
|
-
const SEND_BW_POLL_INTERVAL = 100; // ms
|
|
19
|
+
import { Track as TrackMessage } from "./track.js";
|
|
20
|
+
import { hasDatagrams, hasProbeRtt, hasSetupStream, versionName } from "./version.js";
|
|
19
21
|
/**
|
|
20
22
|
* Represents a connection to a MoQ server.
|
|
21
23
|
*
|
|
@@ -26,6 +28,10 @@ export class Connection {
|
|
|
26
28
|
url;
|
|
27
29
|
// The version of the connection as a human-readable string.
|
|
28
30
|
version;
|
|
31
|
+
// The wire transport this session runs over.
|
|
32
|
+
transport;
|
|
33
|
+
/** Whether the relay supports broadcast discovery; see {@link Established.discovery}. */
|
|
34
|
+
discovery;
|
|
29
35
|
// The version used for encoding/decoding.
|
|
30
36
|
#version;
|
|
31
37
|
// The established WebTransport session.
|
|
@@ -36,44 +42,49 @@ export class Connection {
|
|
|
36
42
|
#publisher;
|
|
37
43
|
// Module for distributing tracks.
|
|
38
44
|
#subscriber;
|
|
39
|
-
/**
|
|
40
|
-
|
|
41
|
-
/** Estimated receive bitrate from PROBE (moq-lite-03+ only). */
|
|
42
|
-
recvBandwidth;
|
|
43
|
-
/** RTT in milliseconds from PROBE (moq-lite-04+ only). */
|
|
44
|
-
rtt;
|
|
45
|
+
/** The peer's PROBE estimates; see {@link Established.probe}. */
|
|
46
|
+
probe;
|
|
45
47
|
/** Random per-connection origin id. Shared by Publisher (for outbound hop
|
|
46
48
|
* chains) and Subscriber (available for optional self-filtering on announces). */
|
|
47
49
|
origin;
|
|
50
|
+
// The peer's SETUP, recorded once its Setup stream is read (lite-05+). Streams whose
|
|
51
|
+
// encoding depends on a negotiated capability (e.g. PROBE) wait on this. undefined
|
|
52
|
+
// until the peer's SETUP arrives; stays undefined forever on older drafts.
|
|
53
|
+
#peerSetup = new Signal(undefined);
|
|
54
|
+
// Mirrors the role out of #peerSetup, so the public surface exposes the peer's declared
|
|
55
|
+
// direction without handing out the whole SETUP (whose probe level gates our own streams).
|
|
56
|
+
#peerRole = new Signal(undefined);
|
|
57
|
+
// Written by the Subscriber as PROBE messages arrive.
|
|
58
|
+
#probe = new Signal({});
|
|
59
|
+
/**
|
|
60
|
+
* The {@link Role} the peer advertised in its SETUP, for a server deciding whether the
|
|
61
|
+
* peer's authorization grants the direction it intends to use.
|
|
62
|
+
*
|
|
63
|
+
* `undefined` until the peer's SETUP arrives, and forever on pre-lite-05 versions, which
|
|
64
|
+
* carry no in-band role. {@link Role.Both} is the absence of the parameter, so it is what
|
|
65
|
+
* a peer reports when it declines to declare a direction, sends a value we don't
|
|
66
|
+
* recognize, or is a server (which never sends one).
|
|
67
|
+
*/
|
|
68
|
+
get peerRole() {
|
|
69
|
+
return this.#peerRole;
|
|
70
|
+
}
|
|
48
71
|
/**
|
|
49
72
|
* Creates a new Connection instance.
|
|
50
|
-
* @param url - The URL of the connection
|
|
51
|
-
* @param quic - The WebTransport session
|
|
52
|
-
* @param session - The session stream
|
|
53
73
|
*
|
|
54
74
|
* @internal
|
|
55
75
|
*/
|
|
56
|
-
constructor(url, quic, version, session) {
|
|
76
|
+
constructor({ url, quic, version, session, discovery = true }) {
|
|
57
77
|
this.url = url;
|
|
58
78
|
this.#quic = quic;
|
|
59
79
|
this.#session = session;
|
|
60
80
|
this.version = versionName(version);
|
|
61
81
|
this.#version = version;
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
this.sendBandwidth = createBandwidth();
|
|
66
|
-
}
|
|
67
|
-
// Recv bandwidth requires PROBE support (Lite03+).
|
|
68
|
-
if (version !== Version.DRAFT_01 && version !== Version.DRAFT_02) {
|
|
69
|
-
this.recvBandwidth = createBandwidth();
|
|
70
|
-
}
|
|
71
|
-
// RTT can be populated by PROBE (Lite04+) or getStats() (when supported).
|
|
72
|
-
// TODO prefer getStats() when both are available.
|
|
73
|
-
this.rtt = new Signal(undefined);
|
|
82
|
+
this.transport = transportOf(quic);
|
|
83
|
+
this.discovery = discovery;
|
|
84
|
+
this.probe = this.#probe;
|
|
74
85
|
this.origin = randomOrigin();
|
|
75
86
|
this.#publisher = new Publisher(this.#quic, this.#version, this.origin);
|
|
76
|
-
this.#subscriber = new Subscriber(this.#quic, this.#version, this.origin, this
|
|
87
|
+
this.#subscriber = new Subscriber(this.#quic, this.#version, this.origin, this.#probe, this.#peerSetup);
|
|
77
88
|
void this.#run();
|
|
78
89
|
}
|
|
79
90
|
/**
|
|
@@ -92,15 +103,14 @@ export class Connection {
|
|
|
92
103
|
}
|
|
93
104
|
async #run() {
|
|
94
105
|
const tasks = [this.#runSession(), this.#runBidis(), this.#runUnis()];
|
|
95
|
-
// moq-lite-05+: each endpoint opens a Setup stream and sends a single SETUP message.
|
|
96
106
|
if (hasSetupStream(this.#version)) {
|
|
97
|
-
tasks.push(this.#
|
|
98
|
-
}
|
|
99
|
-
if (this.sendBandwidth) {
|
|
100
|
-
tasks.push(this.#runSendBandwidth(this.sendBandwidth));
|
|
107
|
+
tasks.push(this.#sendSetup());
|
|
101
108
|
}
|
|
102
|
-
|
|
103
|
-
|
|
109
|
+
tasks.push(this.#subscriber.runProbe());
|
|
110
|
+
// Route incoming QUIC datagrams into their subscriptions (lite-05+; runDatagrams
|
|
111
|
+
// no-ops on a transport that doesn't carry them).
|
|
112
|
+
if (hasDatagrams(this.#version)) {
|
|
113
|
+
tasks.push(this.#subscriber.runDatagrams());
|
|
104
114
|
}
|
|
105
115
|
try {
|
|
106
116
|
await Promise.all(tasks);
|
|
@@ -112,14 +122,23 @@ export class Connection {
|
|
|
112
122
|
this.close();
|
|
113
123
|
}
|
|
114
124
|
}
|
|
115
|
-
publish(path,
|
|
116
|
-
this.#publisher.publish(path,
|
|
125
|
+
publish(path, producer) {
|
|
126
|
+
this.#publisher.publish(path, producer);
|
|
117
127
|
}
|
|
118
128
|
announced(prefix = Path.empty()) {
|
|
119
129
|
return this.#subscriber.announced(prefix);
|
|
120
130
|
}
|
|
121
|
-
consume(
|
|
122
|
-
return this.#subscriber.consume(
|
|
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 });
|
|
123
142
|
}
|
|
124
143
|
async #runSession() {
|
|
125
144
|
if (!this.#session) {
|
|
@@ -136,6 +155,26 @@ export class Connection {
|
|
|
136
155
|
console.debug("session stream closed");
|
|
137
156
|
}
|
|
138
157
|
}
|
|
158
|
+
// Open the unidirectional Setup Stream, send our single SETUP, and FIN (lite-05+).
|
|
159
|
+
// The browser uses WebTransport, which carries the request URI, so we advertise no
|
|
160
|
+
// path and leave routing to the URL. The probe level reflects what this transport
|
|
161
|
+
// can actually measure; we never pad, so we never advertise Increase.
|
|
162
|
+
// Role stays Both: publish/consume are called after this point, so there is nothing
|
|
163
|
+
// to narrow yet. The origin declares our session identity so the peer can filter
|
|
164
|
+
// reflected announcements (lite-06 removed ANNOUNCE_REQUEST's exclude_hop for it).
|
|
165
|
+
async #sendSetup() {
|
|
166
|
+
const writer = await Writer.open(this.#quic);
|
|
167
|
+
try {
|
|
168
|
+
await writer.u53(DataType.Setup);
|
|
169
|
+
const probe = await probeLevel(this.#quic, this.#version);
|
|
170
|
+
await new Setup({ probe, origin: this.origin }).encode(writer, this.#version);
|
|
171
|
+
writer.close();
|
|
172
|
+
}
|
|
173
|
+
catch (err) {
|
|
174
|
+
writer.reset(err);
|
|
175
|
+
throw err;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
139
178
|
async #runBidis() {
|
|
140
179
|
for (;;) {
|
|
141
180
|
const stream = await Stream.accept(this.#quic);
|
|
@@ -156,15 +195,19 @@ export class Connection {
|
|
|
156
195
|
throw new Error("duplicate session stream");
|
|
157
196
|
}
|
|
158
197
|
else if (typ === StreamId.Announce) {
|
|
159
|
-
const msg = await
|
|
198
|
+
const msg = await AnnounceRequest.decode(stream.reader, this.#version);
|
|
160
199
|
await this.#publisher.runAnnounce(msg, stream);
|
|
161
200
|
}
|
|
162
201
|
else if (typ === StreamId.Subscribe) {
|
|
163
202
|
const msg = await Subscribe.decode(stream.reader, this.#version);
|
|
164
203
|
await this.#publisher.runSubscribe(msg, stream);
|
|
165
204
|
}
|
|
205
|
+
else if (typ === StreamId.Fetch) {
|
|
206
|
+
const msg = await Fetch.decode(stream.reader, this.#version);
|
|
207
|
+
await this.#publisher.runFetch(msg, stream);
|
|
208
|
+
}
|
|
166
209
|
else if (typ === StreamId.Track) {
|
|
167
|
-
const msg = await
|
|
210
|
+
const msg = await TrackMessage.decode(stream.reader, this.#version);
|
|
168
211
|
await this.#publisher.runTrackInfo(msg, stream);
|
|
169
212
|
}
|
|
170
213
|
else if (typ === StreamId.Probe) {
|
|
@@ -194,54 +237,58 @@ export class Connection {
|
|
|
194
237
|
}
|
|
195
238
|
}
|
|
196
239
|
async #runUni(stream) {
|
|
197
|
-
const typ = await stream.
|
|
198
|
-
if (typ ===
|
|
240
|
+
const typ = await stream.u53();
|
|
241
|
+
if (typ === DataType.Group) {
|
|
199
242
|
const msg = await Group.decode(stream);
|
|
200
243
|
await this.#subscriber.runGroup(msg, stream);
|
|
201
244
|
}
|
|
202
|
-
else if (typ ===
|
|
203
|
-
//
|
|
204
|
-
//
|
|
205
|
-
await Setup.decode(stream, this.#version);
|
|
245
|
+
else if (typ === DataType.Setup) {
|
|
246
|
+
// The peer sends exactly one SETUP, then FINs. Record it so capability-gated
|
|
247
|
+
// streams (e.g. PROBE) can react, then drain to the FIN.
|
|
248
|
+
const setup = await Setup.decode(stream, this.#version);
|
|
249
|
+
this.#peerSetup.set(setup);
|
|
250
|
+
this.#peerRole.set(setup.role);
|
|
206
251
|
}
|
|
207
252
|
else {
|
|
208
253
|
throw new Error(`unknown stream type: ${typ.toString()}`);
|
|
209
254
|
}
|
|
210
255
|
}
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
const writer = await Writer.open(this.#quic);
|
|
215
|
-
try {
|
|
216
|
-
await writer.u8(DataId.Setup);
|
|
217
|
-
await new Setup().encode(writer, this.#version);
|
|
218
|
-
writer.close();
|
|
219
|
-
}
|
|
220
|
-
catch (err) {
|
|
221
|
-
writer.reset(err);
|
|
222
|
-
}
|
|
223
|
-
}
|
|
224
|
-
async #runSendBandwidth(bandwidth) {
|
|
225
|
-
const quic = this.#quic;
|
|
226
|
-
return new Promise((resolve) => {
|
|
227
|
-
const id = setInterval(async () => {
|
|
228
|
-
try {
|
|
229
|
-
const stats = await quic.getStats();
|
|
230
|
-
bandwidth.set(stats.estimatedSendRate ?? undefined);
|
|
231
|
-
}
|
|
232
|
-
catch {
|
|
233
|
-
clearInterval(id);
|
|
234
|
-
resolve();
|
|
235
|
-
}
|
|
236
|
-
}, SEND_BW_POLL_INTERVAL);
|
|
237
|
-
void this.closed.then(() => {
|
|
238
|
-
clearInterval(id);
|
|
239
|
-
resolve();
|
|
240
|
-
});
|
|
241
|
-
});
|
|
256
|
+
/** Snapshot the transport's counters; see {@link Established.stats}. */
|
|
257
|
+
async stats() {
|
|
258
|
+
return transportStats(this.#quic);
|
|
242
259
|
}
|
|
243
260
|
get closed() {
|
|
244
261
|
return this.#quic.closed.then(() => undefined);
|
|
245
262
|
}
|
|
246
263
|
}
|
|
264
|
+
/**
|
|
265
|
+
* The probe level to advertise in SETUP, from what the transport can measure.
|
|
266
|
+
*
|
|
267
|
+
* `Report` claims we can measure and periodically report, so it is only truthful
|
|
268
|
+
* when a metric this version can carry actually exists. The qmux/WebSocket fallback
|
|
269
|
+
* implements no `getStats()` at all, and even a transport that has one may report
|
|
270
|
+
* neither figure. Advertising `Report` and then holding the subscriber's PROBE
|
|
271
|
+
* stream open with nothing to send is the state this avoids; the subscriber's own
|
|
272
|
+
* gate then skips a stream it could not use.
|
|
273
|
+
*
|
|
274
|
+
* Mirrors `ProbeLevel::detect` in `moq-net`, including its limitation: a metric
|
|
275
|
+
* that only appears after SETUP reads as unsupported here.
|
|
276
|
+
*
|
|
277
|
+
* @internal
|
|
278
|
+
*/
|
|
279
|
+
export async function probeLevel(quic, version) {
|
|
280
|
+
const getStats = quic.getStats;
|
|
281
|
+
if (typeof getStats !== "function")
|
|
282
|
+
return ProbeLevel.None;
|
|
283
|
+
// A transport that can't answer tells us nothing, which is itself an answer.
|
|
284
|
+
let stats;
|
|
285
|
+
try {
|
|
286
|
+
stats = await getStats.call(quic);
|
|
287
|
+
}
|
|
288
|
+
catch {
|
|
289
|
+
return ProbeLevel.None;
|
|
290
|
+
}
|
|
291
|
+
const rtt = hasProbeRtt(version) ? stats.smoothedRtt : undefined;
|
|
292
|
+
return stats.estimatedSendRate != null || rtt != null ? ProbeLevel.Report : ProbeLevel.None;
|
|
293
|
+
}
|
|
247
294
|
//# sourceMappingURL=connection.js.map
|
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 { Signal } from \"@moq/signals\";\nimport type { Announced } from \"../announced.ts\";\nimport { type Bandwidth, createBandwidth } from \"../bandwidth.ts\";\nimport type { Broadcast } from \"../broadcast.ts\";\nimport type { Established } from \"../connection/established.ts\";\nimport * as Path from \"../path.ts\";\nimport { type Reader, Readers, Stream, Writer } from \"../stream.ts\";\nimport type * as Time from \"../time.ts\";\nimport { AnnounceInterest } from \"./announce.ts\";\nimport { Goaway } from \"./goaway.ts\";\nimport { Group } from \"./group.ts\";\nimport { type Origin, randomOrigin } from \"./origin.ts\";\nimport { Publisher } from \"./publisher.ts\";\nimport { SessionInfo } from \"./session.ts\";\nimport { Setup } from \"./setup.ts\";\nimport { DataId, StreamId } from \"./stream.ts\";\nimport { Subscribe } from \"./subscribe.ts\";\nimport { Subscriber } from \"./subscriber.ts\";\nimport { Track } from \"./track.ts\";\nimport { hasSetupStream, Version, versionName } from \"./version.ts\";\n\nconst SEND_BW_POLL_INTERVAL = 100; // ms\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 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/** Estimated send bitrate from the congestion controller. */\n\treadonly sendBandwidth?: Bandwidth;\n\n\t/** Estimated receive bitrate from PROBE (moq-lite-03+ only). */\n\treadonly recvBandwidth?: Bandwidth;\n\n\t/** RTT in milliseconds from PROBE (moq-lite-04+ only). */\n\treadonly rtt?: Signal<Time.Milli | undefined>;\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/**\n\t * Creates a new Connection instance.\n\t * @param url - The URL of the connection\n\t * @param quic - The WebTransport session\n\t * @param session - The session stream\n\t *\n\t * @internal\n\t */\n\tconstructor(url: URL, quic: WebTransport, version: Version, session?: Stream) {\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\n\t\t// Send bandwidth is version-agnostic: depends on browser/QUIC support.\n\t\tconst hasGetStats = typeof (quic as unknown as { getStats?: unknown }).getStats === \"function\";\n\t\tif (hasGetStats) {\n\t\t\tthis.sendBandwidth = createBandwidth();\n\t\t}\n\n\t\t// Recv bandwidth requires PROBE support (Lite03+).\n\t\tif (version !== Version.DRAFT_01 && version !== Version.DRAFT_02) {\n\t\t\tthis.recvBandwidth = createBandwidth();\n\t\t}\n\n\t\t// RTT can be populated by PROBE (Lite04+) or getStats() (when supported).\n\t\t// TODO prefer getStats() when both are available.\n\t\tthis.rtt = new Signal<Time.Milli | undefined>(undefined);\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.recvBandwidth, this.rtt);\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\t// moq-lite-05+: each endpoint opens a Setup stream and sends a single SETUP message.\n\t\tif (hasSetupStream(this.#version)) {\n\t\t\ttasks.push(this.#runSetup());\n\t\t}\n\n\t\tif (this.sendBandwidth) {\n\t\t\ttasks.push(this.#runSendBandwidth(this.sendBandwidth));\n\t\t}\n\n\t\tif (this.recvBandwidth) {\n\t\t\ttasks.push(this.#subscriber.runProbe());\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, broadcast: Broadcast) {\n\t\tthis.#publisher.publish(path, broadcast);\n\t}\n\n\tannounced(prefix = Path.empty()): Announced {\n\t\treturn this.#subscriber.announced(prefix);\n\t}\n\n\tconsume(broadcast: Path.Valid): Broadcast {\n\t\treturn this.#subscriber.consume(broadcast);\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\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 AnnounceInterest.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.Track) {\n\t\t\tconst msg = await Track.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.u8();\n\t\tif (typ === DataId.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 === DataId.Setup) {\n\t\t\t// moq-lite-05+: read the peer's SETUP and discard it (the path, if any,\n\t\t\t// is handled at accept time by the server's transport binding).\n\t\t\tawait Setup.decode(stream, this.#version);\n\t\t} else {\n\t\t\tthrow new Error(`unknown stream type: ${typ.toString()}`);\n\t\t}\n\t}\n\n\t// moq-lite-05+: open a unidirectional Setup stream, send a single SETUP, and FIN.\n\t// The browser conveys its path via the WebTransport URL, so the SETUP is empty.\n\tasync #runSetup(): Promise<void> {\n\t\tconst writer = await Writer.open(this.#quic);\n\t\ttry {\n\t\t\tawait writer.u8(DataId.Setup);\n\t\t\tawait new Setup().encode(writer, this.#version);\n\t\t\twriter.close();\n\t\t} catch (err: unknown) {\n\t\t\twriter.reset(err);\n\t\t}\n\t}\n\n\tasync #runSendBandwidth(bandwidth: Bandwidth): Promise<void> {\n\t\tconst quic = this.#quic as unknown as {\n\t\t\tgetStats: () => Promise<{ estimatedSendRate: number | null }>;\n\t\t};\n\n\t\treturn new Promise<void>((resolve) => {\n\t\t\tconst id = setInterval(async () => {\n\t\t\t\ttry {\n\t\t\t\t\tconst stats = await quic.getStats();\n\t\t\t\t\tbandwidth.set(stats.estimatedSendRate ?? undefined);\n\t\t\t\t} catch {\n\t\t\t\t\tclearInterval(id);\n\t\t\t\t\tresolve();\n\t\t\t\t}\n\t\t\t}, SEND_BW_POLL_INTERVAL);\n\n\t\t\tvoid this.closed.then(() => {\n\t\t\t\tclearInterval(id);\n\t\t\t\tresolve();\n\t\t\t});\n\t\t});\n\t}\n\n\tget closed(): Promise<void> {\n\t\treturn this.#quic.closed.then(() => undefined);\n\t}\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 * 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"]}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A QUIC datagram body: `subscribe (i) | sequence (i) | timestamp (i) | payload (b)`.
|
|
3
|
+
*
|
|
4
|
+
* The payload runs to the datagram boundary, so unlike a size-prefixed lite message there is no
|
|
5
|
+
* inner length prefix. Mirrors the Rust `lite::Datagram`; the model counterpart is
|
|
6
|
+
* {@link Datagram} in `../datagram.ts`.
|
|
7
|
+
*/
|
|
8
|
+
export declare class Datagram {
|
|
9
|
+
/** Subscribe ID this datagram is delivered on. */
|
|
10
|
+
subscribe: bigint;
|
|
11
|
+
/** Group sequence number (shared with the track's group namespace). */
|
|
12
|
+
sequence: number;
|
|
13
|
+
/** Absolute presentation timestamp, in the track's negotiated timescale. */
|
|
14
|
+
timestamp: number;
|
|
15
|
+
/** The frame payload, delimited by the datagram boundary. */
|
|
16
|
+
payload: Uint8Array;
|
|
17
|
+
constructor(subscribe: bigint, sequence: number, timestamp: number, payload: Uint8Array);
|
|
18
|
+
/** Encode the body to a single `Uint8Array` (no length prefix; the datagram boundary delimits it). */
|
|
19
|
+
encode(): Uint8Array;
|
|
20
|
+
/** Decode a datagram body from the raw bytes of one QUIC datagram. */
|
|
21
|
+
static decode(data: Uint8Array): Promise<Datagram>;
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=datagram.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"datagram.d.ts","sourceRoot":"","sources":["../../src/lite/datagram.ts"],"names":[],"mappings":"AAQA;;;;;;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,IAAI,UAAU,CAiBnB;IAED,sEAAsE;IACtE,OAAa,MAAM,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,QAAQ,CAAC,CAOvD;CACD"}
|
package/lite/datagram.js
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/* @ts-self-types="./datagram.d.ts" */
|
|
2
|
+
/**
|
|
3
|
+
* Wire-level QUIC datagram body for moq-lite-05 (§6.4).
|
|
4
|
+
*
|
|
5
|
+
* @module
|
|
6
|
+
*/
|
|
7
|
+
import { Reader } from "../stream.js";
|
|
8
|
+
import * as Varint from "../varint.js";
|
|
9
|
+
/**
|
|
10
|
+
* A QUIC datagram body: `subscribe (i) | sequence (i) | timestamp (i) | payload (b)`.
|
|
11
|
+
*
|
|
12
|
+
* The payload runs to the datagram boundary, so unlike a size-prefixed lite message there is no
|
|
13
|
+
* inner length prefix. Mirrors the Rust `lite::Datagram`; the model counterpart is
|
|
14
|
+
* {@link Datagram} in `../datagram.ts`.
|
|
15
|
+
*/
|
|
16
|
+
export class Datagram {
|
|
17
|
+
/** Subscribe ID this datagram is delivered on. */
|
|
18
|
+
subscribe;
|
|
19
|
+
/** Group sequence number (shared with the track's group namespace). */
|
|
20
|
+
sequence;
|
|
21
|
+
/** Absolute presentation timestamp, in the track's negotiated timescale. */
|
|
22
|
+
timestamp;
|
|
23
|
+
/** The frame payload, delimited by the datagram boundary. */
|
|
24
|
+
payload;
|
|
25
|
+
constructor(subscribe, sequence, timestamp, payload) {
|
|
26
|
+
this.subscribe = subscribe;
|
|
27
|
+
this.sequence = sequence;
|
|
28
|
+
this.timestamp = timestamp;
|
|
29
|
+
this.payload = payload;
|
|
30
|
+
}
|
|
31
|
+
/** Encode the body to a single `Uint8Array` (no length prefix; the datagram boundary delimits it). */
|
|
32
|
+
encode() {
|
|
33
|
+
const subscribe = Varint.encodeTo(new ArrayBuffer(8), this.subscribe);
|
|
34
|
+
const sequence = Varint.encodeTo(new ArrayBuffer(8), this.sequence);
|
|
35
|
+
const timestamp = Varint.encodeTo(new ArrayBuffer(8), this.timestamp);
|
|
36
|
+
const out = new Uint8Array(subscribe.byteLength + sequence.byteLength + timestamp.byteLength + this.payload.byteLength);
|
|
37
|
+
let offset = 0;
|
|
38
|
+
out.set(subscribe, offset);
|
|
39
|
+
offset += subscribe.byteLength;
|
|
40
|
+
out.set(sequence, offset);
|
|
41
|
+
offset += sequence.byteLength;
|
|
42
|
+
out.set(timestamp, offset);
|
|
43
|
+
offset += timestamp.byteLength;
|
|
44
|
+
out.set(this.payload, offset);
|
|
45
|
+
return out;
|
|
46
|
+
}
|
|
47
|
+
/** Decode a datagram body from the raw bytes of one QUIC datagram. */
|
|
48
|
+
static async decode(data) {
|
|
49
|
+
const r = new Reader(undefined, data);
|
|
50
|
+
const subscribe = await r.u62();
|
|
51
|
+
const sequence = await r.u53();
|
|
52
|
+
const timestamp = await r.u53();
|
|
53
|
+
const payload = await r.readAll();
|
|
54
|
+
return new Datagram(subscribe, sequence, timestamp, payload);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=datagram.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"datagram.js","sourceRoot":"","sources":["../../src/lite/datagram.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AACtC,OAAO,KAAK,MAAM,MAAM,cAAc,CAAC;AAEvC;;;;;;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;QACL,MAAM,SAAS,GAAG,MAAM,CAAC,QAAQ,CAAC,IAAI,WAAW,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;QACtE,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC,IAAI,WAAW,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;QACpE,MAAM,SAAS,GAAG,MAAM,CAAC,QAAQ,CAAC,IAAI,WAAW,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;QAEtE,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;QACnC,MAAM,CAAC,GAAG,IAAI,MAAM,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;QACtC,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 { Reader } from \"../stream.ts\";\nimport * as Varint from \"../varint.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(): Uint8Array {\n\t\tconst subscribe = Varint.encodeTo(new ArrayBuffer(8), this.subscribe);\n\t\tconst sequence = Varint.encodeTo(new ArrayBuffer(8), this.sequence);\n\t\tconst timestamp = Varint.encodeTo(new ArrayBuffer(8), this.timestamp);\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): Promise<Datagram> {\n\t\tconst r = new Reader(undefined, data);\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"]}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/** Compatibility helpers for browser WebTransport datagram stream shape changes. */
|
|
2
|
+
/** The max outgoing datagram payload size, or 0 when this transport cannot send datagrams. */
|
|
3
|
+
export declare function maxDatagramSize(quic: WebTransport): number;
|
|
4
|
+
/** Get a datagram reader, or undefined when this browser/transport does not expose one. */
|
|
5
|
+
export declare function datagramReader(quic: WebTransport): ReadableStreamDefaultReader<Uint8Array> | undefined;
|
|
6
|
+
/** Get a datagram writer, or undefined when this browser/transport does not expose one. */
|
|
7
|
+
export declare function datagramWriter(quic: WebTransport): WritableStreamDefaultWriter<Uint8Array> | undefined;
|
|
8
|
+
//# sourceMappingURL=datagram_stream.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"datagram_stream.d.ts","sourceRoot":"","sources":["../../src/lite/datagram_stream.ts"],"names":[],"mappings":"AAAA,oFAAoF;AAcpF,8FAA8F;AAC9F,wBAAgB,eAAe,CAAC,IAAI,EAAE,YAAY,GAAG,MAAM,CAG1D;AAED,2FAA2F;AAC3F,wBAAgB,cAAc,CAAC,IAAI,EAAE,YAAY,GAAG,2BAA2B,CAAC,UAAU,CAAC,GAAG,SAAS,CAatG;AAED,2FAA2F;AAC3F,wBAAgB,cAAc,CAAC,IAAI,EAAE,YAAY,GAAG,2BAA2B,CAAC,UAAU,CAAC,GAAG,SAAS,CAgBtG"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/* @ts-self-types="./datagram_stream.d.ts" */
|
|
2
|
+
/** Compatibility helpers for browser WebTransport datagram stream shape changes. */
|
|
3
|
+
function datagrams(quic) {
|
|
4
|
+
return quic.datagrams;
|
|
5
|
+
}
|
|
6
|
+
/** The max outgoing datagram payload size, or 0 when this transport cannot send datagrams. */
|
|
7
|
+
export function maxDatagramSize(quic) {
|
|
8
|
+
const size = datagrams(quic)?.maxDatagramSize;
|
|
9
|
+
return typeof size === "number" && size > 0 ? size : 0;
|
|
10
|
+
}
|
|
11
|
+
/** Get a datagram reader, or undefined when this browser/transport does not expose one. */
|
|
12
|
+
export function datagramReader(quic) {
|
|
13
|
+
const readable = datagrams(quic)?.readable;
|
|
14
|
+
if (!readable) {
|
|
15
|
+
console.warn("datagram receive disabled: WebTransport datagrams.readable is unavailable");
|
|
16
|
+
return undefined;
|
|
17
|
+
}
|
|
18
|
+
try {
|
|
19
|
+
return readable.getReader();
|
|
20
|
+
}
|
|
21
|
+
catch (err) {
|
|
22
|
+
console.warn("datagram receive disabled: failed to open WebTransport datagram reader", err);
|
|
23
|
+
return undefined;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
/** Get a datagram writer, or undefined when this browser/transport does not expose one. */
|
|
27
|
+
export function datagramWriter(quic) {
|
|
28
|
+
const stream = datagrams(quic);
|
|
29
|
+
if (!stream || maxDatagramSize(quic) === 0)
|
|
30
|
+
return undefined;
|
|
31
|
+
try {
|
|
32
|
+
const writable = typeof stream.createWritable === "function" ? stream.createWritable() : stream.writable;
|
|
33
|
+
if (!writable) {
|
|
34
|
+
console.warn("datagram send disabled: WebTransport datagram writable stream is unavailable");
|
|
35
|
+
return undefined;
|
|
36
|
+
}
|
|
37
|
+
return writable.getWriter();
|
|
38
|
+
}
|
|
39
|
+
catch (err) {
|
|
40
|
+
console.warn("datagram send disabled: failed to open WebTransport datagram writer", err);
|
|
41
|
+
return undefined;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=datagram_stream.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"datagram_stream.js","sourceRoot":"","sources":["../../src/lite/datagram_stream.ts"],"names":[],"mappings":"AAAA,oFAAoF;AAUpF,SAAS,SAAS,CAAC,IAAkB;IACpC,OAAQ,IAAkD,CAAC,SAAS,CAAC;AACtE,CAAC;AAED,8FAA8F;AAC9F,MAAM,UAAU,eAAe,CAAC,IAAkB;IACjD,MAAM,IAAI,GAAG,SAAS,CAAC,IAAI,CAAC,EAAE,eAAe,CAAC;IAC9C,OAAO,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;AACxD,CAAC;AAED,2FAA2F;AAC3F,MAAM,UAAU,cAAc,CAAC,IAAkB;IAChD,MAAM,QAAQ,GAAG,SAAS,CAAC,IAAI,CAAC,EAAE,QAAQ,CAAC;IAC3C,IAAI,CAAC,QAAQ,EAAE,CAAC;QACf,OAAO,CAAC,IAAI,CAAC,2EAA2E,CAAC,CAAC;QAC1F,OAAO,SAAS,CAAC;IAClB,CAAC;IAED,IAAI,CAAC;QACJ,OAAO,QAAQ,CAAC,SAAS,EAAE,CAAC;IAC7B,CAAC;IAAC,OAAO,GAAY,EAAE,CAAC;QACvB,OAAO,CAAC,IAAI,CAAC,wEAAwE,EAAE,GAAG,CAAC,CAAC;QAC5F,OAAO,SAAS,CAAC;IAClB,CAAC;AACF,CAAC;AAED,2FAA2F;AAC3F,MAAM,UAAU,cAAc,CAAC,IAAkB;IAChD,MAAM,MAAM,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;IAC/B,IAAI,CAAC,MAAM,IAAI,eAAe,CAAC,IAAI,CAAC,KAAK,CAAC;QAAE,OAAO,SAAS,CAAC;IAE7D,IAAI,CAAC;QACJ,MAAM,QAAQ,GAAG,OAAO,MAAM,CAAC,cAAc,KAAK,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,cAAc,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC;QACzG,IAAI,CAAC,QAAQ,EAAE,CAAC;YACf,OAAO,CAAC,IAAI,CAAC,8EAA8E,CAAC,CAAC;YAC7F,OAAO,SAAS,CAAC;QAClB,CAAC;QAED,OAAO,QAAQ,CAAC,SAAS,EAAE,CAAC;IAC7B,CAAC;IAAC,OAAO,GAAY,EAAE,CAAC;QACvB,OAAO,CAAC,IAAI,CAAC,qEAAqE,EAAE,GAAG,CAAC,CAAC;QACzF,OAAO,SAAS,CAAC;IAClB,CAAC;AACF,CAAC","sourcesContent":["/** Compatibility helpers for browser WebTransport datagram stream shape changes. */\n\n/** The current standards-track datagram send stream, plus Chrome's legacy writable property. */\ninterface DatagramDuplex {\n\treadonly readable?: ReadableStream<Uint8Array>;\n\treadonly writable?: WritableStream<Uint8Array>;\n\treadonly maxDatagramSize?: number;\n\tcreateWritable?: () => WritableStream<Uint8Array>;\n}\n\nfunction datagrams(quic: WebTransport): DatagramDuplex | undefined {\n\treturn (quic as unknown as { datagrams?: DatagramDuplex }).datagrams;\n}\n\n/** The max outgoing datagram payload size, or 0 when this transport cannot send datagrams. */\nexport function maxDatagramSize(quic: WebTransport): number {\n\tconst size = datagrams(quic)?.maxDatagramSize;\n\treturn typeof size === \"number\" && size > 0 ? size : 0;\n}\n\n/** Get a datagram reader, or undefined when this browser/transport does not expose one. */\nexport function datagramReader(quic: WebTransport): ReadableStreamDefaultReader<Uint8Array> | undefined {\n\tconst readable = datagrams(quic)?.readable;\n\tif (!readable) {\n\t\tconsole.warn(\"datagram receive disabled: WebTransport datagrams.readable is unavailable\");\n\t\treturn undefined;\n\t}\n\n\ttry {\n\t\treturn readable.getReader();\n\t} catch (err: unknown) {\n\t\tconsole.warn(\"datagram receive disabled: failed to open WebTransport datagram reader\", err);\n\t\treturn undefined;\n\t}\n}\n\n/** Get a datagram writer, or undefined when this browser/transport does not expose one. */\nexport function datagramWriter(quic: WebTransport): WritableStreamDefaultWriter<Uint8Array> | undefined {\n\tconst stream = datagrams(quic);\n\tif (!stream || maxDatagramSize(quic) === 0) return undefined;\n\n\ttry {\n\t\tconst writable = typeof stream.createWritable === \"function\" ? stream.createWritable() : stream.writable;\n\t\tif (!writable) {\n\t\t\tconsole.warn(\"datagram send disabled: WebTransport datagram writable stream is unavailable\");\n\t\t\treturn undefined;\n\t\t}\n\n\t\treturn writable.getWriter();\n\t} catch (err: unknown) {\n\t\tconsole.warn(\"datagram send disabled: failed to open WebTransport datagram writer\", err);\n\t\treturn undefined;\n\t}\n}\n"]}
|
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,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAYvC,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,YAAY,SAAS,EAAE,IAAI,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAKhF;
|
|
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,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAYvC,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,YAAY,SAAS,EAAE,IAAI,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAKhF;IAkBK,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
|
@@ -37,11 +37,11 @@ export class Fetch {
|
|
|
37
37
|
}
|
|
38
38
|
async encode(w, version) {
|
|
39
39
|
guardFetch(version);
|
|
40
|
-
return Message.encode(w, this.#encode
|
|
40
|
+
return Message.encode(w, (w) => this.#encode(w));
|
|
41
41
|
}
|
|
42
42
|
static async decode(r, version) {
|
|
43
43
|
guardFetch(version);
|
|
44
|
-
return Message.decode(r, Fetch.#decode);
|
|
44
|
+
return Message.decode(r, (r) => Fetch.#decode(r));
|
|
45
45
|
}
|
|
46
46
|
}
|
|
47
47
|
//# 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;AAEvC,SAAS,UAAU,CAAC,OAAgB;IACnC,QAAQ,OAAO,EAAE,CAAC;QACjB,KAAK,OAAO,CAAC,QAAQ,CAAC;QACtB,KAAK,OAAO,CAAC,QAAQ;YACpB,MAAM,IAAI,KAAK,CAAC,sCAAsC,CAAC,CAAC;QACzD;YACC,MAAM;IACR,CAAC;AACF,CAAC;AAED,MAAM,OAAO,KAAK;IACjB,SAAS,CAAa;IACtB,KAAK,CAAS;IACd,QAAQ,CAAS;IACjB,KAAK,CAAS;IAEd,YAAY,SAAqB,EAAE,KAAa,EAAE,QAAgB,EAAE,KAAa;QAChF,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;QAC3B,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACnB,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;IACpB,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,CAAS;QACtB,MAAM,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC;QAC5C,MAAM,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC3B,MAAM,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC1B,MAAM,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACzB,CAAC;IAED,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAS;QAC7B,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC;QAChD,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,MAAM,EAAE,CAAC;QAC/B,MAAM,QAAQ,GAAG,MAAM,CAAC,CAAC,EAAE,EAAE,CAAC;QAC9B,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC;
|
|
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;AAEvC,SAAS,UAAU,CAAC,OAAgB;IACnC,QAAQ,OAAO,EAAE,CAAC;QACjB,KAAK,OAAO,CAAC,QAAQ,CAAC;QACtB,KAAK,OAAO,CAAC,QAAQ;YACpB,MAAM,IAAI,KAAK,CAAC,sCAAsC,CAAC,CAAC;QACzD;YACC,MAAM;IACR,CAAC;AACF,CAAC;AAED,MAAM,OAAO,KAAK;IACjB,SAAS,CAAa;IACtB,KAAK,CAAS;IACd,QAAQ,CAAS;IACjB,KAAK,CAAS;IAEd,YAAY,SAAqB,EAAE,KAAa,EAAE,QAAgB,EAAE,KAAa;QAChF,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;QAC3B,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACnB,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;IACpB,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,CAAS;QACtB,MAAM,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC;QAC5C,MAAM,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC3B,MAAM,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC1B,MAAM,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACzB,CAAC;IAED,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAS;QAC7B,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC;QAChD,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,MAAM,EAAE,CAAC;QAC/B,MAAM,QAAQ,GAAG,MAAM,CAAC,CAAC,EAAE,EAAE,CAAC;QAC9B,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC;QAE5B,OAAO,IAAI,KAAK,CAAC,SAAS,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC;IACrD,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,CAAS,EAAE,OAAgB;QACvC,UAAU,CAAC,OAAO,CAAC,CAAC;QACpB,OAAO,OAAO,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;IAClD,CAAC;IAED,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAS,EAAE,OAAgB;QAC9C,UAAU,CAAC,OAAO,CAAC,CAAC;QACpB,OAAO,OAAO,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;IACnD,CAAC;CACD","sourcesContent":["import * as Path from \"../path.ts\";\nimport type { Reader, Writer } from \"../stream.ts\";\nimport * as Message from \"./message.ts\";\nimport { 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\tconstructor(broadcast: Path.Valid, track: string, priority: number, group: number) {\n\t\tthis.broadcast = broadcast;\n\t\tthis.track = track;\n\t\tthis.priority = priority;\n\t\tthis.group = group;\n\t}\n\n\tasync #encode(w: Writer) {\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\t}\n\n\tstatic async #decode(r: Reader): 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\treturn new Fetch(broadcast, track, priority, group);\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));\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));\n\t}\n}\n"]}
|
package/lite/index.d.ts
CHANGED
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
export * from "./announce";
|
|
2
2
|
export * from "./connection";
|
|
3
|
+
export * from "./datagram";
|
|
3
4
|
export * from "./fetch";
|
|
4
5
|
export * from "./goaway";
|
|
5
6
|
export * from "./group";
|
|
6
7
|
export * from "./probe";
|
|
7
8
|
export * from "./session";
|
|
9
|
+
export * from "./setup";
|
|
8
10
|
export * from "./stream";
|
|
9
11
|
export * from "./subscribe";
|
|
12
|
+
export * from "./track";
|
|
10
13
|
export * from "./version";
|
|
11
14
|
//# sourceMappingURL=index.d.ts.map
|
package/lite/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/lite/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC;AAC9B,cAAc,iBAAiB,CAAC;AAChC,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC;AAC5B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,cAAc,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/lite/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC;AAC9B,cAAc,iBAAiB,CAAC;AAChC,cAAc,eAAe,CAAC;AAC9B,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC;AAC7B,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC"}
|