moqtail 0.10.1 → 0.11.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/dist/client.cjs CHANGED
@@ -5123,6 +5123,7 @@ var SubscribeRequest = class {
5123
5123
  priority;
5124
5124
  forward;
5125
5125
  subscribeParameters;
5126
+ earlyDiscardPolicy;
5126
5127
  largestLocation;
5127
5128
  // Updated on each received object
5128
5129
  streamsAccepted = 0n;
@@ -5958,6 +5959,11 @@ var handlerRequestsBlocked = async (_client, msg) => {
5958
5959
  logger.debug("handler/requests_blocked", "not implemented", msg);
5959
5960
  };
5960
5961
 
5962
+ // src/client/util/validators.ts
5963
+ function isValidTrackAlias(trackAlias) {
5964
+ return trackAlias !== void 0 && trackAlias >= 0n;
5965
+ }
5966
+
5961
5967
  // src/client/handler/subscribe.ts
5962
5968
  var handlerSubscribe = async (client, msg) => {
5963
5969
  logger.debug("handler/subscribe", `received requestId=${msg.requestId} ftn="${msg.fullTrackName}"`);
@@ -5990,7 +5996,7 @@ var handlerSubscribe = async (client, msg) => {
5990
5996
  await client.controlStream.send(response);
5991
5997
  return;
5992
5998
  }
5993
- if (!track.trackAlias) throw new Error("Expected track alias to be set");
5999
+ if (!isValidTrackAlias(track.trackAlias)) throw new Error("Expected track alias to be set");
5994
6000
  const largestLocation = track.trackSource.live.largestLocation;
5995
6001
  const parameters = [...msg.parameters];
5996
6002
  if (largestLocation) {
@@ -6910,14 +6916,17 @@ var MOQtailClient = class _MOQtailClient {
6910
6916
  }
6911
6917
  }
6912
6918
  /**
6913
- * Sets (or replaces) the early discard policy for incoming subgroup streams.
6919
+ * Sets (or replaces) the client-level default early discard policy for incoming subgroup streams.
6914
6920
  *
6915
6921
  * When set, each incoming subgroup QUIC stream is given a deadline of `subgroupReceiveTimeout` ms to
6916
6922
  * complete. If the stream has not finished within that window it is cancelled — objects already
6917
6923
  * delivered to the subscription are kept, but no further objects arrive from that stream.
6918
6924
  *
6925
+ * This is a client-wide default. Individual subscriptions can override it via the `earlyDiscardPolicy`
6926
+ * field in {@link SubscribeOptions}, which takes precedence over this setting.
6927
+ *
6919
6928
  * 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.
6929
+ * replaces the previous one. Pass `undefined` to remove the default.
6921
6930
  *
6922
6931
  * @example
6923
6932
  * ```ts
@@ -7012,7 +7021,7 @@ var MOQtailClient = class _MOQtailClient {
7012
7021
  */
7013
7022
  addOrUpdateTrack(track) {
7014
7023
  this.#ensureActive();
7015
- if (!track.trackAlias) {
7024
+ if (!isValidTrackAlias(track.trackAlias)) {
7016
7025
  track.trackAlias = random60bitId();
7017
7026
  }
7018
7027
  this.trackSources.set(track.fullTrackName.toString(), track);
@@ -7144,6 +7153,7 @@ var MOQtailClient = class _MOQtailClient {
7144
7153
  break;
7145
7154
  }
7146
7155
  const request = new SubscribeRequest(msg);
7156
+ request.earlyDiscardPolicy = args.earlyDiscardPolicy;
7147
7157
  this.requests.set(request.requestId, request);
7148
7158
  this.requestIdMap.addMapping(request.requestId, request.fullTrackName);
7149
7159
  logger.debug("MOQtailClient", `subscribe: sending SUBSCRIBE requestId=${msg.requestId} ftn="${fullTrackName}"`);
@@ -7292,7 +7302,7 @@ var MOQtailClient = class _MOQtailClient {
7292
7302
  const request = this.requests.get(subscriptionRequestId);
7293
7303
  if (request instanceof SubscribeRequest) {
7294
7304
  const trackAlias = this.subscriptionAliasMap.get(subscriptionRequestId);
7295
- if (!trackAlias)
7305
+ if (!isValidTrackAlias(trackAlias))
7296
7306
  throw new InternalError("MOQtailClient.subscribeUpdate", "Request exists but track alias mapping does not");
7297
7307
  const subscription = this.subscriptions.get(trackAlias);
7298
7308
  if (!subscription)
@@ -7345,7 +7355,7 @@ var MOQtailClient = class _MOQtailClient {
7345
7355
  if (!(request instanceof SubscribeRequest))
7346
7356
  throw new ProtocolViolationError("MOQtailClient.switch", "Request id is not a subscription");
7347
7357
  const trackAlias = this.subscriptionAliasMap.get(subscriptionRequestId);
7348
- if (!trackAlias)
7358
+ if (!isValidTrackAlias(trackAlias))
7349
7359
  throw new InternalError("MOQtailClient.switch", "Request exists but track alias mapping does not");
7350
7360
  const subscription = this.subscriptions.get(trackAlias);
7351
7361
  if (!subscription) throw new InternalError("MOQtailClient.switch", "Request exists but subscription does not");
@@ -8010,11 +8020,12 @@ var MOQtailClient = class _MOQtailClient {
8010
8020
  subscription.streamsAccepted++;
8011
8021
  let firstObjectId = null;
8012
8022
  let subgroupTimeoutId;
8013
- if (this.#earlyDiscardPolicy?.subgroupReceiveTimeout !== void 0) {
8023
+ const effectiveDiscardPolicy = subscription.earlyDiscardPolicy ?? this.#earlyDiscardPolicy;
8024
+ if (effectiveDiscardPolicy?.subgroupReceiveTimeout !== void 0) {
8014
8025
  subgroupTimeoutId = setTimeout(() => {
8015
8026
  reader.cancel("early discard: subgroupReceiveTimeout exceeded").catch(() => {
8016
8027
  });
8017
- }, this.#earlyDiscardPolicy.subgroupReceiveTimeout);
8028
+ }, effectiveDiscardPolicy.subgroupReceiveTimeout);
8018
8029
  }
8019
8030
  try {
8020
8031
  while (true) {
package/dist/client.d.cts CHANGED
@@ -494,6 +494,7 @@ declare class SubscribeRequest implements PromiseLike<SubscribeOk | RequestError
494
494
  priority: number;
495
495
  forward: boolean;
496
496
  subscribeParameters: MessageParameter[];
497
+ earlyDiscardPolicy: EarlyDiscardPolicyConfig | undefined;
497
498
  largestLocation: Location | undefined;
498
499
  streamsAccepted: bigint;
499
500
  expectedStreams: bigint | undefined;
@@ -716,6 +717,8 @@ type SubscribeOptions = {
716
717
  startLocation?: Location;
717
718
  /** Required for {@link FilterType.AbsoluteRange}; exclusive upper group boundary (coerced to bigint if number provided). */
718
719
  endGroup?: bigint | number;
720
+ /** Per-subscription early discard policy. Overrides the client-level default set via {@link MOQtailClient.setEarlyDiscardPolicy}. */
721
+ earlyDiscardPolicy?: EarlyDiscardPolicyConfig;
719
722
  };
720
723
  /**
721
724
  * Narrowing update constraints applied to an existing SUBSCRIBE via {@link MOQtailClient.subscribeUpdate}.
@@ -1285,14 +1288,17 @@ declare class MOQtailClient {
1285
1288
  */
1286
1289
  sendDatagram(trackAlias: bigint, object: MoqtObject): Promise<void>;
1287
1290
  /**
1288
- * Sets (or replaces) the early discard policy for incoming subgroup streams.
1291
+ * Sets (or replaces) the client-level default early discard policy for incoming subgroup streams.
1289
1292
  *
1290
1293
  * When set, each incoming subgroup QUIC stream is given a deadline of `subgroupReceiveTimeout` ms to
1291
1294
  * complete. If the stream has not finished within that window it is cancelled — objects already
1292
1295
  * delivered to the subscription are kept, but no further objects arrive from that stream.
1293
1296
  *
1297
+ * This is a client-wide default. Individual subscriptions can override it via the `earlyDiscardPolicy`
1298
+ * field in {@link SubscribeOptions}, which takes precedence over this setting.
1299
+ *
1294
1300
  * 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.
1301
+ * replaces the previous one. Pass `undefined` to remove the default.
1296
1302
  *
1297
1303
  * @example
1298
1304
  * ```ts
package/dist/client.d.ts CHANGED
@@ -494,6 +494,7 @@ declare class SubscribeRequest implements PromiseLike<SubscribeOk | RequestError
494
494
  priority: number;
495
495
  forward: boolean;
496
496
  subscribeParameters: MessageParameter[];
497
+ earlyDiscardPolicy: EarlyDiscardPolicyConfig | undefined;
497
498
  largestLocation: Location | undefined;
498
499
  streamsAccepted: bigint;
499
500
  expectedStreams: bigint | undefined;
@@ -716,6 +717,8 @@ type SubscribeOptions = {
716
717
  startLocation?: Location;
717
718
  /** Required for {@link FilterType.AbsoluteRange}; exclusive upper group boundary (coerced to bigint if number provided). */
718
719
  endGroup?: bigint | number;
720
+ /** Per-subscription early discard policy. Overrides the client-level default set via {@link MOQtailClient.setEarlyDiscardPolicy}. */
721
+ earlyDiscardPolicy?: EarlyDiscardPolicyConfig;
719
722
  };
720
723
  /**
721
724
  * Narrowing update constraints applied to an existing SUBSCRIBE via {@link MOQtailClient.subscribeUpdate}.
@@ -1285,14 +1288,17 @@ declare class MOQtailClient {
1285
1288
  */
1286
1289
  sendDatagram(trackAlias: bigint, object: MoqtObject): Promise<void>;
1287
1290
  /**
1288
- * Sets (or replaces) the early discard policy for incoming subgroup streams.
1291
+ * Sets (or replaces) the client-level default early discard policy for incoming subgroup streams.
1289
1292
  *
1290
1293
  * When set, each incoming subgroup QUIC stream is given a deadline of `subgroupReceiveTimeout` ms to
1291
1294
  * complete. If the stream has not finished within that window it is cancelled — objects already
1292
1295
  * delivered to the subscription are kept, but no further objects arrive from that stream.
1293
1296
  *
1297
+ * This is a client-wide default. Individual subscriptions can override it via the `earlyDiscardPolicy`
1298
+ * field in {@link SubscribeOptions}, which takes precedence over this setting.
1299
+ *
1294
1300
  * 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.
1301
+ * replaces the previous one. Pass `undefined` to remove the default.
1296
1302
  *
1297
1303
  * @example
1298
1304
  * ```ts
package/dist/client.js CHANGED
@@ -5121,6 +5121,7 @@ var SubscribeRequest = class {
5121
5121
  priority;
5122
5122
  forward;
5123
5123
  subscribeParameters;
5124
+ earlyDiscardPolicy;
5124
5125
  largestLocation;
5125
5126
  // Updated on each received object
5126
5127
  streamsAccepted = 0n;
@@ -5956,6 +5957,11 @@ var handlerRequestsBlocked = async (_client, msg) => {
5956
5957
  logger.debug("handler/requests_blocked", "not implemented", msg);
5957
5958
  };
5958
5959
 
5960
+ // src/client/util/validators.ts
5961
+ function isValidTrackAlias(trackAlias) {
5962
+ return trackAlias !== void 0 && trackAlias >= 0n;
5963
+ }
5964
+
5959
5965
  // src/client/handler/subscribe.ts
5960
5966
  var handlerSubscribe = async (client, msg) => {
5961
5967
  logger.debug("handler/subscribe", `received requestId=${msg.requestId} ftn="${msg.fullTrackName}"`);
@@ -5988,7 +5994,7 @@ var handlerSubscribe = async (client, msg) => {
5988
5994
  await client.controlStream.send(response);
5989
5995
  return;
5990
5996
  }
5991
- if (!track.trackAlias) throw new Error("Expected track alias to be set");
5997
+ if (!isValidTrackAlias(track.trackAlias)) throw new Error("Expected track alias to be set");
5992
5998
  const largestLocation = track.trackSource.live.largestLocation;
5993
5999
  const parameters = [...msg.parameters];
5994
6000
  if (largestLocation) {
@@ -6908,14 +6914,17 @@ var MOQtailClient = class _MOQtailClient {
6908
6914
  }
6909
6915
  }
6910
6916
  /**
6911
- * Sets (or replaces) the early discard policy for incoming subgroup streams.
6917
+ * Sets (or replaces) the client-level default early discard policy for incoming subgroup streams.
6912
6918
  *
6913
6919
  * When set, each incoming subgroup QUIC stream is given a deadline of `subgroupReceiveTimeout` ms to
6914
6920
  * complete. If the stream has not finished within that window it is cancelled — objects already
6915
6921
  * delivered to the subscription are kept, but no further objects arrive from that stream.
6916
6922
  *
6923
+ * This is a client-wide default. Individual subscriptions can override it via the `earlyDiscardPolicy`
6924
+ * field in {@link SubscribeOptions}, which takes precedence over this setting.
6925
+ *
6917
6926
  * 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.
6927
+ * replaces the previous one. Pass `undefined` to remove the default.
6919
6928
  *
6920
6929
  * @example
6921
6930
  * ```ts
@@ -7010,7 +7019,7 @@ var MOQtailClient = class _MOQtailClient {
7010
7019
  */
7011
7020
  addOrUpdateTrack(track) {
7012
7021
  this.#ensureActive();
7013
- if (!track.trackAlias) {
7022
+ if (!isValidTrackAlias(track.trackAlias)) {
7014
7023
  track.trackAlias = random60bitId();
7015
7024
  }
7016
7025
  this.trackSources.set(track.fullTrackName.toString(), track);
@@ -7142,6 +7151,7 @@ var MOQtailClient = class _MOQtailClient {
7142
7151
  break;
7143
7152
  }
7144
7153
  const request = new SubscribeRequest(msg);
7154
+ request.earlyDiscardPolicy = args.earlyDiscardPolicy;
7145
7155
  this.requests.set(request.requestId, request);
7146
7156
  this.requestIdMap.addMapping(request.requestId, request.fullTrackName);
7147
7157
  logger.debug("MOQtailClient", `subscribe: sending SUBSCRIBE requestId=${msg.requestId} ftn="${fullTrackName}"`);
@@ -7290,7 +7300,7 @@ var MOQtailClient = class _MOQtailClient {
7290
7300
  const request = this.requests.get(subscriptionRequestId);
7291
7301
  if (request instanceof SubscribeRequest) {
7292
7302
  const trackAlias = this.subscriptionAliasMap.get(subscriptionRequestId);
7293
- if (!trackAlias)
7303
+ if (!isValidTrackAlias(trackAlias))
7294
7304
  throw new InternalError("MOQtailClient.subscribeUpdate", "Request exists but track alias mapping does not");
7295
7305
  const subscription = this.subscriptions.get(trackAlias);
7296
7306
  if (!subscription)
@@ -7343,7 +7353,7 @@ var MOQtailClient = class _MOQtailClient {
7343
7353
  if (!(request instanceof SubscribeRequest))
7344
7354
  throw new ProtocolViolationError("MOQtailClient.switch", "Request id is not a subscription");
7345
7355
  const trackAlias = this.subscriptionAliasMap.get(subscriptionRequestId);
7346
- if (!trackAlias)
7356
+ if (!isValidTrackAlias(trackAlias))
7347
7357
  throw new InternalError("MOQtailClient.switch", "Request exists but track alias mapping does not");
7348
7358
  const subscription = this.subscriptions.get(trackAlias);
7349
7359
  if (!subscription) throw new InternalError("MOQtailClient.switch", "Request exists but subscription does not");
@@ -8008,11 +8018,12 @@ var MOQtailClient = class _MOQtailClient {
8008
8018
  subscription.streamsAccepted++;
8009
8019
  let firstObjectId = null;
8010
8020
  let subgroupTimeoutId;
8011
- if (this.#earlyDiscardPolicy?.subgroupReceiveTimeout !== void 0) {
8021
+ const effectiveDiscardPolicy = subscription.earlyDiscardPolicy ?? this.#earlyDiscardPolicy;
8022
+ if (effectiveDiscardPolicy?.subgroupReceiveTimeout !== void 0) {
8012
8023
  subgroupTimeoutId = setTimeout(() => {
8013
8024
  reader.cancel("early discard: subgroupReceiveTimeout exceeded").catch(() => {
8014
8025
  });
8015
- }, this.#earlyDiscardPolicy.subgroupReceiveTimeout);
8026
+ }, effectiveDiscardPolicy.subgroupReceiveTimeout);
8016
8027
  }
8017
8028
  try {
8018
8029
  while (true) {
package/dist/index.cjs CHANGED
@@ -5617,6 +5617,7 @@ var SubscribeRequest = class {
5617
5617
  priority;
5618
5618
  forward;
5619
5619
  subscribeParameters;
5620
+ earlyDiscardPolicy;
5620
5621
  largestLocation;
5621
5622
  // Updated on each received object
5622
5623
  streamsAccepted = 0n;
@@ -6452,6 +6453,11 @@ var handlerRequestsBlocked = async (_client, msg) => {
6452
6453
  logger.debug("handler/requests_blocked", "not implemented", msg);
6453
6454
  };
6454
6455
 
6456
+ // src/client/util/validators.ts
6457
+ function isValidTrackAlias(trackAlias) {
6458
+ return trackAlias !== void 0 && trackAlias >= 0n;
6459
+ }
6460
+
6455
6461
  // src/client/handler/subscribe.ts
6456
6462
  var handlerSubscribe = async (client, msg) => {
6457
6463
  logger.debug("handler/subscribe", `received requestId=${msg.requestId} ftn="${msg.fullTrackName}"`);
@@ -6484,7 +6490,7 @@ var handlerSubscribe = async (client, msg) => {
6484
6490
  await client.controlStream.send(response);
6485
6491
  return;
6486
6492
  }
6487
- if (!track.trackAlias) throw new Error("Expected track alias to be set");
6493
+ if (!isValidTrackAlias(track.trackAlias)) throw new Error("Expected track alias to be set");
6488
6494
  const largestLocation = track.trackSource.live.largestLocation;
6489
6495
  const parameters = [...msg.parameters];
6490
6496
  if (largestLocation) {
@@ -7404,14 +7410,17 @@ var MOQtailClient = class _MOQtailClient {
7404
7410
  }
7405
7411
  }
7406
7412
  /**
7407
- * Sets (or replaces) the early discard policy for incoming subgroup streams.
7413
+ * Sets (or replaces) the client-level default early discard policy for incoming subgroup streams.
7408
7414
  *
7409
7415
  * When set, each incoming subgroup QUIC stream is given a deadline of `subgroupReceiveTimeout` ms to
7410
7416
  * complete. If the stream has not finished within that window it is cancelled — objects already
7411
7417
  * delivered to the subscription are kept, but no further objects arrive from that stream.
7412
7418
  *
7419
+ * This is a client-wide default. Individual subscriptions can override it via the `earlyDiscardPolicy`
7420
+ * field in {@link SubscribeOptions}, which takes precedence over this setting.
7421
+ *
7413
7422
  * 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.
7423
+ * replaces the previous one. Pass `undefined` to remove the default.
7415
7424
  *
7416
7425
  * @example
7417
7426
  * ```ts
@@ -7506,7 +7515,7 @@ var MOQtailClient = class _MOQtailClient {
7506
7515
  */
7507
7516
  addOrUpdateTrack(track) {
7508
7517
  this.#ensureActive();
7509
- if (!track.trackAlias) {
7518
+ if (!isValidTrackAlias(track.trackAlias)) {
7510
7519
  track.trackAlias = random60bitId();
7511
7520
  }
7512
7521
  this.trackSources.set(track.fullTrackName.toString(), track);
@@ -7638,6 +7647,7 @@ var MOQtailClient = class _MOQtailClient {
7638
7647
  break;
7639
7648
  }
7640
7649
  const request = new SubscribeRequest(msg);
7650
+ request.earlyDiscardPolicy = args.earlyDiscardPolicy;
7641
7651
  this.requests.set(request.requestId, request);
7642
7652
  this.requestIdMap.addMapping(request.requestId, request.fullTrackName);
7643
7653
  logger.debug("MOQtailClient", `subscribe: sending SUBSCRIBE requestId=${msg.requestId} ftn="${fullTrackName}"`);
@@ -7786,7 +7796,7 @@ var MOQtailClient = class _MOQtailClient {
7786
7796
  const request = this.requests.get(subscriptionRequestId);
7787
7797
  if (request instanceof SubscribeRequest) {
7788
7798
  const trackAlias = this.subscriptionAliasMap.get(subscriptionRequestId);
7789
- if (!trackAlias)
7799
+ if (!isValidTrackAlias(trackAlias))
7790
7800
  throw new InternalError("MOQtailClient.subscribeUpdate", "Request exists but track alias mapping does not");
7791
7801
  const subscription = this.subscriptions.get(trackAlias);
7792
7802
  if (!subscription)
@@ -7839,7 +7849,7 @@ var MOQtailClient = class _MOQtailClient {
7839
7849
  if (!(request instanceof SubscribeRequest))
7840
7850
  throw new ProtocolViolationError("MOQtailClient.switch", "Request id is not a subscription");
7841
7851
  const trackAlias = this.subscriptionAliasMap.get(subscriptionRequestId);
7842
- if (!trackAlias)
7852
+ if (!isValidTrackAlias(trackAlias))
7843
7853
  throw new InternalError("MOQtailClient.switch", "Request exists but track alias mapping does not");
7844
7854
  const subscription = this.subscriptions.get(trackAlias);
7845
7855
  if (!subscription) throw new InternalError("MOQtailClient.switch", "Request exists but subscription does not");
@@ -8504,11 +8514,12 @@ var MOQtailClient = class _MOQtailClient {
8504
8514
  subscription.streamsAccepted++;
8505
8515
  let firstObjectId = null;
8506
8516
  let subgroupTimeoutId;
8507
- if (this.#earlyDiscardPolicy?.subgroupReceiveTimeout !== void 0) {
8517
+ const effectiveDiscardPolicy = subscription.earlyDiscardPolicy ?? this.#earlyDiscardPolicy;
8518
+ if (effectiveDiscardPolicy?.subgroupReceiveTimeout !== void 0) {
8508
8519
  subgroupTimeoutId = setTimeout(() => {
8509
8520
  reader.cancel("early discard: subgroupReceiveTimeout exceeded").catch(() => {
8510
8521
  });
8511
- }, this.#earlyDiscardPolicy.subgroupReceiveTimeout);
8522
+ }, effectiveDiscardPolicy.subgroupReceiveTimeout);
8512
8523
  }
8513
8524
  try {
8514
8525
  while (true) {
package/dist/index.js CHANGED
@@ -5615,6 +5615,7 @@ var SubscribeRequest = class {
5615
5615
  priority;
5616
5616
  forward;
5617
5617
  subscribeParameters;
5618
+ earlyDiscardPolicy;
5618
5619
  largestLocation;
5619
5620
  // Updated on each received object
5620
5621
  streamsAccepted = 0n;
@@ -6450,6 +6451,11 @@ var handlerRequestsBlocked = async (_client, msg) => {
6450
6451
  logger.debug("handler/requests_blocked", "not implemented", msg);
6451
6452
  };
6452
6453
 
6454
+ // src/client/util/validators.ts
6455
+ function isValidTrackAlias(trackAlias) {
6456
+ return trackAlias !== void 0 && trackAlias >= 0n;
6457
+ }
6458
+
6453
6459
  // src/client/handler/subscribe.ts
6454
6460
  var handlerSubscribe = async (client, msg) => {
6455
6461
  logger.debug("handler/subscribe", `received requestId=${msg.requestId} ftn="${msg.fullTrackName}"`);
@@ -6482,7 +6488,7 @@ var handlerSubscribe = async (client, msg) => {
6482
6488
  await client.controlStream.send(response);
6483
6489
  return;
6484
6490
  }
6485
- if (!track.trackAlias) throw new Error("Expected track alias to be set");
6491
+ if (!isValidTrackAlias(track.trackAlias)) throw new Error("Expected track alias to be set");
6486
6492
  const largestLocation = track.trackSource.live.largestLocation;
6487
6493
  const parameters = [...msg.parameters];
6488
6494
  if (largestLocation) {
@@ -7402,14 +7408,17 @@ var MOQtailClient = class _MOQtailClient {
7402
7408
  }
7403
7409
  }
7404
7410
  /**
7405
- * Sets (or replaces) the early discard policy for incoming subgroup streams.
7411
+ * Sets (or replaces) the client-level default early discard policy for incoming subgroup streams.
7406
7412
  *
7407
7413
  * When set, each incoming subgroup QUIC stream is given a deadline of `subgroupReceiveTimeout` ms to
7408
7414
  * complete. If the stream has not finished within that window it is cancelled — objects already
7409
7415
  * delivered to the subscription are kept, but no further objects arrive from that stream.
7410
7416
  *
7417
+ * This is a client-wide default. Individual subscriptions can override it via the `earlyDiscardPolicy`
7418
+ * field in {@link SubscribeOptions}, which takes precedence over this setting.
7419
+ *
7411
7420
  * 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.
7421
+ * replaces the previous one. Pass `undefined` to remove the default.
7413
7422
  *
7414
7423
  * @example
7415
7424
  * ```ts
@@ -7504,7 +7513,7 @@ var MOQtailClient = class _MOQtailClient {
7504
7513
  */
7505
7514
  addOrUpdateTrack(track) {
7506
7515
  this.#ensureActive();
7507
- if (!track.trackAlias) {
7516
+ if (!isValidTrackAlias(track.trackAlias)) {
7508
7517
  track.trackAlias = random60bitId();
7509
7518
  }
7510
7519
  this.trackSources.set(track.fullTrackName.toString(), track);
@@ -7636,6 +7645,7 @@ var MOQtailClient = class _MOQtailClient {
7636
7645
  break;
7637
7646
  }
7638
7647
  const request = new SubscribeRequest(msg);
7648
+ request.earlyDiscardPolicy = args.earlyDiscardPolicy;
7639
7649
  this.requests.set(request.requestId, request);
7640
7650
  this.requestIdMap.addMapping(request.requestId, request.fullTrackName);
7641
7651
  logger.debug("MOQtailClient", `subscribe: sending SUBSCRIBE requestId=${msg.requestId} ftn="${fullTrackName}"`);
@@ -7784,7 +7794,7 @@ var MOQtailClient = class _MOQtailClient {
7784
7794
  const request = this.requests.get(subscriptionRequestId);
7785
7795
  if (request instanceof SubscribeRequest) {
7786
7796
  const trackAlias = this.subscriptionAliasMap.get(subscriptionRequestId);
7787
- if (!trackAlias)
7797
+ if (!isValidTrackAlias(trackAlias))
7788
7798
  throw new InternalError("MOQtailClient.subscribeUpdate", "Request exists but track alias mapping does not");
7789
7799
  const subscription = this.subscriptions.get(trackAlias);
7790
7800
  if (!subscription)
@@ -7837,7 +7847,7 @@ var MOQtailClient = class _MOQtailClient {
7837
7847
  if (!(request instanceof SubscribeRequest))
7838
7848
  throw new ProtocolViolationError("MOQtailClient.switch", "Request id is not a subscription");
7839
7849
  const trackAlias = this.subscriptionAliasMap.get(subscriptionRequestId);
7840
- if (!trackAlias)
7850
+ if (!isValidTrackAlias(trackAlias))
7841
7851
  throw new InternalError("MOQtailClient.switch", "Request exists but track alias mapping does not");
7842
7852
  const subscription = this.subscriptions.get(trackAlias);
7843
7853
  if (!subscription) throw new InternalError("MOQtailClient.switch", "Request exists but subscription does not");
@@ -8502,11 +8512,12 @@ var MOQtailClient = class _MOQtailClient {
8502
8512
  subscription.streamsAccepted++;
8503
8513
  let firstObjectId = null;
8504
8514
  let subgroupTimeoutId;
8505
- if (this.#earlyDiscardPolicy?.subgroupReceiveTimeout !== void 0) {
8515
+ const effectiveDiscardPolicy = subscription.earlyDiscardPolicy ?? this.#earlyDiscardPolicy;
8516
+ if (effectiveDiscardPolicy?.subgroupReceiveTimeout !== void 0) {
8506
8517
  subgroupTimeoutId = setTimeout(() => {
8507
8518
  reader.cancel("early discard: subgroupReceiveTimeout exceeded").catch(() => {
8508
8519
  });
8509
- }, this.#earlyDiscardPolicy.subgroupReceiveTimeout);
8520
+ }, effectiveDiscardPolicy.subgroupReceiveTimeout);
8510
8521
  }
8511
8522
  try {
8512
8523
  while (true) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "moqtail",
3
- "version": "0.10.1",
3
+ "version": "0.11.0",
4
4
  "description": "Media Over QUIC Transport client implementation",
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",