@norskvideo/moq-net 0.1.8 → 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/announce.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
/* @ts-self-types="./announce.d.ts" */
|
|
2
|
-
import {
|
|
2
|
+
import { ProtocolViolation } from "../error.js";
|
|
3
|
+
import { HopSchema, MAX_HOPS, UNKNOWN_HOP } from "../hop.js";
|
|
3
4
|
import * as Path from "../path.js";
|
|
4
5
|
import * as Message from "./message.js";
|
|
5
|
-
import { hasAnnounceId, hasAnnounceOk, hasExcludeHop, hasRouteCost, Version } from "./version.js";
|
|
6
|
+
import { hasAnnounceCompression, hasAnnounceId, hasAnnounceOk, hasExcludeHop, hasHidden, hasRouteCost, Version, } from "./version.js";
|
|
6
7
|
// Pre-lite-06 inner status values, carried inside the single ANNOUNCE_BROADCAST body.
|
|
7
8
|
const STATUS_ENDED = 0;
|
|
8
9
|
const STATUS_ACTIVE = 1;
|
|
@@ -13,9 +14,25 @@ const STATUS_RESTART = 2;
|
|
|
13
14
|
const ANNOUNCE_START = 0;
|
|
14
15
|
const ANNOUNCE_END = 1;
|
|
15
16
|
const ANNOUNCE_RESTART = 2;
|
|
17
|
+
// Both wire rules on a hop chain, applied to what we send and to what we receive: a
|
|
18
|
+
// chain that revisits a hop looped, so neither forwarding it nor subscribing through it
|
|
19
|
+
// is safe, and a receiver must end the session over one. `UNKNOWN_HOP` identifies
|
|
20
|
+
// nothing, so any number of hops may be unknown.
|
|
21
|
+
//
|
|
22
|
+
// `ProtocolViolation` so a receipt takes the session down rather than the one stream,
|
|
23
|
+
// matching what `ietf/cluster.ts` throws for the identical rule.
|
|
16
24
|
function checkHops(hops) {
|
|
17
25
|
if (hops.length > MAX_HOPS) {
|
|
18
|
-
throw new
|
|
26
|
+
throw new ProtocolViolation(`hop count ${hops.length} exceeds maximum ${MAX_HOPS}`);
|
|
27
|
+
}
|
|
28
|
+
// MAX_HOPS is 32, so the quadratic scan is cheaper than allocating a set.
|
|
29
|
+
for (let i = 0; i < hops.length; i++) {
|
|
30
|
+
const hop = hops[i];
|
|
31
|
+
if (hop === UNKNOWN_HOP)
|
|
32
|
+
continue;
|
|
33
|
+
if (hops.indexOf(hop, i + 1) !== -1) {
|
|
34
|
+
throw new ProtocolViolation(`hop ${hop} appears twice in the chain`);
|
|
35
|
+
}
|
|
19
36
|
}
|
|
20
37
|
}
|
|
21
38
|
async function encodeHops(w, version, hops) {
|
|
@@ -28,7 +45,7 @@ async function encodeHops(w, version, hops) {
|
|
|
28
45
|
await w.u53(hops.length);
|
|
29
46
|
break;
|
|
30
47
|
default:
|
|
31
|
-
// Lite04+: hop count + individual
|
|
48
|
+
// Lite04+: hop count + individual Hop varints.
|
|
32
49
|
await w.u53(hops.length);
|
|
33
50
|
for (const origin of hops) {
|
|
34
51
|
await w.u62(origin);
|
|
@@ -47,39 +64,90 @@ async function decodeHops(r, version) {
|
|
|
47
64
|
throw new Error(`hop count ${count} exceeds maximum ${MAX_HOPS}`);
|
|
48
65
|
// Lite03 carries only a hop count, not individual ids, so every entry is
|
|
49
66
|
// the reserved "no identity" id.
|
|
50
|
-
return new Array(count).fill(
|
|
67
|
+
return new Array(count).fill(UNKNOWN_HOP);
|
|
51
68
|
}
|
|
52
69
|
default: {
|
|
53
|
-
// Lite04+: hop count + individual
|
|
70
|
+
// Lite04+: hop count + individual Hop varints.
|
|
54
71
|
const count = await r.u53();
|
|
55
72
|
if (count > MAX_HOPS)
|
|
56
73
|
throw new Error(`hop count ${count} exceeds maximum ${MAX_HOPS}`);
|
|
57
74
|
const hops = [];
|
|
58
75
|
for (let i = 0; i < count; i++) {
|
|
59
|
-
hops.push(
|
|
76
|
+
hops.push(HopSchema.parse(await r.u62()));
|
|
60
77
|
}
|
|
78
|
+
checkHops(hops);
|
|
61
79
|
return hops;
|
|
62
80
|
}
|
|
63
81
|
}
|
|
64
82
|
}
|
|
65
|
-
//
|
|
66
|
-
//
|
|
83
|
+
// Lite-07 carries a base around a path and a hop list. A distance of 0 names
|
|
84
|
+
// nothing, and a keep without a base is a violation. Other versions have no room for
|
|
85
|
+
// a base at all.
|
|
86
|
+
function checkBase(version, base) {
|
|
87
|
+
if (base && !hasAnnounceCompression(version)) {
|
|
88
|
+
throw new Error("announce compression not supported for this version");
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
function toBase(distance, keep) {
|
|
92
|
+
if (distance !== 0n)
|
|
93
|
+
return { distance, keep };
|
|
94
|
+
if (keep !== 0)
|
|
95
|
+
throw new ProtocolViolation("announce keep without a base");
|
|
96
|
+
return undefined;
|
|
97
|
+
}
|
|
98
|
+
async function encodePath(w, version, suffix, base) {
|
|
99
|
+
checkBase(version, base);
|
|
100
|
+
if (hasAnnounceCompression(version)) {
|
|
101
|
+
await w.u62(base?.distance ?? 0n);
|
|
102
|
+
await w.u53(base?.keep ?? 0);
|
|
103
|
+
}
|
|
104
|
+
await w.string(Path.encode(suffix));
|
|
105
|
+
}
|
|
106
|
+
async function decodePath(r, version) {
|
|
107
|
+
if (!hasAnnounceCompression(version))
|
|
108
|
+
return { suffix: Path.decode(await r.string()) };
|
|
109
|
+
const pathBase = toBase(await r.u62(), await r.u53());
|
|
110
|
+
const suffix = Path.decode(await r.string());
|
|
111
|
+
return pathBase ? { suffix, pathBase } : { suffix };
|
|
112
|
+
}
|
|
113
|
+
async function encodeHopsBlock(w, version, hops, base) {
|
|
114
|
+
checkBase(version, base);
|
|
115
|
+
if (!hasAnnounceCompression(version))
|
|
116
|
+
return encodeHops(w, version, hops);
|
|
117
|
+
await w.u62(base?.distance ?? 0n);
|
|
118
|
+
await encodeHops(w, version, hops);
|
|
119
|
+
await w.u53(base?.keep ?? 0);
|
|
120
|
+
}
|
|
121
|
+
async function decodeHopsBlock(r, version) {
|
|
122
|
+
if (!hasAnnounceCompression(version))
|
|
123
|
+
return { hops: await decodeHops(r, version) };
|
|
124
|
+
const distance = await r.u62();
|
|
125
|
+
const hops = await decodeHops(r, version);
|
|
126
|
+
const hopBase = toBase(distance, await r.u53());
|
|
127
|
+
return hopBase ? { hops, hopBase } : { hops };
|
|
128
|
+
}
|
|
129
|
+
// The route cost rides lite-06+ announcements as two varints, warm then cold; older
|
|
130
|
+
// versions carry neither. Costs saturate at 2^62-1 on every version, even where lite-07's
|
|
131
|
+
// varints could carry more, so a cost always forwards to a peer on an older version.
|
|
132
|
+
const MAX_COST = 2n ** 62n - 1n;
|
|
133
|
+
const saturate = (v) => (v > MAX_COST ? MAX_COST : v);
|
|
67
134
|
async function encodeRouteCost(w, version, cost) {
|
|
68
135
|
if (!hasRouteCost(version))
|
|
69
136
|
return;
|
|
70
|
-
await w.u62(cost ?? 0n);
|
|
137
|
+
await w.u62(saturate(cost?.warm ?? 0n));
|
|
138
|
+
await w.u62(saturate(cost?.cold ?? 0n));
|
|
71
139
|
}
|
|
72
140
|
async function decodeRouteCost(r, version) {
|
|
73
141
|
if (!hasRouteCost(version))
|
|
74
|
-
return
|
|
75
|
-
return await r.u62();
|
|
142
|
+
return undefined;
|
|
143
|
+
return { warm: saturate(await r.u62()), cold: saturate(await r.u62()) };
|
|
76
144
|
}
|
|
77
145
|
// lite-06 message body (no discriminator; the type is carried outside the length prefix).
|
|
78
146
|
async function encodeAnnounce06Body(w, msg, version) {
|
|
79
147
|
switch (msg.status) {
|
|
80
148
|
case "active":
|
|
81
|
-
await w.
|
|
82
|
-
await
|
|
149
|
+
await encodePath(w, version, msg.suffix, msg.pathBase);
|
|
150
|
+
await encodeHopsBlock(w, version, msg.hops, msg.hopBase);
|
|
83
151
|
await encodeRouteCost(w, version, msg.cost);
|
|
84
152
|
break;
|
|
85
153
|
case "endedId":
|
|
@@ -87,12 +155,14 @@ async function encodeAnnounce06Body(w, msg, version) {
|
|
|
87
155
|
break;
|
|
88
156
|
case "restart":
|
|
89
157
|
await w.u62(msg.id);
|
|
90
|
-
await
|
|
158
|
+
await encodeHopsBlock(w, version, msg.hops, msg.hopBase);
|
|
91
159
|
await encodeRouteCost(w, version, msg.cost);
|
|
92
160
|
break;
|
|
93
161
|
case "ended":
|
|
94
162
|
// The pre-lite-06 path-form retraction has no place on lite-06.
|
|
95
163
|
throw new Error("ended-by-path not supported for this version");
|
|
164
|
+
case "skipped":
|
|
165
|
+
throw new Error("decode-only announce type cannot be encoded");
|
|
96
166
|
}
|
|
97
167
|
}
|
|
98
168
|
// lite-06 outer message type for a given announcement.
|
|
@@ -106,30 +176,36 @@ function announce06Type(msg) {
|
|
|
106
176
|
return ANNOUNCE_RESTART;
|
|
107
177
|
case "ended":
|
|
108
178
|
throw new Error("ended-by-path not supported for this version");
|
|
179
|
+
case "skipped":
|
|
180
|
+
throw new Error("decode-only announce type cannot be encoded");
|
|
109
181
|
}
|
|
110
182
|
}
|
|
111
183
|
async function decodeAnnounce06Body(r, typ, version) {
|
|
112
184
|
switch (typ) {
|
|
113
185
|
case ANNOUNCE_START: {
|
|
114
|
-
const
|
|
115
|
-
const hops = await
|
|
116
|
-
return { status: "active",
|
|
186
|
+
const path = await decodePath(r, version);
|
|
187
|
+
const hops = await decodeHopsBlock(r, version);
|
|
188
|
+
return { status: "active", ...path, ...hops, cost: await decodeRouteCost(r, version) };
|
|
117
189
|
}
|
|
118
190
|
case ANNOUNCE_END:
|
|
119
191
|
return { status: "endedId", id: await r.u62() };
|
|
120
192
|
case ANNOUNCE_RESTART: {
|
|
121
193
|
const id = await r.u62();
|
|
122
|
-
const hops = await
|
|
123
|
-
return { status: "restart", id, hops, cost: await decodeRouteCost(r, version) };
|
|
194
|
+
const hops = await decodeHopsBlock(r, version);
|
|
195
|
+
return { status: "restart", id, ...hops, cost: await decodeRouteCost(r, version) };
|
|
124
196
|
}
|
|
125
197
|
default:
|
|
126
|
-
|
|
198
|
+
// Skip the length-prefixed body so an earlier Lite06 build negotiating
|
|
199
|
+
// the same ALPN does not kill the announce stream.
|
|
200
|
+
await r.readAll();
|
|
201
|
+
return { status: "skipped" };
|
|
127
202
|
}
|
|
128
203
|
}
|
|
129
204
|
// Pre-lite-06 single ANNOUNCE_BROADCAST body: an inner status byte, then path + hops.
|
|
130
205
|
async function encodeLegacyBody(w, msg, version) {
|
|
131
206
|
switch (msg.status) {
|
|
132
207
|
case "active":
|
|
208
|
+
checkBase(version, msg.pathBase ?? msg.hopBase);
|
|
133
209
|
await w.u8(STATUS_ACTIVE);
|
|
134
210
|
await w.string(Path.encode(msg.suffix));
|
|
135
211
|
await encodeHops(w, version, msg.hops);
|
|
@@ -141,6 +217,7 @@ async function encodeLegacyBody(w, msg, version) {
|
|
|
141
217
|
break;
|
|
142
218
|
case "endedId":
|
|
143
219
|
case "restart":
|
|
220
|
+
case "skipped":
|
|
144
221
|
// The id-referencing forms only exist on lite-06+.
|
|
145
222
|
throw new Error("announce ids not supported for this version");
|
|
146
223
|
}
|
|
@@ -184,33 +261,101 @@ export async function decodeAnnounceBroadcastMaybe(r, version) {
|
|
|
184
261
|
}
|
|
185
262
|
return Message.decodeMaybe(r, (r) => decodeLegacyBody(r, version));
|
|
186
263
|
}
|
|
264
|
+
/**
|
|
265
|
+
* The live announcements on one lite-06+ announce stream, by Announce ID: what
|
|
266
|
+
* ANNOUNCE_END and ANNOUNCE_UPDATE reference, and what a lite-07 base copies from.
|
|
267
|
+
* Every violation throws {@link ProtocolViolation}.
|
|
268
|
+
*/
|
|
269
|
+
export class AnnounceHistory {
|
|
270
|
+
#next = 0n;
|
|
271
|
+
#live = new Map();
|
|
272
|
+
#base(base) {
|
|
273
|
+
const live = this.#live.get(this.#next - base.distance);
|
|
274
|
+
if (!live)
|
|
275
|
+
throw new ProtocolViolation(`announce base ${base.distance} is not live`);
|
|
276
|
+
return live;
|
|
277
|
+
}
|
|
278
|
+
#hops(hops, base) {
|
|
279
|
+
if (!base)
|
|
280
|
+
return hops;
|
|
281
|
+
const tail = this.#base(base).hops;
|
|
282
|
+
if (base.keep > tail.length)
|
|
283
|
+
throw new ProtocolViolation(`announce keeps ${base.keep} of ${tail.length} hops`);
|
|
284
|
+
const resolved = [...hops, ...tail.slice(tail.length - base.keep)];
|
|
285
|
+
checkHops(resolved);
|
|
286
|
+
return resolved;
|
|
287
|
+
}
|
|
288
|
+
/** An ANNOUNCE_START: resolve it and assign it the next id. */
|
|
289
|
+
start(msg) {
|
|
290
|
+
let suffix = msg.suffix;
|
|
291
|
+
if (msg.pathBase) {
|
|
292
|
+
const head = Path.parts(this.#base(msg.pathBase).suffix);
|
|
293
|
+
const keep = msg.pathBase.keep;
|
|
294
|
+
if (keep > head.length)
|
|
295
|
+
throw new ProtocolViolation(`announce keeps ${keep} of ${head.length} segments`);
|
|
296
|
+
suffix = Path.join(Path.from(...head.slice(0, keep)), suffix);
|
|
297
|
+
if (Path.parts(suffix).length > Path.MAX_PARTS) {
|
|
298
|
+
throw new ProtocolViolation(`path exceeds ${Path.MAX_PARTS} parts`);
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
const hops = this.#hops(msg.hops, msg.hopBase);
|
|
302
|
+
this.#live.set(this.#next++, { suffix, hops });
|
|
303
|
+
return { suffix, hops };
|
|
304
|
+
}
|
|
305
|
+
/** An ANNOUNCE_UPDATE: resolve its chain before replacing the old one, which it may be based on. */
|
|
306
|
+
update(msg) {
|
|
307
|
+
const hops = this.#hops(msg.hops, msg.hopBase);
|
|
308
|
+
const live = this.#live.get(msg.id);
|
|
309
|
+
if (!live)
|
|
310
|
+
throw new ProtocolViolation(`unknown announce id: ${msg.id}`);
|
|
311
|
+
this.#live.set(msg.id, { suffix: live.suffix, hops });
|
|
312
|
+
return { suffix: live.suffix, hops };
|
|
313
|
+
}
|
|
314
|
+
/** An ANNOUNCE_END: retire the id, returning its suffix. */
|
|
315
|
+
end(id) {
|
|
316
|
+
const live = this.#live.get(id);
|
|
317
|
+
if (!live)
|
|
318
|
+
throw new ProtocolViolation(`unknown announce id: ${id}`);
|
|
319
|
+
this.#live.delete(id);
|
|
320
|
+
return live.suffix;
|
|
321
|
+
}
|
|
322
|
+
}
|
|
187
323
|
/**
|
|
188
324
|
* ANNOUNCE_REQUEST: sent by the subscriber to request ANNOUNCE_BROADCAST messages
|
|
189
325
|
* for a path prefix. Renamed from `AnnounceInterest` in lite-05.
|
|
190
326
|
*/
|
|
191
327
|
export class AnnounceRequest {
|
|
192
328
|
prefix;
|
|
193
|
-
/** Lite04/05 only: the 62-bit
|
|
329
|
+
/** Lite04/05 only: the 62-bit Hop id of the peer asking for announces, which the
|
|
194
330
|
* publisher uses to skip announces that already passed through it. Zero means "no
|
|
195
331
|
* exclusion". Not on the wire elsewhere, so a value set here is ignored when encoding
|
|
196
332
|
* for another version and decodes as zero.
|
|
197
333
|
*
|
|
198
334
|
* Must be a bigint: peer origins are up to 62 bits and overflow u53. */
|
|
199
335
|
excludeHop;
|
|
200
|
-
|
|
336
|
+
/** Lite07+: also announce routes with a `.`-prefixed segment below the prefix. Not on
|
|
337
|
+
* the wire earlier, so a value set here is ignored when encoding for an older version
|
|
338
|
+
* and decodes as false. */
|
|
339
|
+
hidden;
|
|
340
|
+
constructor(prefix, excludeHop = 0n, hidden = false) {
|
|
201
341
|
this.prefix = prefix;
|
|
202
342
|
this.excludeHop = excludeHop;
|
|
343
|
+
this.hidden = hidden;
|
|
203
344
|
}
|
|
204
345
|
async #encode(w, version) {
|
|
205
346
|
await w.string(Path.encode(this.prefix));
|
|
206
347
|
if (hasExcludeHop(version)) {
|
|
207
348
|
await w.u62(this.excludeHop);
|
|
208
349
|
}
|
|
350
|
+
if (hasHidden(version)) {
|
|
351
|
+
await w.bool(this.hidden);
|
|
352
|
+
}
|
|
209
353
|
}
|
|
210
354
|
static async #decode(r, version) {
|
|
211
355
|
const prefix = Path.decode(await r.string());
|
|
212
356
|
const excludeHop = hasExcludeHop(version) ? await r.u62() : 0n;
|
|
213
|
-
|
|
357
|
+
const hidden = hasHidden(version) ? await r.bool() : false;
|
|
358
|
+
return new AnnounceRequest(prefix, excludeHop, hidden);
|
|
214
359
|
}
|
|
215
360
|
async encode(w, version) {
|
|
216
361
|
return Message.encode(w, (w) => this.#encode(w, version));
|
|
@@ -262,15 +407,15 @@ export class AnnounceInit {
|
|
|
262
407
|
/// Sent by the publisher as the first message on an announce stream, before any
|
|
263
408
|
/// individual Announce messages. Lite05+ only; the successor to AnnounceInit.
|
|
264
409
|
///
|
|
265
|
-
/// `origin` is the responder's
|
|
410
|
+
/// `origin` is the responder's Hop ID, which the subscriber stamps onto each
|
|
266
411
|
/// announce's hop chain (the publisher no longer stamps itself), or the reserved
|
|
267
|
-
/// {@link
|
|
412
|
+
/// {@link UNKNOWN_HOP} when the responder has no identity to give. `active` is
|
|
268
413
|
/// the number of initial Announce messages that follow immediately.
|
|
269
414
|
export class AnnounceOk {
|
|
270
|
-
|
|
415
|
+
hop;
|
|
271
416
|
active;
|
|
272
|
-
constructor(
|
|
273
|
-
this.
|
|
417
|
+
constructor(hop, active) {
|
|
418
|
+
this.hop = hop;
|
|
274
419
|
this.active = active;
|
|
275
420
|
}
|
|
276
421
|
static #guard(version) {
|
|
@@ -279,14 +424,14 @@ export class AnnounceOk {
|
|
|
279
424
|
}
|
|
280
425
|
}
|
|
281
426
|
async #encode(w) {
|
|
282
|
-
await w.u62(this.
|
|
427
|
+
await w.u62(this.hop);
|
|
283
428
|
await w.u53(this.active);
|
|
284
429
|
}
|
|
285
430
|
static async #decode(r) {
|
|
286
431
|
// The draft reserves 0 for "unknown": the responder was never assigned an id, or
|
|
287
432
|
// withholds it to obscure its routing. It names nobody, so callers must not stamp
|
|
288
433
|
// it onto a hop chain, but it is a legal message and not grounds to drop the stream.
|
|
289
|
-
const origin =
|
|
434
|
+
const origin = HopSchema.parse(await r.u62());
|
|
290
435
|
const active = await r.u53();
|
|
291
436
|
return new AnnounceOk(origin, active);
|
|
292
437
|
}
|
package/lite/announce.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"announce.js","sourceRoot":"","sources":["../../src/lite/announce.ts"],"names":[],"mappings":"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","sourcesContent":["import { MAX_HOPS, type Origin, OriginSchema, UNKNOWN_ORIGIN } from \"../origin.ts\";\nimport * as Path from \"../path.ts\";\nimport type { Reader, Writer } from \"../stream.ts\";\nimport * as Message from \"./message.ts\";\nimport { hasAnnounceId, hasAnnounceOk, hasExcludeHop, hasRouteCost, Version } from \"./version.ts\";\n\n// Pre-lite-06 inner status values, carried inside the single ANNOUNCE_BROADCAST body.\nconst STATUS_ENDED = 0;\nconst STATUS_ACTIVE = 1;\nconst STATUS_RESTART = 2;\n\n// lite-06 announce message types: an outer discriminator carried before the length\n// prefix, so each announcement is an independently-typed, length-delimited message\n// (mirroring SUBSCRIBE_START/END/DROP on the subscribe stream).\nconst ANNOUNCE_START = 0;\nconst ANNOUNCE_END = 1;\nconst ANNOUNCE_RESTART = 2;\n\n/**\n * An announcement on the Announce Stream, advertising or retracting a broadcast.\n *\n * On lite-06+ these are three independently-typed messages (`ANNOUNCE_START`,\n * `ANNOUNCE_END`, `ANNOUNCE_RESTART`), each framed as `Type | Length | Body` like the\n * subscribe stream's responses. Each `active` (ANNOUNCE_START) implicitly assigns the\n * next announce id (a per-stream ordinal starting at 0); `endedId`/`restart` reference\n * that id instead of repeating the path. Older versions send a single ANNOUNCE_BROADCAST\n * message that retracts by path (`ended`).\n */\nexport type AnnounceBroadcast =\n\t/** A broadcast is now available, carrying the path suffix, the hop chain, and\n\t * (lite-06+) the route cost. An absent cost encodes as zero. */\n\t| { status: \"active\"; suffix: Path.Valid; hops: Origin[]; cost?: bigint }\n\t/** Pre-lite-06: a broadcast is no longer available, retracted by path. */\n\t| { status: \"ended\"; suffix: Path.Valid }\n\t/** Lite06+: a broadcast is no longer available, retracted by announce id.\n\t * The id is retired; referencing it again is a protocol violation. */\n\t| { status: \"endedId\"; id: bigint }\n\t/** Lite06+: atomically replace the announcement with this id (e.g. a new hop\n\t * chain after a relay failover, or a route whose cost moved). The id stays live. */\n\t| { status: \"restart\"; id: bigint; hops: Origin[]; cost?: bigint };\n\nfunction checkHops(hops: Origin[]) {\n\tif (hops.length > MAX_HOPS) {\n\t\tthrow new Error(`hop count ${hops.length} exceeds maximum ${MAX_HOPS}`);\n\t}\n}\n\nasync function encodeHops(w: Writer, version: Version, hops: Origin[]) {\n\tcheckHops(hops);\n\tswitch (version) {\n\t\tcase Version.DRAFT_01:\n\t\tcase Version.DRAFT_02:\n\t\t\tbreak;\n\t\tcase Version.DRAFT_03:\n\t\t\tawait w.u53(hops.length);\n\t\t\tbreak;\n\t\tdefault:\n\t\t\t// Lite04+: hop count + individual Origin varints.\n\t\t\tawait w.u53(hops.length);\n\t\t\tfor (const origin of hops) {\n\t\t\t\tawait w.u62(origin);\n\t\t\t}\n\t\t\tbreak;\n\t}\n}\n\nasync function decodeHops(r: Reader, version: Version): Promise<Origin[]> {\n\tswitch (version) {\n\t\tcase Version.DRAFT_01:\n\t\tcase Version.DRAFT_02:\n\t\t\treturn [];\n\t\tcase Version.DRAFT_03: {\n\t\t\tconst count = await r.u53();\n\t\t\tif (count > MAX_HOPS) throw new Error(`hop count ${count} exceeds maximum ${MAX_HOPS}`);\n\t\t\t// Lite03 carries only a hop count, not individual ids, so every entry is\n\t\t\t// the reserved \"no identity\" id.\n\t\t\treturn new Array<Origin>(count).fill(UNKNOWN_ORIGIN);\n\t\t}\n\t\tdefault: {\n\t\t\t// Lite04+: hop count + individual Origin varints.\n\t\t\tconst count = await r.u53();\n\t\t\tif (count > MAX_HOPS) throw new Error(`hop count ${count} exceeds maximum ${MAX_HOPS}`);\n\t\t\tconst hops: Origin[] = [];\n\t\t\tfor (let i = 0; i < count; i++) {\n\t\t\t\thops.push(OriginSchema.parse(await r.u62()));\n\t\t\t}\n\t\t\treturn hops;\n\t\t}\n\t}\n}\n\n// The route cost rides lite-06+ announcements as a single varint; older\n// versions carry nothing and decode as zero.\nasync function encodeRouteCost(w: Writer, version: Version, cost: bigint | undefined) {\n\tif (!hasRouteCost(version)) return;\n\tawait w.u62(cost ?? 0n);\n}\n\nasync function decodeRouteCost(r: Reader, version: Version): Promise<bigint> {\n\tif (!hasRouteCost(version)) return 0n;\n\treturn await r.u62();\n}\n\n// lite-06 message body (no discriminator; the type is carried outside the length prefix).\nasync function encodeAnnounce06Body(w: Writer, msg: AnnounceBroadcast, version: Version) {\n\tswitch (msg.status) {\n\t\tcase \"active\":\n\t\t\tawait w.string(Path.encode(msg.suffix));\n\t\t\tawait encodeHops(w, version, msg.hops);\n\t\t\tawait encodeRouteCost(w, version, msg.cost);\n\t\t\tbreak;\n\t\tcase \"endedId\":\n\t\t\tawait w.u62(msg.id);\n\t\t\tbreak;\n\t\tcase \"restart\":\n\t\t\tawait w.u62(msg.id);\n\t\t\tawait encodeHops(w, version, msg.hops);\n\t\t\tawait encodeRouteCost(w, version, msg.cost);\n\t\t\tbreak;\n\t\tcase \"ended\":\n\t\t\t// The pre-lite-06 path-form retraction has no place on lite-06.\n\t\t\tthrow new Error(\"ended-by-path not supported for this version\");\n\t}\n}\n\n// lite-06 outer message type for a given announcement.\nfunction announce06Type(msg: AnnounceBroadcast): number {\n\tswitch (msg.status) {\n\t\tcase \"active\":\n\t\t\treturn ANNOUNCE_START;\n\t\tcase \"endedId\":\n\t\t\treturn ANNOUNCE_END;\n\t\tcase \"restart\":\n\t\t\treturn ANNOUNCE_RESTART;\n\t\tcase \"ended\":\n\t\t\tthrow new Error(\"ended-by-path not supported for this version\");\n\t}\n}\n\nasync function decodeAnnounce06Body(r: Reader, typ: number, version: Version): Promise<AnnounceBroadcast> {\n\tswitch (typ) {\n\t\tcase ANNOUNCE_START: {\n\t\t\tconst suffix = Path.decode(await r.string());\n\t\t\tconst hops = await decodeHops(r, version);\n\t\t\treturn { status: \"active\", suffix, hops, cost: await decodeRouteCost(r, version) };\n\t\t}\n\t\tcase ANNOUNCE_END:\n\t\t\treturn { status: \"endedId\", id: await r.u62() };\n\t\tcase ANNOUNCE_RESTART: {\n\t\t\tconst id = await r.u62();\n\t\t\tconst hops = await decodeHops(r, version);\n\t\t\treturn { status: \"restart\", id, hops, cost: await decodeRouteCost(r, version) };\n\t\t}\n\t\tdefault:\n\t\t\tthrow new Error(`unknown announce message type: ${typ}`);\n\t}\n}\n\n// Pre-lite-06 single ANNOUNCE_BROADCAST body: an inner status byte, then path + hops.\nasync function encodeLegacyBody(w: Writer, msg: AnnounceBroadcast, version: Version) {\n\tswitch (msg.status) {\n\t\tcase \"active\":\n\t\t\tawait w.u8(STATUS_ACTIVE);\n\t\t\tawait w.string(Path.encode(msg.suffix));\n\t\t\tawait encodeHops(w, version, msg.hops);\n\t\t\tbreak;\n\t\tcase \"ended\":\n\t\t\tawait w.u8(STATUS_ENDED);\n\t\t\tawait w.string(Path.encode(msg.suffix));\n\t\t\tawait encodeHops(w, version, []);\n\t\t\tbreak;\n\t\tcase \"endedId\":\n\t\tcase \"restart\":\n\t\t\t// The id-referencing forms only exist on lite-06+.\n\t\t\tthrow new Error(\"announce ids not supported for this version\");\n\t}\n}\n\nasync function decodeLegacyBody(r: Reader, version: Version): Promise<AnnounceBroadcast> {\n\tconst status = await r.u8();\n\t// On lite-05 a restart travels as a duplicate `active`, but the explicit restart\n\t// status is accepted on decode and treated the same. Older versions never defined it.\n\tconst active = status === STATUS_ACTIVE || (status === STATUS_RESTART && hasAnnounceOk(version));\n\tif (status !== STATUS_ENDED && !active) {\n\t\tthrow new Error(\"invalid announce status\");\n\t}\n\tconst suffix = Path.decode(await r.string());\n\tconst hops = await decodeHops(r, version);\n\treturn active ? { status: \"active\", suffix, hops } : { status: \"ended\", suffix };\n}\n\n/** Encode one announcement, including its type discriminator (lite-06+) and length prefix. */\nexport async function encodeAnnounceBroadcast(w: Writer, msg: AnnounceBroadcast, version: Version): Promise<void> {\n\tif (hasAnnounceId(version)) {\n\t\t// lite-06+: outer type discriminator, then a size-prefixed body (like the subscribe stream).\n\t\tawait w.u53(announce06Type(msg));\n\t\treturn Message.encode(w, (w) => encodeAnnounce06Body(w, msg, version));\n\t}\n\treturn Message.encode(w, (w) => encodeLegacyBody(w, msg, version));\n}\n\n/** Decode one announcement, including its type discriminator (lite-06+) and length prefix. */\nexport async function decodeAnnounceBroadcast(r: Reader, version: Version): Promise<AnnounceBroadcast> {\n\tif (hasAnnounceId(version)) {\n\t\tconst typ = await r.u53();\n\t\treturn Message.decode(r, (r) => decodeAnnounce06Body(r, typ, version));\n\t}\n\treturn Message.decode(r, (r) => decodeLegacyBody(r, version));\n}\n\n/** Like {@link decodeAnnounceBroadcast} but resolves `undefined` on a clean FIN. */\nexport async function decodeAnnounceBroadcastMaybe(\n\tr: Reader,\n\tversion: Version,\n): Promise<AnnounceBroadcast | undefined> {\n\tif (hasAnnounceId(version)) {\n\t\tif (await r.done()) return undefined;\n\t\tconst typ = await r.u53();\n\t\treturn Message.decode(r, (r) => decodeAnnounce06Body(r, typ, version));\n\t}\n\treturn Message.decodeMaybe(r, (r) => decodeLegacyBody(r, version));\n}\n\n/**\n * ANNOUNCE_REQUEST: sent by the subscriber to request ANNOUNCE_BROADCAST messages\n * for a path prefix. Renamed from `AnnounceInterest` in lite-05.\n */\nexport class AnnounceRequest {\n\tprefix: Path.Valid;\n\t/** Lite04/05 only: the 62-bit Origin id of the peer asking for announces, which the\n\t * publisher uses to skip announces that already passed through it. Zero means \"no\n\t * exclusion\". Not on the wire elsewhere, so a value set here is ignored when encoding\n\t * for another version and decodes as zero.\n\t *\n\t * Must be a bigint: peer origins are up to 62 bits and overflow u53. */\n\texcludeHop: bigint;\n\n\tconstructor(prefix: Path.Valid, excludeHop: bigint = 0n) {\n\t\tthis.prefix = prefix;\n\t\tthis.excludeHop = excludeHop;\n\t}\n\n\tasync #encode(w: Writer, version: Version) {\n\t\tawait w.string(Path.encode(this.prefix));\n\t\tif (hasExcludeHop(version)) {\n\t\t\tawait w.u62(this.excludeHop);\n\t\t}\n\t}\n\n\tstatic async #decode(r: Reader, version: Version): Promise<AnnounceRequest> {\n\t\tconst prefix = Path.decode(await r.string());\n\t\tconst excludeHop = hasExcludeHop(version) ? await r.u62() : 0n;\n\t\treturn new AnnounceRequest(prefix, excludeHop);\n\t}\n\n\tasync encode(w: Writer, version: Version): Promise<void> {\n\t\treturn Message.encode(w, (w) => this.#encode(w, version));\n\t}\n\n\tstatic async decode(r: Reader, version: Version): Promise<AnnounceRequest> {\n\t\treturn Message.decode(r, (r) => AnnounceRequest.#decode(r, version));\n\t}\n}\n\n/// Sent after setup to communicate the initially announced paths.\n///\n/// Used by Draft01/Draft02 only. Draft03+ uses individual Announce messages instead.\nexport class AnnounceInit {\n\tsuffixes: Path.Valid[];\n\n\tconstructor(paths: Path.Valid[]) {\n\t\tthis.suffixes = paths;\n\t}\n\n\tstatic #guard(version: Version) {\n\t\tswitch (version) {\n\t\t\tcase Version.DRAFT_01:\n\t\t\tcase Version.DRAFT_02:\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tthrow new Error(\"announce init not supported for this version\");\n\t\t}\n\t}\n\n\tasync #encode(w: Writer) {\n\t\tawait w.u53(this.suffixes.length);\n\t\tfor (const path of this.suffixes) {\n\t\t\tawait w.string(Path.encode(path));\n\t\t}\n\t}\n\n\tstatic async #decode(r: Reader): Promise<AnnounceInit> {\n\t\tconst count = await r.u53();\n\t\tconst suffixes: Path.Valid[] = [];\n\t\tfor (let i = 0; i < count; i++) {\n\t\t\tsuffixes.push(Path.decode(await r.string()));\n\t\t}\n\t\treturn new AnnounceInit(suffixes);\n\t}\n\n\tasync encode(w: Writer, version: Version): Promise<void> {\n\t\tAnnounceInit.#guard(version);\n\t\treturn Message.encode(w, this.#encode.bind(this));\n\t}\n\n\tstatic async decode(r: Reader, version: Version): Promise<AnnounceInit> {\n\t\tAnnounceInit.#guard(version);\n\t\treturn Message.decode(r, AnnounceInit.#decode);\n\t}\n}\n\n/// Sent by the publisher as the first message on an announce stream, before any\n/// individual Announce messages. Lite05+ only; the successor to AnnounceInit.\n///\n/// `origin` is the responder's origin id, which the subscriber stamps onto each\n/// announce's hop chain (the publisher no longer stamps itself), or the reserved\n/// {@link UNKNOWN_ORIGIN} when the responder has no identity to give. `active` is\n/// the number of initial Announce messages that follow immediately.\nexport class AnnounceOk {\n\torigin: Origin;\n\tactive: number;\n\n\tconstructor(origin: Origin, active: number) {\n\t\tthis.origin = origin;\n\t\tthis.active = active;\n\t}\n\n\tstatic #guard(version: Version) {\n\t\tif (!hasAnnounceOk(version)) {\n\t\t\tthrow new Error(\"announce ok not supported for this version\");\n\t\t}\n\t}\n\n\tasync #encode(w: Writer) {\n\t\tawait w.u62(this.origin);\n\t\tawait w.u53(this.active);\n\t}\n\n\tstatic async #decode(r: Reader): Promise<AnnounceOk> {\n\t\t// The draft reserves 0 for \"unknown\": the responder was never assigned an id, or\n\t\t// withholds it to obscure its routing. It names nobody, so callers must not stamp\n\t\t// it onto a hop chain, but it is a legal message and not grounds to drop the stream.\n\t\tconst origin = OriginSchema.parse(await r.u62());\n\t\tconst active = await r.u53();\n\t\treturn new AnnounceOk(origin, active);\n\t}\n\n\tasync encode(w: Writer, version: Version): Promise<void> {\n\t\tAnnounceOk.#guard(version);\n\t\treturn Message.encode(w, this.#encode.bind(this));\n\t}\n\n\tstatic async decode(r: Reader, version: Version): Promise<AnnounceOk> {\n\t\tAnnounceOk.#guard(version);\n\t\treturn Message.decode(r, AnnounceOk.#decode);\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"announce.js","sourceRoot":"","sources":["../../src/lite/announce.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,EAAuB,SAAS,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAClF,OAAO,KAAK,IAAI,MAAM,YAAY,CAAC;AAEnC,OAAO,KAAK,OAAO,MAAM,cAAc,CAAC;AACxC,OAAO,EACN,sBAAsB,EACtB,aAAa,EACb,aAAa,EACb,aAAa,EACb,SAAS,EACT,YAAY,EACZ,OAAO,GACP,MAAM,cAAc,CAAC;AAEtB,sFAAsF;AACtF,MAAM,YAAY,GAAG,CAAC,CAAC;AACvB,MAAM,aAAa,GAAG,CAAC,CAAC;AACxB,MAAM,cAAc,GAAG,CAAC,CAAC;AAEzB,mFAAmF;AACnF,mFAAmF;AACnF,gEAAgE;AAChE,MAAM,cAAc,GAAG,CAAC,CAAC;AACzB,MAAM,YAAY,GAAG,CAAC,CAAC;AACvB,MAAM,gBAAgB,GAAG,CAAC,CAAC;AAsC3B,oFAAoF;AACpF,wFAAwF;AACxF,kFAAkF;AAClF,iDAAiD;AACjD,EAAE;AACF,sFAAsF;AACtF,iEAAiE;AACjE,SAAS,SAAS,CAAC,IAAW;IAC7B,IAAI,IAAI,CAAC,MAAM,GAAG,QAAQ,EAAE,CAAC;QAC5B,MAAM,IAAI,iBAAiB,CAAC,aAAa,IAAI,CAAC,MAAM,oBAAoB,QAAQ,EAAE,CAAC,CAAC;IACrF,CAAC;IAED,0EAA0E;IAC1E,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QACpB,IAAI,GAAG,KAAK,WAAW;YAAE,SAAS;QAClC,IAAI,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;YACrC,MAAM,IAAI,iBAAiB,CAAC,OAAO,GAAG,6BAA6B,CAAC,CAAC;QACtE,CAAC;IACF,CAAC;AACF,CAAC;AAED,KAAK,UAAU,UAAU,CAAC,CAAS,EAAE,OAAgB,EAAE,IAAW;IACjE,SAAS,CAAC,IAAI,CAAC,CAAC;IAChB,QAAQ,OAAO,EAAE,CAAC;QACjB,KAAK,OAAO,CAAC,QAAQ,CAAC;QACtB,KAAK,OAAO,CAAC,QAAQ;YACpB,MAAM;QACP,KAAK,OAAO,CAAC,QAAQ;YACpB,MAAM,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YACzB,MAAM;QACP;YACC,+CAA+C;YAC/C,MAAM,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YACzB,KAAK,MAAM,MAAM,IAAI,IAAI,EAAE,CAAC;gBAC3B,MAAM,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YACrB,CAAC;YACD,MAAM;IACR,CAAC;AACF,CAAC;AAED,KAAK,UAAU,UAAU,CAAC,CAAS,EAAE,OAAgB;IACpD,QAAQ,OAAO,EAAE,CAAC;QACjB,KAAK,OAAO,CAAC,QAAQ,CAAC;QACtB,KAAK,OAAO,CAAC,QAAQ;YACpB,OAAO,EAAE,CAAC;QACX,KAAK,OAAO,CAAC,QAAQ,EAAE,CAAC;YACvB,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC;YAC5B,IAAI,KAAK,GAAG,QAAQ;gBAAE,MAAM,IAAI,KAAK,CAAC,aAAa,KAAK,oBAAoB,QAAQ,EAAE,CAAC,CAAC;YACxF,yEAAyE;YACzE,iCAAiC;YACjC,OAAO,IAAI,KAAK,CAAM,KAAK,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QAChD,CAAC;QACD,SAAS,CAAC;YACT,+CAA+C;YAC/C,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC;YAC5B,IAAI,KAAK,GAAG,QAAQ;gBAAE,MAAM,IAAI,KAAK,CAAC,aAAa,KAAK,oBAAoB,QAAQ,EAAE,CAAC,CAAC;YACxF,MAAM,IAAI,GAAU,EAAE,CAAC;YACvB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC;gBAChC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;YAC3C,CAAC;YACD,SAAS,CAAC,IAAI,CAAC,CAAC;YAChB,OAAO,IAAI,CAAC;QACb,CAAC;IACF,CAAC;AACF,CAAC;AAED,6EAA6E;AAC7E,qFAAqF;AACrF,iBAAiB;AACjB,SAAS,SAAS,CAAC,OAAgB,EAAE,IAAsB;IAC1D,IAAI,IAAI,IAAI,CAAC,sBAAsB,CAAC,OAAO,CAAC,EAAE,CAAC;QAC9C,MAAM,IAAI,KAAK,CAAC,qDAAqD,CAAC,CAAC;IACxE,CAAC;AACF,CAAC;AAED,SAAS,MAAM,CAAC,QAAgB,EAAE,IAAY;IAC7C,IAAI,QAAQ,KAAK,EAAE;QAAE,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;IAC/C,IAAI,IAAI,KAAK,CAAC;QAAE,MAAM,IAAI,iBAAiB,CAAC,8BAA8B,CAAC,CAAC;IAC5E,OAAO,SAAS,CAAC;AAClB,CAAC;AAED,KAAK,UAAU,UAAU,CAAC,CAAS,EAAE,OAAgB,EAAE,MAAkB,EAAE,IAAsB;IAChG,SAAS,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;IACzB,IAAI,sBAAsB,CAAC,OAAO,CAAC,EAAE,CAAC;QACrC,MAAM,CAAC,CAAC,GAAG,CAAC,IAAI,EAAE,QAAQ,IAAI,EAAE,CAAC,CAAC;QAClC,MAAM,CAAC,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,IAAI,CAAC,CAAC,CAAC;IAC9B,CAAC;IACD,MAAM,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;AACrC,CAAC;AAED,KAAK,UAAU,UAAU,CAAC,CAAS,EAAE,OAAgB;IACpD,IAAI,CAAC,sBAAsB,CAAC,OAAO,CAAC;QAAE,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC;IACvF,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;IACtD,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC;IAC7C,OAAO,QAAQ,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC;AACrD,CAAC;AAED,KAAK,UAAU,eAAe,CAAC,CAAS,EAAE,OAAgB,EAAE,IAAW,EAAE,IAAsB;IAC9F,SAAS,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;IACzB,IAAI,CAAC,sBAAsB,CAAC,OAAO,CAAC;QAAE,OAAO,UAAU,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC;IAC1E,MAAM,CAAC,CAAC,GAAG,CAAC,IAAI,EAAE,QAAQ,IAAI,EAAE,CAAC,CAAC;IAClC,MAAM,UAAU,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC;IACnC,MAAM,CAAC,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,IAAI,CAAC,CAAC,CAAC;AAC9B,CAAC;AAED,KAAK,UAAU,eAAe,CAAC,CAAS,EAAE,OAAgB;IACzD,IAAI,CAAC,sBAAsB,CAAC,OAAO,CAAC;QAAE,OAAO,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC,CAAC,EAAE,OAAO,CAAC,EAAE,CAAC;IACpF,MAAM,QAAQ,GAAG,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC;IAC/B,MAAM,IAAI,GAAG,MAAM,UAAU,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;IAC1C,MAAM,OAAO,GAAG,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;IAChD,OAAO,OAAO,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC;AAC/C,CAAC;AAED,oFAAoF;AACpF,0FAA0F;AAC1F,qFAAqF;AACrF,MAAM,QAAQ,GAAG,EAAE,IAAI,GAAG,GAAG,EAAE,CAAC;AAChC,MAAM,QAAQ,GAAG,CAAC,CAAS,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAE9D,KAAK,UAAU,eAAe,CAAC,CAAS,EAAE,OAAgB,EAAE,IAAsB;IACjF,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC;QAAE,OAAO;IACnC,MAAM,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,EAAE,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC;IACxC,MAAM,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,EAAE,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC;AACzC,CAAC;AAED,KAAK,UAAU,eAAe,CAAC,CAAS,EAAE,OAAgB;IACzD,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC;QAAE,OAAO,SAAS,CAAC;IAC7C,OAAO,EAAE,IAAI,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC;AACzE,CAAC;AAED,0FAA0F;AAC1F,KAAK,UAAU,oBAAoB,CAAC,CAAS,EAAE,GAAsB,EAAE,OAAgB;IACtF,QAAQ,GAAG,CAAC,MAAM,EAAE,CAAC;QACpB,KAAK,QAAQ;YACZ,MAAM,UAAU,CAAC,CAAC,EAAE,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,QAAQ,CAAC,CAAC;YACvD,MAAM,eAAe,CAAC,CAAC,EAAE,OAAO,EAAE,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;YACzD,MAAM,eAAe,CAAC,CAAC,EAAE,OAAO,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC;YAC5C,MAAM;QACP,KAAK,SAAS;YACb,MAAM,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YACpB,MAAM;QACP,KAAK,SAAS;YACb,MAAM,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YACpB,MAAM,eAAe,CAAC,CAAC,EAAE,OAAO,EAAE,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;YACzD,MAAM,eAAe,CAAC,CAAC,EAAE,OAAO,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC;YAC5C,MAAM;QACP,KAAK,OAAO;YACX,gEAAgE;YAChE,MAAM,IAAI,KAAK,CAAC,8CAA8C,CAAC,CAAC;QACjE,KAAK,SAAS;YACb,MAAM,IAAI,KAAK,CAAC,6CAA6C,CAAC,CAAC;IACjE,CAAC;AACF,CAAC;AAED,uDAAuD;AACvD,SAAS,cAAc,CAAC,GAAsB;IAC7C,QAAQ,GAAG,CAAC,MAAM,EAAE,CAAC;QACpB,KAAK,QAAQ;YACZ,OAAO,cAAc,CAAC;QACvB,KAAK,SAAS;YACb,OAAO,YAAY,CAAC;QACrB,KAAK,SAAS;YACb,OAAO,gBAAgB,CAAC;QACzB,KAAK,OAAO;YACX,MAAM,IAAI,KAAK,CAAC,8CAA8C,CAAC,CAAC;QACjE,KAAK,SAAS;YACb,MAAM,IAAI,KAAK,CAAC,6CAA6C,CAAC,CAAC;IACjE,CAAC;AACF,CAAC;AAED,KAAK,UAAU,oBAAoB,CAAC,CAAS,EAAE,GAAW,EAAE,OAAgB;IAC3E,QAAQ,GAAG,EAAE,CAAC;QACb,KAAK,cAAc,EAAE,CAAC;YACrB,MAAM,IAAI,GAAG,MAAM,UAAU,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;YAC1C,MAAM,IAAI,GAAG,MAAM,eAAe,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;YAC/C,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,IAAI,EAAE,GAAG,IAAI,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC,CAAC,EAAE,OAAO,CAAC,EAAE,CAAC;QACxF,CAAC;QACD,KAAK,YAAY;YAChB,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,EAAE,EAAE,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC;QACjD,KAAK,gBAAgB,EAAE,CAAC;YACvB,MAAM,EAAE,GAAG,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC;YACzB,MAAM,IAAI,GAAG,MAAM,eAAe,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;YAC/C,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,EAAE,EAAE,GAAG,IAAI,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC,CAAC,EAAE,OAAO,CAAC,EAAE,CAAC;QACpF,CAAC;QACD;YACC,uEAAuE;YACvE,mDAAmD;YACnD,MAAM,CAAC,CAAC,OAAO,EAAE,CAAC;YAClB,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC;IAC/B,CAAC;AACF,CAAC;AAED,sFAAsF;AACtF,KAAK,UAAU,gBAAgB,CAAC,CAAS,EAAE,GAAsB,EAAE,OAAgB;IAClF,QAAQ,GAAG,CAAC,MAAM,EAAE,CAAC;QACpB,KAAK,QAAQ;YACZ,SAAS,CAAC,OAAO,EAAE,GAAG,CAAC,QAAQ,IAAI,GAAG,CAAC,OAAO,CAAC,CAAC;YAChD,MAAM,CAAC,CAAC,EAAE,CAAC,aAAa,CAAC,CAAC;YAC1B,MAAM,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;YACxC,MAAM,UAAU,CAAC,CAAC,EAAE,OAAO,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC;YACvC,MAAM;QACP,KAAK,OAAO;YACX,MAAM,CAAC,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC;YACzB,MAAM,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;YACxC,MAAM,UAAU,CAAC,CAAC,EAAE,OAAO,EAAE,EAAE,CAAC,CAAC;YACjC,MAAM;QACP,KAAK,SAAS,CAAC;QACf,KAAK,SAAS,CAAC;QACf,KAAK,SAAS;YACb,mDAAmD;YACnD,MAAM,IAAI,KAAK,CAAC,6CAA6C,CAAC,CAAC;IACjE,CAAC;AACF,CAAC;AAED,KAAK,UAAU,gBAAgB,CAAC,CAAS,EAAE,OAAgB;IAC1D,MAAM,MAAM,GAAG,MAAM,CAAC,CAAC,EAAE,EAAE,CAAC;IAC5B,iFAAiF;IACjF,sFAAsF;IACtF,MAAM,MAAM,GAAG,MAAM,KAAK,aAAa,IAAI,CAAC,MAAM,KAAK,cAAc,IAAI,aAAa,CAAC,OAAO,CAAC,CAAC,CAAC;IACjG,IAAI,MAAM,KAAK,YAAY,IAAI,CAAC,MAAM,EAAE,CAAC;QACxC,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC;IAC5C,CAAC;IACD,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC;IAC7C,MAAM,IAAI,GAAG,MAAM,UAAU,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;IAC1C,OAAO,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC;AAClF,CAAC;AAED,8FAA8F;AAC9F,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAAC,CAAS,EAAE,GAAsB,EAAE,OAAgB;IAChG,IAAI,aAAa,CAAC,OAAO,CAAC,EAAE,CAAC;QAC5B,6FAA6F;QAC7F,MAAM,CAAC,CAAC,GAAG,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC;QACjC,OAAO,OAAO,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,oBAAoB,CAAC,CAAC,EAAE,GAAG,EAAE,OAAO,CAAC,CAAC,CAAC;IACxE,CAAC;IACD,OAAO,OAAO,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,gBAAgB,CAAC,CAAC,EAAE,GAAG,EAAE,OAAO,CAAC,CAAC,CAAC;AACpE,CAAC;AAED,8FAA8F;AAC9F,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAAC,CAAS,EAAE,OAAgB;IACxE,IAAI,aAAa,CAAC,OAAO,CAAC,EAAE,CAAC;QAC5B,MAAM,GAAG,GAAG,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC;QAC1B,OAAO,OAAO,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,oBAAoB,CAAC,CAAC,EAAE,GAAG,EAAE,OAAO,CAAC,CAAC,CAAC;IACxE,CAAC;IACD,OAAO,OAAO,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,gBAAgB,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC;AAC/D,CAAC;AAED,oFAAoF;AACpF,MAAM,CAAC,KAAK,UAAU,4BAA4B,CACjD,CAAS,EACT,OAAgB;IAEhB,IAAI,aAAa,CAAC,OAAO,CAAC,EAAE,CAAC;QAC5B,IAAI,MAAM,CAAC,CAAC,IAAI,EAAE;YAAE,OAAO,SAAS,CAAC;QACrC,MAAM,GAAG,GAAG,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC;QAC1B,OAAO,OAAO,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,oBAAoB,CAAC,CAAC,EAAE,GAAG,EAAE,OAAO,CAAC,CAAC,CAAC;IACxE,CAAC;IACD,OAAO,OAAO,CAAC,WAAW,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,gBAAgB,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC;AACpE,CAAC;AAID;;;;GAIG;AACH,MAAM,OAAO,eAAe;IAC3B,KAAK,GAAG,EAAE,CAAC;IACX,KAAK,GAAG,IAAI,GAAG,EAAsB,CAAC;IAEtC,KAAK,CAAC,IAAU;QACf,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC;QACxD,IAAI,CAAC,IAAI;YAAE,MAAM,IAAI,iBAAiB,CAAC,iBAAiB,IAAI,CAAC,QAAQ,cAAc,CAAC,CAAC;QACrF,OAAO,IAAI,CAAC;IACb,CAAC;IAED,KAAK,CAAC,IAAW,EAAE,IAAsB;QACxC,IAAI,CAAC,IAAI;YAAE,OAAO,IAAI,CAAC;QACvB,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC;QACnC,IAAI,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,MAAM;YAAE,MAAM,IAAI,iBAAiB,CAAC,kBAAkB,IAAI,CAAC,IAAI,OAAO,IAAI,CAAC,MAAM,OAAO,CAAC,CAAC;QAC/G,MAAM,QAAQ,GAAG,CAAC,GAAG,IAAI,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QACnE,SAAS,CAAC,QAAQ,CAAC,CAAC;QACpB,OAAO,QAAQ,CAAC;IACjB,CAAC;IAED,+DAA+D;IAC/D,KAAK,CAAC,GAAyE;QAC9E,IAAI,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC;QACxB,IAAI,GAAG,CAAC,QAAQ,EAAE,CAAC;YAClB,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,CAAC;YACzD,MAAM,IAAI,GAAG,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC;YAC/B,IAAI,IAAI,GAAG,IAAI,CAAC,MAAM;gBAAE,MAAM,IAAI,iBAAiB,CAAC,kBAAkB,IAAI,OAAO,IAAI,CAAC,MAAM,WAAW,CAAC,CAAC;YACzG,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;YAC9D,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,MAAM,GAAG,IAAI,CAAC,SAAS,EAAE,CAAC;gBAChD,MAAM,IAAI,iBAAiB,CAAC,gBAAgB,IAAI,CAAC,SAAS,QAAQ,CAAC,CAAC;YACrE,CAAC;QACF,CAAC;QACD,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;QAC/C,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,EAAE,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;QAC/C,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;IACzB,CAAC;IAED,oGAAoG;IACpG,MAAM,CAAC,GAAgD;QACtD,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;QAC/C,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACpC,IAAI,CAAC,IAAI;YAAE,MAAM,IAAI,iBAAiB,CAAC,wBAAwB,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC;QACzE,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;QACtD,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC;IACtC,CAAC;IAED,4DAA4D;IAC5D,GAAG,CAAC,EAAU;QACb,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAChC,IAAI,CAAC,IAAI;YAAE,MAAM,IAAI,iBAAiB,CAAC,wBAAwB,EAAE,EAAE,CAAC,CAAC;QACrE,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QACtB,OAAO,IAAI,CAAC,MAAM,CAAC;IACpB,CAAC;CACD;AAED;;;GAGG;AACH,MAAM,OAAO,eAAe;IAC3B,MAAM,CAAa;IACnB;;;;;4EAKwE;IACxE,UAAU,CAAS;IACnB;;+BAE2B;IAC3B,MAAM,CAAU;IAEhB,YAAY,MAAkB,EAAE,UAAU,GAAW,EAAE,EAAE,MAAM,GAAG,KAAK;QACtE,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;QAC7B,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACtB,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,CAAS,EAAE,OAAgB;QACxC,MAAM,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;QACzC,IAAI,aAAa,CAAC,OAAO,CAAC,EAAE,CAAC;YAC5B,MAAM,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAC9B,CAAC;QACD,IAAI,SAAS,CAAC,OAAO,CAAC,EAAE,CAAC;YACxB,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC3B,CAAC;IACF,CAAC;IAED,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAS,EAAE,OAAgB;QAC/C,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC;QAC7C,MAAM,UAAU,GAAG,aAAa,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC/D,MAAM,MAAM,GAAG,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC;QAC3D,OAAO,IAAI,eAAe,CAAC,MAAM,EAAE,UAAU,EAAE,MAAM,CAAC,CAAC;IACxD,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,CAAS,EAAE,OAAgB;QACvC,OAAO,OAAO,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC;IAC3D,CAAC;IAED,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAS,EAAE,OAAgB;QAC9C,OAAO,OAAO,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC;IACtE,CAAC;CACD;AAED,kEAAkE;AAClE,GAAG;AACH,qFAAqF;AACrF,MAAM,OAAO,YAAY;IACxB,QAAQ,CAAe;IAEvB,YAAY,KAAmB;QAC9B,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC;IACvB,CAAC;IAED,MAAM,CAAC,MAAM,CAAC,OAAgB;QAC7B,QAAQ,OAAO,EAAE,CAAC;YACjB,KAAK,OAAO,CAAC,QAAQ,CAAC;YACtB,KAAK,OAAO,CAAC,QAAQ;gBACpB,MAAM;YACP;gBACC,MAAM,IAAI,KAAK,CAAC,8CAA8C,CAAC,CAAC;QAClE,CAAC;IACF,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,CAAS;QACtB,MAAM,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;QAClC,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAClC,MAAM,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;QACnC,CAAC;IACF,CAAC;IAED,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAS;QAC7B,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC;QAC5B,MAAM,QAAQ,GAAiB,EAAE,CAAC;QAClC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC;YAChC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;QAC9C,CAAC;QACD,OAAO,IAAI,YAAY,CAAC,QAAQ,CAAC,CAAC;IACnC,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,CAAS,EAAE,OAAgB;QACvC,YAAY,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAC7B,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,YAAY,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAC7B,OAAO,OAAO,CAAC,MAAM,CAAC,CAAC,EAAE,YAAY,CAAC,OAAO,CAAC,CAAC;IAChD,CAAC;CACD;AAED,gFAAgF;AAChF,8EAA8E;AAC9E,GAAG;AACH,6EAA6E;AAC7E,iFAAiF;AACjF,+EAA+E;AAC/E,oEAAoE;AACpE,MAAM,OAAO,UAAU;IACtB,GAAG,CAAM;IACT,MAAM,CAAS;IAEf,YAAY,GAAQ,EAAE,MAAc;QACnC,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC;QACf,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACtB,CAAC;IAED,MAAM,CAAC,MAAM,CAAC,OAAgB;QAC7B,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,EAAE,CAAC;YAC7B,MAAM,IAAI,KAAK,CAAC,4CAA4C,CAAC,CAAC;QAC/D,CAAC;IACF,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,CAAS;QACtB,MAAM,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACtB,MAAM,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAC1B,CAAC;IAED,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAS;QAC7B,iFAAiF;QACjF,kFAAkF;QAClF,qFAAqF;QACrF,MAAM,MAAM,GAAG,SAAS,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;QAC9C,MAAM,MAAM,GAAG,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC;QAC7B,OAAO,IAAI,UAAU,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACvC,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,CAAS,EAAE,OAAgB;QACvC,UAAU,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAC3B,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,UAAU,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAC3B,OAAO,OAAO,CAAC,MAAM,CAAC,CAAC,EAAE,UAAU,CAAC,OAAO,CAAC,CAAC;IAC9C,CAAC;CACD","sourcesContent":["import { ProtocolViolation } from \"../error.ts\";\nimport { type Cost, type Hop, HopSchema, MAX_HOPS, UNKNOWN_HOP } from \"../hop.ts\";\nimport * as Path from \"../path.ts\";\nimport type { Reader, Writer } from \"../stream.ts\";\nimport * as Message from \"./message.ts\";\nimport {\n\thasAnnounceCompression,\n\thasAnnounceId,\n\thasAnnounceOk,\n\thasExcludeHop,\n\thasHidden,\n\thasRouteCost,\n\tVersion,\n} from \"./version.ts\";\n\n// Pre-lite-06 inner status values, carried inside the single ANNOUNCE_BROADCAST body.\nconst STATUS_ENDED = 0;\nconst STATUS_ACTIVE = 1;\nconst STATUS_RESTART = 2;\n\n// lite-06 announce message types: an outer discriminator carried before the length\n// prefix, so each announcement is an independently-typed, length-delimited message\n// (mirroring SUBSCRIBE_START/END/DROP on the subscribe stream).\nconst ANNOUNCE_START = 0;\nconst ANNOUNCE_END = 1;\nconst ANNOUNCE_RESTART = 2;\n\nexport type { Cost };\n\n/**\n * Lite-07: copy `keep` path segments (from the head) or hops (from the tail) of the\n * live announcement `distance` back from the stream's next Announce ID, where 1 is the\n * latest ANNOUNCE_START. Resolved by {@link AnnounceHistory}.\n */\nexport type Base = { distance: bigint; keep: number };\n\n/**\n * An announcement on the Announce Stream, advertising or retracting a broadcast.\n *\n * On lite-06+ these are three independently-typed messages (`ANNOUNCE_START`,\n * `ANNOUNCE_END`, `ANNOUNCE_RESTART`), each framed as `Type | Length | Body` like the\n * subscribe stream's responses. Each `active` (ANNOUNCE_START) implicitly assigns the\n * next announce id (a per-stream ordinal starting at 0); `endedId`/`restart` reference\n * that id instead of repeating the path. Older versions send a single ANNOUNCE_BROADCAST\n * message that retracts by path (`ended`).\n */\nexport type AnnounceBroadcast =\n\t/** A broadcast is now available, carrying the path suffix, the hop chain, and\n\t * (lite-06+) the route cost. An absent cost encodes as zero; it decodes as\n\t * `undefined` on a wire with no room for one. On lite-07, `suffix` follows the\n\t * segments `pathBase` copies and `hops` precede the ones `hopBase` copies. */\n\t| { status: \"active\"; suffix: Path.Valid; hops: Hop[]; cost?: Cost; pathBase?: Base; hopBase?: Base }\n\t/** Pre-lite-06: a broadcast is no longer available, retracted by path. */\n\t| { status: \"ended\"; suffix: Path.Valid }\n\t/** Lite06+: a broadcast is no longer available, retracted by announce id.\n\t * The id is retired; referencing it again is a protocol violation. */\n\t| { status: \"endedId\"; id: bigint }\n\t/** Lite06+: atomically replace the announcement with this id (e.g. a new hop\n\t * chain after a relay failover, or a route whose cost moved). The id stays live. */\n\t| { status: \"restart\"; id: bigint; hops: Hop[]; cost?: Cost; hopBase?: Base }\n\t/** An unknown lite-06+ announce type, skipped by length. Does not assign an id. */\n\t| { status: \"skipped\" };\n\n// Both wire rules on a hop chain, applied to what we send and to what we receive: a\n// chain that revisits a hop looped, so neither forwarding it nor subscribing through it\n// is safe, and a receiver must end the session over one. `UNKNOWN_HOP` identifies\n// nothing, so any number of hops may be unknown.\n//\n// `ProtocolViolation` so a receipt takes the session down rather than the one stream,\n// matching what `ietf/cluster.ts` throws for the identical rule.\nfunction checkHops(hops: Hop[]) {\n\tif (hops.length > MAX_HOPS) {\n\t\tthrow new ProtocolViolation(`hop count ${hops.length} exceeds maximum ${MAX_HOPS}`);\n\t}\n\n\t// MAX_HOPS is 32, so the quadratic scan is cheaper than allocating a set.\n\tfor (let i = 0; i < hops.length; i++) {\n\t\tconst hop = hops[i];\n\t\tif (hop === UNKNOWN_HOP) continue;\n\t\tif (hops.indexOf(hop, i + 1) !== -1) {\n\t\t\tthrow new ProtocolViolation(`hop ${hop} appears twice in the chain`);\n\t\t}\n\t}\n}\n\nasync function encodeHops(w: Writer, version: Version, hops: Hop[]) {\n\tcheckHops(hops);\n\tswitch (version) {\n\t\tcase Version.DRAFT_01:\n\t\tcase Version.DRAFT_02:\n\t\t\tbreak;\n\t\tcase Version.DRAFT_03:\n\t\t\tawait w.u53(hops.length);\n\t\t\tbreak;\n\t\tdefault:\n\t\t\t// Lite04+: hop count + individual Hop varints.\n\t\t\tawait w.u53(hops.length);\n\t\t\tfor (const origin of hops) {\n\t\t\t\tawait w.u62(origin);\n\t\t\t}\n\t\t\tbreak;\n\t}\n}\n\nasync function decodeHops(r: Reader, version: Version): Promise<Hop[]> {\n\tswitch (version) {\n\t\tcase Version.DRAFT_01:\n\t\tcase Version.DRAFT_02:\n\t\t\treturn [];\n\t\tcase Version.DRAFT_03: {\n\t\t\tconst count = await r.u53();\n\t\t\tif (count > MAX_HOPS) throw new Error(`hop count ${count} exceeds maximum ${MAX_HOPS}`);\n\t\t\t// Lite03 carries only a hop count, not individual ids, so every entry is\n\t\t\t// the reserved \"no identity\" id.\n\t\t\treturn new Array<Hop>(count).fill(UNKNOWN_HOP);\n\t\t}\n\t\tdefault: {\n\t\t\t// Lite04+: hop count + individual Hop varints.\n\t\t\tconst count = await r.u53();\n\t\t\tif (count > MAX_HOPS) throw new Error(`hop count ${count} exceeds maximum ${MAX_HOPS}`);\n\t\t\tconst hops: Hop[] = [];\n\t\t\tfor (let i = 0; i < count; i++) {\n\t\t\t\thops.push(HopSchema.parse(await r.u62()));\n\t\t\t}\n\t\t\tcheckHops(hops);\n\t\t\treturn hops;\n\t\t}\n\t}\n}\n\n// Lite-07 carries a base around a path and a hop list. A distance of 0 names\n// nothing, and a keep without a base is a violation. Other versions have no room for\n// a base at all.\nfunction checkBase(version: Version, base: Base | undefined) {\n\tif (base && !hasAnnounceCompression(version)) {\n\t\tthrow new Error(\"announce compression not supported for this version\");\n\t}\n}\n\nfunction toBase(distance: bigint, keep: number): Base | undefined {\n\tif (distance !== 0n) return { distance, keep };\n\tif (keep !== 0) throw new ProtocolViolation(\"announce keep without a base\");\n\treturn undefined;\n}\n\nasync function encodePath(w: Writer, version: Version, suffix: Path.Valid, base: Base | undefined) {\n\tcheckBase(version, base);\n\tif (hasAnnounceCompression(version)) {\n\t\tawait w.u62(base?.distance ?? 0n);\n\t\tawait w.u53(base?.keep ?? 0);\n\t}\n\tawait w.string(Path.encode(suffix));\n}\n\nasync function decodePath(r: Reader, version: Version): Promise<{ suffix: Path.Valid; pathBase?: Base }> {\n\tif (!hasAnnounceCompression(version)) return { suffix: Path.decode(await r.string()) };\n\tconst pathBase = toBase(await r.u62(), await r.u53());\n\tconst suffix = Path.decode(await r.string());\n\treturn pathBase ? { suffix, pathBase } : { suffix };\n}\n\nasync function encodeHopsBlock(w: Writer, version: Version, hops: Hop[], base: Base | undefined) {\n\tcheckBase(version, base);\n\tif (!hasAnnounceCompression(version)) return encodeHops(w, version, hops);\n\tawait w.u62(base?.distance ?? 0n);\n\tawait encodeHops(w, version, hops);\n\tawait w.u53(base?.keep ?? 0);\n}\n\nasync function decodeHopsBlock(r: Reader, version: Version): Promise<{ hops: Hop[]; hopBase?: Base }> {\n\tif (!hasAnnounceCompression(version)) return { hops: await decodeHops(r, version) };\n\tconst distance = await r.u62();\n\tconst hops = await decodeHops(r, version);\n\tconst hopBase = toBase(distance, await r.u53());\n\treturn hopBase ? { hops, hopBase } : { hops };\n}\n\n// The route cost rides lite-06+ announcements as two varints, warm then cold; older\n// versions carry neither. Costs saturate at 2^62-1 on every version, even where lite-07's\n// varints could carry more, so a cost always forwards to a peer on an older version.\nconst MAX_COST = 2n ** 62n - 1n;\nconst saturate = (v: bigint) => (v > MAX_COST ? MAX_COST : v);\n\nasync function encodeRouteCost(w: Writer, version: Version, cost: Cost | undefined) {\n\tif (!hasRouteCost(version)) return;\n\tawait w.u62(saturate(cost?.warm ?? 0n));\n\tawait w.u62(saturate(cost?.cold ?? 0n));\n}\n\nasync function decodeRouteCost(r: Reader, version: Version): Promise<Cost | undefined> {\n\tif (!hasRouteCost(version)) return undefined;\n\treturn { warm: saturate(await r.u62()), cold: saturate(await r.u62()) };\n}\n\n// lite-06 message body (no discriminator; the type is carried outside the length prefix).\nasync function encodeAnnounce06Body(w: Writer, msg: AnnounceBroadcast, version: Version) {\n\tswitch (msg.status) {\n\t\tcase \"active\":\n\t\t\tawait encodePath(w, version, msg.suffix, msg.pathBase);\n\t\t\tawait encodeHopsBlock(w, version, msg.hops, msg.hopBase);\n\t\t\tawait encodeRouteCost(w, version, msg.cost);\n\t\t\tbreak;\n\t\tcase \"endedId\":\n\t\t\tawait w.u62(msg.id);\n\t\t\tbreak;\n\t\tcase \"restart\":\n\t\t\tawait w.u62(msg.id);\n\t\t\tawait encodeHopsBlock(w, version, msg.hops, msg.hopBase);\n\t\t\tawait encodeRouteCost(w, version, msg.cost);\n\t\t\tbreak;\n\t\tcase \"ended\":\n\t\t\t// The pre-lite-06 path-form retraction has no place on lite-06.\n\t\t\tthrow new Error(\"ended-by-path not supported for this version\");\n\t\tcase \"skipped\":\n\t\t\tthrow new Error(\"decode-only announce type cannot be encoded\");\n\t}\n}\n\n// lite-06 outer message type for a given announcement.\nfunction announce06Type(msg: AnnounceBroadcast): number {\n\tswitch (msg.status) {\n\t\tcase \"active\":\n\t\t\treturn ANNOUNCE_START;\n\t\tcase \"endedId\":\n\t\t\treturn ANNOUNCE_END;\n\t\tcase \"restart\":\n\t\t\treturn ANNOUNCE_RESTART;\n\t\tcase \"ended\":\n\t\t\tthrow new Error(\"ended-by-path not supported for this version\");\n\t\tcase \"skipped\":\n\t\t\tthrow new Error(\"decode-only announce type cannot be encoded\");\n\t}\n}\n\nasync function decodeAnnounce06Body(r: Reader, typ: number, version: Version): Promise<AnnounceBroadcast> {\n\tswitch (typ) {\n\t\tcase ANNOUNCE_START: {\n\t\t\tconst path = await decodePath(r, version);\n\t\t\tconst hops = await decodeHopsBlock(r, version);\n\t\t\treturn { status: \"active\", ...path, ...hops, cost: await decodeRouteCost(r, version) };\n\t\t}\n\t\tcase ANNOUNCE_END:\n\t\t\treturn { status: \"endedId\", id: await r.u62() };\n\t\tcase ANNOUNCE_RESTART: {\n\t\t\tconst id = await r.u62();\n\t\t\tconst hops = await decodeHopsBlock(r, version);\n\t\t\treturn { status: \"restart\", id, ...hops, cost: await decodeRouteCost(r, version) };\n\t\t}\n\t\tdefault:\n\t\t\t// Skip the length-prefixed body so an earlier Lite06 build negotiating\n\t\t\t// the same ALPN does not kill the announce stream.\n\t\t\tawait r.readAll();\n\t\t\treturn { status: \"skipped\" };\n\t}\n}\n\n// Pre-lite-06 single ANNOUNCE_BROADCAST body: an inner status byte, then path + hops.\nasync function encodeLegacyBody(w: Writer, msg: AnnounceBroadcast, version: Version) {\n\tswitch (msg.status) {\n\t\tcase \"active\":\n\t\t\tcheckBase(version, msg.pathBase ?? msg.hopBase);\n\t\t\tawait w.u8(STATUS_ACTIVE);\n\t\t\tawait w.string(Path.encode(msg.suffix));\n\t\t\tawait encodeHops(w, version, msg.hops);\n\t\t\tbreak;\n\t\tcase \"ended\":\n\t\t\tawait w.u8(STATUS_ENDED);\n\t\t\tawait w.string(Path.encode(msg.suffix));\n\t\t\tawait encodeHops(w, version, []);\n\t\t\tbreak;\n\t\tcase \"endedId\":\n\t\tcase \"restart\":\n\t\tcase \"skipped\":\n\t\t\t// The id-referencing forms only exist on lite-06+.\n\t\t\tthrow new Error(\"announce ids not supported for this version\");\n\t}\n}\n\nasync function decodeLegacyBody(r: Reader, version: Version): Promise<AnnounceBroadcast> {\n\tconst status = await r.u8();\n\t// On lite-05 a restart travels as a duplicate `active`, but the explicit restart\n\t// status is accepted on decode and treated the same. Older versions never defined it.\n\tconst active = status === STATUS_ACTIVE || (status === STATUS_RESTART && hasAnnounceOk(version));\n\tif (status !== STATUS_ENDED && !active) {\n\t\tthrow new Error(\"invalid announce status\");\n\t}\n\tconst suffix = Path.decode(await r.string());\n\tconst hops = await decodeHops(r, version);\n\treturn active ? { status: \"active\", suffix, hops } : { status: \"ended\", suffix };\n}\n\n/** Encode one announcement, including its type discriminator (lite-06+) and length prefix. */\nexport async function encodeAnnounceBroadcast(w: Writer, msg: AnnounceBroadcast, version: Version): Promise<void> {\n\tif (hasAnnounceId(version)) {\n\t\t// lite-06+: outer type discriminator, then a size-prefixed body (like the subscribe stream).\n\t\tawait w.u53(announce06Type(msg));\n\t\treturn Message.encode(w, (w) => encodeAnnounce06Body(w, msg, version));\n\t}\n\treturn Message.encode(w, (w) => encodeLegacyBody(w, msg, version));\n}\n\n/** Decode one announcement, including its type discriminator (lite-06+) and length prefix. */\nexport async function decodeAnnounceBroadcast(r: Reader, version: Version): Promise<AnnounceBroadcast> {\n\tif (hasAnnounceId(version)) {\n\t\tconst typ = await r.u53();\n\t\treturn Message.decode(r, (r) => decodeAnnounce06Body(r, typ, version));\n\t}\n\treturn Message.decode(r, (r) => decodeLegacyBody(r, version));\n}\n\n/** Like {@link decodeAnnounceBroadcast} but resolves `undefined` on a clean FIN. */\nexport async function decodeAnnounceBroadcastMaybe(\n\tr: Reader,\n\tversion: Version,\n): Promise<AnnounceBroadcast | undefined> {\n\tif (hasAnnounceId(version)) {\n\t\tif (await r.done()) return undefined;\n\t\tconst typ = await r.u53();\n\t\treturn Message.decode(r, (r) => decodeAnnounce06Body(r, typ, version));\n\t}\n\treturn Message.decodeMaybe(r, (r) => decodeLegacyBody(r, version));\n}\n\ntype Advertised = { suffix: Path.Valid; hops: Hop[] };\n\n/**\n * The live announcements on one lite-06+ announce stream, by Announce ID: what\n * ANNOUNCE_END and ANNOUNCE_UPDATE reference, and what a lite-07 base copies from.\n * Every violation throws {@link ProtocolViolation}.\n */\nexport class AnnounceHistory {\n\t#next = 0n;\n\t#live = new Map<bigint, Advertised>();\n\n\t#base(base: Base): Advertised {\n\t\tconst live = this.#live.get(this.#next - base.distance);\n\t\tif (!live) throw new ProtocolViolation(`announce base ${base.distance} is not live`);\n\t\treturn live;\n\t}\n\n\t#hops(hops: Hop[], base: Base | undefined): Hop[] {\n\t\tif (!base) return hops;\n\t\tconst tail = this.#base(base).hops;\n\t\tif (base.keep > tail.length) throw new ProtocolViolation(`announce keeps ${base.keep} of ${tail.length} hops`);\n\t\tconst resolved = [...hops, ...tail.slice(tail.length - base.keep)];\n\t\tcheckHops(resolved);\n\t\treturn resolved;\n\t}\n\n\t/** An ANNOUNCE_START: resolve it and assign it the next id. */\n\tstart(msg: { suffix: Path.Valid; hops: Hop[]; pathBase?: Base; hopBase?: Base }): Advertised {\n\t\tlet suffix = msg.suffix;\n\t\tif (msg.pathBase) {\n\t\t\tconst head = Path.parts(this.#base(msg.pathBase).suffix);\n\t\t\tconst keep = msg.pathBase.keep;\n\t\t\tif (keep > head.length) throw new ProtocolViolation(`announce keeps ${keep} of ${head.length} segments`);\n\t\t\tsuffix = Path.join(Path.from(...head.slice(0, keep)), suffix);\n\t\t\tif (Path.parts(suffix).length > Path.MAX_PARTS) {\n\t\t\t\tthrow new ProtocolViolation(`path exceeds ${Path.MAX_PARTS} parts`);\n\t\t\t}\n\t\t}\n\t\tconst hops = this.#hops(msg.hops, msg.hopBase);\n\t\tthis.#live.set(this.#next++, { suffix, hops });\n\t\treturn { suffix, hops };\n\t}\n\n\t/** An ANNOUNCE_UPDATE: resolve its chain before replacing the old one, which it may be based on. */\n\tupdate(msg: { id: bigint; hops: Hop[]; hopBase?: Base }): Advertised {\n\t\tconst hops = this.#hops(msg.hops, msg.hopBase);\n\t\tconst live = this.#live.get(msg.id);\n\t\tif (!live) throw new ProtocolViolation(`unknown announce id: ${msg.id}`);\n\t\tthis.#live.set(msg.id, { suffix: live.suffix, hops });\n\t\treturn { suffix: live.suffix, hops };\n\t}\n\n\t/** An ANNOUNCE_END: retire the id, returning its suffix. */\n\tend(id: bigint): Path.Valid {\n\t\tconst live = this.#live.get(id);\n\t\tif (!live) throw new ProtocolViolation(`unknown announce id: ${id}`);\n\t\tthis.#live.delete(id);\n\t\treturn live.suffix;\n\t}\n}\n\n/**\n * ANNOUNCE_REQUEST: sent by the subscriber to request ANNOUNCE_BROADCAST messages\n * for a path prefix. Renamed from `AnnounceInterest` in lite-05.\n */\nexport class AnnounceRequest {\n\tprefix: Path.Valid;\n\t/** Lite04/05 only: the 62-bit Hop id of the peer asking for announces, which the\n\t * publisher uses to skip announces that already passed through it. Zero means \"no\n\t * exclusion\". Not on the wire elsewhere, so a value set here is ignored when encoding\n\t * for another version and decodes as zero.\n\t *\n\t * Must be a bigint: peer origins are up to 62 bits and overflow u53. */\n\texcludeHop: bigint;\n\t/** Lite07+: also announce routes with a `.`-prefixed segment below the prefix. Not on\n\t * the wire earlier, so a value set here is ignored when encoding for an older version\n\t * and decodes as false. */\n\thidden: boolean;\n\n\tconstructor(prefix: Path.Valid, excludeHop: bigint = 0n, hidden = false) {\n\t\tthis.prefix = prefix;\n\t\tthis.excludeHop = excludeHop;\n\t\tthis.hidden = hidden;\n\t}\n\n\tasync #encode(w: Writer, version: Version) {\n\t\tawait w.string(Path.encode(this.prefix));\n\t\tif (hasExcludeHop(version)) {\n\t\t\tawait w.u62(this.excludeHop);\n\t\t}\n\t\tif (hasHidden(version)) {\n\t\t\tawait w.bool(this.hidden);\n\t\t}\n\t}\n\n\tstatic async #decode(r: Reader, version: Version): Promise<AnnounceRequest> {\n\t\tconst prefix = Path.decode(await r.string());\n\t\tconst excludeHop = hasExcludeHop(version) ? await r.u62() : 0n;\n\t\tconst hidden = hasHidden(version) ? await r.bool() : false;\n\t\treturn new AnnounceRequest(prefix, excludeHop, hidden);\n\t}\n\n\tasync encode(w: Writer, version: Version): Promise<void> {\n\t\treturn Message.encode(w, (w) => this.#encode(w, version));\n\t}\n\n\tstatic async decode(r: Reader, version: Version): Promise<AnnounceRequest> {\n\t\treturn Message.decode(r, (r) => AnnounceRequest.#decode(r, version));\n\t}\n}\n\n/// Sent after setup to communicate the initially announced paths.\n///\n/// Used by Draft01/Draft02 only. Draft03+ uses individual Announce messages instead.\nexport class AnnounceInit {\n\tsuffixes: Path.Valid[];\n\n\tconstructor(paths: Path.Valid[]) {\n\t\tthis.suffixes = paths;\n\t}\n\n\tstatic #guard(version: Version) {\n\t\tswitch (version) {\n\t\t\tcase Version.DRAFT_01:\n\t\t\tcase Version.DRAFT_02:\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tthrow new Error(\"announce init not supported for this version\");\n\t\t}\n\t}\n\n\tasync #encode(w: Writer) {\n\t\tawait w.u53(this.suffixes.length);\n\t\tfor (const path of this.suffixes) {\n\t\t\tawait w.string(Path.encode(path));\n\t\t}\n\t}\n\n\tstatic async #decode(r: Reader): Promise<AnnounceInit> {\n\t\tconst count = await r.u53();\n\t\tconst suffixes: Path.Valid[] = [];\n\t\tfor (let i = 0; i < count; i++) {\n\t\t\tsuffixes.push(Path.decode(await r.string()));\n\t\t}\n\t\treturn new AnnounceInit(suffixes);\n\t}\n\n\tasync encode(w: Writer, version: Version): Promise<void> {\n\t\tAnnounceInit.#guard(version);\n\t\treturn Message.encode(w, this.#encode.bind(this));\n\t}\n\n\tstatic async decode(r: Reader, version: Version): Promise<AnnounceInit> {\n\t\tAnnounceInit.#guard(version);\n\t\treturn Message.decode(r, AnnounceInit.#decode);\n\t}\n}\n\n/// Sent by the publisher as the first message on an announce stream, before any\n/// individual Announce messages. Lite05+ only; the successor to AnnounceInit.\n///\n/// `origin` is the responder's Hop ID, which the subscriber stamps onto each\n/// announce's hop chain (the publisher no longer stamps itself), or the reserved\n/// {@link UNKNOWN_HOP} when the responder has no identity to give. `active` is\n/// the number of initial Announce messages that follow immediately.\nexport class AnnounceOk {\n\thop: Hop;\n\tactive: number;\n\n\tconstructor(hop: Hop, active: number) {\n\t\tthis.hop = hop;\n\t\tthis.active = active;\n\t}\n\n\tstatic #guard(version: Version) {\n\t\tif (!hasAnnounceOk(version)) {\n\t\t\tthrow new Error(\"announce ok not supported for this version\");\n\t\t}\n\t}\n\n\tasync #encode(w: Writer) {\n\t\tawait w.u62(this.hop);\n\t\tawait w.u53(this.active);\n\t}\n\n\tstatic async #decode(r: Reader): Promise<AnnounceOk> {\n\t\t// The draft reserves 0 for \"unknown\": the responder was never assigned an id, or\n\t\t// withholds it to obscure its routing. It names nobody, so callers must not stamp\n\t\t// it onto a hop chain, but it is a legal message and not grounds to drop the stream.\n\t\tconst origin = HopSchema.parse(await r.u62());\n\t\tconst active = await r.u53();\n\t\treturn new AnnounceOk(origin, active);\n\t}\n\n\tasync encode(w: Writer, version: Version): Promise<void> {\n\t\tAnnounceOk.#guard(version);\n\t\treturn Message.encode(w, this.#encode.bind(this));\n\t}\n\n\tstatic async decode(r: Reader, version: Version): Promise<AnnounceOk> {\n\t\tAnnounceOk.#guard(version);\n\t\treturn Message.decode(r, AnnounceOk.#decode);\n\t}\n}\n"]}
|
package/lite/connection.d.ts
CHANGED
|
@@ -1,31 +1,11 @@
|
|
|
1
1
|
import { type Getter } from "@norskvideo/moq-signals";
|
|
2
|
-
import * as announce from "../announced";
|
|
3
|
-
import type * as broadcast from "../broadcast";
|
|
2
|
+
import type * as announce from "../announced";
|
|
4
3
|
import type { Established } from "../connection/established";
|
|
5
4
|
import { type Probe, type Stats } from "../connection/stats";
|
|
6
5
|
import { type Transport } from "../connection/transport";
|
|
7
|
-
import { type
|
|
8
|
-
import * as Path from "../path";
|
|
9
|
-
import {
|
|
10
|
-
import { ProbeLevel, type Role } from "./setup";
|
|
11
|
-
import { type Version } from "./version";
|
|
12
|
-
/**
|
|
13
|
-
* Constructor options for {@link Connection}.
|
|
14
|
-
*
|
|
15
|
-
* @internal
|
|
16
|
-
*/
|
|
17
|
-
export interface ConnectionProps {
|
|
18
|
-
/** The URL of the connection. */
|
|
19
|
-
url: URL;
|
|
20
|
-
/** The established WebTransport session. */
|
|
21
|
-
quic: WebTransport;
|
|
22
|
-
/** The negotiated wire version. */
|
|
23
|
-
version: Version;
|
|
24
|
-
/** The session stream, absent on drafts that have none. */
|
|
25
|
-
session?: Stream;
|
|
26
|
-
/** Whether the relay supports broadcast discovery. Defaults to true. */
|
|
27
|
-
discovery?: boolean;
|
|
28
|
-
}
|
|
6
|
+
import { type Hop } from "../hop";
|
|
7
|
+
import type * as Path from "../path";
|
|
8
|
+
import { type Role } from "./setup";
|
|
29
9
|
/**
|
|
30
10
|
* Represents a connection to a MoQ server.
|
|
31
11
|
*
|
|
@@ -40,9 +20,9 @@ export declare class Connection implements Established {
|
|
|
40
20
|
readonly discovery: boolean;
|
|
41
21
|
/** The peer's PROBE estimates; see {@link Established.probe}. */
|
|
42
22
|
readonly probe: Getter<Probe>;
|
|
43
|
-
/** Random per-connection
|
|
23
|
+
/** Random per-connection Hop ID. Shared by Publisher (for outbound hop
|
|
44
24
|
* chains) and Subscriber (available for optional self-filtering on announces). */
|
|
45
|
-
readonly
|
|
25
|
+
readonly hop: Hop;
|
|
46
26
|
/**
|
|
47
27
|
* The {@link Role} the peer advertised in its SETUP, for a server deciding whether the
|
|
48
28
|
* peer's authorization grants the direction it intends to use.
|
|
@@ -53,44 +33,14 @@ export declare class Connection implements Established {
|
|
|
53
33
|
* recognize, or is a server (which never sends one).
|
|
54
34
|
*/
|
|
55
35
|
get peerRole(): Getter<Role | undefined>;
|
|
56
|
-
/**
|
|
57
|
-
* Creates a new Connection instance.
|
|
58
|
-
*
|
|
59
|
-
* @internal
|
|
60
|
-
*/
|
|
61
|
-
constructor({ url, quic, version, session, discovery }: ConnectionProps);
|
|
62
36
|
/**
|
|
63
37
|
* Closes the connection.
|
|
64
38
|
*/
|
|
65
39
|
close(): void;
|
|
66
|
-
|
|
67
|
-
announced(prefix?: Path.Valid): announce.Consumer;
|
|
68
|
-
consume(path: Path.Valid): broadcast.Consumer;
|
|
69
|
-
/**
|
|
70
|
-
* Watches a broadcast, live only while it is announced.
|
|
71
|
-
*
|
|
72
|
-
* @param path - The path of the broadcast to watch
|
|
73
|
-
* @returns A reactive handle to the broadcast
|
|
74
|
-
*/
|
|
75
|
-
announcedBroadcast(path: Path.Valid): announce.Broadcast;
|
|
40
|
+
announced(scope?: Path.Pattern, options?: announce.Options): announce.Consumer;
|
|
76
41
|
/** Snapshot the transport's counters; see {@link Established.stats}. */
|
|
77
42
|
stats(): Promise<Stats>;
|
|
78
|
-
|
|
43
|
+
/** Resolves when the session closes, decoding the peer's close code; see {@link Established.closed}. */
|
|
44
|
+
get closed(): Promise<Error | null>;
|
|
79
45
|
}
|
|
80
|
-
/**
|
|
81
|
-
* The probe level to advertise in SETUP, from what the transport can measure.
|
|
82
|
-
*
|
|
83
|
-
* `Report` claims we can measure and periodically report, so it is only truthful
|
|
84
|
-
* when a metric this version can carry actually exists. The qmux/WebSocket fallback
|
|
85
|
-
* implements no `getStats()` at all, and even a transport that has one may report
|
|
86
|
-
* neither figure. Advertising `Report` and then holding the subscriber's PROBE
|
|
87
|
-
* stream open with nothing to send is the state this avoids; the subscriber's own
|
|
88
|
-
* gate then skips a stream it could not use.
|
|
89
|
-
*
|
|
90
|
-
* Mirrors `ProbeLevel::detect` in `moq-net`, including its limitation: a metric
|
|
91
|
-
* that only appears after SETUP reads as unsupported here.
|
|
92
|
-
*
|
|
93
|
-
* @internal
|
|
94
|
-
*/
|
|
95
|
-
export declare function probeLevel(quic: WebTransport, version: Version): Promise<ProbeLevel>;
|
|
96
46
|
//# sourceMappingURL=connection.d.ts.map
|
package/lite/connection.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"connection.d.ts","sourceRoot":"","sources":["../../src/lite/connection.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,MAAM,EAAU,MAAM,cAAc,CAAC;AACnD,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"connection.d.ts","sourceRoot":"","sources":["../../src/lite/connection.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,MAAM,EAAU,MAAM,cAAc,CAAC;AACnD,OAAO,KAAK,KAAK,QAAQ,MAAM,iBAAiB,CAAC;AACjD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAChE,OAAO,EAAE,KAAK,KAAK,EAAE,KAAK,KAAK,EAAkB,MAAM,wBAAwB,CAAC;AAChF,OAAO,EAAE,KAAK,SAAS,EAAe,MAAM,4BAA4B,CAAC;AAEzE,OAAO,EAAE,KAAK,GAAG,EAAa,MAAM,WAAW,CAAC;AAEhD,OAAO,KAAK,KAAK,IAAI,MAAM,YAAY,CAAC;AASxC,OAAO,EAAc,KAAK,IAAI,EAAS,MAAM,YAAY,CAAC;AA2B1D;;;;GAIG;AACH,qBAAa,UAAW,YAAW,WAAW;;IAE7C,QAAQ,CAAC,GAAG,EAAE,GAAG,CAAC;IAGlB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IAGzB,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAC;IAE9B,yFAAyF;IACzF,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAiB5B,iEAAiE;IACjE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC;IAE9B;sFACkF;IAClF,QAAQ,CAAC,GAAG,EAAE,GAAG,CAAC;IAclB;;;;;;;;OAQG;IACH,IAAI,QAAQ,IAAI,MAAM,CAAC,IAAI,GAAG,SAAS,CAAC,CAEvC;IA+BD;;OAEG;IACH,KAAK,SAUJ;IAgCD,SAAS,CAAC,KAAK,CAAC,EAAE,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,EAAE,QAAQ,CAAC,OAAO,GAAG,QAAQ,CAAC,QAAQ,CAE7E;IAiHD,wEAAwE;IAClE,KAAK,IAAI,OAAO,CAAC,KAAK,CAAC,CAE5B;IAED,wGAAwG;IACxG,IAAI,MAAM,IAAI,OAAO,CAAC,KAAK,GAAG,IAAI,CAAC,CAElC;CACD"}
|