moqtail 0.10.0 → 0.10.1
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/client.cjs +66 -34
- package/dist/client.d.cts +24 -1
- package/dist/client.d.ts +24 -1
- package/dist/client.js +66 -34
- package/dist/index.cjs +66 -34
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +66 -34
- package/package.json +1 -1
package/dist/client.cjs
CHANGED
|
@@ -6456,6 +6456,8 @@ var MOQtailClient = class _MOQtailClient {
|
|
|
6456
6456
|
#isDestroyed = false;
|
|
6457
6457
|
/** Internal monotonically increasing client-assigned request id counter (even/odd parity scheme advances by 2). */
|
|
6458
6458
|
#dontUseRequestId = 0n;
|
|
6459
|
+
/** Active early discard policy; undefined means no per-stream deadline is applied. */
|
|
6460
|
+
#earlyDiscardPolicy;
|
|
6459
6461
|
/**
|
|
6460
6462
|
* TODO: onNamespaceAnnounced may be a better name
|
|
6461
6463
|
* Fired when an PUBLISH_NAMESPACE control message is processed for a track namespace.
|
|
@@ -6907,6 +6909,25 @@ var MOQtailClient = class _MOQtailClient {
|
|
|
6907
6909
|
return FullTrackName.tryNew("unknown", `track-${trackAlias}`);
|
|
6908
6910
|
}
|
|
6909
6911
|
}
|
|
6912
|
+
/**
|
|
6913
|
+
* Sets (or replaces) the early discard policy for incoming subgroup streams.
|
|
6914
|
+
*
|
|
6915
|
+
* When set, each incoming subgroup QUIC stream is given a deadline of `subgroupReceiveTimeout` ms to
|
|
6916
|
+
* complete. If the stream has not finished within that window it is cancelled — objects already
|
|
6917
|
+
* delivered to the subscription are kept, but no further objects arrive from that stream.
|
|
6918
|
+
*
|
|
6919
|
+
* The policy takes effect on the next stream accepted after this call. Passing a new config
|
|
6920
|
+
* replaces the previous one. Pass `undefined` to remove the policy.
|
|
6921
|
+
*
|
|
6922
|
+
* @example
|
|
6923
|
+
* ```ts
|
|
6924
|
+
* client.setEarlyDiscardPolicy({ subgroupReceiveTimeout: 2000 })
|
|
6925
|
+
* ```
|
|
6926
|
+
*/
|
|
6927
|
+
setEarlyDiscardPolicy(config) {
|
|
6928
|
+
this.#ensureActive();
|
|
6929
|
+
this.#earlyDiscardPolicy = config;
|
|
6930
|
+
}
|
|
6910
6931
|
/**
|
|
6911
6932
|
* Gracefully terminates this {@link MOQtailClient} session and releases underlying {@link https://developer.mozilla.org/docs/Web/API/WebTransport | WebTransport} resources.
|
|
6912
6933
|
*
|
|
@@ -7988,43 +8009,54 @@ var MOQtailClient = class _MOQtailClient {
|
|
|
7988
8009
|
if (subscription) {
|
|
7989
8010
|
subscription.streamsAccepted++;
|
|
7990
8011
|
let firstObjectId = null;
|
|
7991
|
-
|
|
7992
|
-
|
|
7993
|
-
|
|
7994
|
-
|
|
7995
|
-
|
|
7996
|
-
|
|
7997
|
-
|
|
7998
|
-
|
|
7999
|
-
|
|
8000
|
-
|
|
8001
|
-
|
|
8002
|
-
|
|
8003
|
-
|
|
8004
|
-
|
|
8005
|
-
|
|
8006
|
-
|
|
8007
|
-
|
|
8008
|
-
|
|
8009
|
-
|
|
8010
|
-
|
|
8011
|
-
|
|
8012
|
+
let subgroupTimeoutId;
|
|
8013
|
+
if (this.#earlyDiscardPolicy?.subgroupReceiveTimeout !== void 0) {
|
|
8014
|
+
subgroupTimeoutId = setTimeout(() => {
|
|
8015
|
+
reader.cancel("early discard: subgroupReceiveTimeout exceeded").catch(() => {
|
|
8016
|
+
});
|
|
8017
|
+
}, this.#earlyDiscardPolicy.subgroupReceiveTimeout);
|
|
8018
|
+
}
|
|
8019
|
+
try {
|
|
8020
|
+
while (true) {
|
|
8021
|
+
const { done, value: nextObject } = await reader.read();
|
|
8022
|
+
if (done) {
|
|
8023
|
+
break;
|
|
8024
|
+
}
|
|
8025
|
+
if (nextObject) {
|
|
8026
|
+
if (nextObject instanceof SubgroupObject) {
|
|
8027
|
+
if (!firstObjectId) {
|
|
8028
|
+
firstObjectId = nextObject.objectId;
|
|
8029
|
+
}
|
|
8030
|
+
let subgroupId = null;
|
|
8031
|
+
if (SubgroupHeaderType.isSubgroupIdZero(header.type)) {
|
|
8032
|
+
subgroupId = 0n;
|
|
8033
|
+
} else if (SubgroupHeaderType.isSubgroupIdFirstObjectId(header.type)) {
|
|
8034
|
+
subgroupId = firstObjectId ?? null;
|
|
8035
|
+
} else if (SubgroupHeaderType.hasExplicitSubgroupId(header.type)) {
|
|
8036
|
+
subgroupId = header.subgroupId ?? null;
|
|
8037
|
+
}
|
|
8038
|
+
const fullTrackName = this.aliasFullTrackNameMap.get(header.trackAlias);
|
|
8039
|
+
if (!fullTrackName) {
|
|
8040
|
+
throw new ProtocolViolationError("MOQtailClient", "No full track name for received track alias");
|
|
8041
|
+
}
|
|
8042
|
+
const moqtObject = MoqtObject.fromSubgroupObject(
|
|
8043
|
+
nextObject,
|
|
8044
|
+
header.groupId,
|
|
8045
|
+
header.publisherPriority,
|
|
8046
|
+
subgroupId,
|
|
8047
|
+
fullTrackName
|
|
8048
|
+
);
|
|
8049
|
+
if (!subscription.largestLocation) subscription.largestLocation = moqtObject.location;
|
|
8050
|
+
if (subscription.largestLocation.compare(moqtObject.location) == -1)
|
|
8051
|
+
subscription.largestLocation = moqtObject.location;
|
|
8052
|
+
subscription.controller?.enqueue(moqtObject);
|
|
8053
|
+
continue;
|
|
8012
8054
|
}
|
|
8013
|
-
|
|
8014
|
-
nextObject,
|
|
8015
|
-
header.groupId,
|
|
8016
|
-
header.publisherPriority,
|
|
8017
|
-
subgroupId,
|
|
8018
|
-
fullTrackName
|
|
8019
|
-
);
|
|
8020
|
-
if (!subscription.largestLocation) subscription.largestLocation = moqtObject.location;
|
|
8021
|
-
if (subscription.largestLocation.compare(moqtObject.location) == -1)
|
|
8022
|
-
subscription.largestLocation = moqtObject.location;
|
|
8023
|
-
subscription.controller?.enqueue(moqtObject);
|
|
8024
|
-
continue;
|
|
8055
|
+
throw new ProtocolViolationError("MOQtailClient", "Received fetch object after subgroup header");
|
|
8025
8056
|
}
|
|
8026
|
-
throw new ProtocolViolationError("MOQtailClient", "Received fetch object after subgroup header");
|
|
8027
8057
|
}
|
|
8058
|
+
} finally {
|
|
8059
|
+
if (subgroupTimeoutId !== void 0) clearTimeout(subgroupTimeoutId);
|
|
8028
8060
|
}
|
|
8029
8061
|
if (subscription.expectedStreams && subscription.expectedStreams === subscription.streamsAccepted) {
|
|
8030
8062
|
subscription.controller?.close();
|
package/dist/client.d.cts
CHANGED
|
@@ -799,6 +799,13 @@ type SwitchOptions = {
|
|
|
799
799
|
* })
|
|
800
800
|
* ```
|
|
801
801
|
*/
|
|
802
|
+
/**
|
|
803
|
+
* Configuration for the early discard policy applied to incoming subgroup streams.
|
|
804
|
+
*/
|
|
805
|
+
type EarlyDiscardPolicyConfig = {
|
|
806
|
+
/** Cancel a subgroup QUIC stream if it has not fully completed within this many milliseconds. */
|
|
807
|
+
subgroupReceiveTimeout: number;
|
|
808
|
+
};
|
|
802
809
|
type FetchOptions = {
|
|
803
810
|
/** Request priority (0 = highest, 255 = lowest). Rounded & clamped. */
|
|
804
811
|
priority: number;
|
|
@@ -1277,6 +1284,22 @@ declare class MOQtailClient {
|
|
|
1277
1284
|
* ```
|
|
1278
1285
|
*/
|
|
1279
1286
|
sendDatagram(trackAlias: bigint, object: MoqtObject): Promise<void>;
|
|
1287
|
+
/**
|
|
1288
|
+
* Sets (or replaces) the early discard policy for incoming subgroup streams.
|
|
1289
|
+
*
|
|
1290
|
+
* When set, each incoming subgroup QUIC stream is given a deadline of `subgroupReceiveTimeout` ms to
|
|
1291
|
+
* complete. If the stream has not finished within that window it is cancelled — objects already
|
|
1292
|
+
* delivered to the subscription are kept, but no further objects arrive from that stream.
|
|
1293
|
+
*
|
|
1294
|
+
* The policy takes effect on the next stream accepted after this call. Passing a new config
|
|
1295
|
+
* replaces the previous one. Pass `undefined` to remove the policy.
|
|
1296
|
+
*
|
|
1297
|
+
* @example
|
|
1298
|
+
* ```ts
|
|
1299
|
+
* client.setEarlyDiscardPolicy({ subgroupReceiveTimeout: 2000 })
|
|
1300
|
+
* ```
|
|
1301
|
+
*/
|
|
1302
|
+
setEarlyDiscardPolicy(config: EarlyDiscardPolicyConfig | undefined): void;
|
|
1280
1303
|
/**
|
|
1281
1304
|
* Gracefully terminates this {@link MOQtailClient} session and releases underlying {@link https://developer.mozilla.org/docs/Web/API/WebTransport | WebTransport} resources.
|
|
1282
1305
|
*
|
|
@@ -1820,4 +1843,4 @@ declare class RecvStream {
|
|
|
1820
1843
|
static new(readStream: ReadableStream<Uint8Array>, partialDataTimeout?: number, onDataReceived?: (data: SubgroupObject | SubgroupHeader | FetchObject | FetchHeader) => void): Promise<RecvStream>;
|
|
1821
1844
|
}
|
|
1822
1845
|
|
|
1823
|
-
export { ControlStream, type FetchOptions, FetchPublication, FetchRequest, HybridTrackSource, type LiveObjectSource, LiveTrackSource, MOQtailClient, type MOQtailClientOptions, type MOQtailRequest, MemoryObjectCache, type ObjectCache, type PastObjectSource, PublishNamespaceRequest, PublishPublication, PublishRequest, RecvDatagramStream, RecvStream, RingBufferObjectCache, SendDatagramStream, SendStream, StaticTrackSource, SubscribeNamespaceRequest, type SubscribeOptions, SubscribePublication, SubscribeRequest, type SubscribeUpdateOptions, type SwitchOptions, type Track, type TrackSource, TrackStatusRequest };
|
|
1846
|
+
export { ControlStream, type EarlyDiscardPolicyConfig, type FetchOptions, FetchPublication, FetchRequest, HybridTrackSource, type LiveObjectSource, LiveTrackSource, MOQtailClient, type MOQtailClientOptions, type MOQtailRequest, MemoryObjectCache, type ObjectCache, type PastObjectSource, PublishNamespaceRequest, PublishPublication, PublishRequest, RecvDatagramStream, RecvStream, RingBufferObjectCache, SendDatagramStream, SendStream, StaticTrackSource, SubscribeNamespaceRequest, type SubscribeOptions, SubscribePublication, SubscribeRequest, type SubscribeUpdateOptions, type SwitchOptions, type Track, type TrackSource, TrackStatusRequest };
|
package/dist/client.d.ts
CHANGED
|
@@ -799,6 +799,13 @@ type SwitchOptions = {
|
|
|
799
799
|
* })
|
|
800
800
|
* ```
|
|
801
801
|
*/
|
|
802
|
+
/**
|
|
803
|
+
* Configuration for the early discard policy applied to incoming subgroup streams.
|
|
804
|
+
*/
|
|
805
|
+
type EarlyDiscardPolicyConfig = {
|
|
806
|
+
/** Cancel a subgroup QUIC stream if it has not fully completed within this many milliseconds. */
|
|
807
|
+
subgroupReceiveTimeout: number;
|
|
808
|
+
};
|
|
802
809
|
type FetchOptions = {
|
|
803
810
|
/** Request priority (0 = highest, 255 = lowest). Rounded & clamped. */
|
|
804
811
|
priority: number;
|
|
@@ -1277,6 +1284,22 @@ declare class MOQtailClient {
|
|
|
1277
1284
|
* ```
|
|
1278
1285
|
*/
|
|
1279
1286
|
sendDatagram(trackAlias: bigint, object: MoqtObject): Promise<void>;
|
|
1287
|
+
/**
|
|
1288
|
+
* Sets (or replaces) the early discard policy for incoming subgroup streams.
|
|
1289
|
+
*
|
|
1290
|
+
* When set, each incoming subgroup QUIC stream is given a deadline of `subgroupReceiveTimeout` ms to
|
|
1291
|
+
* complete. If the stream has not finished within that window it is cancelled — objects already
|
|
1292
|
+
* delivered to the subscription are kept, but no further objects arrive from that stream.
|
|
1293
|
+
*
|
|
1294
|
+
* The policy takes effect on the next stream accepted after this call. Passing a new config
|
|
1295
|
+
* replaces the previous one. Pass `undefined` to remove the policy.
|
|
1296
|
+
*
|
|
1297
|
+
* @example
|
|
1298
|
+
* ```ts
|
|
1299
|
+
* client.setEarlyDiscardPolicy({ subgroupReceiveTimeout: 2000 })
|
|
1300
|
+
* ```
|
|
1301
|
+
*/
|
|
1302
|
+
setEarlyDiscardPolicy(config: EarlyDiscardPolicyConfig | undefined): void;
|
|
1280
1303
|
/**
|
|
1281
1304
|
* Gracefully terminates this {@link MOQtailClient} session and releases underlying {@link https://developer.mozilla.org/docs/Web/API/WebTransport | WebTransport} resources.
|
|
1282
1305
|
*
|
|
@@ -1820,4 +1843,4 @@ declare class RecvStream {
|
|
|
1820
1843
|
static new(readStream: ReadableStream<Uint8Array>, partialDataTimeout?: number, onDataReceived?: (data: SubgroupObject | SubgroupHeader | FetchObject | FetchHeader) => void): Promise<RecvStream>;
|
|
1821
1844
|
}
|
|
1822
1845
|
|
|
1823
|
-
export { ControlStream, type FetchOptions, FetchPublication, FetchRequest, HybridTrackSource, type LiveObjectSource, LiveTrackSource, MOQtailClient, type MOQtailClientOptions, type MOQtailRequest, MemoryObjectCache, type ObjectCache, type PastObjectSource, PublishNamespaceRequest, PublishPublication, PublishRequest, RecvDatagramStream, RecvStream, RingBufferObjectCache, SendDatagramStream, SendStream, StaticTrackSource, SubscribeNamespaceRequest, type SubscribeOptions, SubscribePublication, SubscribeRequest, type SubscribeUpdateOptions, type SwitchOptions, type Track, type TrackSource, TrackStatusRequest };
|
|
1846
|
+
export { ControlStream, type EarlyDiscardPolicyConfig, type FetchOptions, FetchPublication, FetchRequest, HybridTrackSource, type LiveObjectSource, LiveTrackSource, MOQtailClient, type MOQtailClientOptions, type MOQtailRequest, MemoryObjectCache, type ObjectCache, type PastObjectSource, PublishNamespaceRequest, PublishPublication, PublishRequest, RecvDatagramStream, RecvStream, RingBufferObjectCache, SendDatagramStream, SendStream, StaticTrackSource, SubscribeNamespaceRequest, type SubscribeOptions, SubscribePublication, SubscribeRequest, type SubscribeUpdateOptions, type SwitchOptions, type Track, type TrackSource, TrackStatusRequest };
|
package/dist/client.js
CHANGED
|
@@ -6454,6 +6454,8 @@ var MOQtailClient = class _MOQtailClient {
|
|
|
6454
6454
|
#isDestroyed = false;
|
|
6455
6455
|
/** Internal monotonically increasing client-assigned request id counter (even/odd parity scheme advances by 2). */
|
|
6456
6456
|
#dontUseRequestId = 0n;
|
|
6457
|
+
/** Active early discard policy; undefined means no per-stream deadline is applied. */
|
|
6458
|
+
#earlyDiscardPolicy;
|
|
6457
6459
|
/**
|
|
6458
6460
|
* TODO: onNamespaceAnnounced may be a better name
|
|
6459
6461
|
* Fired when an PUBLISH_NAMESPACE control message is processed for a track namespace.
|
|
@@ -6905,6 +6907,25 @@ var MOQtailClient = class _MOQtailClient {
|
|
|
6905
6907
|
return FullTrackName.tryNew("unknown", `track-${trackAlias}`);
|
|
6906
6908
|
}
|
|
6907
6909
|
}
|
|
6910
|
+
/**
|
|
6911
|
+
* Sets (or replaces) the early discard policy for incoming subgroup streams.
|
|
6912
|
+
*
|
|
6913
|
+
* When set, each incoming subgroup QUIC stream is given a deadline of `subgroupReceiveTimeout` ms to
|
|
6914
|
+
* complete. If the stream has not finished within that window it is cancelled — objects already
|
|
6915
|
+
* delivered to the subscription are kept, but no further objects arrive from that stream.
|
|
6916
|
+
*
|
|
6917
|
+
* The policy takes effect on the next stream accepted after this call. Passing a new config
|
|
6918
|
+
* replaces the previous one. Pass `undefined` to remove the policy.
|
|
6919
|
+
*
|
|
6920
|
+
* @example
|
|
6921
|
+
* ```ts
|
|
6922
|
+
* client.setEarlyDiscardPolicy({ subgroupReceiveTimeout: 2000 })
|
|
6923
|
+
* ```
|
|
6924
|
+
*/
|
|
6925
|
+
setEarlyDiscardPolicy(config) {
|
|
6926
|
+
this.#ensureActive();
|
|
6927
|
+
this.#earlyDiscardPolicy = config;
|
|
6928
|
+
}
|
|
6908
6929
|
/**
|
|
6909
6930
|
* Gracefully terminates this {@link MOQtailClient} session and releases underlying {@link https://developer.mozilla.org/docs/Web/API/WebTransport | WebTransport} resources.
|
|
6910
6931
|
*
|
|
@@ -7986,43 +8007,54 @@ var MOQtailClient = class _MOQtailClient {
|
|
|
7986
8007
|
if (subscription) {
|
|
7987
8008
|
subscription.streamsAccepted++;
|
|
7988
8009
|
let firstObjectId = null;
|
|
7989
|
-
|
|
7990
|
-
|
|
7991
|
-
|
|
7992
|
-
|
|
7993
|
-
|
|
7994
|
-
|
|
7995
|
-
|
|
7996
|
-
|
|
7997
|
-
|
|
7998
|
-
|
|
7999
|
-
|
|
8000
|
-
|
|
8001
|
-
|
|
8002
|
-
|
|
8003
|
-
|
|
8004
|
-
|
|
8005
|
-
|
|
8006
|
-
|
|
8007
|
-
|
|
8008
|
-
|
|
8009
|
-
|
|
8010
|
+
let subgroupTimeoutId;
|
|
8011
|
+
if (this.#earlyDiscardPolicy?.subgroupReceiveTimeout !== void 0) {
|
|
8012
|
+
subgroupTimeoutId = setTimeout(() => {
|
|
8013
|
+
reader.cancel("early discard: subgroupReceiveTimeout exceeded").catch(() => {
|
|
8014
|
+
});
|
|
8015
|
+
}, this.#earlyDiscardPolicy.subgroupReceiveTimeout);
|
|
8016
|
+
}
|
|
8017
|
+
try {
|
|
8018
|
+
while (true) {
|
|
8019
|
+
const { done, value: nextObject } = await reader.read();
|
|
8020
|
+
if (done) {
|
|
8021
|
+
break;
|
|
8022
|
+
}
|
|
8023
|
+
if (nextObject) {
|
|
8024
|
+
if (nextObject instanceof SubgroupObject) {
|
|
8025
|
+
if (!firstObjectId) {
|
|
8026
|
+
firstObjectId = nextObject.objectId;
|
|
8027
|
+
}
|
|
8028
|
+
let subgroupId = null;
|
|
8029
|
+
if (SubgroupHeaderType.isSubgroupIdZero(header.type)) {
|
|
8030
|
+
subgroupId = 0n;
|
|
8031
|
+
} else if (SubgroupHeaderType.isSubgroupIdFirstObjectId(header.type)) {
|
|
8032
|
+
subgroupId = firstObjectId ?? null;
|
|
8033
|
+
} else if (SubgroupHeaderType.hasExplicitSubgroupId(header.type)) {
|
|
8034
|
+
subgroupId = header.subgroupId ?? null;
|
|
8035
|
+
}
|
|
8036
|
+
const fullTrackName = this.aliasFullTrackNameMap.get(header.trackAlias);
|
|
8037
|
+
if (!fullTrackName) {
|
|
8038
|
+
throw new ProtocolViolationError("MOQtailClient", "No full track name for received track alias");
|
|
8039
|
+
}
|
|
8040
|
+
const moqtObject = MoqtObject.fromSubgroupObject(
|
|
8041
|
+
nextObject,
|
|
8042
|
+
header.groupId,
|
|
8043
|
+
header.publisherPriority,
|
|
8044
|
+
subgroupId,
|
|
8045
|
+
fullTrackName
|
|
8046
|
+
);
|
|
8047
|
+
if (!subscription.largestLocation) subscription.largestLocation = moqtObject.location;
|
|
8048
|
+
if (subscription.largestLocation.compare(moqtObject.location) == -1)
|
|
8049
|
+
subscription.largestLocation = moqtObject.location;
|
|
8050
|
+
subscription.controller?.enqueue(moqtObject);
|
|
8051
|
+
continue;
|
|
8010
8052
|
}
|
|
8011
|
-
|
|
8012
|
-
nextObject,
|
|
8013
|
-
header.groupId,
|
|
8014
|
-
header.publisherPriority,
|
|
8015
|
-
subgroupId,
|
|
8016
|
-
fullTrackName
|
|
8017
|
-
);
|
|
8018
|
-
if (!subscription.largestLocation) subscription.largestLocation = moqtObject.location;
|
|
8019
|
-
if (subscription.largestLocation.compare(moqtObject.location) == -1)
|
|
8020
|
-
subscription.largestLocation = moqtObject.location;
|
|
8021
|
-
subscription.controller?.enqueue(moqtObject);
|
|
8022
|
-
continue;
|
|
8053
|
+
throw new ProtocolViolationError("MOQtailClient", "Received fetch object after subgroup header");
|
|
8023
8054
|
}
|
|
8024
|
-
throw new ProtocolViolationError("MOQtailClient", "Received fetch object after subgroup header");
|
|
8025
8055
|
}
|
|
8056
|
+
} finally {
|
|
8057
|
+
if (subgroupTimeoutId !== void 0) clearTimeout(subgroupTimeoutId);
|
|
8026
8058
|
}
|
|
8027
8059
|
if (subscription.expectedStreams && subscription.expectedStreams === subscription.streamsAccepted) {
|
|
8028
8060
|
subscription.controller?.close();
|
package/dist/index.cjs
CHANGED
|
@@ -6950,6 +6950,8 @@ var MOQtailClient = class _MOQtailClient {
|
|
|
6950
6950
|
#isDestroyed = false;
|
|
6951
6951
|
/** Internal monotonically increasing client-assigned request id counter (even/odd parity scheme advances by 2). */
|
|
6952
6952
|
#dontUseRequestId = 0n;
|
|
6953
|
+
/** Active early discard policy; undefined means no per-stream deadline is applied. */
|
|
6954
|
+
#earlyDiscardPolicy;
|
|
6953
6955
|
/**
|
|
6954
6956
|
* TODO: onNamespaceAnnounced may be a better name
|
|
6955
6957
|
* Fired when an PUBLISH_NAMESPACE control message is processed for a track namespace.
|
|
@@ -7401,6 +7403,25 @@ var MOQtailClient = class _MOQtailClient {
|
|
|
7401
7403
|
return FullTrackName.tryNew("unknown", `track-${trackAlias}`);
|
|
7402
7404
|
}
|
|
7403
7405
|
}
|
|
7406
|
+
/**
|
|
7407
|
+
* Sets (or replaces) the early discard policy for incoming subgroup streams.
|
|
7408
|
+
*
|
|
7409
|
+
* When set, each incoming subgroup QUIC stream is given a deadline of `subgroupReceiveTimeout` ms to
|
|
7410
|
+
* complete. If the stream has not finished within that window it is cancelled — objects already
|
|
7411
|
+
* delivered to the subscription are kept, but no further objects arrive from that stream.
|
|
7412
|
+
*
|
|
7413
|
+
* The policy takes effect on the next stream accepted after this call. Passing a new config
|
|
7414
|
+
* replaces the previous one. Pass `undefined` to remove the policy.
|
|
7415
|
+
*
|
|
7416
|
+
* @example
|
|
7417
|
+
* ```ts
|
|
7418
|
+
* client.setEarlyDiscardPolicy({ subgroupReceiveTimeout: 2000 })
|
|
7419
|
+
* ```
|
|
7420
|
+
*/
|
|
7421
|
+
setEarlyDiscardPolicy(config) {
|
|
7422
|
+
this.#ensureActive();
|
|
7423
|
+
this.#earlyDiscardPolicy = config;
|
|
7424
|
+
}
|
|
7404
7425
|
/**
|
|
7405
7426
|
* Gracefully terminates this {@link MOQtailClient} session and releases underlying {@link https://developer.mozilla.org/docs/Web/API/WebTransport | WebTransport} resources.
|
|
7406
7427
|
*
|
|
@@ -8482,43 +8503,54 @@ var MOQtailClient = class _MOQtailClient {
|
|
|
8482
8503
|
if (subscription) {
|
|
8483
8504
|
subscription.streamsAccepted++;
|
|
8484
8505
|
let firstObjectId = null;
|
|
8485
|
-
|
|
8486
|
-
|
|
8487
|
-
|
|
8488
|
-
|
|
8489
|
-
|
|
8490
|
-
|
|
8491
|
-
|
|
8492
|
-
|
|
8493
|
-
|
|
8494
|
-
|
|
8495
|
-
|
|
8496
|
-
|
|
8497
|
-
|
|
8498
|
-
|
|
8499
|
-
|
|
8500
|
-
|
|
8501
|
-
|
|
8502
|
-
|
|
8503
|
-
|
|
8504
|
-
|
|
8505
|
-
|
|
8506
|
+
let subgroupTimeoutId;
|
|
8507
|
+
if (this.#earlyDiscardPolicy?.subgroupReceiveTimeout !== void 0) {
|
|
8508
|
+
subgroupTimeoutId = setTimeout(() => {
|
|
8509
|
+
reader.cancel("early discard: subgroupReceiveTimeout exceeded").catch(() => {
|
|
8510
|
+
});
|
|
8511
|
+
}, this.#earlyDiscardPolicy.subgroupReceiveTimeout);
|
|
8512
|
+
}
|
|
8513
|
+
try {
|
|
8514
|
+
while (true) {
|
|
8515
|
+
const { done, value: nextObject } = await reader.read();
|
|
8516
|
+
if (done) {
|
|
8517
|
+
break;
|
|
8518
|
+
}
|
|
8519
|
+
if (nextObject) {
|
|
8520
|
+
if (nextObject instanceof SubgroupObject) {
|
|
8521
|
+
if (!firstObjectId) {
|
|
8522
|
+
firstObjectId = nextObject.objectId;
|
|
8523
|
+
}
|
|
8524
|
+
let subgroupId = null;
|
|
8525
|
+
if (exports.SubgroupHeaderType.isSubgroupIdZero(header.type)) {
|
|
8526
|
+
subgroupId = 0n;
|
|
8527
|
+
} else if (exports.SubgroupHeaderType.isSubgroupIdFirstObjectId(header.type)) {
|
|
8528
|
+
subgroupId = firstObjectId ?? null;
|
|
8529
|
+
} else if (exports.SubgroupHeaderType.hasExplicitSubgroupId(header.type)) {
|
|
8530
|
+
subgroupId = header.subgroupId ?? null;
|
|
8531
|
+
}
|
|
8532
|
+
const fullTrackName = this.aliasFullTrackNameMap.get(header.trackAlias);
|
|
8533
|
+
if (!fullTrackName) {
|
|
8534
|
+
throw new ProtocolViolationError("MOQtailClient", "No full track name for received track alias");
|
|
8535
|
+
}
|
|
8536
|
+
const moqtObject = MoqtObject.fromSubgroupObject(
|
|
8537
|
+
nextObject,
|
|
8538
|
+
header.groupId,
|
|
8539
|
+
header.publisherPriority,
|
|
8540
|
+
subgroupId,
|
|
8541
|
+
fullTrackName
|
|
8542
|
+
);
|
|
8543
|
+
if (!subscription.largestLocation) subscription.largestLocation = moqtObject.location;
|
|
8544
|
+
if (subscription.largestLocation.compare(moqtObject.location) == -1)
|
|
8545
|
+
subscription.largestLocation = moqtObject.location;
|
|
8546
|
+
subscription.controller?.enqueue(moqtObject);
|
|
8547
|
+
continue;
|
|
8506
8548
|
}
|
|
8507
|
-
|
|
8508
|
-
nextObject,
|
|
8509
|
-
header.groupId,
|
|
8510
|
-
header.publisherPriority,
|
|
8511
|
-
subgroupId,
|
|
8512
|
-
fullTrackName
|
|
8513
|
-
);
|
|
8514
|
-
if (!subscription.largestLocation) subscription.largestLocation = moqtObject.location;
|
|
8515
|
-
if (subscription.largestLocation.compare(moqtObject.location) == -1)
|
|
8516
|
-
subscription.largestLocation = moqtObject.location;
|
|
8517
|
-
subscription.controller?.enqueue(moqtObject);
|
|
8518
|
-
continue;
|
|
8549
|
+
throw new ProtocolViolationError("MOQtailClient", "Received fetch object after subgroup header");
|
|
8519
8550
|
}
|
|
8520
|
-
throw new ProtocolViolationError("MOQtailClient", "Received fetch object after subgroup header");
|
|
8521
8551
|
}
|
|
8552
|
+
} finally {
|
|
8553
|
+
if (subgroupTimeoutId !== void 0) clearTimeout(subgroupTimeoutId);
|
|
8522
8554
|
}
|
|
8523
8555
|
if (subscription.expectedStreams && subscription.expectedStreams === subscription.streamsAccepted) {
|
|
8524
8556
|
subscription.controller?.close();
|
package/dist/index.d.cts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { ControlStream, FetchOptions, FetchPublication, FetchRequest, HybridTrackSource, LiveObjectSource, LiveTrackSource, MOQtailClient, MOQtailClientOptions, MOQtailRequest, MemoryObjectCache, ObjectCache, PastObjectSource, PublishNamespaceRequest, PublishPublication, PublishRequest, RecvDatagramStream, RecvStream, RingBufferObjectCache, SendDatagramStream, SendStream, StaticTrackSource, SubscribeNamespaceRequest, SubscribeOptions, SubscribePublication, SubscribeRequest, SubscribeUpdateOptions, SwitchOptions, Track, TrackSource, TrackStatusRequest } from './client.cjs';
|
|
1
|
+
export { ControlStream, EarlyDiscardPolicyConfig, FetchOptions, FetchPublication, FetchRequest, HybridTrackSource, LiveObjectSource, LiveTrackSource, MOQtailClient, MOQtailClientOptions, MOQtailRequest, MemoryObjectCache, ObjectCache, PastObjectSource, PublishNamespaceRequest, PublishPublication, PublishRequest, RecvDatagramStream, RecvStream, RingBufferObjectCache, SendDatagramStream, SendStream, StaticTrackSource, SubscribeNamespaceRequest, SubscribeOptions, SubscribePublication, SubscribeRequest, SubscribeUpdateOptions, SwitchOptions, Track, TrackSource, TrackStatusRequest } from './client.cjs';
|
|
2
2
|
export { AudioLevel, CMSF, CMSFCatalog, CMSFTrack, CaptureTimestamp, CastingError, ExtensionHeader, ExtensionHeaders, ImmutableExtensionsObjectExtension, InternalError, InvalidTypeError, InvalidUTF8Error, KeyValueFormattingError, LengthExceedsMaxError, MOQtailError, NotEnoughBytesError, ObjectExtension, PriorGroupIdGapExtension, PriorObjectIdGapExtension, ProtocolViolationError, RequestIdError, Switch, TerminationCode, TerminationError, TimeoutError, TrackNameError, UnknownObjectExtension, VarIntOverflowError, VideoConfig, VideoFrameMarking } from './model.cjs';
|
|
3
3
|
export { A as AuthTokenVariant, a as AuthorizationToken, B as BaseByteBuffer, b as ByteBuffer, C as ClientSetup, c as ControlMessage, d as ControlMessageType, D as Datagram, e as DefaultPublisherGroupOrderExtension, f as DefaultPublisherPriorityExtension, g as DeliveryTimeout, h as DeliveryTimeoutExtension, i as DynamicGroupsExtension, E as EndOfRangeKind, j as Expires, F as Fetch, k as FetchCancel, l as FetchHeader, m as FetchHeaderType, n as FetchObject, o as FetchObjectContext, p as FetchOk, q as FetchType, r as FilterType, s as Forward, t as FrozenByteBuffer, u as FullTrackName, G as GoAway, v as GroupOrder, w as GroupOrderParam, H as Header, I as ImmutableExtensionsExtension, K as KeyValuePair, L as LOCHeaderExtensionId, x as LargestObject, y as Location, M as MAX_FULL_TRACK_NAME_LENGTH, z as MAX_NAMESPACE_TUPLE_COUNT, J as MAX_REASON_PHRASE_LEN, N as MaxAuthTokenCacheSize, O as MaxCacheDurationExtension, P as MaxRequestId, Q as MaxRequestIdParameter, R as MessageParameter, S as MessageParameterType, T as MessageParameters, U as MoqtObject, V as Namespace, W as NamespaceDone, X as NamespaceSubscribeOptions, Y as NewGroupRequest, Z as ObjectDatagramType, _ as ObjectForwardingPreference, $ as ObjectStatus, a0 as Parameter, a1 as Path, a2 as Publish, a3 as PublishDone, a4 as PublishDoneStatusCode, a5 as PublishNamespace, a6 as PublishNamespaceCancel, a7 as PublishNamespaceDone, a8 as PublishOk, a9 as ReasonPhrase, aa as RequestError, ab as RequestErrorCode, ac as RequestIdMap, ad as RequestOk, ae as RequestUpdate, af as RequestsBlocked, ag as SUPPORTED_VERSIONS, ah as ServerSetup, ai as SetupParameter, aj as SetupParameterType, ak as SetupParameters, al as SubgroupHeader, am as SubgroupHeaderType, an as SubgroupObject, ao as Subscribe, ap as SubscribeNamespace, aq as SubscribeOk, ar as SubscriberPriority, as as SubscriptionFilter, at as TokenAliasType, au as TrackExtension, av as TrackExtensionType, aw as TrackStatus, ax as TrackStatusCode, ay as Tuple, az as TupleField, aA as UnknownTrackExtension, aB as Unsubscribe, aC as UnsubscribeNamespace, aD as applyMessageParameterUpdate, aE as controlMessageTypeFromBigInt, aF as fetchTypeFromBigInt, aG as filterTypeFromBigInt, aH as groupOrderFromNumber, aI as isBytes, aJ as isVarInt, aK as locHeaderExtensionIdFromNumber, aL as messageParameterTypeFromNumber, aM as publishDoneStatusCodeFromBigInt, aN as requestErrorCodeFromBigInt, aO as setupParameterTypeFromNumber, aP as tokenAliasTypeFromNumber, aQ as trackStatusCodeFromBigInt } from './setup_parameter-BOeGq6Mv.cjs';
|
|
4
4
|
export { ClockNormalizer, NetworkTelemetry } from './util.cjs';
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { ControlStream, FetchOptions, FetchPublication, FetchRequest, HybridTrackSource, LiveObjectSource, LiveTrackSource, MOQtailClient, MOQtailClientOptions, MOQtailRequest, MemoryObjectCache, ObjectCache, PastObjectSource, PublishNamespaceRequest, PublishPublication, PublishRequest, RecvDatagramStream, RecvStream, RingBufferObjectCache, SendDatagramStream, SendStream, StaticTrackSource, SubscribeNamespaceRequest, SubscribeOptions, SubscribePublication, SubscribeRequest, SubscribeUpdateOptions, SwitchOptions, Track, TrackSource, TrackStatusRequest } from './client.js';
|
|
1
|
+
export { ControlStream, EarlyDiscardPolicyConfig, FetchOptions, FetchPublication, FetchRequest, HybridTrackSource, LiveObjectSource, LiveTrackSource, MOQtailClient, MOQtailClientOptions, MOQtailRequest, MemoryObjectCache, ObjectCache, PastObjectSource, PublishNamespaceRequest, PublishPublication, PublishRequest, RecvDatagramStream, RecvStream, RingBufferObjectCache, SendDatagramStream, SendStream, StaticTrackSource, SubscribeNamespaceRequest, SubscribeOptions, SubscribePublication, SubscribeRequest, SubscribeUpdateOptions, SwitchOptions, Track, TrackSource, TrackStatusRequest } from './client.js';
|
|
2
2
|
export { AudioLevel, CMSF, CMSFCatalog, CMSFTrack, CaptureTimestamp, CastingError, ExtensionHeader, ExtensionHeaders, ImmutableExtensionsObjectExtension, InternalError, InvalidTypeError, InvalidUTF8Error, KeyValueFormattingError, LengthExceedsMaxError, MOQtailError, NotEnoughBytesError, ObjectExtension, PriorGroupIdGapExtension, PriorObjectIdGapExtension, ProtocolViolationError, RequestIdError, Switch, TerminationCode, TerminationError, TimeoutError, TrackNameError, UnknownObjectExtension, VarIntOverflowError, VideoConfig, VideoFrameMarking } from './model.js';
|
|
3
3
|
export { A as AuthTokenVariant, a as AuthorizationToken, B as BaseByteBuffer, b as ByteBuffer, C as ClientSetup, c as ControlMessage, d as ControlMessageType, D as Datagram, e as DefaultPublisherGroupOrderExtension, f as DefaultPublisherPriorityExtension, g as DeliveryTimeout, h as DeliveryTimeoutExtension, i as DynamicGroupsExtension, E as EndOfRangeKind, j as Expires, F as Fetch, k as FetchCancel, l as FetchHeader, m as FetchHeaderType, n as FetchObject, o as FetchObjectContext, p as FetchOk, q as FetchType, r as FilterType, s as Forward, t as FrozenByteBuffer, u as FullTrackName, G as GoAway, v as GroupOrder, w as GroupOrderParam, H as Header, I as ImmutableExtensionsExtension, K as KeyValuePair, L as LOCHeaderExtensionId, x as LargestObject, y as Location, M as MAX_FULL_TRACK_NAME_LENGTH, z as MAX_NAMESPACE_TUPLE_COUNT, J as MAX_REASON_PHRASE_LEN, N as MaxAuthTokenCacheSize, O as MaxCacheDurationExtension, P as MaxRequestId, Q as MaxRequestIdParameter, R as MessageParameter, S as MessageParameterType, T as MessageParameters, U as MoqtObject, V as Namespace, W as NamespaceDone, X as NamespaceSubscribeOptions, Y as NewGroupRequest, Z as ObjectDatagramType, _ as ObjectForwardingPreference, $ as ObjectStatus, a0 as Parameter, a1 as Path, a2 as Publish, a3 as PublishDone, a4 as PublishDoneStatusCode, a5 as PublishNamespace, a6 as PublishNamespaceCancel, a7 as PublishNamespaceDone, a8 as PublishOk, a9 as ReasonPhrase, aa as RequestError, ab as RequestErrorCode, ac as RequestIdMap, ad as RequestOk, ae as RequestUpdate, af as RequestsBlocked, ag as SUPPORTED_VERSIONS, ah as ServerSetup, ai as SetupParameter, aj as SetupParameterType, ak as SetupParameters, al as SubgroupHeader, am as SubgroupHeaderType, an as SubgroupObject, ao as Subscribe, ap as SubscribeNamespace, aq as SubscribeOk, ar as SubscriberPriority, as as SubscriptionFilter, at as TokenAliasType, au as TrackExtension, av as TrackExtensionType, aw as TrackStatus, ax as TrackStatusCode, ay as Tuple, az as TupleField, aA as UnknownTrackExtension, aB as Unsubscribe, aC as UnsubscribeNamespace, aD as applyMessageParameterUpdate, aE as controlMessageTypeFromBigInt, aF as fetchTypeFromBigInt, aG as filterTypeFromBigInt, aH as groupOrderFromNumber, aI as isBytes, aJ as isVarInt, aK as locHeaderExtensionIdFromNumber, aL as messageParameterTypeFromNumber, aM as publishDoneStatusCodeFromBigInt, aN as requestErrorCodeFromBigInt, aO as setupParameterTypeFromNumber, aP as tokenAliasTypeFromNumber, aQ as trackStatusCodeFromBigInt } from './setup_parameter-BOeGq6Mv.js';
|
|
4
4
|
export { ClockNormalizer, NetworkTelemetry } from './util.js';
|
package/dist/index.js
CHANGED
|
@@ -6948,6 +6948,8 @@ var MOQtailClient = class _MOQtailClient {
|
|
|
6948
6948
|
#isDestroyed = false;
|
|
6949
6949
|
/** Internal monotonically increasing client-assigned request id counter (even/odd parity scheme advances by 2). */
|
|
6950
6950
|
#dontUseRequestId = 0n;
|
|
6951
|
+
/** Active early discard policy; undefined means no per-stream deadline is applied. */
|
|
6952
|
+
#earlyDiscardPolicy;
|
|
6951
6953
|
/**
|
|
6952
6954
|
* TODO: onNamespaceAnnounced may be a better name
|
|
6953
6955
|
* Fired when an PUBLISH_NAMESPACE control message is processed for a track namespace.
|
|
@@ -7399,6 +7401,25 @@ var MOQtailClient = class _MOQtailClient {
|
|
|
7399
7401
|
return FullTrackName.tryNew("unknown", `track-${trackAlias}`);
|
|
7400
7402
|
}
|
|
7401
7403
|
}
|
|
7404
|
+
/**
|
|
7405
|
+
* Sets (or replaces) the early discard policy for incoming subgroup streams.
|
|
7406
|
+
*
|
|
7407
|
+
* When set, each incoming subgroup QUIC stream is given a deadline of `subgroupReceiveTimeout` ms to
|
|
7408
|
+
* complete. If the stream has not finished within that window it is cancelled — objects already
|
|
7409
|
+
* delivered to the subscription are kept, but no further objects arrive from that stream.
|
|
7410
|
+
*
|
|
7411
|
+
* The policy takes effect on the next stream accepted after this call. Passing a new config
|
|
7412
|
+
* replaces the previous one. Pass `undefined` to remove the policy.
|
|
7413
|
+
*
|
|
7414
|
+
* @example
|
|
7415
|
+
* ```ts
|
|
7416
|
+
* client.setEarlyDiscardPolicy({ subgroupReceiveTimeout: 2000 })
|
|
7417
|
+
* ```
|
|
7418
|
+
*/
|
|
7419
|
+
setEarlyDiscardPolicy(config) {
|
|
7420
|
+
this.#ensureActive();
|
|
7421
|
+
this.#earlyDiscardPolicy = config;
|
|
7422
|
+
}
|
|
7402
7423
|
/**
|
|
7403
7424
|
* Gracefully terminates this {@link MOQtailClient} session and releases underlying {@link https://developer.mozilla.org/docs/Web/API/WebTransport | WebTransport} resources.
|
|
7404
7425
|
*
|
|
@@ -8480,43 +8501,54 @@ var MOQtailClient = class _MOQtailClient {
|
|
|
8480
8501
|
if (subscription) {
|
|
8481
8502
|
subscription.streamsAccepted++;
|
|
8482
8503
|
let firstObjectId = null;
|
|
8483
|
-
|
|
8484
|
-
|
|
8485
|
-
|
|
8486
|
-
|
|
8487
|
-
|
|
8488
|
-
|
|
8489
|
-
|
|
8490
|
-
|
|
8491
|
-
|
|
8492
|
-
|
|
8493
|
-
|
|
8494
|
-
|
|
8495
|
-
|
|
8496
|
-
|
|
8497
|
-
|
|
8498
|
-
|
|
8499
|
-
|
|
8500
|
-
|
|
8501
|
-
|
|
8502
|
-
|
|
8503
|
-
|
|
8504
|
+
let subgroupTimeoutId;
|
|
8505
|
+
if (this.#earlyDiscardPolicy?.subgroupReceiveTimeout !== void 0) {
|
|
8506
|
+
subgroupTimeoutId = setTimeout(() => {
|
|
8507
|
+
reader.cancel("early discard: subgroupReceiveTimeout exceeded").catch(() => {
|
|
8508
|
+
});
|
|
8509
|
+
}, this.#earlyDiscardPolicy.subgroupReceiveTimeout);
|
|
8510
|
+
}
|
|
8511
|
+
try {
|
|
8512
|
+
while (true) {
|
|
8513
|
+
const { done, value: nextObject } = await reader.read();
|
|
8514
|
+
if (done) {
|
|
8515
|
+
break;
|
|
8516
|
+
}
|
|
8517
|
+
if (nextObject) {
|
|
8518
|
+
if (nextObject instanceof SubgroupObject) {
|
|
8519
|
+
if (!firstObjectId) {
|
|
8520
|
+
firstObjectId = nextObject.objectId;
|
|
8521
|
+
}
|
|
8522
|
+
let subgroupId = null;
|
|
8523
|
+
if (SubgroupHeaderType.isSubgroupIdZero(header.type)) {
|
|
8524
|
+
subgroupId = 0n;
|
|
8525
|
+
} else if (SubgroupHeaderType.isSubgroupIdFirstObjectId(header.type)) {
|
|
8526
|
+
subgroupId = firstObjectId ?? null;
|
|
8527
|
+
} else if (SubgroupHeaderType.hasExplicitSubgroupId(header.type)) {
|
|
8528
|
+
subgroupId = header.subgroupId ?? null;
|
|
8529
|
+
}
|
|
8530
|
+
const fullTrackName = this.aliasFullTrackNameMap.get(header.trackAlias);
|
|
8531
|
+
if (!fullTrackName) {
|
|
8532
|
+
throw new ProtocolViolationError("MOQtailClient", "No full track name for received track alias");
|
|
8533
|
+
}
|
|
8534
|
+
const moqtObject = MoqtObject.fromSubgroupObject(
|
|
8535
|
+
nextObject,
|
|
8536
|
+
header.groupId,
|
|
8537
|
+
header.publisherPriority,
|
|
8538
|
+
subgroupId,
|
|
8539
|
+
fullTrackName
|
|
8540
|
+
);
|
|
8541
|
+
if (!subscription.largestLocation) subscription.largestLocation = moqtObject.location;
|
|
8542
|
+
if (subscription.largestLocation.compare(moqtObject.location) == -1)
|
|
8543
|
+
subscription.largestLocation = moqtObject.location;
|
|
8544
|
+
subscription.controller?.enqueue(moqtObject);
|
|
8545
|
+
continue;
|
|
8504
8546
|
}
|
|
8505
|
-
|
|
8506
|
-
nextObject,
|
|
8507
|
-
header.groupId,
|
|
8508
|
-
header.publisherPriority,
|
|
8509
|
-
subgroupId,
|
|
8510
|
-
fullTrackName
|
|
8511
|
-
);
|
|
8512
|
-
if (!subscription.largestLocation) subscription.largestLocation = moqtObject.location;
|
|
8513
|
-
if (subscription.largestLocation.compare(moqtObject.location) == -1)
|
|
8514
|
-
subscription.largestLocation = moqtObject.location;
|
|
8515
|
-
subscription.controller?.enqueue(moqtObject);
|
|
8516
|
-
continue;
|
|
8547
|
+
throw new ProtocolViolationError("MOQtailClient", "Received fetch object after subgroup header");
|
|
8517
8548
|
}
|
|
8518
|
-
throw new ProtocolViolationError("MOQtailClient", "Received fetch object after subgroup header");
|
|
8519
8549
|
}
|
|
8550
|
+
} finally {
|
|
8551
|
+
if (subgroupTimeoutId !== void 0) clearTimeout(subgroupTimeoutId);
|
|
8520
8552
|
}
|
|
8521
8553
|
if (subscription.expectedStreams && subscription.expectedStreams === subscription.streamsAccepted) {
|
|
8522
8554
|
subscription.controller?.close();
|