bun-torrent 0.0.3-beta → 0.0.4-beta

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -66,8 +66,13 @@ import { Client } from 'bun-torrent';
66
66
 
67
67
  const client = new Client({
68
68
  outputDirectory: './downloads',
69
+ targetConnections: 20,
70
+ maxConnecting: 30,
69
71
  maxInFlightRequestsPerPeer: 20,
72
+ peerConnectTimeoutMs: 5_000,
73
+ trackerTimeoutMs: 5_000,
70
74
  requestTimeoutMs: 15_000,
75
+ seed: false,
71
76
  progressEvents: 'piece',
72
77
  speedSampleIntervalMs: 500,
73
78
  });
@@ -77,8 +82,14 @@ Client options:
77
82
 
78
83
  - `outputDirectory`: directory where downloaded files are written. Defaults to `process.cwd()`.
79
84
  - `files`: optional default file selection for downloads.
85
+ - `targetConnections`: preferred number of connected peers. Defaults to `20`.
86
+ - `minConnections`: minimum connectable peer count before downloading starts. Defaults to `0`.
87
+ - `maxConnecting`: maximum simultaneous peer connection attempts. Defaults to `30`.
88
+ - `peerConnectTimeoutMs`: timeout for connecting to one peer. Defaults to `5000`.
89
+ - `trackerTimeoutMs`: timeout for tracker announces. Defaults to `5000`.
80
90
  - `maxInFlightRequestsPerPeer`: maximum active block requests per peer. Defaults to `20`.
81
91
  - `requestTimeoutMs`: timeout for an individual block request. Defaults to `15000`.
92
+ - `seed`: reserved for future seeding support. Currently only `false` is supported.
82
93
  - `progressEvents`: `'piece'` emits progress when a piece completes, `'block'` emits for every received block. Defaults to `'piece'`.
83
94
  - `speedSampleIntervalMs`: minimum interval used to refresh speed calculations. Defaults to `500`.
84
95
 
@@ -109,8 +120,11 @@ const torrent = await client.download(
109
120
  },
110
121
  {
111
122
  outputDirectory: './downloads',
123
+ targetConnections: 50,
124
+ maxConnecting: 100,
112
125
  minConnections: 5,
113
126
  announcePort: 6881,
127
+ seed: false,
114
128
  progressEvents: 'block',
115
129
  onChangeState: (state) => {
116
130
  console.log('client state:', state);
@@ -123,10 +137,15 @@ Download options:
123
137
 
124
138
  - `outputDirectory`: override the output directory for this download.
125
139
  - `files`: download only selected files.
140
+ - `targetConnections`: override the preferred peer connection count.
126
141
  - `minConnections`: minimum connectable peer count requested before downloading starts.
142
+ - `maxConnecting`: override simultaneous peer connection attempts.
143
+ - `peerConnectTimeoutMs`: override peer connection timeout.
144
+ - `trackerTimeoutMs`: override tracker announce timeout.
127
145
  - `announcePort`: port sent to trackers in announce requests.
128
146
  - `maxInFlightRequestsPerPeer`: override request concurrency per peer.
129
147
  - `requestTimeoutMs`: override block request timeout.
148
+ - `seed`: reserved for future seeding support. Currently only `false` is supported.
130
149
  - `progressEvents`: `'piece'` or `'block'`.
131
150
  - `speedSampleIntervalMs`: override speed sample interval.
132
151
  - `onChangeState`: receives client setup states: `parsing`, `tracking`, `connecting`, `downloading`.
@@ -185,8 +204,8 @@ torrent.on('progress', (progress) => {
185
204
  console.log(progress.percent, progress.speed);
186
205
  });
187
206
 
188
- torrent.on('peer', (peer) => {
189
- console.log('peer connected', peer);
207
+ torrent.on('peer', (stats) => {
208
+ console.log('peer connected', stats.connections, '/', stats.targetConnections);
190
209
  });
191
210
 
192
211
  torrent.on('done', () => {
@@ -209,7 +228,7 @@ The current torrent state is also available through `torrent.state`. Possible st
209
228
  - `failed`
210
229
  - `closed`
211
230
 
212
- Call `torrent.close()` to stop the download and close peer connections.
231
+ When a download completes, `torrent.done` resolves, the state becomes `completed`, and internal peer connections are closed automatically because seeding is not implemented yet. Call `torrent.close()` to stop an active download early or to mark a completed torrent as explicitly closed.
213
232
 
214
233
  ## Progress Shape
215
234
 
package/dist/client.d.ts CHANGED
@@ -11,16 +11,28 @@ export declare enum DownloadState {
11
11
  export type ClientConfig = {
12
12
  files?: TorrentFileSelection;
13
13
  maxInFlightRequestsPerPeer?: number;
14
+ maxConnecting?: number;
15
+ minConnections?: number;
14
16
  outputDirectory?: string;
17
+ peerConnectTimeoutMs?: number;
15
18
  progressEvents?: DownloadProgressEventMode;
16
19
  requestTimeoutMs?: number;
20
+ seed?: false;
17
21
  speedSampleIntervalMs?: number;
22
+ targetConnections?: number;
23
+ trackerTimeoutMs?: number;
18
24
  };
19
25
  export declare const DEFAULT_CLIENT_CONFIG: {
20
26
  readonly maxInFlightRequestsPerPeer: 20;
27
+ readonly maxConnecting: 30;
28
+ readonly minConnections: 0;
29
+ readonly peerConnectTimeoutMs: 5000;
21
30
  readonly progressEvents: "piece";
22
31
  readonly requestTimeoutMs: 15000;
32
+ readonly seed: false;
23
33
  readonly speedSampleIntervalMs: 500;
34
+ readonly targetConnections: 20;
35
+ readonly trackerTimeoutMs: 5000;
24
36
  };
25
37
  export declare class Client {
26
38
  private readonly config;
@@ -38,12 +50,17 @@ export type DownloadOptions = {
38
50
  announcePort?: number;
39
51
  files?: TorrentFileSelection;
40
52
  maxInFlightRequestsPerPeer?: number;
53
+ maxConnecting?: number;
41
54
  minConnections?: number;
42
55
  onChangeState?: (state: DownloadState) => unknown;
43
56
  outputDirectory?: string;
57
+ peerConnectTimeoutMs?: number;
44
58
  progressEvents?: DownloadProgressEventMode;
45
59
  requestTimeoutMs?: number;
60
+ seed?: false;
46
61
  speedSampleIntervalMs?: number;
62
+ targetConnections?: number;
63
+ trackerTimeoutMs?: number;
47
64
  };
48
65
  export type TorrentFileInput = string | Uint8Array | ArrayBuffer;
49
66
  export declare const readTorrentFile: (input: TorrentFileInput) => Promise<Uint8Array>;
package/dist/client.js CHANGED
@@ -15,9 +15,15 @@ export var DownloadState;
15
15
  })(DownloadState || (DownloadState = {}));
16
16
  export const DEFAULT_CLIENT_CONFIG = {
17
17
  maxInFlightRequestsPerPeer: 20,
18
+ maxConnecting: 30,
19
+ minConnections: 0,
20
+ peerConnectTimeoutMs: 5_000,
18
21
  progressEvents: 'piece',
19
22
  requestTimeoutMs: 15_000,
23
+ seed: false,
20
24
  speedSampleIntervalMs: 500,
25
+ targetConnections: 20,
26
+ trackerTimeoutMs: 5_000,
21
27
  };
22
28
  export class Client {
23
29
  config;
@@ -32,16 +38,16 @@ export class Client {
32
38
  const downloadConfig = resolveDownloadConfig(this.config, options);
33
39
  assertValidFileSelection(meta, downloadConfig.files);
34
40
  options.onChangeState?.(DownloadState.TRACKING);
35
- const peers = await this.trackPeers(meta, options);
41
+ const peers = await this.trackPeers(meta, options, downloadConfig);
36
42
  options.onChangeState?.(DownloadState.CONNECTING);
37
43
  const pool = await openPeerPool(peers, {
38
44
  infoHash: meta.infoHash,
39
45
  peerId: this.peerId,
40
- targetConnections: 20,
46
+ targetConnections: downloadConfig.targetConnections,
41
47
  totalPieces: meta.pieces.length,
42
- minConnections: options.minConnections ?? 0,
43
- maxConnecting: 30,
44
- timeoutMs: 5_000,
48
+ minConnections: downloadConfig.minConnections,
49
+ maxConnecting: downloadConfig.maxConnecting,
50
+ timeoutMs: downloadConfig.peerConnectTimeoutMs,
45
51
  });
46
52
  options.onChangeState?.(DownloadState.DOWNLOADING);
47
53
  return new Torrent(meta, pool, new DownloadManager({
@@ -53,19 +59,19 @@ export class Client {
53
59
  progressEvents: downloadConfig.progressEvents,
54
60
  requestTimeoutMs: downloadConfig.requestTimeoutMs,
55
61
  speedSampleIntervalMs: downloadConfig.speedSampleIntervalMs,
56
- }), normalizeTorrentFileSelection(downloadConfig.files));
62
+ }), normalizeTorrentFileSelection(downloadConfig.files), downloadConfig.seed);
57
63
  }
58
64
  async inspect(input) {
59
65
  const bytes = await readTorrentFile(input.torrentFile);
60
66
  return parseTorrent(bytes);
61
67
  }
62
- async trackPeers(meta, options) {
68
+ async trackPeers(meta, options, config) {
63
69
  try {
64
70
  return await trackPeers({
65
71
  meta,
66
72
  peerId: this.peerId,
67
73
  announcePort: options.announcePort,
68
- timeoutMs: 5_000,
74
+ timeoutMs: config.trackerTimeoutMs,
69
75
  });
70
76
  }
71
77
  catch (error) {
@@ -84,14 +90,26 @@ const resolveDownloadConfig = (config, options) => ({
84
90
  maxInFlightRequestsPerPeer: options.maxInFlightRequestsPerPeer ??
85
91
  config.maxInFlightRequestsPerPeer ??
86
92
  DEFAULT_CLIENT_CONFIG.maxInFlightRequestsPerPeer,
93
+ maxConnecting: options.maxConnecting ?? config.maxConnecting ?? DEFAULT_CLIENT_CONFIG.maxConnecting,
94
+ minConnections: options.minConnections ?? config.minConnections ?? DEFAULT_CLIENT_CONFIG.minConnections,
87
95
  outputDirectory: options.outputDirectory ?? config.outputDirectory ?? process.cwd(),
96
+ peerConnectTimeoutMs: options.peerConnectTimeoutMs ??
97
+ config.peerConnectTimeoutMs ??
98
+ DEFAULT_CLIENT_CONFIG.peerConnectTimeoutMs,
88
99
  progressEvents: options.progressEvents ?? config.progressEvents ?? DEFAULT_CLIENT_CONFIG.progressEvents,
89
100
  requestTimeoutMs: options.requestTimeoutMs ??
90
101
  config.requestTimeoutMs ??
91
102
  DEFAULT_CLIENT_CONFIG.requestTimeoutMs,
103
+ seed: options.seed ?? config.seed ?? DEFAULT_CLIENT_CONFIG.seed,
92
104
  speedSampleIntervalMs: options.speedSampleIntervalMs ??
93
105
  config.speedSampleIntervalMs ??
94
106
  DEFAULT_CLIENT_CONFIG.speedSampleIntervalMs,
107
+ targetConnections: options.targetConnections ??
108
+ config.targetConnections ??
109
+ DEFAULT_CLIENT_CONFIG.targetConnections,
110
+ trackerTimeoutMs: options.trackerTimeoutMs ??
111
+ config.trackerTimeoutMs ??
112
+ DEFAULT_CLIENT_CONFIG.trackerTimeoutMs,
95
113
  });
96
114
  const assertValidFileSelection = (metadata, files) => {
97
115
  const unknownFiles = getUnknownSelectedFiles(metadata, files);
@@ -1 +1 @@
1
- {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -2,11 +2,12 @@
2
2
  * Copyright (c) 2026 Nikola Nedeljkovic
3
3
  * SPDX-License-Identifier: MIT
4
4
  */
5
- export * from './client';
5
+ export { Client, DEFAULT_CLIENT_CONFIG, DownloadState, TorrentClient } from './client';
6
6
  export { ClientError, ClientErrorCode } from './client.error';
7
- export { BencodeDecodeError, BencodeDecodeErrorCode, BencodeEncodeError, BencodeEncodeErrorCode, computeInfoHash, decodeBencode, encodeBencode, parseTorrent, Torrent, TorrentState, toBValue, TorrentParseError, TorrentParseErrorCode, type TorrentFileSelection, type TorrentMetadata, } from './torrent/index';
8
- export { connectToPeers, createPeerId, decodeHandshake, decodePeerMessage, encodePeerMessage, encodeHandshake, HandshakeErrorCode, PeerMessageError, PeerMessageErrorCode, PeerMessageId, PeerHandshakeError, PeerPoolError, PeerPoolErrorCode, PeerPool, PeerSession, PeerSessionError, PeerSessionErrorCode, openPeerPool, type PeerHandshake, } from './peer/index';
7
+ export type { ClientConfig, DownloadOptions, TorrentFileInput } from './client';
8
+ export { Torrent, TorrentState, TorrentParseError, TorrentParseErrorCode, TorrentStorageError, TorrentStorageErrorCode, PiecePlannerError, PiecePlannerErrorCode, } from './torrent/index';
9
+ export { PeerPoolError, PeerPoolErrorCode, PeerSessionError, PeerSessionErrorCode } from './peer';
9
10
  export { TrackerError, TrackerErrorCode } from './tracker';
10
- export type { BitfieldMessage, CancelMessage, ChokeMessage, HaveMessage, InterestedMessage, KeepAliveMessage, NotInterestedMessage, PeerMessage, PieceMessage, RequestMessage, UnchokeMessage, PeerConnectionSession, PeerPoolOptions, PeerSessionConnectOptions, } from './peer/index';
11
+ export type { DownloadProgress, DownloadProgressEventMode, TorrentFileSelection, TorrentFiles, TorrentMetadata, TorrentStats, TorrentStateChange, } from './torrent/index';
12
+ export type { TorrentFile } from './torrent/types';
11
13
  export { BunTorrentError } from './utils/errors';
12
- export type { BBytes, BDict, BInteger, BList, BValue, BencodeInput, TorrentFiles, TorrentStats, TorrentStateChange, } from './torrent/index';
package/dist/index.js CHANGED
@@ -2,10 +2,10 @@
2
2
  * Copyright (c) 2026 Nikola Nedeljkovic
3
3
  * SPDX-License-Identifier: MIT
4
4
  */
5
- export * from './client';
5
+ export { Client, DEFAULT_CLIENT_CONFIG, DownloadState, TorrentClient } from './client';
6
6
  export { ClientError, ClientErrorCode } from './client.error';
7
- export { BencodeDecodeError, BencodeDecodeErrorCode, BencodeEncodeError, BencodeEncodeErrorCode, computeInfoHash, decodeBencode, encodeBencode, parseTorrent, Torrent, TorrentState, toBValue, TorrentParseError, TorrentParseErrorCode, } from './torrent/index';
8
- export { connectToPeers, createPeerId, decodeHandshake, decodePeerMessage, encodePeerMessage, encodeHandshake, HandshakeErrorCode, PeerMessageError, PeerMessageErrorCode, PeerMessageId, PeerHandshakeError, PeerPoolError, PeerPoolErrorCode, PeerPool, PeerSession, PeerSessionError, PeerSessionErrorCode, openPeerPool, } from './peer/index';
7
+ export { Torrent, TorrentState, TorrentParseError, TorrentParseErrorCode, TorrentStorageError, TorrentStorageErrorCode, PiecePlannerError, PiecePlannerErrorCode, } from './torrent/index';
8
+ export { PeerPoolError, PeerPoolErrorCode, PeerSessionError, PeerSessionErrorCode } from './peer';
9
9
  export { TrackerError, TrackerErrorCode } from './tracker';
10
10
  export { BunTorrentError } from './utils/errors';
11
11
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,cAAc,UAAU,CAAC;AACzB,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAE9D,OAAO,EACH,kBAAkB,EAClB,sBAAsB,EACtB,kBAAkB,EAClB,sBAAsB,EACtB,eAAe,EACf,aAAa,EACb,aAAa,EACb,YAAY,EACZ,OAAO,EACP,YAAY,EACZ,QAAQ,EACR,iBAAiB,EACjB,qBAAqB,GAGxB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACH,cAAc,EACd,YAAY,EACZ,eAAe,EACf,iBAAiB,EACjB,iBAAiB,EACjB,eAAe,EACf,kBAAkB,EAClB,gBAAgB,EAChB,oBAAoB,EACpB,aAAa,EACb,kBAAkB,EAClB,aAAa,EACb,iBAAiB,EACjB,QAAQ,EACR,WAAW,EACX,gBAAgB,EAChB,oBAAoB,EACpB,YAAY,GAEf,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAkB3D,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,MAAM,EAAE,qBAAqB,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACvF,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAG9D,OAAO,EACH,OAAO,EACP,YAAY,EACZ,iBAAiB,EACjB,qBAAqB,EACrB,mBAAmB,EACnB,uBAAuB,EACvB,iBAAiB,EACjB,qBAAqB,GACxB,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,MAAM,QAAQ,CAAC;AAClG,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAa3D,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC"}
@@ -0,0 +1,15 @@
1
+ export type PeerDownloadStats = {
2
+ receivedBytes: number;
3
+ receivedBlocks: number;
4
+ timedOutRequests: number;
5
+ sentRequests: number;
6
+ completedPieces: number;
7
+ invalidPieces: number;
8
+ lastBlockAt: number | null;
9
+ totalRequestTimeMs: number;
10
+ completedRequests: number;
11
+ };
12
+ export declare class PeerScorer {
13
+ getScore(stats: PeerDownloadStats): number;
14
+ getRequestLimit(stats: PeerDownloadStats, defaultLimit: number): number;
15
+ }
@@ -0,0 +1,24 @@
1
+ export class PeerScorer {
2
+ getScore(stats) {
3
+ const averageRequestTime = stats.completedRequests === 0
4
+ ? Number.POSITIVE_INFINITY
5
+ : stats.totalRequestTimeMs / stats.completedRequests;
6
+ const timeoutPenalty = stats.timedOutRequests * 1000;
7
+ const invalidPenalty = stats.invalidPieces * 2000;
8
+ const speedBonus = stats.receivedBytes / Math.max(1, averageRequestTime);
9
+ return speedBonus + stats.completedPieces * 100 - timeoutPenalty - invalidPenalty;
10
+ }
11
+ getRequestLimit(stats, defaultLimit) {
12
+ if (stats.timedOutRequests >= 3 && stats.completedRequests === 0)
13
+ return 1;
14
+ if (stats.completedRequests < 3)
15
+ return defaultLimit;
16
+ const timeoutRate = stats.timedOutRequests / Math.max(1, stats.sentRequests);
17
+ if (timeoutRate > 0.5)
18
+ return Math.max(1, Math.floor(defaultLimit / 4));
19
+ if (timeoutRate > 0.25)
20
+ return Math.max(1, Math.floor(defaultLimit / 2));
21
+ return defaultLimit;
22
+ }
23
+ }
24
+ //# sourceMappingURL=PeerScorer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PeerScorer.js","sourceRoot":"","sources":["../../../src/torrent/download/PeerScorer.ts"],"names":[],"mappings":"AAYA,MAAM,OAAO,UAAU;IACZ,QAAQ,CAAC,KAAwB;QACpC,MAAM,kBAAkB,GACpB,KAAK,CAAC,iBAAiB,KAAK,CAAC;YACzB,CAAC,CAAC,MAAM,CAAC,iBAAiB;YAC1B,CAAC,CAAC,KAAK,CAAC,kBAAkB,GAAG,KAAK,CAAC,iBAAiB,CAAC;QAE7D,MAAM,cAAc,GAAG,KAAK,CAAC,gBAAgB,GAAG,IAAI,CAAC;QACrD,MAAM,cAAc,GAAG,KAAK,CAAC,aAAa,GAAG,IAAI,CAAC;QAClD,MAAM,UAAU,GAAG,KAAK,CAAC,aAAa,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,kBAAkB,CAAC,CAAC;QAEzE,OAAO,UAAU,GAAG,KAAK,CAAC,eAAe,GAAG,GAAG,GAAG,cAAc,GAAG,cAAc,CAAC;IACtF,CAAC;IAEM,eAAe,CAAC,KAAwB,EAAE,YAAoB;QACjE,IAAI,KAAK,CAAC,gBAAgB,IAAI,CAAC,IAAI,KAAK,CAAC,iBAAiB,KAAK,CAAC;YAAE,OAAO,CAAC,CAAC;QAC3E,IAAI,KAAK,CAAC,iBAAiB,GAAG,CAAC;YAAE,OAAO,YAAY,CAAC;QAErD,MAAM,WAAW,GAAG,KAAK,CAAC,gBAAgB,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,YAAY,CAAC,CAAC;QAE7E,IAAI,WAAW,GAAG,GAAG;YAAE,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,YAAY,GAAG,CAAC,CAAC,CAAC,CAAC;QACxE,IAAI,WAAW,GAAG,IAAI;YAAE,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,YAAY,GAAG,CAAC,CAAC,CAAC,CAAC;QAEzE,OAAO,YAAY,CAAC;IACxB,CAAC;CACJ"}
@@ -1,2 +1,4 @@
1
1
  export { DownloadManager } from './manager';
2
- export type { DownloadManagerOptions, DownloadPeerPool, DownloadPeerSession, DownloadProgress, DownloadProgressEventMode, DownloadProgressListener, } from './manager';
2
+ export type { DownloadManagerOptions, DownloadProgress, DownloadProgressEventMode, DownloadProgressListener, } from './manager';
3
+ export { PeerScorer } from './PeerScorer';
4
+ export type { PeerDownloadStats } from './PeerScorer';
@@ -1,2 +1,3 @@
1
1
  export { DownloadManager } from './manager';
2
+ export { PeerScorer } from './PeerScorer';
2
3
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/torrent/download/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/torrent/download/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAO5C,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC"}
@@ -1,23 +1,14 @@
1
- import type { PeerMessage } from '../../peer/messages';
2
- import type { PieceAvailability, PiecePlanner } from '../pieces';
1
+ import type { PeerPool } from '../../peer/pool';
2
+ import type { PeerSession } from '../../peer/session';
3
+ import type { PiecePlanner } from '../pieces';
3
4
  import type { TorrentMetadata } from '../types';
4
5
  import { writeValidatedPiece } from '../storage';
5
6
  import type { TorrentFileSelection } from '../file-selection';
6
- export type DownloadPeerSession = {
7
- readonly choked: boolean;
8
- readonly peerAvailability: PieceAvailability;
9
- onClose(callback: () => void): () => void;
10
- onMessage(callback: (message: PeerMessage) => void): () => void;
11
- sendMessage(message: PeerMessage): void;
12
- };
13
- export type DownloadPeerPool<TPeer extends DownloadPeerSession = DownloadPeerSession> = {
14
- readonly done?: Promise<readonly TPeer[]>;
15
- onSession(callback: (session: TPeer) => void): () => void;
16
- };
17
- export type DownloadManagerOptions<TPeer extends DownloadPeerSession = DownloadPeerSession> = {
7
+ import { type PeerDownloadStats } from './PeerScorer';
8
+ export type DownloadManagerOptions = {
18
9
  metadata: TorrentMetadata;
19
10
  outputDirectory: string;
20
- peerPool: DownloadPeerPool<TPeer>;
11
+ peerPool: PeerPool;
21
12
  files?: TorrentFileSelection;
22
13
  maxInFlightRequestsPerPeer?: number;
23
14
  progressEvents?: DownloadProgressEventMode;
@@ -38,7 +29,7 @@ export type DownloadProgress = {
38
29
  speed: string;
39
30
  };
40
31
  export type DownloadProgressListener = (progress: DownloadProgress) => void;
41
- export declare class DownloadManager<TPeer extends DownloadPeerSession = DownloadPeerSession> {
32
+ export declare class DownloadManager {
42
33
  private readonly options;
43
34
  readonly done: Promise<void>;
44
35
  private readonly planner;
@@ -55,10 +46,13 @@ export declare class DownloadManager<TPeer extends DownloadPeerSession = Downloa
55
46
  private closed;
56
47
  private resolveDone;
57
48
  private rejectDone;
58
- constructor(options: DownloadManagerOptions<TPeer>);
49
+ private readonly peerScorer;
50
+ constructor(options: DownloadManagerOptions);
59
51
  get progress(): DownloadProgress;
52
+ private getProgressTotals;
60
53
  start(): void;
61
54
  onProgress(listener: DownloadProgressListener): () => void;
55
+ getPeerStats(peer: PeerSession): PeerDownloadStats | undefined;
62
56
  close(): void;
63
57
  private attachPeer;
64
58
  private detachPeer;
@@ -69,8 +63,16 @@ export declare class DownloadManager<TPeer extends DownloadPeerSession = Downloa
69
63
  private pumpPeer;
70
64
  private handleRequestTimeout;
71
65
  private sendInterestedIfUseful;
66
+ private hasUsefulRequest;
67
+ private getPeerRequestLimit;
68
+ private sendRequest;
69
+ private rollbackFailedSend;
70
+ private takePendingPieceRequest;
71
+ private takePendingRequest;
72
72
  private resetPieceForRetry;
73
+ private dropPendingRequestsForPiece;
73
74
  private pumpPeers;
75
+ private recordReceivedBlock;
74
76
  private clearPendingTimeouts;
75
77
  private emitProgress;
76
78
  private updateSpeed;
@@ -2,6 +2,7 @@ import { createPiecePlanner } from '../pieces';
2
2
  import { writeValidatedPiece } from '../storage';
3
3
  import { formatBytes } from '../../utils/formats';
4
4
  import { getSelectedPieceIndexes } from '../file-selection';
5
+ import { PeerScorer } from './PeerScorer';
5
6
  const DEFAULT_MAX_IN_FLIGHT_REQUESTS_PER_PEER = 20;
6
7
  const DEFAULT_PROGRESS_EVENTS = 'piece';
7
8
  const DEFAULT_REQUEST_TIMEOUT_MS = 15_000;
@@ -23,6 +24,7 @@ export class DownloadManager {
23
24
  closed = false;
24
25
  resolveDone;
25
26
  rejectDone;
27
+ peerScorer = new PeerScorer();
26
28
  constructor(options) {
27
29
  this.options = options;
28
30
  this.planner =
@@ -43,6 +45,15 @@ export class DownloadManager {
43
45
  });
44
46
  }
45
47
  get progress() {
48
+ const totals = this.getProgressTotals();
49
+ return {
50
+ ...totals,
51
+ percent: totals.totalBytes === 0 ? 1 : totals.downloadedBytes / totals.totalBytes,
52
+ speedBytesPerSecond: this.currentSpeedBytesPerSecond,
53
+ speed: `${formatBytes(this.currentSpeedBytesPerSecond)}ps`,
54
+ };
55
+ }
56
+ getProgressTotals() {
46
57
  let receivedBytes = 0;
47
58
  let downloadedBytes = 0;
48
59
  let totalBytes = 0;
@@ -59,14 +70,12 @@ export class DownloadManager {
59
70
  downloadedBytes,
60
71
  totalPieces: this.planner.totalPieces,
61
72
  completedPieces: this.planner.completedPieces,
62
- percent: totalBytes === 0 ? 1 : downloadedBytes / totalBytes,
63
- speedBytesPerSecond: this.currentSpeedBytesPerSecond,
64
- speed: `${formatBytes(this.currentSpeedBytesPerSecond)}ps`,
65
73
  };
66
74
  }
67
75
  start() {
68
76
  if (this.closed || this.offSession)
69
77
  return;
78
+ // The peer pool may already have connected sessions, so onSession is both a replay and a subscription.
70
79
  this.offSession = this.options.peerPool.onSession((session) => this.attachPeer(session));
71
80
  void this.options.peerPool.done?.then((sessions) => {
72
81
  if (sessions.length === 0)
@@ -80,6 +89,12 @@ export class DownloadManager {
80
89
  this.progressListeners.delete(listener);
81
90
  };
82
91
  }
92
+ getPeerStats(peer) {
93
+ const stats = this.peerStates.get(peer)?.stats;
94
+ if (!stats)
95
+ return undefined;
96
+ return { ...stats };
97
+ }
83
98
  close() {
84
99
  if (this.closed)
85
100
  return;
@@ -99,6 +114,7 @@ export class DownloadManager {
99
114
  peer,
100
115
  pending: [],
101
116
  interestedSent: false,
117
+ stats: createInitialPeerStats(),
102
118
  offClose: peer.onClose(() => this.handlePeerClosed(peer)),
103
119
  offMessage: peer.onMessage((message) => this.handlePeerMessage(peer, message)),
104
120
  };
@@ -108,6 +124,7 @@ export class DownloadManager {
108
124
  detachPeer(state) {
109
125
  state.offClose();
110
126
  state.offMessage();
127
+ // Any in-flight blocks owned by this peer must become available for another peer.
111
128
  this.clearPendingTimeouts(state.pending);
112
129
  this.planner.resetPeerRequests(state.pending.map((pending) => pending.request));
113
130
  state.pending = [];
@@ -123,6 +140,7 @@ export class DownloadManager {
123
140
  const state = this.peerStates.get(peer);
124
141
  if (!state || this.closed)
125
142
  return;
143
+ // Availability/choke changes are scheduling signals even when no block data arrived.
126
144
  if (message.type === 'unchoke' || message.type === 'have' || message.type === 'bitfield') {
127
145
  this.pumpPeer(state);
128
146
  return;
@@ -132,17 +150,13 @@ export class DownloadManager {
132
150
  }
133
151
  }
134
152
  async handlePiece(state, message) {
135
- const pendingIndex = state.pending.findIndex(({ request }) => request.pieceIndex === message.pieceIndex &&
136
- request.offset === message.offset &&
137
- request.length === message.block.byteLength);
138
- if (pendingIndex === -1)
153
+ const pending = this.takePendingPieceRequest(state, message);
154
+ if (!pending)
139
155
  return;
140
- const [pending] = state.pending.splice(pendingIndex, 1);
141
- if (pending)
142
- clearTimeout(pending.timeout);
156
+ this.recordReceivedBlock(state, pending, message);
143
157
  const completion = this.planner.receiveBlock(message);
144
158
  if (completion) {
145
- await this.handleCompletion(completion);
159
+ await this.handleCompletion(state, completion);
146
160
  this.emitProgress();
147
161
  }
148
162
  else if (this.progressEvents === 'block') {
@@ -151,78 +165,140 @@ export class DownloadManager {
151
165
  this.pumpPeer(state);
152
166
  this.resolveIfComplete();
153
167
  }
154
- async handleCompletion(completion) {
168
+ async handleCompletion(state, completion) {
155
169
  const result = await this.writeValidated(this.options.metadata, completion, {
156
170
  outputDirectory: this.options.outputDirectory,
157
171
  files: this.options.files,
158
172
  });
159
173
  if (!result.valid) {
174
+ state.stats.invalidPieces += 1;
160
175
  this.resetPieceForRetry(completion.pieceIndex);
176
+ return;
161
177
  }
178
+ state.stats.completedPieces += 1;
162
179
  }
163
180
  pumpPeer(state) {
164
- if (this.planner.complete)
181
+ if (this.closed || this.planner.complete)
165
182
  return;
166
183
  this.sendInterestedIfUseful(state);
167
184
  if (state.peer.choked)
168
185
  return;
169
- while (state.pending.length < this.maxInFlightRequestsPerPeer) {
186
+ // The scorer can throttle unreliable peers without disconnecting them.
187
+ const requestLimit = this.getPeerRequestLimit(state);
188
+ while (state.pending.length < requestLimit) {
170
189
  const request = this.planner.nextRequest(state.peer.peerAvailability);
171
190
  if (!request)
172
191
  break;
173
- this.planner.markPending(request);
174
- const timeout = setTimeout(() => this.handleRequestTimeout(state, request), this.requestTimeoutMs);
175
- unrefTimer(timeout);
176
- state.pending.push({
177
- request,
178
- timeout,
179
- });
180
- state.peer.sendMessage(request);
192
+ if (!this.sendRequest(state, request))
193
+ break;
181
194
  }
182
195
  }
183
196
  handleRequestTimeout(state, request) {
184
197
  if (this.closed || this.planner.complete)
185
198
  return;
186
- const pendingIndex = state.pending.findIndex((pending) => isSameRequest(pending.request, request));
187
- if (pendingIndex === -1)
199
+ const pending = this.takePendingRequest(state, request);
200
+ if (!pending)
188
201
  return;
189
- const [pending] = state.pending.splice(pendingIndex, 1);
190
- if (pending)
191
- clearTimeout(pending.timeout);
202
+ // Prefer retrying timed-out work on other peers before giving the same peer another slot.
203
+ state.stats.timedOutRequests += 1;
192
204
  this.planner.resetPending(request);
193
205
  this.pumpPeers(state);
194
206
  }
195
207
  sendInterestedIfUseful(state) {
196
208
  if (state.interestedSent)
197
209
  return;
198
- if (!this.planner.nextRequest(state.peer.peerAvailability))
210
+ if (!this.hasUsefulRequest(state))
199
211
  return;
200
212
  state.peer.sendMessage({ type: 'interested' });
201
213
  state.interestedSent = true;
202
214
  }
215
+ hasUsefulRequest(state) {
216
+ return this.planner.nextRequest(state.peer.peerAvailability) !== null;
217
+ }
218
+ getPeerRequestLimit(state) {
219
+ return this.peerScorer.getRequestLimit(state.stats, this.maxInFlightRequestsPerPeer);
220
+ }
221
+ sendRequest(state, request) {
222
+ this.planner.markPending(request);
223
+ // Keep the timer tied to this exact request so late blocks can cancel it deterministically.
224
+ const timeout = setTimeout(() => this.handleRequestTimeout(state, request), this.requestTimeoutMs);
225
+ unrefTimer(timeout);
226
+ state.pending.push({
227
+ request,
228
+ timeout,
229
+ requestedAt: Date.now(),
230
+ });
231
+ state.stats.sentRequests += 1;
232
+ try {
233
+ state.peer.sendMessage(request);
234
+ return true;
235
+ }
236
+ catch {
237
+ this.rollbackFailedSend(state, request);
238
+ this.handlePeerClosed(state.peer);
239
+ this.pumpPeers();
240
+ return false;
241
+ }
242
+ }
243
+ rollbackFailedSend(state, request) {
244
+ const pending = this.takePendingRequest(state, request);
245
+ if (!pending)
246
+ return;
247
+ this.planner.resetPending(request);
248
+ }
249
+ takePendingPieceRequest(state, message) {
250
+ return this.takePendingRequest(state, {
251
+ type: 'request',
252
+ pieceIndex: message.pieceIndex,
253
+ offset: message.offset,
254
+ length: message.block.byteLength,
255
+ });
256
+ }
257
+ takePendingRequest(state, request) {
258
+ const pendingIndex = state.pending.findIndex((pending) => isSameRequest(pending.request, request));
259
+ if (pendingIndex === -1)
260
+ return null;
261
+ const [pending] = state.pending.splice(pendingIndex, 1);
262
+ if (!pending)
263
+ return null;
264
+ clearTimeout(pending.timeout);
265
+ return pending;
266
+ }
203
267
  resetPieceForRetry(pieceIndex) {
204
268
  this.planner.resetPiece(pieceIndex);
269
+ // A bad piece invalidates every pending block for that piece, across all peers.
205
270
  for (const state of this.peerStates.values()) {
206
- const kept = [];
207
- for (const pending of state.pending) {
208
- if (pending.request.pieceIndex === pieceIndex) {
209
- clearTimeout(pending.timeout);
210
- }
211
- else {
212
- kept.push(pending);
213
- }
271
+ this.dropPendingRequestsForPiece(state, pieceIndex);
272
+ }
273
+ }
274
+ dropPendingRequestsForPiece(state, pieceIndex) {
275
+ const kept = [];
276
+ for (const pending of state.pending) {
277
+ if (pending.request.pieceIndex === pieceIndex) {
278
+ clearTimeout(pending.timeout);
279
+ continue;
214
280
  }
215
- state.pending = kept;
281
+ kept.push(pending);
216
282
  }
283
+ state.pending = kept;
217
284
  }
218
285
  pumpPeers(last) {
219
- for (const state of this.peerStates.values()) {
286
+ const states = [...this.peerStates.values()].sort((a, b) => this.peerScorer.getScore(b.stats) - this.peerScorer.getScore(a.stats));
287
+ for (const state of states) {
220
288
  if (state !== last)
221
289
  this.pumpPeer(state);
222
290
  }
223
291
  if (last)
224
292
  this.pumpPeer(last);
225
293
  }
294
+ recordReceivedBlock(state, pending, message) {
295
+ const now = Date.now();
296
+ state.stats.receivedBytes += message.block.byteLength;
297
+ state.stats.receivedBlocks += 1;
298
+ state.stats.completedRequests += 1;
299
+ state.stats.totalRequestTimeMs += Math.max(0, now - pending.requestedAt);
300
+ state.stats.lastBlockAt = now;
301
+ }
226
302
  clearPendingTimeouts(pending) {
227
303
  for (const request of pending)
228
304
  clearTimeout(request.timeout);
@@ -262,6 +338,17 @@ export class DownloadManager {
262
338
  }
263
339
  }
264
340
  const isSameRequest = (a, b) => a.pieceIndex === b.pieceIndex && a.offset === b.offset && a.length === b.length;
341
+ const createInitialPeerStats = () => ({
342
+ receivedBytes: 0,
343
+ receivedBlocks: 0,
344
+ timedOutRequests: 0,
345
+ sentRequests: 0,
346
+ completedPieces: 0,
347
+ invalidPieces: 0,
348
+ lastBlockAt: null,
349
+ totalRequestTimeMs: 0,
350
+ completedRequests: 0,
351
+ });
265
352
  const unrefTimer = (timer) => {
266
353
  if (typeof timer === 'object' && timer && 'unref' in timer) {
267
354
  timer.unref();
@@ -1 +1 @@
1
- {"version":3,"file":"manager.js","sourceRoot":"","sources":["../../../src/torrent/download/manager.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AAE/C,OAAO,EAAE,mBAAmB,EAA0B,MAAM,YAAY,CAAC;AACzE,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAElD,OAAO,EAAE,uBAAuB,EAAE,MAAM,mBAAmB,CAAC;AAwD5D,MAAM,uCAAuC,GAAG,EAAE,CAAC;AACnD,MAAM,uBAAuB,GAA8B,OAAO,CAAC;AACnE,MAAM,0BAA0B,GAAG,MAAM,CAAC;AAC1C,MAAM,gCAAgC,GAAG,GAAG,CAAC;AAE7C,MAAM,OAAO,eAAe;IAkBY;IAjBpB,IAAI,CAAgB;IAEnB,OAAO,CAAe;IACtB,0BAA0B,CAAS;IACnC,cAAc,CAA4B;IAC1C,gBAAgB,CAAS;IACzB,qBAAqB,CAAS;IAC9B,UAAU,GAAG,IAAI,GAAG,EAAmC,CAAC;IACxD,iBAAiB,GAAG,IAAI,GAAG,EAA4B,CAAC;IACxD,cAAc,CAA6B;IACpD,UAAU,GAAwB,IAAI,CAAC;IACvC,kBAAkB,GAA0D,IAAI,CAAC;IACjF,0BAA0B,GAAG,CAAC,CAAC;IAC/B,MAAM,GAAG,KAAK,CAAC;IACf,WAAW,CAAc;IACzB,UAAU,CAA4B;IAE9C,YAAoC,OAAsC;QAAtC,YAAO,GAAP,OAAO,CAA+B;QACtE,IAAI,CAAC,OAAO;YACR,OAAO,CAAC,OAAO;gBACf,kBAAkB,CAAC,OAAO,CAAC,QAAQ,EAAE;oBACjC,YAAY,EAAE,uBAAuB,CAAC,OAAO,CAAC,QAAQ,EAAE,OAAO,CAAC,KAAK,CAAC;iBACzE,CAAC,CAAC;QACP,IAAI,CAAC,0BAA0B;YAC3B,OAAO,CAAC,0BAA0B,IAAI,uCAAuC,CAAC;QAClF,IAAI,CAAC,cAAc,GAAG,OAAO,CAAC,cAAc,IAAI,uBAAuB,CAAC;QACxE,IAAI,CAAC,gBAAgB,GAAG,OAAO,CAAC,gBAAgB,IAAI,0BAA0B,CAAC;QAC/E,IAAI,CAAC,qBAAqB;YACtB,OAAO,CAAC,qBAAqB,IAAI,gCAAgC,CAAC;QACtE,IAAI,CAAC,cAAc,GAAG,OAAO,CAAC,mBAAmB,IAAI,mBAAmB,CAAC;QACzE,IAAI,CAAC,IAAI,GAAG,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACxC,IAAI,CAAC,WAAW,GAAG,OAAO,CAAC;YAC3B,IAAI,CAAC,UAAU,GAAG,MAAM,CAAC;QAC7B,CAAC,CAAC,CAAC;IACP,CAAC;IAED,IAAW,QAAQ;QACf,IAAI,aAAa,GAAG,CAAC,CAAC;QACtB,IAAI,eAAe,GAAG,CAAC,CAAC;QACxB,IAAI,UAAU,GAAG,CAAC,CAAC;QAEnB,KAAK,MAAM,UAAU,IAAI,IAAI,CAAC,OAAO,CAAC,YAAY,EAAE,CAAC;YACjD,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC;YACnD,UAAU,IAAI,KAAK,CAAC,MAAM,CAAC;YAC3B,aAAa,IAAI,KAAK,CAAC,aAAa,CAAC;YACrC,IAAI,KAAK,CAAC,MAAM,KAAK,UAAU;gBAAE,eAAe,IAAI,KAAK,CAAC,MAAM,CAAC;QACrE,CAAC;QAED,OAAO;YACH,UAAU;YACV,aAAa;YACb,eAAe;YACf,WAAW,EAAE,IAAI,CAAC,OAAO,CAAC,WAAW;YACrC,eAAe,EAAE,IAAI,CAAC,OAAO,CAAC,eAAe;YAC7C,OAAO,EAAE,UAAU,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,eAAe,GAAG,UAAU;YAC5D,mBAAmB,EAAE,IAAI,CAAC,0BAA0B;YACpD,KAAK,EAAE,GAAG,WAAW,CAAC,IAAI,CAAC,0BAA0B,CAAC,IAAI;SAC7D,CAAC;IACN,CAAC;IAEM,KAAK;QACR,IAAI,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,UAAU;YAAE,OAAO;QAE3C,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC;QACzF,KAAK,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,QAAQ,EAAE,EAAE;YAC/C,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;gBAAE,IAAI,CAAC,WAAW,EAAE,CAAC;QAClD,CAAC,CAAC,CAAC;QACH,IAAI,CAAC,iBAAiB,EAAE,CAAC;IAC7B,CAAC;IAEM,UAAU,CAAC,QAAkC;QAChD,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAErC,OAAO,GAAG,EAAE;YACR,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QAC5C,CAAC,CAAC;IACN,CAAC;IAEM,KAAK;QACR,IAAI,IAAI,CAAC,MAAM;YAAE,OAAO;QAExB,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;QACnB,IAAI,CAAC,UAAU,EAAE,EAAE,CAAC;QACpB,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;QAEvB,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,EAAE,CAAC;YAC3C,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;QAC3B,CAAC;QACD,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC;QACxB,IAAI,CAAC,WAAW,EAAE,CAAC;IACvB,CAAC;IAEO,UAAU,CAAC,IAAW;QAC1B,IAAI,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC;YAAE,OAAO;QAErD,MAAM,KAAK,GAA6B;YACpC,IAAI;YACJ,OAAO,EAAE,EAAE;YACX,cAAc,EAAE,KAAK;YACrB,QAAQ,EAAE,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC;YACzD,UAAU,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,IAAI,CAAC,iBAAiB,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;SACjF,CAAC;QAEF,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QACjC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IACzB,CAAC;IAEO,UAAU,CAAC,KAA+B;QAC9C,KAAK,CAAC,QAAQ,EAAE,CAAC;QACjB,KAAK,CAAC,UAAU,EAAE,CAAC;QACnB,IAAI,CAAC,oBAAoB,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QACzC,IAAI,CAAC,OAAO,CAAC,iBAAiB,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC;QAChF,KAAK,CAAC,OAAO,GAAG,EAAE,CAAC;IACvB,CAAC;IAEO,gBAAgB,CAAC,IAAW;QAChC,MAAM,KAAK,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACxC,IAAI,CAAC,KAAK;YAAE,OAAO;QAEnB,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;QACvB,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IACjC,CAAC;IAEO,iBAAiB,CAAC,IAAW,EAAE,OAAoB;QACvD,MAAM,KAAK,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACxC,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,MAAM;YAAE,OAAO;QAElC,IAAI,OAAO,CAAC,IAAI,KAAK,SAAS,IAAI,OAAO,CAAC,IAAI,KAAK,MAAM,IAAI,OAAO,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;YACvF,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;YACrB,OAAO;QACX,CAAC;QAED,IAAI,OAAO,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;YAC3B,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC;QAC9E,CAAC;IACL,CAAC;IAEO,KAAK,CAAC,WAAW,CACrB,KAA+B,EAC/B,OAAgD;QAEhD,MAAM,YAAY,GAAG,KAAK,CAAC,OAAO,CAAC,SAAS,CACxC,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,CACZ,OAAO,CAAC,UAAU,KAAK,OAAO,CAAC,UAAU;YACzC,OAAO,CAAC,MAAM,KAAK,OAAO,CAAC,MAAM;YACjC,OAAO,CAAC,MAAM,KAAK,OAAO,CAAC,KAAK,CAAC,UAAU,CAClD,CAAC;QACF,IAAI,YAAY,KAAK,CAAC,CAAC;YAAE,OAAO;QAEhC,MAAM,CAAC,OAAO,CAAC,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC;QACxD,IAAI,OAAO;YAAE,YAAY,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QAE3C,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;QAEtD,IAAI,UAAU,EAAE,CAAC;YACb,MAAM,IAAI,CAAC,gBAAgB,CAAC,UAAU,CAAC,CAAC;YACxC,IAAI,CAAC,YAAY,EAAE,CAAC;QACxB,CAAC;aAAM,IAAI,IAAI,CAAC,cAAc,KAAK,OAAO,EAAE,CAAC;YACzC,IAAI,CAAC,YAAY,EAAE,CAAC;QACxB,CAAC;QAED,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;QACrB,IAAI,CAAC,iBAAiB,EAAE,CAAC;IAC7B,CAAC;IAEO,KAAK,CAAC,gBAAgB,CAAC,UAA2B;QACtD,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,UAAU,EAAE;YACxE,eAAe,EAAE,IAAI,CAAC,OAAO,CAAC,eAAe;YAC7C,KAAK,EAAE,IAAI,CAAC,OAAO,CAAC,KAAK;SACA,CAAC,CAAC;QAE/B,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;YAChB,IAAI,CAAC,kBAAkB,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC;QACnD,CAAC;IACL,CAAC;IAEO,QAAQ,CAAC,KAA+B;QAC5C,IAAI,IAAI,CAAC,OAAO,CAAC,QAAQ;YAAE,OAAO;QAElC,IAAI,CAAC,sBAAsB,CAAC,KAAK,CAAC,CAAC;QACnC,IAAI,KAAK,CAAC,IAAI,CAAC,MAAM;YAAE,OAAO;QAE9B,OAAO,KAAK,CAAC,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,0BAA0B,EAAE,CAAC;YAC5D,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,KAAK,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;YACtE,IAAI,CAAC,OAAO;gBAAE,MAAM;YAEpB,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;YAClC,MAAM,OAAO,GAAG,UAAU,CACtB,GAAG,EAAE,CAAC,IAAI,CAAC,oBAAoB,CAAC,KAAK,EAAE,OAAO,CAAC,EAC/C,IAAI,CAAC,gBAAgB,CACxB,CAAC;YACF,UAAU,CAAC,OAAO,CAAC,CAAC;YACpB,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC;gBACf,OAAO;gBACP,OAAO;aACV,CAAC,CAAC;YACH,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;QACpC,CAAC;IACL,CAAC;IAEO,oBAAoB,CACxB,KAA+B,EAC/B,OAA0B;QAE1B,IAAI,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,OAAO,CAAC,QAAQ;YAAE,OAAO;QAEjD,MAAM,YAAY,GAAG,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,EAAE,CACrD,aAAa,CAAC,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,CAC1C,CAAC;QACF,IAAI,YAAY,KAAK,CAAC,CAAC;YAAE,OAAO;QAEhC,MAAM,CAAC,OAAO,CAAC,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC;QACxD,IAAI,OAAO;YAAE,YAAY,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QAE3C,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;QACnC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;IAC1B,CAAC;IAEO,sBAAsB,CAAC,KAA+B;QAC1D,IAAI,KAAK,CAAC,cAAc;YAAE,OAAO;QACjC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,KAAK,CAAC,IAAI,CAAC,gBAAgB,CAAC;YAAE,OAAO;QAEnE,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC,CAAC;QAC/C,KAAK,CAAC,cAAc,GAAG,IAAI,CAAC;IAChC,CAAC;IAEO,kBAAkB,CAAC,UAAkB;QACzC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC;QAEpC,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,EAAE,CAAC;YAC3C,MAAM,IAAI,GAAyB,EAAE,CAAC;YACtC,KAAK,MAAM,OAAO,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;gBAClC,IAAI,OAAO,CAAC,OAAO,CAAC,UAAU,KAAK,UAAU,EAAE,CAAC;oBAC5C,YAAY,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;gBAClC,CAAC;qBAAM,CAAC;oBACJ,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;gBACvB,CAAC;YACL,CAAC;YACD,KAAK,CAAC,OAAO,GAAG,IAAI,CAAC;QACzB,CAAC;IACL,CAAC;IAEO,SAAS,CAAC,IAA+B;QAC7C,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,EAAE,CAAC;YAC3C,IAAI,KAAK,KAAK,IAAI;gBAAE,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;QAC7C,CAAC;QACD,IAAI,IAAI;YAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;IAClC,CAAC;IAEO,oBAAoB,CAAC,OAA6B;QACtD,KAAK,MAAM,OAAO,IAAI,OAAO;YAAE,YAAY,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IACjE,CAAC;IAEO,YAAY;QAChB,IAAI,CAAC,WAAW,EAAE,CAAC;QACnB,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC;QAC/B,KAAK,MAAM,QAAQ,IAAI,IAAI,CAAC,iBAAiB;YAAE,QAAQ,CAAC,QAAQ,CAAC,CAAC;IACtE,CAAC;IAEO,WAAW;QACf,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,MAAM,aAAa,GAAG,IAAI,CAAC,gBAAgB,EAAE,CAAC;QAC9C,MAAM,IAAI,GAAG,IAAI,CAAC,kBAAkB,CAAC;QAErC,IAAI,IAAI,EAAE,CAAC;YACP,MAAM,SAAS,GAAG,GAAG,GAAG,IAAI,CAAC,WAAW,CAAC;YACzC,IAAI,SAAS,GAAG,IAAI,CAAC,qBAAqB;gBAAE,OAAO;YAEnD,MAAM,cAAc,GAAG,SAAS,GAAG,KAAK,CAAC;YACzC,MAAM,aAAa,GAAG,aAAa,GAAG,IAAI,CAAC,aAAa,CAAC;YACzD,IAAI,CAAC,0BAA0B;gBAC3B,cAAc,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,aAAa,GAAG,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC7E,CAAC;QAED,IAAI,CAAC,kBAAkB,GAAG,EAAE,aAAa,EAAE,WAAW,EAAE,GAAG,EAAE,CAAC;IAClE,CAAC;IAEO,gBAAgB;QACpB,IAAI,aAAa,GAAG,CAAC,CAAC;QAEtB,KAAK,MAAM,UAAU,IAAI,IAAI,CAAC,OAAO,CAAC,YAAY,EAAE,CAAC;YACjD,aAAa,IAAI,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC,aAAa,CAAC;QACxE,CAAC;QAED,OAAO,aAAa,CAAC;IACzB,CAAC;IAEO,iBAAiB;QACrB,IAAI,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC;YACxB,IAAI,CAAC,WAAW,EAAE,CAAC;QACvB,CAAC;IACL,CAAC;CACJ;AAED,MAAM,aAAa,GAAG,CAAC,CAAoB,EAAE,CAAoB,EAAW,EAAE,CAC1E,CAAC,CAAC,UAAU,KAAK,CAAC,CAAC,UAAU,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,MAAM,CAAC;AAEpF,MAAM,UAAU,GAAG,CAAC,KAAoC,EAAQ,EAAE;IAC9D,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,IAAI,OAAO,IAAI,KAAK,EAAE,CAAC;QACxD,KAA+B,CAAC,KAAK,EAAE,CAAC;IAC7C,CAAC;AACL,CAAC,CAAC"}
1
+ {"version":3,"file":"manager.js","sourceRoot":"","sources":["../../../src/torrent/download/manager.ts"],"names":[],"mappings":"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"}
@@ -10,7 +10,7 @@ export { BencodeDecodeError, BencodeDecodeErrorCode, BencodeEncodeError, Bencode
10
10
  export { TorrentParseError, TorrentParseErrorCode } from './parser/parser.error';
11
11
  export type { BBytes, BDict, BInteger, BList, BValue, BencodeInput } from './bencode';
12
12
  export type { PieceAvailability, PieceBlock, PieceBlockRequest, PieceCompletion, PiecePlanner, PiecePlannerOptions, PieceProgress, PieceStatus, PieceValidationResult, } from './pieces';
13
- export type { DownloadManagerOptions, DownloadPeerPool, DownloadPeerSession, DownloadProgress, DownloadProgressEventMode, DownloadProgressListener, } from './download';
13
+ export type { DownloadManagerOptions, DownloadProgress, DownloadProgressEventMode, DownloadProgressListener, PeerDownloadStats, } from './download';
14
14
  export type { TorrentFileSelection } from './file-selection';
15
15
  export type { FileWrite, WritePieceOptions } from './storage';
16
16
  export type { TorrentFiles, TorrentStateChange, TorrentStats } from './session/index';
@@ -22,7 +22,7 @@ export type TorrentEventMap = {
22
22
  close: [];
23
23
  done: [];
24
24
  error: [error: unknown];
25
- peer: [session: unknown];
25
+ peer: [stats: TorrentStats];
26
26
  progress: [progress: DownloadProgress];
27
27
  state: [change: TorrentStateChange];
28
28
  };
@@ -55,11 +55,13 @@ export declare class Torrent {
55
55
  private readonly peerPool;
56
56
  private readonly downloadManager?;
57
57
  private readonly selectedFiles?;
58
+ private readonly seed;
58
59
  readonly done: Promise<void>;
59
60
  private readonly listeners;
60
61
  private currentState;
61
62
  private lastError;
62
- constructor(metadata: TorrentMetadata, peerPool: TorrentPeerPool, downloadManager?: TorrentDownloadManager | undefined, selectedFiles?: (Set<string> | null) | undefined);
63
+ private resourcesClosed;
64
+ constructor(metadata: TorrentMetadata, peerPool: TorrentPeerPool, downloadManager?: TorrentDownloadManager | undefined, selectedFiles?: (Set<string> | null) | undefined, seed?: false);
63
65
  get state(): TorrentState;
64
66
  get error(): unknown;
65
67
  get stats(): TorrentStats;
@@ -67,6 +69,7 @@ export declare class Torrent {
67
69
  get files(): TorrentFiles;
68
70
  on<TEvent extends TorrentEventName>(event: TEvent, listener: TorrentEventListener<TEvent>): () => void;
69
71
  close(): void;
72
+ private closeResources;
70
73
  private setState;
71
74
  private emit;
72
75
  private getListeners;
@@ -10,15 +10,18 @@ export class Torrent {
10
10
  peerPool;
11
11
  downloadManager;
12
12
  selectedFiles;
13
+ seed;
13
14
  done;
14
15
  listeners = new Map();
15
16
  currentState = TorrentState.DOWNLOADING;
16
17
  lastError;
17
- constructor(metadata, peerPool, downloadManager, selectedFiles) {
18
+ resourcesClosed = false;
19
+ constructor(metadata, peerPool, downloadManager, selectedFiles, seed = false) {
18
20
  this.metadata = metadata;
19
21
  this.peerPool = peerPool;
20
22
  this.downloadManager = downloadManager;
21
23
  this.selectedFiles = selectedFiles;
24
+ this.seed = seed;
22
25
  this.downloadManager?.onProgress((progress) => this.emit('progress', progress));
23
26
  this.downloadManager?.start();
24
27
  this.done = downloadManager?.done ?? peerPool.done.then(() => undefined);
@@ -27,12 +30,15 @@ export class Torrent {
27
30
  return;
28
31
  this.setState(TorrentState.COMPLETED);
29
32
  this.emit('done');
33
+ if (!this.seed)
34
+ this.closeResources();
30
35
  }, (error) => {
31
36
  if (this.currentState === TorrentState.CLOSED)
32
37
  return;
33
38
  this.lastError = error;
34
39
  this.setState(TorrentState.FAILED);
35
40
  this.emit('error', error);
41
+ this.closeResources();
36
42
  });
37
43
  }
38
44
  get state() {
@@ -72,8 +78,8 @@ export class Torrent {
72
78
  }
73
79
  on(event, listener) {
74
80
  if (event === 'peer') {
75
- return this.peerPool.onSession((session) => {
76
- listener(session);
81
+ return this.peerPool.onSession(() => {
82
+ listener(this.stats);
77
83
  });
78
84
  }
79
85
  const listeners = this.getListeners(event);
@@ -85,11 +91,17 @@ export class Torrent {
85
91
  close() {
86
92
  if (this.currentState === TorrentState.CLOSED)
87
93
  return;
88
- this.downloadManager?.close();
89
- this.peerPool.close();
94
+ this.closeResources();
90
95
  this.setState(TorrentState.CLOSED);
91
96
  this.emit('close');
92
97
  }
98
+ closeResources() {
99
+ if (this.resourcesClosed)
100
+ return;
101
+ this.resourcesClosed = true;
102
+ this.downloadManager?.close();
103
+ this.peerPool.close();
104
+ }
93
105
  setState(state) {
94
106
  if (this.currentState === state)
95
107
  return;
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/torrent/session/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/torrent/session/index.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bun-torrent",
3
- "version": "0.0.3-beta",
3
+ "version": "0.0.4-beta",
4
4
  "type": "module",
5
5
  "module": "dist/index.js",
6
6
  "types": "dist/index.d.ts",