fix: [#86 post-fix] don't create redundant data before transferring files

This commit is contained in:
Jeremy Kahn 2023-02-15 21:48:57 -06:00
parent 50aecb4af9
commit 44ba2181be
3 changed files with 6 additions and 89 deletions

1
package-lock.json generated
View File

@ -21,7 +21,6 @@
"@types/node": "^18.6.5",
"@types/react": "^18.0.17",
"@types/react-dom": "^18.0.6",
"block-iterator": "^1.1.1",
"buffer": "^6.0.3",
"classnames": "^2.3.1",
"detectincognitojs": "^1.1.2",

View File

@ -17,7 +17,6 @@
"@types/node": "^18.6.5",
"@types/react": "^18.0.17",
"@types/react-dom": "^18.0.6",
"block-iterator": "^1.1.1",
"buffer": "^6.0.3",
"classnames": "^2.3.1",
"detectincognitojs": "^1.1.2",

View File

@ -9,8 +9,6 @@ import { detectIncognito } from 'detectincognitojs'
import { trackerUrls } from 'config/trackerUrls'
import { streamSaverUrl } from 'config/streamSaverUrl'
// @ts-ignore
import blockIterator from 'block-iterator'
// @ts-ignore
import nodeToWebStream from 'readable-stream-node-to-web'
@ -126,92 +124,21 @@ export class FileTransfer {
const filesToSeed: File[] =
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(
filesToSeed.map(async file => {
const streamFactory = fileToEncryptedStoreMap.get(file)
const encryptedStream = await getKeychain(password).encryptStream(
file.stream()
)
if (!streamFactory) {
throw new Error(`streamFactory is undefined`)
}
// Prevent ReadableStreams from being reused (which would throw an error)
const tees = encryptedStream.tee()
const encryptedFile = Object.setPrototypeOf(
{
...file,
name: file.name,
size: encryptedSize(file.size),
stream: () => streamFactory(),
stream: () => tees.pop(),
},
File.prototype
)
@ -237,14 +164,6 @@ export class FileTransfer {
)
})
for (const store of tempStores) {
await new Promise<void>(resolve => {
store.destroy(() => {
resolve()
})
})
}
const { magnetURI } = offer
this.torrents[magnetURI] = offer