bun-torrent 0.0.7 → 0.0.8
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.d.ts +121 -0
- package/dist/client.error.d.ts +10 -0
- package/dist/client.error.js +10 -0
- package/dist/client.error.js.map +1 -1
- package/dist/client.js +75 -0
- package/dist/client.js.map +1 -1
- package/dist/magnet/base32/errors.d.ts +11 -1
- package/dist/magnet/base32/errors.js +10 -1
- package/dist/magnet/base32/errors.js.map +1 -1
- package/dist/magnet/parser/errors.d.ts +19 -1
- package/dist/magnet/parser/errors.js +17 -1
- package/dist/magnet/parser/errors.js.map +1 -1
- package/dist/peer/pool/pool.error.d.ts +14 -1
- package/dist/peer/pool/pool.error.js +13 -1
- package/dist/peer/pool/pool.error.js.map +1 -1
- package/dist/peer/session/session.error.d.ts +16 -1
- package/dist/peer/session/session.error.js +15 -1
- package/dist/peer/session/session.error.js.map +1 -1
- package/dist/torrent/download/DownloadManager.d.ts +12 -0
- package/dist/torrent/download/DownloadManager.js.map +1 -1
- package/dist/torrent/parser/parser.error.d.ts +11 -1
- package/dist/torrent/parser/parser.error.js +10 -1
- package/dist/torrent/parser/parser.error.js.map +1 -1
- package/dist/torrent/pieces/planner.error.d.ts +10 -1
- package/dist/torrent/pieces/planner.error.js +9 -1
- package/dist/torrent/pieces/planner.error.js.map +1 -1
- package/dist/torrent/session/Torrent.d.ts +83 -0
- package/dist/torrent/session/Torrent.js +66 -0
- package/dist/torrent/session/Torrent.js.map +1 -1
- package/dist/torrent/storage/storage.error.d.ts +10 -1
- package/dist/torrent/storage/storage.error.js +9 -1
- package/dist/torrent/storage/storage.error.js.map +1 -1
- package/dist/torrent/types.d.ts +18 -0
- package/dist/tracker/tracker.error.d.ts +12 -1
- package/dist/tracker/tracker.error.js +11 -1
- package/dist/tracker/tracker.error.js.map +1 -1
- package/dist/utils/errors.d.ts +20 -1
- package/dist/utils/errors.js +19 -1
- package/dist/utils/errors.js.map +1 -1
- package/package.json +1 -1
package/dist/client.d.ts
CHANGED
|
@@ -3,29 +3,60 @@ import { Torrent } from './torrent/session/index';
|
|
|
3
3
|
import type { TorrentMetadata } from './torrent/types';
|
|
4
4
|
import type { TorrentFileSelection } from './torrent/file-selection';
|
|
5
5
|
import type { PeerInfo } from './tracker/types';
|
|
6
|
+
/**
|
|
7
|
+
* Setup phases reported through {@link DownloadOptions.onChangeState} before download starts.
|
|
8
|
+
*
|
|
9
|
+
* The values are emitted in order: `parsing` → `tracking` → `connecting` → `downloading`.
|
|
10
|
+
* Once `downloading` fires, progress events take over via {@link Torrent.on}.
|
|
11
|
+
*/
|
|
6
12
|
export declare enum DownloadState {
|
|
7
13
|
PARSING = "parsing",
|
|
8
14
|
TRACKING = "tracking",
|
|
9
15
|
CONNECTING = "connecting",
|
|
10
16
|
DOWNLOADING = "downloading"
|
|
11
17
|
}
|
|
18
|
+
/**
|
|
19
|
+
* Minimal DHT contract used by {@link Client} for peer discovery.
|
|
20
|
+
*
|
|
21
|
+
* Implement this to swap the default in-memory DHT for a persistent or
|
|
22
|
+
* shared implementation. `close` is called from {@link Client.close}.
|
|
23
|
+
*/
|
|
12
24
|
export type ClientDht = {
|
|
13
25
|
lookupPeers(infoHash: Uint8Array): Promise<PeerInfo[]>;
|
|
14
26
|
close?(): void;
|
|
15
27
|
};
|
|
28
|
+
/**
|
|
29
|
+
* Default options applied to every download started by a {@link Client}.
|
|
30
|
+
*
|
|
31
|
+
* All fields are optional. Any field can be overridden per-download via
|
|
32
|
+
* {@link DownloadOptions}.
|
|
33
|
+
*/
|
|
16
34
|
export type ClientConfig = {
|
|
35
|
+
/** Custom DHT implementation, or `false` to disable DHT entirely. Defaults to an in-memory {@link DhtClient}. */
|
|
17
36
|
dht?: ClientDht | false;
|
|
37
|
+
/** Default file selection for multi-file torrents. `null`/omitted downloads every file. */
|
|
18
38
|
files?: TorrentFileSelection;
|
|
39
|
+
/** Maximum block requests in flight per peer. Higher values increase throughput but also memory. Defaults to 300. */
|
|
19
40
|
maxInFlightRequestsPerPeer?: number;
|
|
41
|
+
/** Maximum simultaneous peer connection attempts. Defaults to 30. */
|
|
20
42
|
maxConnecting?: number;
|
|
43
|
+
/** Minimum connected peers required before download starts. `0` allows downloads to start with no peers. Defaults to 0. */
|
|
21
44
|
minConnections?: number;
|
|
45
|
+
/** Directory where downloaded files are written. Defaults to `process.cwd()`. */
|
|
22
46
|
outputDirectory?: string;
|
|
47
|
+
/** Timeout for a single peer TCP connect + handshake, in milliseconds. Defaults to 5000. */
|
|
23
48
|
peerConnectTimeoutMs?: number;
|
|
49
|
+
/** Granularity of `progress` events: `'piece'` (once per validated piece) or `'block'` (every received block). Defaults to `'piece'`. */
|
|
24
50
|
progressEvents?: DownloadProgressEventMode;
|
|
51
|
+
/** Timeout for a single block request, in milliseconds. Timed-out requests are retried on other peers. Defaults to 15000. */
|
|
25
52
|
requestTimeoutMs?: number;
|
|
53
|
+
/** Reserved for future seeding support. Currently only `false` is supported. */
|
|
26
54
|
seed?: false;
|
|
55
|
+
/** Minimum interval between speed recalculations, in milliseconds. Defaults to 500. */
|
|
27
56
|
speedSampleIntervalMs?: number;
|
|
57
|
+
/** Preferred number of connected peers. The pool stops opening new connections once this is reached. Defaults to 20. */
|
|
28
58
|
targetConnections?: number;
|
|
59
|
+
/** Timeout for tracker announce requests, in milliseconds. Defaults to 5000. */
|
|
29
60
|
trackerTimeoutMs?: number;
|
|
30
61
|
};
|
|
31
62
|
type InspectInput = {
|
|
@@ -40,6 +71,25 @@ type InspectInput = {
|
|
|
40
71
|
type DownloadInput = {
|
|
41
72
|
meta: TorrentMetadata;
|
|
42
73
|
} | InspectInput;
|
|
74
|
+
/**
|
|
75
|
+
* Entry point of the library. Holds shared state (peer id, DHT node) across downloads.
|
|
76
|
+
*
|
|
77
|
+
* One `Client` instance can run multiple concurrent downloads. The same client is also
|
|
78
|
+
* reused across `inspect` → `download` flows so the DHT routing table and peer cache
|
|
79
|
+
* can warm up once and pay off on subsequent calls.
|
|
80
|
+
*
|
|
81
|
+
* Call {@link Client.close} when the client is no longer needed — it closes every
|
|
82
|
+
* active torrent and the DHT socket. After close, every method throws {@link ClientError}.
|
|
83
|
+
*
|
|
84
|
+
* @example
|
|
85
|
+
* const client = new Client({ outputDirectory: './downloads' });
|
|
86
|
+
* try {
|
|
87
|
+
* const torrent = await client.download({ torrentFile: './example.torrent' });
|
|
88
|
+
* await torrent.done;
|
|
89
|
+
* } finally {
|
|
90
|
+
* client.close();
|
|
91
|
+
* }
|
|
92
|
+
*/
|
|
43
93
|
export declare class Client {
|
|
44
94
|
private readonly config;
|
|
45
95
|
private readonly peerId;
|
|
@@ -47,33 +97,104 @@ export declare class Client {
|
|
|
47
97
|
private readonly dht?;
|
|
48
98
|
private readonly torrents;
|
|
49
99
|
private closed;
|
|
100
|
+
/**
|
|
101
|
+
* Build a client with optional defaults that apply to every download.
|
|
102
|
+
*
|
|
103
|
+
* The constructor is cheap: it generates a peer id and a DHT node id but does not
|
|
104
|
+
* open any sockets. The default DHT instance opens its UDP socket lazily on the
|
|
105
|
+
* first lookup.
|
|
106
|
+
*
|
|
107
|
+
* @param config - Defaults applied to downloads started by this client.
|
|
108
|
+
*/
|
|
50
109
|
constructor(config?: ClientConfig);
|
|
110
|
+
/**
|
|
111
|
+
* Start downloading a torrent and return a {@link Torrent} that emits progress events.
|
|
112
|
+
*
|
|
113
|
+
* The returned promise settles once the client has parsed metadata, discovered peers,
|
|
114
|
+
* opened the peer pool, and started the download manager. The actual download runs
|
|
115
|
+
* in the background — `await torrent.done` or listen for the `done` event to wait
|
|
116
|
+
* for it to finish.
|
|
117
|
+
*
|
|
118
|
+
* Tracker failures are non-fatal: if no tracker returns peers, DHT lookup is attempted
|
|
119
|
+
* when DHT is enabled. With DHT disabled, the download continues with whatever peers
|
|
120
|
+
* were found provided `minConnections` is `0`.
|
|
121
|
+
*
|
|
122
|
+
* @param input - Torrent source: a `.torrent` file path/bytes, a magnet URI, or already-parsed `meta`.
|
|
123
|
+
* @param options - Per-download overrides for {@link ClientConfig}, plus `announcePort` and `onChangeState`.
|
|
124
|
+
* @returns A {@link Torrent} whose `done` promise settles when the download finishes or fails.
|
|
125
|
+
* @throws {ClientError} When the client is closed, the input is unsupported, or file selection is invalid.
|
|
126
|
+
*/
|
|
51
127
|
download(input: DownloadInput, options?: DownloadOptions): Promise<Torrent>;
|
|
128
|
+
/**
|
|
129
|
+
* Parse a `.torrent` file or magnet URI and return its metadata without starting a download.
|
|
130
|
+
*
|
|
131
|
+
* Useful for showing the file list, computing total size, or letting the user pick
|
|
132
|
+
* a subset of files before calling {@link Client.download}. For magnet links this
|
|
133
|
+
* method fetches the info dictionary from a peer using the `ut_metadata` extension,
|
|
134
|
+
* so it may discover and warm DHT state that a later `download({ meta })` call reuses.
|
|
135
|
+
*
|
|
136
|
+
* @param input - Either `{ torrentFile }` (path/bytes/ArrayBuffer) or `{ magnet }` (URI string).
|
|
137
|
+
* @param options - Optional overrides. `timeout` caps the per-peer metadata fetch for magnets.
|
|
138
|
+
* @returns Parsed torrent metadata, including computed info hash.
|
|
139
|
+
* @throws {ClientError} When the client is closed or no input is provided.
|
|
140
|
+
* @throws {TorrentParseError} When the torrent file or magnet info dictionary cannot be parsed.
|
|
141
|
+
* @throws {MagnetParseError} When the magnet URI is invalid or no peer returned metadata.
|
|
142
|
+
*/
|
|
52
143
|
inspect(input: InspectInput, options?: {
|
|
53
144
|
timeout?: number;
|
|
54
145
|
}): Promise<TorrentMetadata>;
|
|
146
|
+
/**
|
|
147
|
+
* Stop the client, close every active torrent, and release the DHT socket.
|
|
148
|
+
*
|
|
149
|
+
* Idempotent — calling close more than once is a no-op. After close, every other
|
|
150
|
+
* method throws {@link ClientError} with code `CLIENT_CLOSED`.
|
|
151
|
+
*/
|
|
55
152
|
close(): void;
|
|
56
153
|
private discoverPeers;
|
|
57
154
|
private trackPeers;
|
|
58
155
|
private trackTorrent;
|
|
59
156
|
private assertOpen;
|
|
60
157
|
}
|
|
158
|
+
/**
|
|
159
|
+
* Per-download overrides passed to {@link Client.download}.
|
|
160
|
+
*
|
|
161
|
+
* Every field except `announcePort` and `onChangeState` overrides the matching field
|
|
162
|
+
* in {@link ClientConfig} for this download only.
|
|
163
|
+
*/
|
|
61
164
|
export type DownloadOptions = {
|
|
165
|
+
/** Port sent to trackers in announce requests. Defaults to 6881. */
|
|
62
166
|
announcePort?: number;
|
|
167
|
+
/** Restrict the download to specific files. Selectable by `'a/b.txt'` string or `['a','b.txt']` array. */
|
|
63
168
|
files?: TorrentFileSelection;
|
|
169
|
+
/** Override {@link ClientConfig.maxInFlightRequestsPerPeer} for this download. */
|
|
64
170
|
maxInFlightRequestsPerPeer?: number;
|
|
171
|
+
/** Override {@link ClientConfig.maxConnecting} for this download. */
|
|
65
172
|
maxConnecting?: number;
|
|
173
|
+
/** Override {@link ClientConfig.minConnections} for this download. */
|
|
66
174
|
minConnections?: number;
|
|
175
|
+
/** Called with each setup phase before download starts. See {@link DownloadState}. */
|
|
67
176
|
onChangeState?: (state: DownloadState) => unknown;
|
|
177
|
+
/** Override {@link ClientConfig.outputDirectory} for this download. */
|
|
68
178
|
outputDirectory?: string;
|
|
179
|
+
/** Override {@link ClientConfig.peerConnectTimeoutMs} for this download. */
|
|
69
180
|
peerConnectTimeoutMs?: number;
|
|
181
|
+
/** Override {@link ClientConfig.progressEvents} for this download. */
|
|
70
182
|
progressEvents?: DownloadProgressEventMode;
|
|
183
|
+
/** Override {@link ClientConfig.requestTimeoutMs} for this download. */
|
|
71
184
|
requestTimeoutMs?: number;
|
|
185
|
+
/** Reserved for future seeding support. Currently only `false` is supported. */
|
|
72
186
|
seed?: false;
|
|
187
|
+
/** Override {@link ClientConfig.speedSampleIntervalMs} for this download. */
|
|
73
188
|
speedSampleIntervalMs?: number;
|
|
189
|
+
/** Override {@link ClientConfig.targetConnections} for this download. */
|
|
74
190
|
targetConnections?: number;
|
|
191
|
+
/** Override {@link ClientConfig.trackerTimeoutMs} for this download. */
|
|
75
192
|
trackerTimeoutMs?: number;
|
|
76
193
|
};
|
|
194
|
+
/** Supported torrent file sources. */
|
|
77
195
|
export type TorrentFileInput = string | Uint8Array | ArrayBuffer;
|
|
196
|
+
/**
|
|
197
|
+
* @internal
|
|
198
|
+
*/
|
|
78
199
|
export declare const readTorrentFile: (input: unknown) => Promise<Uint8Array>;
|
|
79
200
|
export { Client as TorrentClient };
|
package/dist/client.error.d.ts
CHANGED
|
@@ -1,9 +1,19 @@
|
|
|
1
1
|
import { BunTorrentError } from './utils/errors';
|
|
2
|
+
/** Error codes set on {@link ClientError.code}. */
|
|
2
3
|
export declare enum ClientErrorCode {
|
|
4
|
+
/** {@link Client.download} or {@link Client.inspect} called after {@link Client.close}. */
|
|
3
5
|
CLOSED = "CLIENT_CLOSED",
|
|
6
|
+
/** `files` option referenced paths that do not exist in the torrent. */
|
|
4
7
|
INVALID_FILE_SELECTION = "CLIENT_INVALID_FILE_SELECTION",
|
|
8
|
+
/** Torrent file input was neither a string path, `Uint8Array`, nor `ArrayBuffer`. */
|
|
5
9
|
UNSUPPORTED_TORRENT_FILE_INPUT = "CLIENT_UNSUPPORTED_TORRENT_FILE_INPUT"
|
|
6
10
|
}
|
|
11
|
+
/**
|
|
12
|
+
* Errors thrown directly by {@link Client}. See {@link ClientErrorCode}.
|
|
13
|
+
*
|
|
14
|
+
* Errors from underlying subsystems (parser, tracker, peer pool, DHT) are thrown as
|
|
15
|
+
* their own classes — this one only wraps client-level failures.
|
|
16
|
+
*/
|
|
7
17
|
export declare class ClientError extends BunTorrentError {
|
|
8
18
|
constructor(code: ClientErrorCode, message: string);
|
|
9
19
|
}
|
package/dist/client.error.js
CHANGED
|
@@ -1,10 +1,20 @@
|
|
|
1
1
|
import { BunTorrentError } from './utils/errors';
|
|
2
|
+
/** Error codes set on {@link ClientError.code}. */
|
|
2
3
|
export var ClientErrorCode;
|
|
3
4
|
(function (ClientErrorCode) {
|
|
5
|
+
/** {@link Client.download} or {@link Client.inspect} called after {@link Client.close}. */
|
|
4
6
|
ClientErrorCode["CLOSED"] = "CLIENT_CLOSED";
|
|
7
|
+
/** `files` option referenced paths that do not exist in the torrent. */
|
|
5
8
|
ClientErrorCode["INVALID_FILE_SELECTION"] = "CLIENT_INVALID_FILE_SELECTION";
|
|
9
|
+
/** Torrent file input was neither a string path, `Uint8Array`, nor `ArrayBuffer`. */
|
|
6
10
|
ClientErrorCode["UNSUPPORTED_TORRENT_FILE_INPUT"] = "CLIENT_UNSUPPORTED_TORRENT_FILE_INPUT";
|
|
7
11
|
})(ClientErrorCode || (ClientErrorCode = {}));
|
|
12
|
+
/**
|
|
13
|
+
* Errors thrown directly by {@link Client}. See {@link ClientErrorCode}.
|
|
14
|
+
*
|
|
15
|
+
* Errors from underlying subsystems (parser, tracker, peer pool, DHT) are thrown as
|
|
16
|
+
* their own classes — this one only wraps client-level failures.
|
|
17
|
+
*/
|
|
8
18
|
export class ClientError extends BunTorrentError {
|
|
9
19
|
constructor(code, message) {
|
|
10
20
|
super(message, code);
|
package/dist/client.error.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.error.js","sourceRoot":"","sources":["../src/client.error.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAEjD,MAAM,CAAN,IAAY,
|
|
1
|
+
{"version":3,"file":"client.error.js","sourceRoot":"","sources":["../src/client.error.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAEjD,mDAAmD;AACnD,MAAM,CAAN,IAAY,eAOX;AAPD,WAAY,eAAe;IACvB,2FAA2F;IAC3F,2CAAwB,CAAA;IACxB,wEAAwE;IACxE,2EAAwD,CAAA;IACxD,qFAAqF;IACrF,2FAAwE,CAAA;AAC5E,CAAC,EAPW,eAAe,KAAf,eAAe,QAO1B;AAED;;;;;GAKG;AACH,MAAM,OAAO,WAAY,SAAQ,eAAe;IAC5C,YAAY,IAAqB,EAAE,OAAe;QAC9C,KAAK,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;IACzB,CAAC;CACJ"}
|
package/dist/client.js
CHANGED
|
@@ -11,6 +11,12 @@ import { BunTorrentError } from './utils/errors';
|
|
|
11
11
|
import { parseMagnet } from './magnet';
|
|
12
12
|
import { DhtClient } from './dht';
|
|
13
13
|
import { createDhtNodeId } from './dht/utils/distance';
|
|
14
|
+
/**
|
|
15
|
+
* Setup phases reported through {@link DownloadOptions.onChangeState} before download starts.
|
|
16
|
+
*
|
|
17
|
+
* The values are emitted in order: `parsing` → `tracking` → `connecting` → `downloading`.
|
|
18
|
+
* Once `downloading` fires, progress events take over via {@link Torrent.on}.
|
|
19
|
+
*/
|
|
14
20
|
export var DownloadState;
|
|
15
21
|
(function (DownloadState) {
|
|
16
22
|
DownloadState["PARSING"] = "parsing";
|
|
@@ -18,6 +24,25 @@ export var DownloadState;
|
|
|
18
24
|
DownloadState["CONNECTING"] = "connecting";
|
|
19
25
|
DownloadState["DOWNLOADING"] = "downloading";
|
|
20
26
|
})(DownloadState || (DownloadState = {}));
|
|
27
|
+
/**
|
|
28
|
+
* Entry point of the library. Holds shared state (peer id, DHT node) across downloads.
|
|
29
|
+
*
|
|
30
|
+
* One `Client` instance can run multiple concurrent downloads. The same client is also
|
|
31
|
+
* reused across `inspect` → `download` flows so the DHT routing table and peer cache
|
|
32
|
+
* can warm up once and pay off on subsequent calls.
|
|
33
|
+
*
|
|
34
|
+
* Call {@link Client.close} when the client is no longer needed — it closes every
|
|
35
|
+
* active torrent and the DHT socket. After close, every method throws {@link ClientError}.
|
|
36
|
+
*
|
|
37
|
+
* @example
|
|
38
|
+
* const client = new Client({ outputDirectory: './downloads' });
|
|
39
|
+
* try {
|
|
40
|
+
* const torrent = await client.download({ torrentFile: './example.torrent' });
|
|
41
|
+
* await torrent.done;
|
|
42
|
+
* } finally {
|
|
43
|
+
* client.close();
|
|
44
|
+
* }
|
|
45
|
+
*/
|
|
21
46
|
export class Client {
|
|
22
47
|
config;
|
|
23
48
|
peerId;
|
|
@@ -25,6 +50,15 @@ export class Client {
|
|
|
25
50
|
dht;
|
|
26
51
|
torrents = new Set();
|
|
27
52
|
closed = false;
|
|
53
|
+
/**
|
|
54
|
+
* Build a client with optional defaults that apply to every download.
|
|
55
|
+
*
|
|
56
|
+
* The constructor is cheap: it generates a peer id and a DHT node id but does not
|
|
57
|
+
* open any sockets. The default DHT instance opens its UDP socket lazily on the
|
|
58
|
+
* first lookup.
|
|
59
|
+
*
|
|
60
|
+
* @param config - Defaults applied to downloads started by this client.
|
|
61
|
+
*/
|
|
28
62
|
constructor(config = {}) {
|
|
29
63
|
this.config = config;
|
|
30
64
|
this.peerId = createPeerId();
|
|
@@ -34,6 +68,23 @@ export class Client {
|
|
|
34
68
|
? undefined
|
|
35
69
|
: (config.dht ?? new DhtClient({ nodeId: this.dhtNodeId }));
|
|
36
70
|
}
|
|
71
|
+
/**
|
|
72
|
+
* Start downloading a torrent and return a {@link Torrent} that emits progress events.
|
|
73
|
+
*
|
|
74
|
+
* The returned promise settles once the client has parsed metadata, discovered peers,
|
|
75
|
+
* opened the peer pool, and started the download manager. The actual download runs
|
|
76
|
+
* in the background — `await torrent.done` or listen for the `done` event to wait
|
|
77
|
+
* for it to finish.
|
|
78
|
+
*
|
|
79
|
+
* Tracker failures are non-fatal: if no tracker returns peers, DHT lookup is attempted
|
|
80
|
+
* when DHT is enabled. With DHT disabled, the download continues with whatever peers
|
|
81
|
+
* were found provided `minConnections` is `0`.
|
|
82
|
+
*
|
|
83
|
+
* @param input - Torrent source: a `.torrent` file path/bytes, a magnet URI, or already-parsed `meta`.
|
|
84
|
+
* @param options - Per-download overrides for {@link ClientConfig}, plus `announcePort` and `onChangeState`.
|
|
85
|
+
* @returns A {@link Torrent} whose `done` promise settles when the download finishes or fails.
|
|
86
|
+
* @throws {ClientError} When the client is closed, the input is unsupported, or file selection is invalid.
|
|
87
|
+
*/
|
|
37
88
|
async download(input, options = {}) {
|
|
38
89
|
this.assertOpen();
|
|
39
90
|
options.onChangeState?.(DownloadState.PARSING);
|
|
@@ -66,6 +117,21 @@ export class Client {
|
|
|
66
117
|
this.trackTorrent(torrent);
|
|
67
118
|
return torrent;
|
|
68
119
|
}
|
|
120
|
+
/**
|
|
121
|
+
* Parse a `.torrent` file or magnet URI and return its metadata without starting a download.
|
|
122
|
+
*
|
|
123
|
+
* Useful for showing the file list, computing total size, or letting the user pick
|
|
124
|
+
* a subset of files before calling {@link Client.download}. For magnet links this
|
|
125
|
+
* method fetches the info dictionary from a peer using the `ut_metadata` extension,
|
|
126
|
+
* so it may discover and warm DHT state that a later `download({ meta })` call reuses.
|
|
127
|
+
*
|
|
128
|
+
* @param input - Either `{ torrentFile }` (path/bytes/ArrayBuffer) or `{ magnet }` (URI string).
|
|
129
|
+
* @param options - Optional overrides. `timeout` caps the per-peer metadata fetch for magnets.
|
|
130
|
+
* @returns Parsed torrent metadata, including computed info hash.
|
|
131
|
+
* @throws {ClientError} When the client is closed or no input is provided.
|
|
132
|
+
* @throws {TorrentParseError} When the torrent file or magnet info dictionary cannot be parsed.
|
|
133
|
+
* @throws {MagnetParseError} When the magnet URI is invalid or no peer returned metadata.
|
|
134
|
+
*/
|
|
69
135
|
async inspect(input, options) {
|
|
70
136
|
this.assertOpen();
|
|
71
137
|
if ('torrentFile' in input && input.torrentFile !== undefined) {
|
|
@@ -77,6 +143,12 @@ export class Client {
|
|
|
77
143
|
}
|
|
78
144
|
throw new BunTorrentError('No input provided', 'NO_INPUT');
|
|
79
145
|
}
|
|
146
|
+
/**
|
|
147
|
+
* Stop the client, close every active torrent, and release the DHT socket.
|
|
148
|
+
*
|
|
149
|
+
* Idempotent — calling close more than once is a no-op. After close, every other
|
|
150
|
+
* method throws {@link ClientError} with code `CLIENT_CLOSED`.
|
|
151
|
+
*/
|
|
80
152
|
close() {
|
|
81
153
|
if (this.closed)
|
|
82
154
|
return;
|
|
@@ -160,6 +232,9 @@ const assertValidFileSelection = (metadata, files) => {
|
|
|
160
232
|
return;
|
|
161
233
|
throw new ClientError(ClientErrorCode.INVALID_FILE_SELECTION, `Unknown torrent file selection: ${unknownFiles.join(', ')}`);
|
|
162
234
|
};
|
|
235
|
+
/**
|
|
236
|
+
* @internal
|
|
237
|
+
*/
|
|
163
238
|
export const readTorrentFile = async (input) => {
|
|
164
239
|
if (typeof input === 'string')
|
|
165
240
|
return await Bun.file(input).bytes();
|
package/dist/client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,eAAe,EAAkC,MAAM,oBAAoB,CAAC;AACrF,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAChD,OAAO,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;AAElD,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAC9D,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAEvE,OAAO,EAAE,uBAAuB,EAAE,6BAA6B,EAAE,MAAM,0BAA0B,CAAC;AAClG,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AACvC,OAAO,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAClC,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAGvD,MAAM,CAAN,IAAY,aAKX;AALD,WAAY,aAAa;IACrB,oCAAmB,CAAA;IACnB,sCAAqB,CAAA;IACrB,0CAAyB,CAAA;IACzB,4CAA2B,CAAA;AAC/B,CAAC,EALW,aAAa,KAAb,aAAa,QAKxB;
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,eAAe,EAAkC,MAAM,oBAAoB,CAAC;AACrF,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAChD,OAAO,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;AAElD,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAC9D,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAEvE,OAAO,EAAE,uBAAuB,EAAE,6BAA6B,EAAE,MAAM,0BAA0B,CAAC;AAClG,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AACvC,OAAO,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAClC,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAGvD;;;;;GAKG;AACH,MAAM,CAAN,IAAY,aAKX;AALD,WAAY,aAAa;IACrB,oCAAmB,CAAA;IACnB,sCAAqB,CAAA;IACrB,0CAAyB,CAAA;IACzB,4CAA2B,CAAA;AAC/B,CAAC,EALW,aAAa,KAAb,aAAa,QAKxB;AA8DD;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,OAAO,MAAM;IAgBc;IAfZ,MAAM,CAAa;IACnB,SAAS,CAAa;IACtB,GAAG,CAAa;IAChB,QAAQ,GAAG,IAAI,GAAG,EAAW,CAAC;IACvC,MAAM,GAAG,KAAK,CAAC;IAEvB;;;;;;;;OAQG;IACH,YAA6B,SAAuB,EAAE;QAAzB,WAAM,GAAN,MAAM,CAAmB;QAClD,IAAI,CAAC,MAAM,GAAG,YAAY,EAAE,CAAC;QAC7B,IAAI,CAAC,SAAS,GAAG,eAAe,EAAE,CAAC;QACnC,IAAI,CAAC,GAAG;YACJ,MAAM,CAAC,GAAG,KAAK,KAAK;gBAChB,CAAC,CAAC,SAAS;gBACX,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,IAAI,IAAI,SAAS,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC;IACxE,CAAC;IAED;;;;;;;;;;;;;;;;OAgBG;IACI,KAAK,CAAC,QAAQ,CAAC,KAAoB,EAAE,UAA2B,EAAE;QACrE,IAAI,CAAC,UAAU,EAAE,CAAC;QAClB,OAAO,CAAC,aAAa,EAAE,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;QAC/C,MAAM,IAAI,GACN,KAAK,CAAC,IAAI,IAAI,CAAC,MAAM,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,OAAO,EAAE,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAAC,CAAC;QACrF,MAAM,cAAc,GAAG,qBAAqB,CAAC,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QACnE,wBAAwB,CAAC,IAAI,EAAE,cAAc,CAAC,KAAK,CAAC,CAAC;QAErD,OAAO,CAAC,aAAa,EAAE,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;QAChD,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,IAAI,EAAE,OAAO,EAAE,cAAc,CAAC,CAAC;QAEtE,OAAO,CAAC,aAAa,EAAE,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC;QAClD,MAAM,IAAI,GAAG,MAAM,YAAY,CAAC,KAAK,EAAE;YACnC,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,iBAAiB,EAAE,cAAc,CAAC,iBAAiB;YACnD,WAAW,EAAE,IAAI,CAAC,MAAM,CAAC,MAAM;YAC/B,cAAc,EAAE,cAAc,CAAC,cAAc;YAC7C,aAAa,EAAE,cAAc,CAAC,aAAa;YAC3C,SAAS,EAAE,cAAc,CAAC,oBAAoB;SACjD,CAAC,CAAC;QAEH,OAAO,CAAC,aAAa,EAAE,CAAC,aAAa,CAAC,WAAW,CAAC,CAAC;QACnD,MAAM,OAAO,GAAG,IAAI,OAAO,CACvB,IAAI,EACJ,IAAI,EACJ,IAAI,eAAe,CAAC;YAChB,QAAQ,EAAE,IAAI;YACd,KAAK,EAAE,cAAc,CAAC,KAAK;YAC3B,eAAe,EAAE,cAAc,CAAC,eAAe;YAC/C,QAAQ,EAAE,IAAI;YACd,0BAA0B,EAAE,cAAc,CAAC,0BAA0B;YACrE,cAAc,EAAE,cAAc,CAAC,cAAc;YAC7C,gBAAgB,EAAE,cAAc,CAAC,gBAAgB;YACjD,qBAAqB,EAAE,cAAc,CAAC,qBAAqB;SAC9D,CAAC,EACF,6BAA6B,CAAC,cAAc,CAAC,KAAK,CAAC,EACnD,cAAc,CAAC,IAAI,CACtB,CAAC;QAEF,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;QAC3B,OAAO,OAAO,CAAC;IACnB,CAAC;IAED;;;;;;;;;;;;;;OAcG;IACI,KAAK,CAAC,OAAO,CAChB,KAAmB,EACnB,OAA8B;QAE9B,IAAI,CAAC,UAAU,EAAE,CAAC;QAClB,IAAI,aAAa,IAAI,KAAK,IAAI,KAAK,CAAC,WAAW,KAAK,SAAS,EAAE,CAAC;YAC5D,MAAM,KAAK,GAAG,MAAM,eAAe,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;YACvD,OAAO,YAAY,CAAC,KAAK,CAAC,CAAC;QAC/B,CAAC;QACD,IAAI,QAAQ,IAAI,KAAK,IAAI,KAAK,CAAC,MAAM,KAAK,SAAS,IAAI,KAAK,CAAC,MAAM,KAAK,IAAI,EAAE,CAAC;YAC3E,OAAO,WAAW,CAAC,KAAK,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,EAAE,GAAG,OAAO,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;QACjF,CAAC;QACD,MAAM,IAAI,eAAe,CAAC,mBAAmB,EAAE,UAAU,CAAC,CAAC;IAC/D,CAAC;IAED;;;;;OAKG;IACI,KAAK;QACR,IAAI,IAAI,CAAC,MAAM;YAAE,OAAO;QAExB,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;QACnB,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,QAAQ;YAAE,OAAO,CAAC,KAAK,EAAE,CAAC;QACrD,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC;QACtB,IAAI,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE,CAAC;IACxB,CAAC;IAEO,KAAK,CAAC,aAAa,CACvB,IAAqB,EACrB,OAAwB,EACxB,MAA8B;QAE9B,MAAM,KAAK,GAAG,IAAI,GAAG,EAAoB,CAAC;QAE1C,KAAK,MAAM,IAAI,IAAI,MAAM,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,CAAC;YAC9D,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC,CAAC;QACnC,CAAC;QAED,IAAI,KAAK,CAAC,IAAI,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG;YAAE,OAAO,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC;QAE5D,IAAI,CAAC;YACD,KAAK,MAAM,IAAI,IAAI,MAAM,IAAI,CAAC,GAAG,CAAC,WAAW,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;gBAC3D,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC,CAAC;YACnC,CAAC;QACL,CAAC;QAAC,MAAM,CAAC;YACL,OAAO,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC;QAC/B,CAAC;QAED,OAAO,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC;IAC/B,CAAC;IAEO,KAAK,CAAC,UAAU,CACpB,IAAqB,EACrB,OAAwB,EACxB,MAA8B;QAE9B,IAAI,CAAC;YACD,OAAO,MAAM,UAAU,CAAC;gBACpB,IAAI;gBACJ,MAAM,EAAE,IAAI,CAAC,MAAM;gBACnB,YAAY,EAAE,OAAO,CAAC,YAAY;gBAClC,SAAS,EAAE,MAAM,CAAC,gBAAgB;aACrC,CAAC,CAAC;QACP,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACb,IAAI,sBAAsB,CAAC,KAAK,CAAC;gBAAE,OAAO,EAAE,CAAC;YAC7C,MAAM,KAAK,CAAC;QAChB,CAAC;IACL,CAAC;IAEO,YAAY,CAAC,OAAgB;QACjC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QAC3B,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC;QACzD,KAAK,OAAO,CAAC,IAAI,CAAC,IAAI,CAClB,GAAG,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,EACnC,GAAG,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,CACtC,CAAC;IACN,CAAC;IAEO,UAAU;QACd,IAAI,CAAC,IAAI,CAAC,MAAM;YAAE,OAAO;QAEzB,MAAM,IAAI,WAAW,CAAC,eAAe,CAAC,MAAM,EAAE,0BAA0B,CAAC,CAAC;IAC9E,CAAC;CACJ;AAyCD,MAAM,sBAAsB,GAAG,CAAC,KAAc,EAAyB,EAAE,CACrE,KAAK,YAAY,YAAY;IAC7B,CAAC,KAAK,CAAC,IAAI,KAAK,gBAAgB,CAAC,eAAe;QAC5C,KAAK,CAAC,IAAI,KAAK,gBAAgB,CAAC,QAAQ;QACxC,KAAK,CAAC,IAAI,KAAK,gBAAgB,CAAC,qBAAqB,CAAC,CAAC;AAE/D,MAAM,OAAO,GAAG,CAAC,IAAc,EAAU,EAAE,CAAC,GAAG,IAAI,CAAC,EAAE,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;AAEtE,MAAM,qBAAqB,GAAG,CAC1B,MAAoB,EACpB,OAAwB,EACF,EAAE,CAAC,CAAC;IAC1B,KAAK,EAAE,OAAO,CAAC,KAAK,IAAI,MAAM,CAAC,KAAK,IAAI,IAAI;IAC5C,0BAA0B,EACtB,OAAO,CAAC,0BAA0B;QAClC,MAAM,CAAC,0BAA0B;QACjC,QAAQ,CAAC,QAAQ,CAAC,0BAA0B;IAChD,aAAa,EAAE,OAAO,CAAC,aAAa,IAAI,MAAM,CAAC,aAAa,IAAI,QAAQ,CAAC,KAAK,CAAC,aAAa;IAC5F,cAAc,EACV,OAAO,CAAC,cAAc,IAAI,MAAM,CAAC,cAAc,IAAI,QAAQ,CAAC,KAAK,CAAC,cAAc;IACpF,eAAe,EAAE,OAAO,CAAC,eAAe,IAAI,MAAM,CAAC,eAAe,IAAI,OAAO,CAAC,GAAG,EAAE;IACnF,oBAAoB,EAChB,OAAO,CAAC,oBAAoB;QAC5B,MAAM,CAAC,oBAAoB;QAC3B,QAAQ,CAAC,KAAK,CAAC,gBAAgB;IACnC,cAAc,EAAE,OAAO,CAAC,cAAc,IAAI,MAAM,CAAC,cAAc,IAAI,QAAQ,CAAC,QAAQ,CAAC,MAAM;IAC3F,gBAAgB,EACZ,OAAO,CAAC,gBAAgB,IAAI,MAAM,CAAC,gBAAgB,IAAI,QAAQ,CAAC,QAAQ,CAAC,gBAAgB;IAC7F,IAAI,EAAE,OAAO,CAAC,IAAI,IAAI,MAAM,CAAC,IAAI,IAAI,QAAQ,CAAC,QAAQ,CAAC,IAAI;IAC3D,qBAAqB,EACjB,OAAO,CAAC,qBAAqB;QAC7B,MAAM,CAAC,qBAAqB;QAC5B,QAAQ,CAAC,QAAQ,CAAC,qBAAqB;IAC3C,iBAAiB,EACb,OAAO,CAAC,iBAAiB,IAAI,MAAM,CAAC,iBAAiB,IAAI,QAAQ,CAAC,KAAK,CAAC,iBAAiB;IAC7F,gBAAgB,EACZ,OAAO,CAAC,gBAAgB,IAAI,MAAM,CAAC,gBAAgB,IAAI,QAAQ,CAAC,QAAQ,CAAC,SAAS;CACzF,CAAC,CAAC;AAEH,MAAM,wBAAwB,GAAG,CAC7B,QAAyB,EACzB,KAAuC,EACnC,EAAE;IACN,MAAM,YAAY,GAAG,uBAAuB,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;IAC9D,IAAI,YAAY,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO;IAEtC,MAAM,IAAI,WAAW,CACjB,eAAe,CAAC,sBAAsB,EACtC,mCAAmC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAC/D,CAAC;AACN,CAAC,CAAC;AAKF;;GAEG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,KAAK,EAAE,KAAc,EAAuB,EAAE;IACzE,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,MAAM,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,CAAC;IACpE,IAAI,KAAK,YAAY,UAAU;QAAE,OAAO,KAAK,CAAC;IAC9C,IAAI,KAAK,YAAY,WAAW;QAAE,OAAO,IAAI,UAAU,CAAC,KAAK,CAAC,CAAC;IAE/D,MAAM,IAAI,WAAW,CACjB,eAAe,CAAC,8BAA8B,EAC9C,gCAAgC,CACnC,CAAC;AACN,CAAC,CAAC;AAEF,OAAO,EAAE,MAAM,IAAI,aAAa,EAAE,CAAC"}
|
|
@@ -1,8 +1,18 @@
|
|
|
1
1
|
import { BunTorrentError } from '../../utils/errors';
|
|
2
|
+
/** Error codes set on {@link Base32DecoderError.code}. */
|
|
2
3
|
export declare enum Base32DecoderErrorCode {
|
|
4
|
+
/** Input contained a character outside the base32 alphabet. */
|
|
3
5
|
INVALID_CHAR = "INVALID_BASE32_CHAR"
|
|
4
6
|
}
|
|
7
|
+
/**
|
|
8
|
+
* Errors from base32 decoding of magnet info hashes (BEP 9 short form, 32 chars).
|
|
9
|
+
*
|
|
10
|
+
* Surfaces during {@link parseMagnetURI} when the `xt` info hash uses base32 instead of hex.
|
|
11
|
+
*/
|
|
5
12
|
export declare class Base32DecoderError extends BunTorrentError {
|
|
13
|
+
/** Optional field path for context. */
|
|
6
14
|
readonly field?: string | undefined;
|
|
7
|
-
constructor(code: Base32DecoderErrorCode, message: string,
|
|
15
|
+
constructor(code: Base32DecoderErrorCode, message: string,
|
|
16
|
+
/** Optional field path for context. */
|
|
17
|
+
field?: string | undefined);
|
|
8
18
|
}
|
|
@@ -1,11 +1,20 @@
|
|
|
1
1
|
import { BunTorrentError } from '../../utils/errors';
|
|
2
|
+
/** Error codes set on {@link Base32DecoderError.code}. */
|
|
2
3
|
export var Base32DecoderErrorCode;
|
|
3
4
|
(function (Base32DecoderErrorCode) {
|
|
5
|
+
/** Input contained a character outside the base32 alphabet. */
|
|
4
6
|
Base32DecoderErrorCode["INVALID_CHAR"] = "INVALID_BASE32_CHAR";
|
|
5
7
|
})(Base32DecoderErrorCode || (Base32DecoderErrorCode = {}));
|
|
8
|
+
/**
|
|
9
|
+
* Errors from base32 decoding of magnet info hashes (BEP 9 short form, 32 chars).
|
|
10
|
+
*
|
|
11
|
+
* Surfaces during {@link parseMagnetURI} when the `xt` info hash uses base32 instead of hex.
|
|
12
|
+
*/
|
|
6
13
|
export class Base32DecoderError extends BunTorrentError {
|
|
7
14
|
field;
|
|
8
|
-
constructor(code, message,
|
|
15
|
+
constructor(code, message,
|
|
16
|
+
/** Optional field path for context. */
|
|
17
|
+
field) {
|
|
9
18
|
super(message, code);
|
|
10
19
|
this.field = field;
|
|
11
20
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../../src/magnet/base32/errors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAErD,MAAM,CAAN,IAAY,
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../../src/magnet/base32/errors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAErD,0DAA0D;AAC1D,MAAM,CAAN,IAAY,sBAGX;AAHD,WAAY,sBAAsB;IAC9B,+DAA+D;IAC/D,8DAAoC,CAAA;AACxC,CAAC,EAHW,sBAAsB,KAAtB,sBAAsB,QAGjC;AAED;;;;GAIG;AACH,MAAM,OAAO,kBAAmB,SAAQ,eAAe;IAK/B;IAJpB,YACI,IAA4B,EAC5B,OAAe;IACf,uCAAuC;IACvB,KAAc;QAE9B,KAAK,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;QAFL,UAAK,GAAL,KAAK,CAAS;IAGlC,CAAC;CACJ"}
|
|
@@ -1,13 +1,31 @@
|
|
|
1
1
|
import { BunTorrentError } from '../../utils/errors';
|
|
2
|
+
/** Error codes set on {@link MagnetParseError.code}. */
|
|
2
3
|
export declare enum MagnetParseErrorCode {
|
|
4
|
+
/** Magnet string is not a valid `magnet:` URI. */
|
|
3
5
|
INVALID_URI = "INVALID_MAGNET_URI",
|
|
6
|
+
/** The `xt` parameter is missing, has the wrong scheme, or carries a malformed info hash. */
|
|
4
7
|
INVALID_XT = "INVALID_XT_PARAM",
|
|
8
|
+
/** Magnet had no trackers and no DHT was provided to resolve peers. */
|
|
5
9
|
NOT_IMPLEMENTED = "NOT_IMPLEMENTED",
|
|
10
|
+
/** No peer returned the info dictionary via `ut_metadata` within the timeout. */
|
|
6
11
|
NO_METADATA = "NO_METADATA",
|
|
12
|
+
/** Info dictionary was received but failed to parse. See `cause`. */
|
|
7
13
|
PARSING_FAILED = "METADATA_FAILED_TO_PARSE"
|
|
8
14
|
}
|
|
15
|
+
/**
|
|
16
|
+
* Errors thrown while parsing a magnet URI or fetching its info dictionary from peers.
|
|
17
|
+
*
|
|
18
|
+
* For magnets the parser must discover peers (trackers + DHT) and fetch the info dict
|
|
19
|
+
* via the `ut_metadata` extension; this class covers failures along that pipeline.
|
|
20
|
+
*/
|
|
9
21
|
export declare class MagnetParseError extends BunTorrentError {
|
|
22
|
+
/** Field name involved in the failure, when applicable. */
|
|
10
23
|
readonly field?: string | undefined;
|
|
24
|
+
/** Underlying error (e.g. the bencode parse failure for `PARSING_FAILED`). */
|
|
11
25
|
readonly cause?: unknown | undefined;
|
|
12
|
-
constructor(code: MagnetParseErrorCode, message: string,
|
|
26
|
+
constructor(code: MagnetParseErrorCode, message: string,
|
|
27
|
+
/** Field name involved in the failure, when applicable. */
|
|
28
|
+
field?: string | undefined,
|
|
29
|
+
/** Underlying error (e.g. the bencode parse failure for `PARSING_FAILED`). */
|
|
30
|
+
cause?: unknown | undefined);
|
|
13
31
|
}
|
|
@@ -1,16 +1,32 @@
|
|
|
1
1
|
import { BunTorrentError } from '../../utils/errors';
|
|
2
|
+
/** Error codes set on {@link MagnetParseError.code}. */
|
|
2
3
|
export var MagnetParseErrorCode;
|
|
3
4
|
(function (MagnetParseErrorCode) {
|
|
5
|
+
/** Magnet string is not a valid `magnet:` URI. */
|
|
4
6
|
MagnetParseErrorCode["INVALID_URI"] = "INVALID_MAGNET_URI";
|
|
7
|
+
/** The `xt` parameter is missing, has the wrong scheme, or carries a malformed info hash. */
|
|
5
8
|
MagnetParseErrorCode["INVALID_XT"] = "INVALID_XT_PARAM";
|
|
9
|
+
/** Magnet had no trackers and no DHT was provided to resolve peers. */
|
|
6
10
|
MagnetParseErrorCode["NOT_IMPLEMENTED"] = "NOT_IMPLEMENTED";
|
|
11
|
+
/** No peer returned the info dictionary via `ut_metadata` within the timeout. */
|
|
7
12
|
MagnetParseErrorCode["NO_METADATA"] = "NO_METADATA";
|
|
13
|
+
/** Info dictionary was received but failed to parse. See `cause`. */
|
|
8
14
|
MagnetParseErrorCode["PARSING_FAILED"] = "METADATA_FAILED_TO_PARSE";
|
|
9
15
|
})(MagnetParseErrorCode || (MagnetParseErrorCode = {}));
|
|
16
|
+
/**
|
|
17
|
+
* Errors thrown while parsing a magnet URI or fetching its info dictionary from peers.
|
|
18
|
+
*
|
|
19
|
+
* For magnets the parser must discover peers (trackers + DHT) and fetch the info dict
|
|
20
|
+
* via the `ut_metadata` extension; this class covers failures along that pipeline.
|
|
21
|
+
*/
|
|
10
22
|
export class MagnetParseError extends BunTorrentError {
|
|
11
23
|
field;
|
|
12
24
|
cause;
|
|
13
|
-
constructor(code, message,
|
|
25
|
+
constructor(code, message,
|
|
26
|
+
/** Field name involved in the failure, when applicable. */
|
|
27
|
+
field,
|
|
28
|
+
/** Underlying error (e.g. the bencode parse failure for `PARSING_FAILED`). */
|
|
29
|
+
cause) {
|
|
14
30
|
super(message, code);
|
|
15
31
|
this.field = field;
|
|
16
32
|
this.cause = cause;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../../src/magnet/parser/errors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAErD,MAAM,CAAN,IAAY,
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../../src/magnet/parser/errors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAErD,wDAAwD;AACxD,MAAM,CAAN,IAAY,oBAWX;AAXD,WAAY,oBAAoB;IAC5B,kDAAkD;IAClD,0DAAkC,CAAA;IAClC,6FAA6F;IAC7F,uDAA+B,CAAA;IAC/B,uEAAuE;IACvE,2DAAmC,CAAA;IACnC,iFAAiF;IACjF,mDAA2B,CAAA;IAC3B,qEAAqE;IACrE,mEAA2C,CAAA;AAC/C,CAAC,EAXW,oBAAoB,KAApB,oBAAoB,QAW/B;AAED;;;;;GAKG;AACH,MAAM,OAAO,gBAAiB,SAAQ,eAAe;IAK7B;IAES;IAN7B,YACI,IAA0B,EAC1B,OAAe;IACf,2DAA2D;IAC3C,KAAc;IAC9B,8EAA8E;IACrD,KAAe;QAExC,KAAK,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;QAJL,UAAK,GAAL,KAAK,CAAS;QAEL,UAAK,GAAL,KAAK,CAAU;IAG5C,CAAC;CACJ"}
|
|
@@ -1,10 +1,23 @@
|
|
|
1
1
|
import { BunTorrentError } from '../../utils/errors';
|
|
2
|
+
/** Error codes set on {@link PeerPoolError.code}. */
|
|
2
3
|
export declare enum PeerPoolErrorCode {
|
|
4
|
+
/** A pool option (e.g. `targetConnections`) failed validation. */
|
|
3
5
|
INVALID_OPTION = "PEER_POOL_INVALID_OPTION",
|
|
6
|
+
/** Every peer attempt failed and the connected count is below `minConnections`. See `causes` for details. */
|
|
4
7
|
NO_CONNECTABLE_PEERS = "PEER_POOL_NO_CONNECTABLE_PEERS",
|
|
8
|
+
/** No peers were provided and `minConnections` is greater than zero. */
|
|
5
9
|
NO_PEERS = "PEER_POOL_NO_PEERS"
|
|
6
10
|
}
|
|
11
|
+
/**
|
|
12
|
+
* Errors thrown by the peer connection pool.
|
|
13
|
+
*
|
|
14
|
+
* Typically reaches the caller as a download-time failure when no peers can be reached
|
|
15
|
+
* and `minConnections` is not zero.
|
|
16
|
+
*/
|
|
7
17
|
export declare class PeerPoolError extends BunTorrentError {
|
|
18
|
+
/** Individual peer connection errors collected during pool ramp-up. */
|
|
8
19
|
readonly causes: unknown[];
|
|
9
|
-
constructor(code: PeerPoolErrorCode, message: string,
|
|
20
|
+
constructor(code: PeerPoolErrorCode, message: string,
|
|
21
|
+
/** Individual peer connection errors collected during pool ramp-up. */
|
|
22
|
+
causes?: unknown[]);
|
|
10
23
|
}
|
|
@@ -1,13 +1,25 @@
|
|
|
1
1
|
import { BunTorrentError } from '../../utils/errors';
|
|
2
|
+
/** Error codes set on {@link PeerPoolError.code}. */
|
|
2
3
|
export var PeerPoolErrorCode;
|
|
3
4
|
(function (PeerPoolErrorCode) {
|
|
5
|
+
/** A pool option (e.g. `targetConnections`) failed validation. */
|
|
4
6
|
PeerPoolErrorCode["INVALID_OPTION"] = "PEER_POOL_INVALID_OPTION";
|
|
7
|
+
/** Every peer attempt failed and the connected count is below `minConnections`. See `causes` for details. */
|
|
5
8
|
PeerPoolErrorCode["NO_CONNECTABLE_PEERS"] = "PEER_POOL_NO_CONNECTABLE_PEERS";
|
|
9
|
+
/** No peers were provided and `minConnections` is greater than zero. */
|
|
6
10
|
PeerPoolErrorCode["NO_PEERS"] = "PEER_POOL_NO_PEERS";
|
|
7
11
|
})(PeerPoolErrorCode || (PeerPoolErrorCode = {}));
|
|
12
|
+
/**
|
|
13
|
+
* Errors thrown by the peer connection pool.
|
|
14
|
+
*
|
|
15
|
+
* Typically reaches the caller as a download-time failure when no peers can be reached
|
|
16
|
+
* and `minConnections` is not zero.
|
|
17
|
+
*/
|
|
8
18
|
export class PeerPoolError extends BunTorrentError {
|
|
9
19
|
causes;
|
|
10
|
-
constructor(code, message,
|
|
20
|
+
constructor(code, message,
|
|
21
|
+
/** Individual peer connection errors collected during pool ramp-up. */
|
|
22
|
+
causes = []) {
|
|
11
23
|
super(message, code);
|
|
12
24
|
this.causes = causes;
|
|
13
25
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pool.error.js","sourceRoot":"","sources":["../../../src/peer/pool/pool.error.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAErD,MAAM,CAAN,IAAY,
|
|
1
|
+
{"version":3,"file":"pool.error.js","sourceRoot":"","sources":["../../../src/peer/pool/pool.error.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAErD,qDAAqD;AACrD,MAAM,CAAN,IAAY,iBAOX;AAPD,WAAY,iBAAiB;IACzB,kEAAkE;IAClE,gEAA2C,CAAA;IAC3C,6GAA6G;IAC7G,4EAAuD,CAAA;IACvD,wEAAwE;IACxE,oDAA+B,CAAA;AACnC,CAAC,EAPW,iBAAiB,KAAjB,iBAAiB,QAO5B;AAED;;;;;GAKG;AACH,MAAM,OAAO,aAAc,SAAQ,eAAe;IAK1B;IAJpB,YACI,IAAuB,EACvB,OAAe;IACf,uEAAuE;IACvD,SAAoB,EAAE;QAEtC,KAAK,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;QAFL,WAAM,GAAN,MAAM,CAAgB;IAG1C,CAAC;CACJ"}
|
|
@@ -1,12 +1,27 @@
|
|
|
1
1
|
import { BunTorrentError } from '../../utils/errors';
|
|
2
|
+
/** Error codes set on {@link PeerSessionError.code}. */
|
|
2
3
|
export declare enum PeerSessionErrorCode {
|
|
4
|
+
/** The session was closed before or during the operation. */
|
|
3
5
|
CLOSED = "PEER_SESSION_CLOSED",
|
|
6
|
+
/** The TCP connect or handshake exceeded `peerConnectTimeoutMs`. */
|
|
4
7
|
CONNECT_TIMEOUT = "PEER_SESSION_CONNECT_TIMEOUT",
|
|
8
|
+
/** The peer's handshake info hash did not match the torrent's info hash. */
|
|
5
9
|
INFO_HASH_MISMATCH = "PEER_SESSION_INFO_HASH_MISMATCH",
|
|
10
|
+
/** The socket closed before a full handshake was received. */
|
|
6
11
|
SOCKET_CLOSED_BEFORE_HANDSHAKE = "PEER_SESSION_SOCKET_CLOSED_BEFORE_HANDSHAKE",
|
|
12
|
+
/** Lower-level socket error (e.g. ECONNREFUSED, ECONNRESET). See `cause`. */
|
|
7
13
|
SOCKET_ERROR = "PEER_SESSION_SOCKET_ERROR"
|
|
8
14
|
}
|
|
15
|
+
/**
|
|
16
|
+
* Errors thrown by an individual peer session.
|
|
17
|
+
*
|
|
18
|
+
* Surfaced as `causes` entries on {@link PeerPoolError} when the pool fails to reach
|
|
19
|
+
* its connection target.
|
|
20
|
+
*/
|
|
9
21
|
export declare class PeerSessionError extends BunTorrentError {
|
|
22
|
+
/** Underlying error (typically a Node `net.Socket` error). */
|
|
10
23
|
readonly cause?: unknown | undefined;
|
|
11
|
-
constructor(code: PeerSessionErrorCode, message: string,
|
|
24
|
+
constructor(code: PeerSessionErrorCode, message: string,
|
|
25
|
+
/** Underlying error (typically a Node `net.Socket` error). */
|
|
26
|
+
cause?: unknown | undefined);
|
|
12
27
|
}
|
|
@@ -1,15 +1,29 @@
|
|
|
1
1
|
import { BunTorrentError } from '../../utils/errors';
|
|
2
|
+
/** Error codes set on {@link PeerSessionError.code}. */
|
|
2
3
|
export var PeerSessionErrorCode;
|
|
3
4
|
(function (PeerSessionErrorCode) {
|
|
5
|
+
/** The session was closed before or during the operation. */
|
|
4
6
|
PeerSessionErrorCode["CLOSED"] = "PEER_SESSION_CLOSED";
|
|
7
|
+
/** The TCP connect or handshake exceeded `peerConnectTimeoutMs`. */
|
|
5
8
|
PeerSessionErrorCode["CONNECT_TIMEOUT"] = "PEER_SESSION_CONNECT_TIMEOUT";
|
|
9
|
+
/** The peer's handshake info hash did not match the torrent's info hash. */
|
|
6
10
|
PeerSessionErrorCode["INFO_HASH_MISMATCH"] = "PEER_SESSION_INFO_HASH_MISMATCH";
|
|
11
|
+
/** The socket closed before a full handshake was received. */
|
|
7
12
|
PeerSessionErrorCode["SOCKET_CLOSED_BEFORE_HANDSHAKE"] = "PEER_SESSION_SOCKET_CLOSED_BEFORE_HANDSHAKE";
|
|
13
|
+
/** Lower-level socket error (e.g. ECONNREFUSED, ECONNRESET). See `cause`. */
|
|
8
14
|
PeerSessionErrorCode["SOCKET_ERROR"] = "PEER_SESSION_SOCKET_ERROR";
|
|
9
15
|
})(PeerSessionErrorCode || (PeerSessionErrorCode = {}));
|
|
16
|
+
/**
|
|
17
|
+
* Errors thrown by an individual peer session.
|
|
18
|
+
*
|
|
19
|
+
* Surfaced as `causes` entries on {@link PeerPoolError} when the pool fails to reach
|
|
20
|
+
* its connection target.
|
|
21
|
+
*/
|
|
10
22
|
export class PeerSessionError extends BunTorrentError {
|
|
11
23
|
cause;
|
|
12
|
-
constructor(code, message,
|
|
24
|
+
constructor(code, message,
|
|
25
|
+
/** Underlying error (typically a Node `net.Socket` error). */
|
|
26
|
+
cause) {
|
|
13
27
|
super(message, code);
|
|
14
28
|
this.cause = cause;
|
|
15
29
|
}
|