fix: [#86 post-fix] Reduce file transfer memory usage (#88)

* fix: [#86] don't bloat memory when seeding files
This commit is contained in:
Jeremy Kahn 2023-02-15 09:45:45 -06:00 committed by GitHub
parent 62a453807a
commit 50aecb4af9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 309 additions and 226 deletions

401
package-lock.json generated
View File

@ -21,6 +21,7 @@
"@types/node": "^18.6.5", "@types/node": "^18.6.5",
"@types/react": "^18.0.17", "@types/react": "^18.0.17",
"@types/react-dom": "^18.0.6", "@types/react-dom": "^18.0.6",
"block-iterator": "^1.1.1",
"buffer": "^6.0.3", "buffer": "^6.0.3",
"classnames": "^2.3.1", "classnames": "^2.3.1",
"detectincognitojs": "^1.1.2", "detectincognitojs": "^1.1.2",
@ -47,7 +48,7 @@
"typescript": "^4.7.4", "typescript": "^4.7.4",
"uuid": "^8.3.2", "uuid": "^8.3.2",
"web-vitals": "^2.1.4", "web-vitals": "^2.1.4",
"webtorrent": "^1.9.4", "webtorrent": "^1.9.7",
"wormhole-crypto": "^0.3.1" "wormhole-crypto": "^0.3.1"
}, },
"devDependencies": { "devDependencies": {
@ -7518,11 +7519,6 @@
"resolved": "https://registry.npmjs.org/bencode/-/bencode-2.0.3.tgz", "resolved": "https://registry.npmjs.org/bencode/-/bencode-2.0.3.tgz",
"integrity": "sha512-D/vrAD4dLVX23NalHwb8dSvsUsxeRPO8Y7ToKA015JQYq69MLDOMkC0uGZYA/MPpltLO8rt8eqFC2j8DxjTZ/w==" "integrity": "sha512-D/vrAD4dLVX23NalHwb8dSvsUsxeRPO8Y7ToKA015JQYq69MLDOMkC0uGZYA/MPpltLO8rt8eqFC2j8DxjTZ/w=="
}, },
"node_modules/bep53-range": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/bep53-range/-/bep53-range-1.1.1.tgz",
"integrity": "sha512-ct6s33iiwRCUPp9KXnJ4QMWDgHIgaw36caK/5XEQ9L8dCzSQlJt1Vk6VmHh1VD4AlGCAI4C2zmtfItifBBPrhQ=="
},
"node_modules/bfj": { "node_modules/bfj": {
"version": "7.0.2", "version": "7.0.2",
"resolved": "https://registry.npmjs.org/bfj/-/bfj-7.0.2.tgz", "resolved": "https://registry.npmjs.org/bfj/-/bfj-7.0.2.tgz",
@ -7591,9 +7587,9 @@
} }
}, },
"node_modules/bittorrent-dht": { "node_modules/bittorrent-dht": {
"version": "10.0.6", "version": "10.0.7",
"resolved": "https://registry.npmjs.org/bittorrent-dht/-/bittorrent-dht-10.0.6.tgz", "resolved": "https://registry.npmjs.org/bittorrent-dht/-/bittorrent-dht-10.0.7.tgz",
"integrity": "sha512-Odmfmo36/vr0E4PWicans0fesjCfRib2daGaYfB8WHljPTO/U2820EFOA9HBhzdzekGBhBHlSPVi6Jf9vu7/yQ==", "integrity": "sha512-o6elCANGteECXz82LFqG1Ov2fG4uNzfUU7pBMx9ixxKUh99ZXNrhbiNLRNN2F2vBnqKSN7SHlUW4LJ5Z2u1eKw==",
"funding": [ "funding": [
{ {
"type": "github", "type": "github",
@ -7792,9 +7788,9 @@
} }
}, },
"node_modules/block-iterator": { "node_modules/block-iterator": {
"version": "1.0.1", "version": "1.1.1",
"resolved": "https://registry.npmjs.org/block-iterator/-/block-iterator-1.0.1.tgz", "resolved": "https://registry.npmjs.org/block-iterator/-/block-iterator-1.1.1.tgz",
"integrity": "sha512-ral9Gh8BXqVkh4lnhLLL5QJ67+VMOBNzsHJZX4n+Pwer9bzcSM2ZOjTLMErkWWETvnis+ZP1a6EULebjEg3bTA==" "integrity": "sha512-DrjdVWZemVO4iBf4tiOXjUrY5cNesjzy0t7sIiu2rdl8cOCHRxAgKjSJFc3vBZYYMMmshUAxajl8QQh/uxXTKQ=="
}, },
"node_modules/block-stream2": { "node_modules/block-stream2": {
"version": "2.1.0", "version": "2.1.0",
@ -9167,44 +9163,6 @@
"sha.js": "^2.4.8" "sha.js": "^2.4.8"
} }
}, },
"node_modules/create-torrent": {
"version": "5.0.9",
"resolved": "https://registry.npmjs.org/create-torrent/-/create-torrent-5.0.9.tgz",
"integrity": "sha512-WQ/bMe+aCBSa5EonIkgw7CTM/1JnJDQuLJhA78omSWvuEbXDwaUy0rG3a+IYt+EiO+rdTLxdsBwrsn/wfWOMQA==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/feross"
},
{
"type": "patreon",
"url": "https://www.patreon.com/feross"
},
{
"type": "consulting",
"url": "https://feross.org/support"
}
],
"dependencies": {
"bencode": "^2.0.3",
"block-iterator": "^1.0.1",
"fast-readable-async-iterator": "^1.1.1",
"is-file": "^1.0.0",
"join-async-iterator": "^1.1.1",
"junk": "^3.1.0",
"minimist": "^1.2.7",
"piece-length": "^2.0.1",
"queue-microtask": "^1.2.3",
"run-parallel": "^1.2.0",
"simple-sha1": "^3.1.0"
},
"bin": {
"create-torrent": "bin/cmd.js"
},
"engines": {
"node": ">=12"
}
},
"node_modules/cross-env": { "node_modules/cross-env": {
"version": "7.0.3", "version": "7.0.3",
"resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz", "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz",
@ -12395,17 +12353,6 @@
"node": ">=8.0.0" "node": ">=8.0.0"
} }
}, },
"node_modules/get-stdin": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-8.0.0.tgz",
"integrity": "sha512-sY22aA6xchAzprjyqmSEQv4UbAAzRN0L2dQB0NlN5acTTK9Don6nhoc3eAbUnpZiCANAMfd/+40kVdKfFygohg==",
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/get-stream": { "node_modules/get-stream": {
"version": "6.0.1", "version": "6.0.1",
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz",
@ -17857,29 +17804,6 @@
"sourcemap-codec": "^1.4.8" "sourcemap-codec": "^1.4.8"
} }
}, },
"node_modules/magnet-uri": {
"version": "6.2.0",
"resolved": "https://registry.npmjs.org/magnet-uri/-/magnet-uri-6.2.0.tgz",
"integrity": "sha512-O9AgdDwT771fnUj0giPYu/rACpz8173y8UXCSOdLITjOVfBenZ9H9q3FqQmveK+ORUMuD+BkKNSZP8C3+IMAKQ==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/feross"
},
{
"type": "patreon",
"url": "https://www.patreon.com/feross"
},
{
"type": "consulting",
"url": "https://feross.org/support"
}
],
"dependencies": {
"bep53-range": "^1.1.0",
"thirty-two": "^1.0.2"
}
},
"node_modules/make-dir": { "node_modules/make-dir": {
"version": "3.1.0", "version": "3.1.0",
"resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz",
@ -19909,37 +19833,6 @@
"url": "https://github.com/sponsors/sindresorhus" "url": "https://github.com/sponsors/sindresorhus"
} }
}, },
"node_modules/parse-torrent": {
"version": "9.1.5",
"resolved": "https://registry.npmjs.org/parse-torrent/-/parse-torrent-9.1.5.tgz",
"integrity": "sha512-K8FXRwTOaZMI0/xuv0dpng1MVHZRtMJ0jRWBJ3qZWVNTrC1MzWUxm9QwaXDz/2qPhV2XC4UIHI92IGHwseAwaA==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/feross"
},
{
"type": "patreon",
"url": "https://www.patreon.com/feross"
},
{
"type": "consulting",
"url": "https://feross.org/support"
}
],
"dependencies": {
"bencode": "^2.0.2",
"blob-to-buffer": "^1.2.9",
"get-stdin": "^8.0.0",
"magnet-uri": "^6.2.0",
"queue-microtask": "^1.2.3",
"simple-get": "^4.0.1",
"simple-sha1": "^3.1.0"
},
"bin": {
"parse-torrent": "bin/cmd.js"
}
},
"node_modules/parse5": { "node_modules/parse5": {
"version": "6.0.1", "version": "6.0.1",
"resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz",
@ -24241,12 +24134,12 @@
] ]
}, },
"node_modules/streamx": { "node_modules/streamx": {
"version": "2.12.5", "version": "2.13.2",
"resolved": "https://registry.npmjs.org/streamx/-/streamx-2.12.5.tgz", "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.13.2.tgz",
"integrity": "sha512-Y+nkFw57Z5JHT3zLlqFm3GccOy2FeYdUrrqita6Dd8kr/8enPn9GKa8IYf3/DmEKfZl/E2sWoSKUnd4qhonrgg==", "integrity": "sha512-+TWqixPhGDXEG9L/XczSbhfkmwAtGs3BJX5QNU6cvno+pOLKeszByWcnaTu6dg8efsTYqR8ZZuXWHhZfgrxMvA==",
"dependencies": { "dependencies": {
"fast-fifo": "^1.0.0", "fast-fifo": "^1.1.0",
"queue-tick": "^1.0.0" "queue-tick": "^1.0.1"
} }
}, },
"node_modules/string_decoder": { "node_modules/string_decoder": {
@ -24917,9 +24810,9 @@
} }
}, },
"node_modules/torrent-discovery": { "node_modules/torrent-discovery": {
"version": "9.4.14", "version": "9.4.15",
"resolved": "https://registry.npmjs.org/torrent-discovery/-/torrent-discovery-9.4.14.tgz", "resolved": "https://registry.npmjs.org/torrent-discovery/-/torrent-discovery-9.4.15.tgz",
"integrity": "sha512-IyzlrHctvqqKtN8Y2BMxNL3d2FLazs6pC2yzKOHJlXWYUFkLpZhZSaSZcAkfmZXgdjwq59N2umr1przsRDMzkA==", "integrity": "sha512-71nx+TpLaF27mbsSj/tZTr588Dfk7XVzx+Rf1+nrxfXqe8qn5dIlRhgA+yY4cg8Ib69vWwkKFhAzbRqg8z42aw==",
"funding": [ "funding": [
{ {
"type": "github", "type": "github",
@ -24935,7 +24828,7 @@
} }
], ],
"dependencies": { "dependencies": {
"bittorrent-dht": "^10.0.6", "bittorrent-dht": "^10.0.7",
"bittorrent-lsd": "^1.1.1", "bittorrent-lsd": "^1.1.1",
"bittorrent-tracker": "^9.19.0", "bittorrent-tracker": "^9.19.0",
"debug": "^4.3.4", "debug": "^4.3.4",
@ -26152,9 +26045,9 @@
} }
}, },
"node_modules/webtorrent": { "node_modules/webtorrent": {
"version": "1.9.4", "version": "1.9.7",
"resolved": "https://registry.npmjs.org/webtorrent/-/webtorrent-1.9.4.tgz", "resolved": "https://registry.npmjs.org/webtorrent/-/webtorrent-1.9.7.tgz",
"integrity": "sha512-dW/7Cj/fRiJe97Vac071VhbfbiDSF6iAW1wwbs47uArOBbRSAgDRTem70M7ONF3IwRC/mu1+bTSwv+ojxJ+2/A==", "integrity": "sha512-N+hRuVctWviTAYem/sI6tuFP2J/Rn3/ETEh++7GnJv6Oro49kDjcPuz1W6s+vfS65xKr3Eh4HMuxf3hH82LGfg==",
"funding": [ "funding": [
{ {
"type": "github", "type": "github",
@ -26173,7 +26066,7 @@
"@webtorrent/http-node": "^1.3.0", "@webtorrent/http-node": "^1.3.0",
"addr-to-ip-port": "^1.5.4", "addr-to-ip-port": "^1.5.4",
"bitfield": "^4.1.0", "bitfield": "^4.1.0",
"bittorrent-dht": "^10.0.6", "bittorrent-dht": "^10.0.7",
"bittorrent-protocol": "^3.5.5", "bittorrent-protocol": "^3.5.5",
"cache-chunk-store": "^3.2.2", "cache-chunk-store": "^3.2.2",
"chrome-net": "^3.3.4", "chrome-net": "^3.3.4",
@ -26209,7 +26102,7 @@
"stream-with-known-length-to-buffer": "^1.0.4", "stream-with-known-length-to-buffer": "^1.0.4",
"streamx": "^2.12.5", "streamx": "^2.12.5",
"throughput": "^1.0.1", "throughput": "^1.0.1",
"torrent-discovery": "^9.4.14", "torrent-discovery": "^9.4.15",
"torrent-piece": "^2.0.1", "torrent-piece": "^2.0.1",
"unordered-array-remove": "^1.0.2", "unordered-array-remove": "^1.0.2",
"ut_metadata": "^3.5.2", "ut_metadata": "^3.5.2",
@ -26222,6 +26115,83 @@
"utp-native": "^2.5.3" "utp-native": "^2.5.3"
} }
}, },
"node_modules/webtorrent/node_modules/bep53-range": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/bep53-range/-/bep53-range-1.1.1.tgz",
"integrity": "sha512-ct6s33iiwRCUPp9KXnJ4QMWDgHIgaw36caK/5XEQ9L8dCzSQlJt1Vk6VmHh1VD4AlGCAI4C2zmtfItifBBPrhQ=="
},
"node_modules/webtorrent/node_modules/create-torrent": {
"version": "5.0.9",
"resolved": "https://registry.npmjs.org/create-torrent/-/create-torrent-5.0.9.tgz",
"integrity": "sha512-WQ/bMe+aCBSa5EonIkgw7CTM/1JnJDQuLJhA78omSWvuEbXDwaUy0rG3a+IYt+EiO+rdTLxdsBwrsn/wfWOMQA==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/feross"
},
{
"type": "patreon",
"url": "https://www.patreon.com/feross"
},
{
"type": "consulting",
"url": "https://feross.org/support"
}
],
"dependencies": {
"bencode": "^2.0.3",
"block-iterator": "^1.0.1",
"fast-readable-async-iterator": "^1.1.1",
"is-file": "^1.0.0",
"join-async-iterator": "^1.1.1",
"junk": "^3.1.0",
"minimist": "^1.2.7",
"piece-length": "^2.0.1",
"queue-microtask": "^1.2.3",
"run-parallel": "^1.2.0",
"simple-sha1": "^3.1.0"
},
"bin": {
"create-torrent": "bin/cmd.js"
},
"engines": {
"node": ">=12"
}
},
"node_modules/webtorrent/node_modules/get-stdin": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-8.0.0.tgz",
"integrity": "sha512-sY22aA6xchAzprjyqmSEQv4UbAAzRN0L2dQB0NlN5acTTK9Don6nhoc3eAbUnpZiCANAMfd/+40kVdKfFygohg==",
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/webtorrent/node_modules/magnet-uri": {
"version": "6.2.0",
"resolved": "https://registry.npmjs.org/magnet-uri/-/magnet-uri-6.2.0.tgz",
"integrity": "sha512-O9AgdDwT771fnUj0giPYu/rACpz8173y8UXCSOdLITjOVfBenZ9H9q3FqQmveK+ORUMuD+BkKNSZP8C3+IMAKQ==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/feross"
},
{
"type": "patreon",
"url": "https://www.patreon.com/feross"
},
{
"type": "consulting",
"url": "https://feross.org/support"
}
],
"dependencies": {
"bep53-range": "^1.1.0",
"thirty-two": "^1.0.2"
}
},
"node_modules/webtorrent/node_modules/mime": { "node_modules/webtorrent/node_modules/mime": {
"version": "3.0.0", "version": "3.0.0",
"resolved": "https://registry.npmjs.org/mime/-/mime-3.0.0.tgz", "resolved": "https://registry.npmjs.org/mime/-/mime-3.0.0.tgz",
@ -26233,6 +26203,37 @@
"node": ">=10.0.0" "node": ">=10.0.0"
} }
}, },
"node_modules/webtorrent/node_modules/parse-torrent": {
"version": "9.1.5",
"resolved": "https://registry.npmjs.org/parse-torrent/-/parse-torrent-9.1.5.tgz",
"integrity": "sha512-K8FXRwTOaZMI0/xuv0dpng1MVHZRtMJ0jRWBJ3qZWVNTrC1MzWUxm9QwaXDz/2qPhV2XC4UIHI92IGHwseAwaA==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/feross"
},
{
"type": "patreon",
"url": "https://www.patreon.com/feross"
},
{
"type": "consulting",
"url": "https://feross.org/support"
}
],
"dependencies": {
"bencode": "^2.0.2",
"blob-to-buffer": "^1.2.9",
"get-stdin": "^8.0.0",
"magnet-uri": "^6.2.0",
"queue-microtask": "^1.2.3",
"simple-get": "^4.0.1",
"simple-sha1": "^3.1.0"
},
"bin": {
"parse-torrent": "bin/cmd.js"
}
},
"node_modules/whatwg-encoding": { "node_modules/whatwg-encoding": {
"version": "1.0.5", "version": "1.0.5",
"resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz", "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz",
@ -32342,11 +32343,6 @@
"resolved": "https://registry.npmjs.org/bencode/-/bencode-2.0.3.tgz", "resolved": "https://registry.npmjs.org/bencode/-/bencode-2.0.3.tgz",
"integrity": "sha512-D/vrAD4dLVX23NalHwb8dSvsUsxeRPO8Y7ToKA015JQYq69MLDOMkC0uGZYA/MPpltLO8rt8eqFC2j8DxjTZ/w==" "integrity": "sha512-D/vrAD4dLVX23NalHwb8dSvsUsxeRPO8Y7ToKA015JQYq69MLDOMkC0uGZYA/MPpltLO8rt8eqFC2j8DxjTZ/w=="
}, },
"bep53-range": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/bep53-range/-/bep53-range-1.1.1.tgz",
"integrity": "sha512-ct6s33iiwRCUPp9KXnJ4QMWDgHIgaw36caK/5XEQ9L8dCzSQlJt1Vk6VmHh1VD4AlGCAI4C2zmtfItifBBPrhQ=="
},
"bfj": { "bfj": {
"version": "7.0.2", "version": "7.0.2",
"resolved": "https://registry.npmjs.org/bfj/-/bfj-7.0.2.tgz", "resolved": "https://registry.npmjs.org/bfj/-/bfj-7.0.2.tgz",
@ -32397,9 +32393,9 @@
"integrity": "sha512-6cEDG3K+PK9f+B7WyhWYjp09bqSa+uaAaecVA7Y5giFixyVe1s6HKGnvOqYNR4Mi4fBMjfDPLBpHkKvzzgP7kg==" "integrity": "sha512-6cEDG3K+PK9f+B7WyhWYjp09bqSa+uaAaecVA7Y5giFixyVe1s6HKGnvOqYNR4Mi4fBMjfDPLBpHkKvzzgP7kg=="
}, },
"bittorrent-dht": { "bittorrent-dht": {
"version": "10.0.6", "version": "10.0.7",
"resolved": "https://registry.npmjs.org/bittorrent-dht/-/bittorrent-dht-10.0.6.tgz", "resolved": "https://registry.npmjs.org/bittorrent-dht/-/bittorrent-dht-10.0.7.tgz",
"integrity": "sha512-Odmfmo36/vr0E4PWicans0fesjCfRib2daGaYfB8WHljPTO/U2820EFOA9HBhzdzekGBhBHlSPVi6Jf9vu7/yQ==", "integrity": "sha512-o6elCANGteECXz82LFqG1Ov2fG4uNzfUU7pBMx9ixxKUh99ZXNrhbiNLRNN2F2vBnqKSN7SHlUW4LJ5Z2u1eKw==",
"requires": { "requires": {
"bencode": "^2.0.3", "bencode": "^2.0.3",
"debug": "^4.3.4", "debug": "^4.3.4",
@ -32505,9 +32501,9 @@
} }
}, },
"block-iterator": { "block-iterator": {
"version": "1.0.1", "version": "1.1.1",
"resolved": "https://registry.npmjs.org/block-iterator/-/block-iterator-1.0.1.tgz", "resolved": "https://registry.npmjs.org/block-iterator/-/block-iterator-1.1.1.tgz",
"integrity": "sha512-ral9Gh8BXqVkh4lnhLLL5QJ67+VMOBNzsHJZX4n+Pwer9bzcSM2ZOjTLMErkWWETvnis+ZP1a6EULebjEg3bTA==" "integrity": "sha512-DrjdVWZemVO4iBf4tiOXjUrY5cNesjzy0t7sIiu2rdl8cOCHRxAgKjSJFc3vBZYYMMmshUAxajl8QQh/uxXTKQ=="
}, },
"block-stream2": { "block-stream2": {
"version": "2.1.0", "version": "2.1.0",
@ -33498,24 +33494,6 @@
"sha.js": "^2.4.8" "sha.js": "^2.4.8"
} }
}, },
"create-torrent": {
"version": "5.0.9",
"resolved": "https://registry.npmjs.org/create-torrent/-/create-torrent-5.0.9.tgz",
"integrity": "sha512-WQ/bMe+aCBSa5EonIkgw7CTM/1JnJDQuLJhA78omSWvuEbXDwaUy0rG3a+IYt+EiO+rdTLxdsBwrsn/wfWOMQA==",
"requires": {
"bencode": "^2.0.3",
"block-iterator": "^1.0.1",
"fast-readable-async-iterator": "^1.1.1",
"is-file": "^1.0.0",
"join-async-iterator": "^1.1.1",
"junk": "^3.1.0",
"minimist": "^1.2.7",
"piece-length": "^2.0.1",
"queue-microtask": "^1.2.3",
"run-parallel": "^1.2.0",
"simple-sha1": "^3.1.0"
}
},
"cross-env": { "cross-env": {
"version": "7.0.3", "version": "7.0.3",
"resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz", "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz",
@ -35868,11 +35846,6 @@
"resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz",
"integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==" "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q=="
}, },
"get-stdin": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-8.0.0.tgz",
"integrity": "sha512-sY22aA6xchAzprjyqmSEQv4UbAAzRN0L2dQB0NlN5acTTK9Don6nhoc3eAbUnpZiCANAMfd/+40kVdKfFygohg=="
},
"get-stream": { "get-stream": {
"version": "6.0.1", "version": "6.0.1",
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz",
@ -40104,15 +40077,6 @@
"sourcemap-codec": "^1.4.8" "sourcemap-codec": "^1.4.8"
} }
}, },
"magnet-uri": {
"version": "6.2.0",
"resolved": "https://registry.npmjs.org/magnet-uri/-/magnet-uri-6.2.0.tgz",
"integrity": "sha512-O9AgdDwT771fnUj0giPYu/rACpz8173y8UXCSOdLITjOVfBenZ9H9q3FqQmveK+ORUMuD+BkKNSZP8C3+IMAKQ==",
"requires": {
"bep53-range": "^1.1.0",
"thirty-two": "^1.0.2"
}
},
"make-dir": { "make-dir": {
"version": "3.1.0", "version": "3.1.0",
"resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz",
@ -41507,20 +41471,6 @@
"lines-and-columns": "^1.1.6" "lines-and-columns": "^1.1.6"
} }
}, },
"parse-torrent": {
"version": "9.1.5",
"resolved": "https://registry.npmjs.org/parse-torrent/-/parse-torrent-9.1.5.tgz",
"integrity": "sha512-K8FXRwTOaZMI0/xuv0dpng1MVHZRtMJ0jRWBJ3qZWVNTrC1MzWUxm9QwaXDz/2qPhV2XC4UIHI92IGHwseAwaA==",
"requires": {
"bencode": "^2.0.2",
"blob-to-buffer": "^1.2.9",
"get-stdin": "^8.0.0",
"magnet-uri": "^6.2.0",
"queue-microtask": "^1.2.3",
"simple-get": "^4.0.1",
"simple-sha1": "^3.1.0"
}
},
"parse5": { "parse5": {
"version": "6.0.1", "version": "6.0.1",
"resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz",
@ -44484,12 +44434,12 @@
"integrity": "sha512-LK4e7TfCV8HzuM0PKXuVUfKyCB1FtT9L0EGxsFk5Up8njj0bXK8pJM9+Wq2Nya7/jslmCQwRK39LFm55h7NBTw==" "integrity": "sha512-LK4e7TfCV8HzuM0PKXuVUfKyCB1FtT9L0EGxsFk5Up8njj0bXK8pJM9+Wq2Nya7/jslmCQwRK39LFm55h7NBTw=="
}, },
"streamx": { "streamx": {
"version": "2.12.5", "version": "2.13.2",
"resolved": "https://registry.npmjs.org/streamx/-/streamx-2.12.5.tgz", "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.13.2.tgz",
"integrity": "sha512-Y+nkFw57Z5JHT3zLlqFm3GccOy2FeYdUrrqita6Dd8kr/8enPn9GKa8IYf3/DmEKfZl/E2sWoSKUnd4qhonrgg==", "integrity": "sha512-+TWqixPhGDXEG9L/XczSbhfkmwAtGs3BJX5QNU6cvno+pOLKeszByWcnaTu6dg8efsTYqR8ZZuXWHhZfgrxMvA==",
"requires": { "requires": {
"fast-fifo": "^1.0.0", "fast-fifo": "^1.1.0",
"queue-tick": "^1.0.0" "queue-tick": "^1.0.1"
} }
}, },
"string_decoder": { "string_decoder": {
@ -44997,11 +44947,11 @@
"integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==" "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA=="
}, },
"torrent-discovery": { "torrent-discovery": {
"version": "9.4.14", "version": "9.4.15",
"resolved": "https://registry.npmjs.org/torrent-discovery/-/torrent-discovery-9.4.14.tgz", "resolved": "https://registry.npmjs.org/torrent-discovery/-/torrent-discovery-9.4.15.tgz",
"integrity": "sha512-IyzlrHctvqqKtN8Y2BMxNL3d2FLazs6pC2yzKOHJlXWYUFkLpZhZSaSZcAkfmZXgdjwq59N2umr1przsRDMzkA==", "integrity": "sha512-71nx+TpLaF27mbsSj/tZTr588Dfk7XVzx+Rf1+nrxfXqe8qn5dIlRhgA+yY4cg8Ib69vWwkKFhAzbRqg8z42aw==",
"requires": { "requires": {
"bittorrent-dht": "^10.0.6", "bittorrent-dht": "^10.0.7",
"bittorrent-lsd": "^1.1.1", "bittorrent-lsd": "^1.1.1",
"bittorrent-tracker": "^9.19.0", "bittorrent-tracker": "^9.19.0",
"debug": "^4.3.4", "debug": "^4.3.4",
@ -45874,14 +45824,14 @@
"integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==" "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg=="
}, },
"webtorrent": { "webtorrent": {
"version": "1.9.4", "version": "1.9.7",
"resolved": "https://registry.npmjs.org/webtorrent/-/webtorrent-1.9.4.tgz", "resolved": "https://registry.npmjs.org/webtorrent/-/webtorrent-1.9.7.tgz",
"integrity": "sha512-dW/7Cj/fRiJe97Vac071VhbfbiDSF6iAW1wwbs47uArOBbRSAgDRTem70M7ONF3IwRC/mu1+bTSwv+ojxJ+2/A==", "integrity": "sha512-N+hRuVctWviTAYem/sI6tuFP2J/Rn3/ETEh++7GnJv6Oro49kDjcPuz1W6s+vfS65xKr3Eh4HMuxf3hH82LGfg==",
"requires": { "requires": {
"@webtorrent/http-node": "^1.3.0", "@webtorrent/http-node": "^1.3.0",
"addr-to-ip-port": "^1.5.4", "addr-to-ip-port": "^1.5.4",
"bitfield": "^4.1.0", "bitfield": "^4.1.0",
"bittorrent-dht": "^10.0.6", "bittorrent-dht": "^10.0.7",
"bittorrent-protocol": "^3.5.5", "bittorrent-protocol": "^3.5.5",
"cache-chunk-store": "^3.2.2", "cache-chunk-store": "^3.2.2",
"chrome-net": "^3.3.4", "chrome-net": "^3.3.4",
@ -45917,7 +45867,7 @@
"stream-with-known-length-to-buffer": "^1.0.4", "stream-with-known-length-to-buffer": "^1.0.4",
"streamx": "^2.12.5", "streamx": "^2.12.5",
"throughput": "^1.0.1", "throughput": "^1.0.1",
"torrent-discovery": "^9.4.14", "torrent-discovery": "^9.4.15",
"torrent-piece": "^2.0.1", "torrent-piece": "^2.0.1",
"unordered-array-remove": "^1.0.2", "unordered-array-remove": "^1.0.2",
"ut_metadata": "^3.5.2", "ut_metadata": "^3.5.2",
@ -45925,10 +45875,61 @@
"utp-native": "^2.5.3" "utp-native": "^2.5.3"
}, },
"dependencies": { "dependencies": {
"bep53-range": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/bep53-range/-/bep53-range-1.1.1.tgz",
"integrity": "sha512-ct6s33iiwRCUPp9KXnJ4QMWDgHIgaw36caK/5XEQ9L8dCzSQlJt1Vk6VmHh1VD4AlGCAI4C2zmtfItifBBPrhQ=="
},
"create-torrent": {
"version": "5.0.9",
"resolved": "https://registry.npmjs.org/create-torrent/-/create-torrent-5.0.9.tgz",
"integrity": "sha512-WQ/bMe+aCBSa5EonIkgw7CTM/1JnJDQuLJhA78omSWvuEbXDwaUy0rG3a+IYt+EiO+rdTLxdsBwrsn/wfWOMQA==",
"requires": {
"bencode": "^2.0.3",
"block-iterator": "^1.0.1",
"fast-readable-async-iterator": "^1.1.1",
"is-file": "^1.0.0",
"join-async-iterator": "^1.1.1",
"junk": "^3.1.0",
"minimist": "^1.2.7",
"piece-length": "^2.0.1",
"queue-microtask": "^1.2.3",
"run-parallel": "^1.2.0",
"simple-sha1": "^3.1.0"
}
},
"get-stdin": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-8.0.0.tgz",
"integrity": "sha512-sY22aA6xchAzprjyqmSEQv4UbAAzRN0L2dQB0NlN5acTTK9Don6nhoc3eAbUnpZiCANAMfd/+40kVdKfFygohg=="
},
"magnet-uri": {
"version": "6.2.0",
"resolved": "https://registry.npmjs.org/magnet-uri/-/magnet-uri-6.2.0.tgz",
"integrity": "sha512-O9AgdDwT771fnUj0giPYu/rACpz8173y8UXCSOdLITjOVfBenZ9H9q3FqQmveK+ORUMuD+BkKNSZP8C3+IMAKQ==",
"requires": {
"bep53-range": "^1.1.0",
"thirty-two": "^1.0.2"
}
},
"mime": { "mime": {
"version": "3.0.0", "version": "3.0.0",
"resolved": "https://registry.npmjs.org/mime/-/mime-3.0.0.tgz", "resolved": "https://registry.npmjs.org/mime/-/mime-3.0.0.tgz",
"integrity": "sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==" "integrity": "sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A=="
},
"parse-torrent": {
"version": "9.1.5",
"resolved": "https://registry.npmjs.org/parse-torrent/-/parse-torrent-9.1.5.tgz",
"integrity": "sha512-K8FXRwTOaZMI0/xuv0dpng1MVHZRtMJ0jRWBJ3qZWVNTrC1MzWUxm9QwaXDz/2qPhV2XC4UIHI92IGHwseAwaA==",
"requires": {
"bencode": "^2.0.2",
"blob-to-buffer": "^1.2.9",
"get-stdin": "^8.0.0",
"magnet-uri": "^6.2.0",
"queue-microtask": "^1.2.3",
"simple-get": "^4.0.1",
"simple-sha1": "^3.1.0"
}
} }
} }
}, },

View File

@ -17,6 +17,7 @@
"@types/node": "^18.6.5", "@types/node": "^18.6.5",
"@types/react": "^18.0.17", "@types/react": "^18.0.17",
"@types/react-dom": "^18.0.6", "@types/react-dom": "^18.0.6",
"block-iterator": "^1.1.1",
"buffer": "^6.0.3", "buffer": "^6.0.3",
"classnames": "^2.3.1", "classnames": "^2.3.1",
"detectincognitojs": "^1.1.2", "detectincognitojs": "^1.1.2",
@ -43,7 +44,7 @@
"typescript": "^4.7.4", "typescript": "^4.7.4",
"uuid": "^8.3.2", "uuid": "^8.3.2",
"web-vitals": "^2.1.4", "web-vitals": "^2.1.4",
"webtorrent": "^1.9.4", "webtorrent": "^1.9.7",
"wormhole-crypto": "^0.3.1" "wormhole-crypto": "^0.3.1"
}, },
"scripts": { "scripts": {

View File

@ -1,24 +1,22 @@
import WebTorrent, { Torrent, TorrentFile } from 'webtorrent' import WebTorrent, { Torrent, TorrentFile } from 'webtorrent'
// @ts-ignore
import streamSaver from 'streamsaver' import streamSaver from 'streamsaver'
// @ts-ignore // @ts-ignore
import { Keychain, plaintextSize } from 'wormhole-crypto' import { Keychain, plaintextSize, encryptedSize } from 'wormhole-crypto'
// @ts-ignore // @ts-ignore
import idbChunkStore from 'idb-chunk-store' import idbChunkStore from 'idb-chunk-store'
import { detectIncognito } from 'detectincognitojs' import { detectIncognito } from 'detectincognitojs'
import { trackerUrls } from 'config/trackerUrls' import { trackerUrls } from 'config/trackerUrls'
import { streamSaverUrl } from 'config/streamSaverUrl' import { streamSaverUrl } from 'config/streamSaverUrl'
// @ts-ignore
import blockIterator from 'block-iterator'
import { ReadableWebToNodeStream } from 'readable-web-to-node-stream'
// @ts-ignore // @ts-ignore
import nodeToWebStream from 'readable-stream-node-to-web' import nodeToWebStream from 'readable-stream-node-to-web'
streamSaver.mitm = streamSaverUrl streamSaver.mitm = streamSaverUrl
interface NamedReadableWebToNodeStream extends NodeJS.ReadableStream {
name?: string
}
const getKeychain = (password: string) => { const getKeychain = (password: string) => {
const encoder = new TextEncoder() const encoder = new TextEncoder()
const keyLength = 16 const keyLength = 16
@ -64,11 +62,12 @@ export class FileTransfer {
async getDecryptedFileReadStream(file: TorrentFile, password: string) { async getDecryptedFileReadStream(file: TorrentFile, password: string) {
const keychain = getKeychain(password) const keychain = getKeychain(password)
const readStream: ReadableStream = await keychain.decryptStream(
nodeToWebStream(file.createReadStream()) const decryptedStream: ReadableStream = await keychain.decryptStream(
new nodeToWebStream(file.createReadStream())
) )
return readStream return decryptedStream
} }
async download( async download(
@ -127,27 +126,101 @@ export class FileTransfer {
const filesToSeed: File[] = const filesToSeed: File[] =
files instanceof FileList ? Array.from(files) : files files instanceof FileList ? Array.from(files) : files
const pieceLength = 16 * 1024
const fileToEncryptedStoreMap: Map<File, () => ReadableStream<Buffer>> =
new Map()
const tempStores: idbChunkStore[] = []
for (const file of filesToSeed) {
const tempStore = new idbChunkStore(pieceLength, {
name: `${file.name} - temp`,
length: encryptedSize(file.size),
})
tempStores.push(tempStore)
const encryptedStream = await getKeychain(password).encryptStream(
file.stream()
)
const blockStream = blockIterator(encryptedStream, pieceLength, {
zeroPadding: false,
})
let numberOfChunks = 0
let i = 0
for await (const chunk of blockStream) {
// eslint-disable-next-line no-loop-func
await new Promise<void>((resolve, reject) => {
tempStore.put(i, chunk, (err?: Error) => {
if (err) return reject(err)
resolve()
})
})
i++
numberOfChunks = i
}
const streamFactory = () => {
let i = 0
const readableStream = new ReadableStream<Buffer>({
async pull(controller) {
const buffer = await new Promise<Buffer>(resolve => {
tempStore.get(
i,
undefined,
(_err: Error | null, buffer: Buffer) => {
resolve(buffer)
}
)
})
i++
const done = i > numberOfChunks
if (done) {
controller.close()
} else {
controller.enqueue(buffer)
}
},
})
return readableStream
}
fileToEncryptedStoreMap.set(file, streamFactory)
}
const encryptedFiles = await Promise.all( const encryptedFiles = await Promise.all(
filesToSeed.map(async file => { filesToSeed.map(async file => {
const encryptedStream = await getKeychain(password).encryptStream( const streamFactory = fileToEncryptedStoreMap.get(file)
file.stream()
if (!streamFactory) {
throw new Error(`streamFactory is undefined`)
}
const encryptedFile = Object.setPrototypeOf(
{
...file,
name: file.name,
size: encryptedSize(file.size),
stream: () => streamFactory(),
},
File.prototype
) )
// WebTorrent only accepts Node-style ReadableStreams return encryptedFile
const nodeStream: NamedReadableWebToNodeStream =
new ReadableWebToNodeStream(
encryptedStream
// ReadableWebToNodeStream is the same as NodeJS.ReadableStream.
// The library's typing is wrong.
) as any as NodeJS.ReadableStream
nodeStream.name = file.name
return nodeStream
}) })
) )
const torrent = await new Promise<Torrent>(res => { const offer = await new Promise<Torrent>(res => {
this.webTorrentClient.seed( this.webTorrentClient.seed(
encryptedFiles, encryptedFiles,
{ {
@ -164,8 +237,16 @@ export class FileTransfer {
) )
}) })
const { magnetURI } = torrent for (const store of tempStores) {
this.torrents[magnetURI] = torrent await new Promise<void>(resolve => {
store.destroy(() => {
resolve()
})
})
}
const { magnetURI } = offer
this.torrents[magnetURI] = offer
return magnetURI return magnetURI
} }