forked from Shiloh/remnantchat
fix: [#86 post-fix] don't create redundant data before transferring files
This commit is contained in:
parent
50aecb4af9
commit
44ba2181be
1
package-lock.json
generated
1
package-lock.json
generated
@ -21,7 +21,6 @@
|
|||||||
"@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",
|
||||||
|
@ -17,7 +17,6 @@
|
|||||||
"@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",
|
||||||
|
@ -9,8 +9,6 @@ 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'
|
|
||||||
|
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
import nodeToWebStream from 'readable-stream-node-to-web'
|
import nodeToWebStream from 'readable-stream-node-to-web'
|
||||||
@ -126,92 +124,21 @@ 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 streamFactory = fileToEncryptedStoreMap.get(file)
|
const encryptedStream = await getKeychain(password).encryptStream(
|
||||||
|
file.stream()
|
||||||
|
)
|
||||||
|
|
||||||
if (!streamFactory) {
|
// Prevent ReadableStreams from being reused (which would throw an error)
|
||||||
throw new Error(`streamFactory is undefined`)
|
const tees = encryptedStream.tee()
|
||||||
}
|
|
||||||
|
|
||||||
const encryptedFile = Object.setPrototypeOf(
|
const encryptedFile = Object.setPrototypeOf(
|
||||||
{
|
{
|
||||||
...file,
|
...file,
|
||||||
name: file.name,
|
name: file.name,
|
||||||
size: encryptedSize(file.size),
|
size: encryptedSize(file.size),
|
||||||
stream: () => streamFactory(),
|
stream: () => tees.pop(),
|
||||||
},
|
},
|
||||||
File.prototype
|
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
|
const { magnetURI } = offer
|
||||||
this.torrents[magnetURI] = offer
|
this.torrents[magnetURI] = offer
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user