@blockcast/mmt-container 2.1.0 → 2.2.0-main.10bec7edb00b
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/dist/browser-runtime.js +647 -83
- package/dist/browser-runtime.js.map +4 -4
- package/dist/carp-catalog.js.map +1 -1
- package/dist/catalog-fec-params.d.ts +16 -0
- package/dist/catalog-fec-params.d.ts.map +1 -1
- package/dist/catalog-fec-params.js +15 -0
- package/dist/catalog-fec-params.js.map +2 -2
- package/dist/catalog-network-source.js.map +1 -1
- package/dist/cmcd-producer.d.ts +5 -0
- package/dist/cmcd-producer.d.ts.map +1 -1
- package/dist/cmcd-producer.js.map +2 -2
- package/dist/delivery-catalog.js +11 -6
- package/dist/delivery-catalog.js.map +2 -2
- package/dist/delta-fallback-config.js.map +1 -1
- package/dist/fec-manager.js.map +2 -2
- package/dist/fec-state.js.map +1 -1
- package/dist/fec-worker-setup.js.map +1 -1
- package/dist/held-layer-admission.js.map +1 -1
- package/dist/index.d.ts +3 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -0
- package/dist/index.js.map +2 -2
- package/dist/iso-block-locator.js.map +1 -1
- package/dist/mfu-reassembler.js +12 -19
- package/dist/mfu-reassembler.js.map +2 -2
- package/dist/mmtp-container-parser.js +12 -19
- package/dist/mmtp-container-parser.js.map +2 -2
- package/dist/mmtp-container-parser.no-modules.js +133 -34
- package/dist/mmtp-container-parser.no-modules.js.map +3 -3
- package/dist/mmtp-decode-pipeline.js +12 -19
- package/dist/mmtp-decode-pipeline.js.map +2 -2
- package/dist/mmtp-fec-session.d.ts +41 -3
- package/dist/mmtp-fec-session.d.ts.map +1 -1
- package/dist/mmtp-fec-session.js +118 -13
- package/dist/mmtp-fec-session.js.map +3 -3
- package/dist/mmtp-router.d.ts +9 -1
- package/dist/mmtp-router.d.ts.map +1 -1
- package/dist/mmtp-router.js +1473 -33
- package/dist/mmtp-router.js.map +4 -4
- package/dist/multicast-auth-catalog.js.map +1 -1
- package/dist/multicast-input.js.map +1 -1
- package/dist/multicast-manager.d.ts +15 -2
- package/dist/multicast-manager.d.ts.map +1 -1
- package/dist/multicast-manager.js +15216 -14934
- package/dist/multicast-manager.js.map +4 -4
- package/dist/multicast-transport.d.ts +11 -3
- package/dist/multicast-transport.d.ts.map +1 -1
- package/dist/multicast-transport.js +266 -25
- package/dist/multicast-transport.js.map +4 -4
- package/dist/multicast-unwrap.js +12 -19
- package/dist/multicast-unwrap.js.map +2 -2
- package/dist/no-modules.js +130 -33
- package/dist/no-modules.js.map +3 -3
- package/dist/repair-fetch.js.map +1 -1
- package/dist/repair-layer-subscriptions.d.ts +82 -0
- package/dist/repair-layer-subscriptions.d.ts.map +1 -0
- package/dist/repair-layer-subscriptions.js +192 -0
- package/dist/repair-layer-subscriptions.js.map +7 -0
- package/dist/signaling.js.map +2 -2
- package/dist/timestamp-codec.js +12 -19
- package/dist/timestamp-codec.js.map +2 -2
- package/dist/wasm-mfu-reassembler.js.map +1 -1
- package/dist/wasm-mmtp-container-parser.js +12 -19
- package/dist/wasm-mmtp-container-parser.js.map +2 -2
- package/package.json +5 -5
- package/schemas/catalog.schema.json +4 -0
- package/src/catalog-fec-params.ts +35 -0
- package/src/cmcd-producer.ts +5 -0
- package/src/index.ts +12 -0
- package/src/mmtp-fec-session.ts +115 -15
- package/src/mmtp-router.ts +81 -16
- package/src/multicast-manager.ts +26 -5
- package/src/multicast-transport.ts +44 -20
- package/src/repair-layer-subscriptions.ts +261 -0
|
@@ -42,7 +42,13 @@ export interface MulticastTransportConfig {
|
|
|
42
42
|
*/
|
|
43
43
|
protected?: boolean;
|
|
44
44
|
}
|
|
45
|
-
|
|
45
|
+
/**
|
|
46
|
+
* The leg a join resolved to. `'user-agent'`: the browser's own
|
|
47
|
+
* `MulticastReceiver` delivers it, which picks native or AMT itself and does
|
|
48
|
+
* not say which. CMCD has no user-agent value, so a caller reports a
|
|
49
|
+
* `'user-agent'` join as `'native'` (`TransportSnapshot.transport`).
|
|
50
|
+
*/
|
|
51
|
+
export type ResolvedMulticastTransport = 'native' | 'amt' | 'user-agent';
|
|
46
52
|
/**
|
|
47
53
|
* Why a joined transport handed control back to MoQ.
|
|
48
54
|
*
|
|
@@ -268,8 +274,10 @@ export declare class MulticastTransport<TPacketContext = never> {
|
|
|
268
274
|
/** Whether a subscription is live: joined, and not yet released or replaced. */
|
|
269
275
|
get joined(): boolean;
|
|
270
276
|
/**
|
|
271
|
-
*
|
|
272
|
-
*
|
|
277
|
+
* The live join's context as the caller gave it (the join's `context`, or
|
|
278
|
+
* the last setContext), or undefined without a live join. On a native
|
|
279
|
+
* provider each accepted packet is delivered with a marked copy of it
|
|
280
|
+
* (`userAgentVerifiedIngress`); this getter never carries the mark.
|
|
273
281
|
*/
|
|
274
282
|
get context(): TPacketContext | undefined;
|
|
275
283
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"multicast-transport.d.ts","sourceRoot":"","sources":["../src/multicast-transport.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,
|
|
1
|
+
{"version":3,"file":"multicast-transport.d.ts","sourceRoot":"","sources":["../src/multicast-transport.ts"],"names":[],"mappings":"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"}
|
|
@@ -206,11 +206,33 @@ var AdaptiveBitrateController = class {
|
|
|
206
206
|
};
|
|
207
207
|
|
|
208
208
|
// node_modules/@blockcast/mmt-base/dist/mmtp.js
|
|
209
|
+
var MMTP_HEADER_SIZE = 12;
|
|
209
210
|
var MPU_HEADER_SIZE = 8;
|
|
210
211
|
var MPU_LENGTH_FIELD_SIZE = 2;
|
|
211
212
|
var MPU_HEADER_REMAINDER_SIZE = MPU_HEADER_SIZE - MPU_LENGTH_FIELD_SIZE;
|
|
212
213
|
var MMTP_SIGNALING_PACKET_ID = 0;
|
|
213
214
|
var MMTP_PACKET_ID_MAX = 65535;
|
|
215
|
+
function readMMTPPacketId(buffer) {
|
|
216
|
+
if (buffer.length < MMTP_HEADER_SIZE)
|
|
217
|
+
return null;
|
|
218
|
+
const flags = buffer[0];
|
|
219
|
+
if ((flags >> 6 & 3) !== 0)
|
|
220
|
+
return null;
|
|
221
|
+
let offset = MMTP_HEADER_SIZE;
|
|
222
|
+
if ((flags & 32) !== 0) {
|
|
223
|
+
if (offset + 4 > buffer.length)
|
|
224
|
+
return null;
|
|
225
|
+
offset += 4;
|
|
226
|
+
}
|
|
227
|
+
if ((flags & 2) !== 0) {
|
|
228
|
+
if (offset + 4 > buffer.length)
|
|
229
|
+
return null;
|
|
230
|
+
const length = buffer[offset + 2] << 8 | buffer[offset + 3];
|
|
231
|
+
if (offset + 4 + length > buffer.length)
|
|
232
|
+
return null;
|
|
233
|
+
}
|
|
234
|
+
return buffer[2] << 8 | buffer[3];
|
|
235
|
+
}
|
|
214
236
|
|
|
215
237
|
// node_modules/@blockcast/mmt-base/dist/net-constants.js
|
|
216
238
|
var DEFAULT_AMT_RELAY_PORT = 2268;
|
|
@@ -1196,6 +1218,205 @@ var TransportManager = class {
|
|
|
1196
1218
|
};
|
|
1197
1219
|
var transportManager = new TransportManager();
|
|
1198
1220
|
|
|
1221
|
+
// node_modules/@blockcast/mmt-transport/dist/multicast-receiver-gateway.js
|
|
1222
|
+
var REGISTRY = /* @__PURE__ */ Symbol.for("@blockcast/mmt-transport/native-provider-registry/v1");
|
|
1223
|
+
var USER_AGENT_VERIFIED = /* @__PURE__ */ Symbol.for("@blockcast/mmt-transport/user-agent-verified/v1");
|
|
1224
|
+
var INTEGRITY_SCHEME = "manifest-ed25519-2";
|
|
1225
|
+
var MulticastError = class extends Error {
|
|
1226
|
+
code;
|
|
1227
|
+
constructor(code, message, cause) {
|
|
1228
|
+
super(message, cause === void 0 ? void 0 : { cause });
|
|
1229
|
+
this.name = "MulticastError";
|
|
1230
|
+
this.code = code;
|
|
1231
|
+
}
|
|
1232
|
+
};
|
|
1233
|
+
function datagramsOf(chunk) {
|
|
1234
|
+
const list = Array.isArray(chunk) ? chunk : chunk?.datagrams ?? [];
|
|
1235
|
+
const out = [];
|
|
1236
|
+
for (const d of list) {
|
|
1237
|
+
const data = d instanceof Uint8Array || d instanceof ArrayBuffer ? d : d?.data;
|
|
1238
|
+
if (data instanceof Uint8Array)
|
|
1239
|
+
out.push(data);
|
|
1240
|
+
else if (data instanceof ArrayBuffer)
|
|
1241
|
+
out.push(new Uint8Array(data));
|
|
1242
|
+
}
|
|
1243
|
+
return out;
|
|
1244
|
+
}
|
|
1245
|
+
function reasonOf(value) {
|
|
1246
|
+
return typeof value === "object" && value !== null && "reason" in value ? value.reason : value;
|
|
1247
|
+
}
|
|
1248
|
+
function registry() {
|
|
1249
|
+
const g = globalThis;
|
|
1250
|
+
if (g[REGISTRY] === void 0) {
|
|
1251
|
+
const providers = /* @__PURE__ */ new WeakSet();
|
|
1252
|
+
const byScope = /* @__PURE__ */ new WeakMap();
|
|
1253
|
+
Object.defineProperty(g, REGISTRY, {
|
|
1254
|
+
value: Object.freeze({
|
|
1255
|
+
isProvider: (x) => typeof x === "object" && x !== null && providers.has(x),
|
|
1256
|
+
providerFor: (scope) => {
|
|
1257
|
+
let provider = byScope.get(scope);
|
|
1258
|
+
if (provider === void 0) {
|
|
1259
|
+
provider = createProvider(scope);
|
|
1260
|
+
providers.add(provider);
|
|
1261
|
+
byScope.set(scope, provider);
|
|
1262
|
+
}
|
|
1263
|
+
return provider;
|
|
1264
|
+
}
|
|
1265
|
+
}),
|
|
1266
|
+
writable: false,
|
|
1267
|
+
configurable: false,
|
|
1268
|
+
enumerable: false
|
|
1269
|
+
});
|
|
1270
|
+
}
|
|
1271
|
+
return g[REGISTRY];
|
|
1272
|
+
}
|
|
1273
|
+
function resolveMulticastGateway(scope = globalThis) {
|
|
1274
|
+
const s = scope;
|
|
1275
|
+
if (typeof s.MulticastReceiver === "function")
|
|
1276
|
+
return registry().providerFor(scope);
|
|
1277
|
+
if (typeof s.multicast?.subscribe === "function")
|
|
1278
|
+
return s.multicast;
|
|
1279
|
+
return void 0;
|
|
1280
|
+
}
|
|
1281
|
+
function isUserAgentVerifiedGateway(gateway) {
|
|
1282
|
+
return registry().isProvider(gateway);
|
|
1283
|
+
}
|
|
1284
|
+
function userAgentVerifiedIngress(ingress, gateway) {
|
|
1285
|
+
if (isUserAgentVerifiedGateway(gateway))
|
|
1286
|
+
return { ...ingress, admittedBy: USER_AGENT_VERIFIED };
|
|
1287
|
+
if (!("admittedBy" in ingress))
|
|
1288
|
+
return ingress;
|
|
1289
|
+
const { admittedBy: _, ...rest } = ingress;
|
|
1290
|
+
return rest;
|
|
1291
|
+
}
|
|
1292
|
+
function unsupported(message, cause) {
|
|
1293
|
+
return new MulticastError("capability-unsupported", message, cause);
|
|
1294
|
+
}
|
|
1295
|
+
function createProvider(scope) {
|
|
1296
|
+
const Receiver = scope.MulticastReceiver;
|
|
1297
|
+
let gate = null;
|
|
1298
|
+
return {
|
|
1299
|
+
capabilities: () => Promise.resolve({ consumeModes: ["bytes"] }),
|
|
1300
|
+
subscribe: async (config) => {
|
|
1301
|
+
const c = config;
|
|
1302
|
+
if (c.consume !== "bytes")
|
|
1303
|
+
throw unsupported(`consume mode ${String(c.consume)} is not supported`);
|
|
1304
|
+
const origin = c.origin ?? "ip-multicast";
|
|
1305
|
+
if (origin !== "ip-multicast" && !(origin === "amt" && c.discovery === "driad")) {
|
|
1306
|
+
throw unsupported(`origin ${String(origin)} is not supported by MulticastReceiver`);
|
|
1307
|
+
}
|
|
1308
|
+
if (c.relay !== void 0)
|
|
1309
|
+
throw unsupported("MulticastReceiver picks its own AMT relay");
|
|
1310
|
+
if (!c.source)
|
|
1311
|
+
throw unsupported("MulticastReceiver needs an SSM source");
|
|
1312
|
+
if (c.senderAddress !== void 0 && c.senderAddress !== c.source) {
|
|
1313
|
+
throw unsupported("MulticastReceiver filters by source only");
|
|
1314
|
+
}
|
|
1315
|
+
const options = { sourceAddress: c.source, groupAddress: c.group, localPort: c.port };
|
|
1316
|
+
if (gate !== null)
|
|
1317
|
+
await gate;
|
|
1318
|
+
let rx;
|
|
1319
|
+
try {
|
|
1320
|
+
rx = new Receiver(options);
|
|
1321
|
+
} catch (error) {
|
|
1322
|
+
throw unsupported("MulticastReceiver refused the request", error);
|
|
1323
|
+
}
|
|
1324
|
+
const opened = rx.opened;
|
|
1325
|
+
if (gate === null)
|
|
1326
|
+
gate = opened.then(() => void 0, () => void 0);
|
|
1327
|
+
return openSubscription(rx, opened, options, c.packetIds);
|
|
1328
|
+
}
|
|
1329
|
+
};
|
|
1330
|
+
}
|
|
1331
|
+
async function openSubscription(rx, openedPromise, options, packetIds) {
|
|
1332
|
+
let opened;
|
|
1333
|
+
try {
|
|
1334
|
+
opened = await openedPromise;
|
|
1335
|
+
} catch (error) {
|
|
1336
|
+
throw new MulticastError("subscription-failed", "MulticastReceiver did not open", error);
|
|
1337
|
+
}
|
|
1338
|
+
if (rx.integrityScheme !== INTEGRITY_SCHEME) {
|
|
1339
|
+
await rx.close();
|
|
1340
|
+
throw unsupported(`integrity scheme ${String(rx.integrityScheme)} is not ${INTEGRITY_SCHEME}`);
|
|
1341
|
+
}
|
|
1342
|
+
const events = new EventTarget();
|
|
1343
|
+
let state = "connected";
|
|
1344
|
+
let filter = packetIds?.length ? new Set(packetIds) : null;
|
|
1345
|
+
let closing = false;
|
|
1346
|
+
const setState = (next) => {
|
|
1347
|
+
if (state === next)
|
|
1348
|
+
return;
|
|
1349
|
+
state = next;
|
|
1350
|
+
events.dispatchEvent(new CustomEvent("state", { detail: next }));
|
|
1351
|
+
};
|
|
1352
|
+
const sourceAddress = options.sourceAddress;
|
|
1353
|
+
const subscription = {
|
|
1354
|
+
id: `${options.sourceAddress}|${options.groupAddress}|${options.localPort}`,
|
|
1355
|
+
get state() {
|
|
1356
|
+
return state;
|
|
1357
|
+
},
|
|
1358
|
+
delivery: "datagram",
|
|
1359
|
+
eventTypes: Object.freeze(["bytes", "packets", "state", "error"]),
|
|
1360
|
+
setPacketIds(ids) {
|
|
1361
|
+
filter = ids.length ? new Set(ids) : null;
|
|
1362
|
+
},
|
|
1363
|
+
addEventListener: events.addEventListener.bind(events),
|
|
1364
|
+
removeEventListener: events.removeEventListener.bind(events),
|
|
1365
|
+
async unsubscribe() {
|
|
1366
|
+
closing = true;
|
|
1367
|
+
await rx.close();
|
|
1368
|
+
setState("closed");
|
|
1369
|
+
}
|
|
1370
|
+
};
|
|
1371
|
+
void (async () => {
|
|
1372
|
+
const reader = opened.readable.getReader();
|
|
1373
|
+
try {
|
|
1374
|
+
for (; ; ) {
|
|
1375
|
+
const { value, done } = await reader.read();
|
|
1376
|
+
if (done)
|
|
1377
|
+
break;
|
|
1378
|
+
const packets = [];
|
|
1379
|
+
for (const data of datagramsOf(value)) {
|
|
1380
|
+
if (filter !== null) {
|
|
1381
|
+
const id = readMMTPPacketId(data);
|
|
1382
|
+
if (id === null || !filter.has(id))
|
|
1383
|
+
continue;
|
|
1384
|
+
}
|
|
1385
|
+
const copy = data.slice().buffer;
|
|
1386
|
+
packets.push(copy);
|
|
1387
|
+
events.dispatchEvent(Object.assign(new CustomEvent("bytes", { detail: copy }), { sourceAddress }));
|
|
1388
|
+
}
|
|
1389
|
+
if (packets.length > 0)
|
|
1390
|
+
events.dispatchEvent(new CustomEvent("packets", { detail: packets }));
|
|
1391
|
+
}
|
|
1392
|
+
} catch {
|
|
1393
|
+
}
|
|
1394
|
+
})();
|
|
1395
|
+
void rx.closed.then((value) => {
|
|
1396
|
+
const reason = reasonOf(value);
|
|
1397
|
+
if (!closing) {
|
|
1398
|
+
if (reason === "consent-withdrawn") {
|
|
1399
|
+
events.dispatchEvent(new CustomEvent("error", {
|
|
1400
|
+
detail: new MulticastError("origin-not-trusted", "multicast consent withdrawn")
|
|
1401
|
+
}));
|
|
1402
|
+
} else if (reason === "oversubscribed" || reason === "network") {
|
|
1403
|
+
events.dispatchEvent(new CustomEvent("error", {
|
|
1404
|
+
detail: new MulticastError("subscription-failed", `MulticastReceiver closed: ${reason}`)
|
|
1405
|
+
}));
|
|
1406
|
+
}
|
|
1407
|
+
}
|
|
1408
|
+
setState("closed");
|
|
1409
|
+
}, (error) => {
|
|
1410
|
+
if (!closing) {
|
|
1411
|
+
events.dispatchEvent(new CustomEvent("error", {
|
|
1412
|
+
detail: new MulticastError("subscription-failed", "MulticastReceiver failed", error)
|
|
1413
|
+
}));
|
|
1414
|
+
}
|
|
1415
|
+
setState("closed");
|
|
1416
|
+
});
|
|
1417
|
+
return subscription;
|
|
1418
|
+
}
|
|
1419
|
+
|
|
1199
1420
|
// node_modules/@blockcast/mmt-transport/dist/moqt-priority.js
|
|
1200
1421
|
var MAX_MOQT_PRIORITY = 255;
|
|
1201
1422
|
function moqtPriority(value, field) {
|
|
@@ -1238,6 +1459,7 @@ var MOQT_PUBLISHER_PRIORITY = Object.freeze({
|
|
|
1238
1459
|
var AMTGatewayManager = class {
|
|
1239
1460
|
subscriptions = /* @__PURE__ */ new Map();
|
|
1240
1461
|
messageHandler;
|
|
1462
|
+
messageListenerRegistered = false;
|
|
1241
1463
|
pendingPackets = /* @__PURE__ */ new Map();
|
|
1242
1464
|
constructor() {
|
|
1243
1465
|
this.messageHandler = (event) => {
|
|
@@ -1251,12 +1473,14 @@ var AMTGatewayManager = class {
|
|
|
1251
1473
|
console.log(`[AMT SW Debug] ${data.message}`);
|
|
1252
1474
|
}
|
|
1253
1475
|
};
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
console.warn("[AMT] Service worker not available");
|
|
1476
|
+
}
|
|
1477
|
+
ensureMessageListener() {
|
|
1478
|
+
if (this.messageListenerRegistered || typeof navigator === "undefined" || !navigator.serviceWorker || !this.messageHandler) {
|
|
1479
|
+
return;
|
|
1259
1480
|
}
|
|
1481
|
+
navigator.serviceWorker.addEventListener("message", this.messageHandler);
|
|
1482
|
+
this.messageListenerRegistered = true;
|
|
1483
|
+
console.log("[AMT] Registered service worker message handler");
|
|
1260
1484
|
}
|
|
1261
1485
|
/**
|
|
1262
1486
|
* Subscribe via AMT tunnel
|
|
@@ -1266,6 +1490,7 @@ var AMTGatewayManager = class {
|
|
|
1266
1490
|
if (config.protected) {
|
|
1267
1491
|
throw new Error("AMTGatewayManager refuses a protected join: it reports no per-datagram sender (multicast-02 7.2.7)");
|
|
1268
1492
|
}
|
|
1493
|
+
this.ensureMessageListener();
|
|
1269
1494
|
const keyStr = this.getKeyString(key);
|
|
1270
1495
|
if (this.subscriptions.has(keyStr)) {
|
|
1271
1496
|
console.log(`[AMT] Reusing existing subscription to ${keyStr}`);
|
|
@@ -1381,8 +1606,9 @@ var AMTGatewayManager = class {
|
|
|
1381
1606
|
* Cleanup on destroy
|
|
1382
1607
|
*/
|
|
1383
1608
|
destroy() {
|
|
1384
|
-
if (this.messageHandler && typeof navigator !== "undefined" && navigator.serviceWorker) {
|
|
1609
|
+
if (this.messageListenerRegistered && this.messageHandler && typeof navigator !== "undefined" && navigator.serviceWorker) {
|
|
1385
1610
|
navigator.serviceWorker.removeEventListener("message", this.messageHandler);
|
|
1611
|
+
this.messageListenerRegistered = false;
|
|
1386
1612
|
}
|
|
1387
1613
|
const handles = Array.from(this.subscriptions.keys());
|
|
1388
1614
|
for (const handle of handles) {
|
|
@@ -1402,19 +1628,19 @@ var AMTGatewayManager = class {
|
|
|
1402
1628
|
var amtGatewayManager = new AMTGatewayManager();
|
|
1403
1629
|
|
|
1404
1630
|
// ../mmt-base/dist/mmtp.js
|
|
1405
|
-
var
|
|
1631
|
+
var MMTP_HEADER_SIZE2 = 12;
|
|
1406
1632
|
var MPU_HEADER_SIZE2 = 8;
|
|
1407
1633
|
var MPU_LENGTH_FIELD_SIZE2 = 2;
|
|
1408
1634
|
var MPU_HEADER_REMAINDER_SIZE2 = MPU_HEADER_SIZE2 - MPU_LENGTH_FIELD_SIZE2;
|
|
1409
1635
|
var MMTP_SIGNALING_PACKET_ID2 = 0;
|
|
1410
1636
|
var MMTP_PACKET_ID_MAX2 = 65535;
|
|
1411
|
-
function
|
|
1412
|
-
if (buffer.length <
|
|
1637
|
+
function readMMTPPacketId2(buffer) {
|
|
1638
|
+
if (buffer.length < MMTP_HEADER_SIZE2)
|
|
1413
1639
|
return null;
|
|
1414
1640
|
const flags = buffer[0];
|
|
1415
1641
|
if ((flags >> 6 & 3) !== 0)
|
|
1416
1642
|
return null;
|
|
1417
|
-
let offset =
|
|
1643
|
+
let offset = MMTP_HEADER_SIZE2;
|
|
1418
1644
|
if ((flags & 32) !== 0) {
|
|
1419
1645
|
if (offset + 4 > buffer.length)
|
|
1420
1646
|
return null;
|
|
@@ -1544,11 +1770,8 @@ function providerErrorOf(error) {
|
|
|
1544
1770
|
return Object.freeze(typeof code === "string" ? { name, message, code } : { name, message });
|
|
1545
1771
|
}
|
|
1546
1772
|
var MAX_TRACKED_DROPPED_PIDS = 16;
|
|
1547
|
-
function getMulticastGlobals() {
|
|
1548
|
-
return globalThis;
|
|
1549
|
-
}
|
|
1550
1773
|
function hasMulticastGateway() {
|
|
1551
|
-
return typeof
|
|
1774
|
+
return typeof resolveMulticastGateway()?.subscribe === "function";
|
|
1552
1775
|
}
|
|
1553
1776
|
function senderOf(event) {
|
|
1554
1777
|
const sourceAddress = event.sourceAddress;
|
|
@@ -1640,6 +1863,9 @@ var MulticastTransport = class {
|
|
|
1640
1863
|
// listener closure, so an in-place admission change (setContext) applies
|
|
1641
1864
|
// from the next packet on without rejoining.
|
|
1642
1865
|
#context = void 0;
|
|
1866
|
+
#deliveredContext = void 0;
|
|
1867
|
+
/** The live join's gateway, when it is the user agent's MulticastReceiver provider. */
|
|
1868
|
+
#userAgentGateway = void 0;
|
|
1643
1869
|
// The live join's provider-side filter. An in-place widening must reach it,
|
|
1644
1870
|
// or the provider never delivers the new ID; null without a live join.
|
|
1645
1871
|
#providerFilter = null;
|
|
@@ -1676,7 +1902,7 @@ var MulticastTransport = class {
|
|
|
1676
1902
|
this.#dataPlaneLive = false;
|
|
1677
1903
|
this.#sender = void 0;
|
|
1678
1904
|
if (this.#disposed) return this.#declined(generation, "disposed");
|
|
1679
|
-
const gateway = this.#gateway ??
|
|
1905
|
+
const gateway = this.#gateway ?? resolveMulticastGateway();
|
|
1680
1906
|
if (typeof gateway?.subscribe !== "function") {
|
|
1681
1907
|
console.warn("[MulticastTransport] Multicast API not available");
|
|
1682
1908
|
return this.#declined(generation, "unavailable");
|
|
@@ -1692,15 +1918,16 @@ var MulticastTransport = class {
|
|
|
1692
1918
|
console.log(
|
|
1693
1919
|
`[MulticastTransport] window.multicast.subscribe(${config.sourceAddress ?? config.senderAddress ?? "*"}, ${config.groupAddress}, ${config.port})`
|
|
1694
1920
|
);
|
|
1921
|
+
const userAgent = isUserAgentVerifiedGateway(gateway);
|
|
1695
1922
|
const subscribeConfig = toWindowMulticastSubscribeConfig({
|
|
1696
1923
|
source: config.sourceAddress,
|
|
1697
1924
|
senderAddress: config.senderAddress,
|
|
1698
1925
|
group: config.groupAddress,
|
|
1699
1926
|
port: config.port,
|
|
1700
|
-
mode: config.mode,
|
|
1701
|
-
amtRelay: config.amtRelay,
|
|
1702
|
-
amtRelayPort: config.amtRelayPort,
|
|
1703
|
-
amtDiscovery: config.amtDiscovery,
|
|
1927
|
+
mode: userAgent ? "native" : config.mode,
|
|
1928
|
+
amtRelay: userAgent ? void 0 : config.amtRelay,
|
|
1929
|
+
amtRelayPort: userAgent ? void 0 : config.amtRelayPort,
|
|
1930
|
+
amtDiscovery: userAgent ? void 0 : config.amtDiscovery,
|
|
1704
1931
|
packetIds: config.packetIds,
|
|
1705
1932
|
tracks: config.tracks,
|
|
1706
1933
|
atsc3: config.atsc3
|
|
@@ -1746,7 +1973,8 @@ var MulticastTransport = class {
|
|
|
1746
1973
|
acknowledgedUpdate: 0,
|
|
1747
1974
|
inFlight: 0
|
|
1748
1975
|
};
|
|
1749
|
-
this.#
|
|
1976
|
+
this.#userAgentGateway = userAgent ? gateway : void 0;
|
|
1977
|
+
this.#setContext(context);
|
|
1750
1978
|
if (packetIds) {
|
|
1751
1979
|
for (const packetId of packetIds) {
|
|
1752
1980
|
if (!this.#acceptedBytesByPacketId.has(packetId)) {
|
|
@@ -1754,7 +1982,7 @@ var MulticastTransport = class {
|
|
|
1754
1982
|
}
|
|
1755
1983
|
}
|
|
1756
1984
|
}
|
|
1757
|
-
this.#resolvedTransport = subscribeConfig.origin === "amt" ? "amt" : "native";
|
|
1985
|
+
this.#resolvedTransport = userAgent ? "user-agent" : subscribeConfig.origin === "amt" ? "amt" : "native";
|
|
1758
1986
|
const delivery = subscription.delivery ?? "datagram";
|
|
1759
1987
|
if (delivery !== "datagram" && delivery !== "ordered-relay") {
|
|
1760
1988
|
throw new Error(
|
|
@@ -1835,7 +2063,7 @@ var MulticastTransport = class {
|
|
|
1835
2063
|
}
|
|
1836
2064
|
if (!this.#acceptPacket(packet, sourceAddress)) return false;
|
|
1837
2065
|
const liveness = !this.#isRecordCandidate(packet);
|
|
1838
|
-
this.#onPacket(packet, this.#
|
|
2066
|
+
this.#onPacket(packet, this.#deliveredContext);
|
|
1839
2067
|
return liveness;
|
|
1840
2068
|
}
|
|
1841
2069
|
#isRecordCandidate(packet) {
|
|
@@ -2046,8 +2274,10 @@ var MulticastTransport = class {
|
|
|
2046
2274
|
return this.#subscription !== null;
|
|
2047
2275
|
}
|
|
2048
2276
|
/**
|
|
2049
|
-
*
|
|
2050
|
-
*
|
|
2277
|
+
* The live join's context as the caller gave it (the join's `context`, or
|
|
2278
|
+
* the last setContext), or undefined without a live join. On a native
|
|
2279
|
+
* provider each accepted packet is delivered with a marked copy of it
|
|
2280
|
+
* (`userAgentVerifiedIngress`); this getter never carries the mark.
|
|
2051
2281
|
*/
|
|
2052
2282
|
get context() {
|
|
2053
2283
|
return this.#context;
|
|
@@ -2071,7 +2301,16 @@ var MulticastTransport = class {
|
|
|
2071
2301
|
"[MulticastTransport] setContext needs a live join; join() carries the first context"
|
|
2072
2302
|
);
|
|
2073
2303
|
}
|
|
2304
|
+
this.#setContext(context);
|
|
2305
|
+
}
|
|
2306
|
+
/**
|
|
2307
|
+
* The join's context, and what the subscription delivers with each packet:
|
|
2308
|
+
* marked admitted by the user agent when the gateway is its native
|
|
2309
|
+
* MulticastReceiver provider. feedPacket never marks.
|
|
2310
|
+
*/
|
|
2311
|
+
#setContext(context) {
|
|
2074
2312
|
this.#context = context;
|
|
2313
|
+
this.#deliveredContext = this.#userAgentGateway !== void 0 && typeof context === "object" && context !== null ? userAgentVerifiedIngress(context, this.#userAgentGateway) : context;
|
|
2075
2314
|
}
|
|
2076
2315
|
/**
|
|
2077
2316
|
* Replace the live join's packet-ID allow-list in place, without rejoining.
|
|
@@ -2203,6 +2442,8 @@ var MulticastTransport = class {
|
|
|
2203
2442
|
this.#matchedSource = void 0;
|
|
2204
2443
|
this.#providerFilter = null;
|
|
2205
2444
|
this.#context = void 0;
|
|
2445
|
+
this.#deliveredContext = void 0;
|
|
2446
|
+
this.#userAgentGateway = void 0;
|
|
2206
2447
|
this.#withdrawnPacketIds.clear();
|
|
2207
2448
|
}
|
|
2208
2449
|
/** The ingress filter; an accepted packet is counted here, once. */
|
|
@@ -2224,7 +2465,7 @@ var MulticastTransport = class {
|
|
|
2224
2465
|
this.#countAccepted(packet, null, void 0);
|
|
2225
2466
|
return true;
|
|
2226
2467
|
}
|
|
2227
|
-
const packetId =
|
|
2468
|
+
const packetId = readMMTPPacketId2(packet);
|
|
2228
2469
|
if (packetId === null) {
|
|
2229
2470
|
if (!this.#packetIds) {
|
|
2230
2471
|
this.#countAccepted(packet, null, sourceAddress);
|