@torrent-tv/proxy 2.107.35 → 2.107.36

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@torrent-tv/proxy",
3
- "version": "2.107.35",
3
+ "version": "2.107.36",
4
4
  "description": "Torrent proxy client that exposes webseed-like HTTP stream endpoint.",
5
5
  "license": "GPL-3.0-or-later",
6
6
  "repository": {
@@ -286,19 +286,30 @@ export class DownloadMaps {
286
286
  viewersChanged() {
287
287
  const sent = [];
288
288
  for (const file of this.#files.values()) {
289
- const own = [...file.metadata].filter(([, metadata]) => metadata.owner === "file");
290
- if (own.length === 0) continue;
291
- const wanted = this.#fileWanted(file.sourceKey, file.fileIndex) === true;
292
- if (file.ownReadsWanted === wanted) continue;
293
- file.ownReadsWanted = wanted;
294
- this.#log?.(`download map ${file.sourceKey}:${file.fileIndex}: ${own.length} read(s) of the file itself ` +
295
- `${wanted ? "stated again — a viewer holds the file" : "withheld — no present viewer holds the file"} ` +
296
- `[${own.map(([statement]) => statement).join(", ")}]`);
289
+ if (![...file.metadata.values()].some(metadata => metadata.owner === "file")) continue;
290
+ if (file.ownReadsWanted === (this.#fileWanted(file.sourceKey, file.fileIndex) === true)) continue;
297
291
  sent.push(this.#emit(file));
298
292
  }
299
293
  return Promise.all(sent);
300
294
  }
301
295
 
296
+ /**
297
+ * Whether a present viewer holds this file, decided where the map is built
298
+ * and said when it changes for a file that has reads of its own.
299
+ *
300
+ * @returns {boolean}
301
+ */
302
+ #ownReadsWanted(file) {
303
+ const wanted = this.#fileWanted(file.sourceKey, file.fileIndex) === true;
304
+ const own = [...file.metadata].filter(([, metadata]) => metadata.owner === "file").map(([statement]) => statement);
305
+ if (own.length && wanted !== file.ownReadsWanted && (file.ownReadsWanted !== undefined || !wanted)) {
306
+ this.#log?.(`download map ${file.sourceKey}:${file.fileIndex}: ${own.length} read(s) of the file itself ` +
307
+ `${wanted ? "stated again — a viewer holds the file" : "withheld — no present viewer holds the file"} [${own.join(", ")}]`);
308
+ }
309
+ file.ownReadsWanted = wanted;
310
+ return wanted;
311
+ }
312
+
302
313
  forget(sourceKey, fileIndex, { keepPreparation = false } = {}) {
303
314
  const file = this.#file(sourceKey, fileIndex);
304
315
  this.#setZones(file, []);
@@ -347,8 +358,7 @@ export class DownloadMaps {
347
358
  // Compared and sent as the torrent is to act on it: the playback zones
348
359
  // packed into as few windows as say the same (`coalescedZones`).
349
360
  const zones = [...this.#packedPlayback(file)];
350
- const ownReadsWanted = this.#fileWanted(file.sourceKey, file.fileIndex) === true;
351
- file.ownReadsWanted = ownReadsWanted;
361
+ const ownReadsWanted = this.#ownReadsWanted(file);
352
362
  for (const { ranges, requestId, priority, urgent, deadlineAt, order, owner } of file.metadata.values()) {
353
363
  if (owner === "file" && !ownReadsWanted) continue;
354
364
  for (const [byteStart, byteEnd] of ranges) {