This commit is contained in:
Manav Rathi 2024-04-30 10:31:33 +05:30
parent 5f0103682b
commit c1a3fb4896
No known key found for this signature in database
2 changed files with 37 additions and 31 deletions

View file

@ -91,21 +91,24 @@ const maxConcurrentUploads = 4;
* *
* 2. A file drag-and-dropped or selected by the user when we are running in the * 2. A file drag-and-dropped or selected by the user when we are running in the
* context of our desktop app. In such cases, we also have the absolute path * context of our desktop app. In such cases, we also have the absolute path
* of the file in the user's local file system. this is the * of the file in the user's local file system. This is the
* {@link FileAndPath} case. * {@link FileAndPath} case.
* *
* 3. A file path programmatically requested by the desktop app. For example, we * 3. A file path programmatically requested by the desktop app. For example, we
* might be resuming a previously interrupted upload after an app restart * might be resuming a previously interrupted upload after an app restart
* (thus we no longer have access to the {@link File} from case 2). Or we * (thus we no longer have access to the {@link File} from case 2). Or we
* could be uploading a file this is in one of the folders the user has asked * could be uploading a file this is in one of the folders the user has asked
* us to watch for changes. This is the {@link string} case. * us to watch for changes. This is the `string` case.
* *
* 4. A file within a zip file. This too is only possible when we are running in * 4. A file within a zip file on the user's local file system. This too is only
* the context of our desktop app. The user might have drag-and-dropped or * possible when we are running in the context of our desktop app. The user
* selected the zip file, or it might be a zip file that they'd previously * might have drag-and-dropped or selected a zip file, or it might be a zip
* selected but we now are resuming an interrupted upload. Either ways, what * file that they'd previously selected but we now are resuming an
* we have is a path to zip file, and the name of an entry within that zip * interrupted upload of. Either ways, what we have is a tuple containing the
* file. This is the {@link ZipItem} case. * (path to zip file, and the name of an entry within that zip file). This is
* the {@link ZipItem} case.
*
* Also see: [Note: Reading a UploadItem].
*/ */
export type UploadItem = File | FileAndPath | string | ZipItem; export type UploadItem = File | FileAndPath | string | ZipItem;

View file

@ -482,45 +482,48 @@ export const uploader = async (
* *
* In the web context, we'll always get a File, since within the browser we * In the web context, we'll always get a File, since within the browser we
* cannot programmatically construct paths to or arbitrarily access files on the * cannot programmatically construct paths to or arbitrarily access files on the
* user's file system. Note that even if we were to have an absolute path at * user's file system.
* hand, we cannot programmatically create such File objects to arbitrary *
* absolute paths on user's local file system for security reasons. * > Note that even if we were to somehow have an absolute path at hand, we
* cannot programmatically create such File objects to arbitrary absolute
* paths on user's local file system for security reasons.
* *
* So in the web context, this will always be a File we get as a result of an * So in the web context, this will always be a File we get as a result of an
* explicit user interaction (e.g. drag and drop). * explicit user interaction (e.g. drag and drop or using a file selector).
* *
* In the desktop context, this can be either a File (+ path), or a path, or an * In the desktop context, this can be either a File (+ path), or a path, or an
* entry within a zip file. * entry within a zip file.
* *
* 2. If the user provided us this file via some user interaction (say a drag * 2. If the user provided us this file via some user interaction (say a drag
* and a drop), this'll still be a File. Note that unlike in the web context, * and a drop), this'll still be a File. But unlike in the web context, we
* such File objects also have the full path. See: [Note: File paths when * also have access to the full path of this file.
* running under Electron].
* *
* 3. However, when running in the desktop app we have the ability to access * 3. In addition, when running in the desktop app we have the ability to
* absolute paths on the user's file system. For example, if the user asks us * initate programmatic access absolute paths on the user's file system. For
* to watch certain folders on their disk for changes, we'll be able to pick * example, if the user asks us to watch certain folders on their disk for
* up new images being added, and in such cases, the parameter here will be a * changes, we'll be able to pick up new images being added, and in such
* path. Another example is when resuming an previously interrupted upload - * cases, the parameter here will be a path. Another example is when resuming
* we'll only have the path at hand in such cases, not the File object. * an previously interrupted upload - we'll only have the path at hand in
* such cases, not the original File object since the app subsequently
* restarted.
* *
* 4. The user might've also initiated an upload of a zip file. In this case we * 4. The user might've also initiated an upload of a zip file (or we might be
* will get a tuple (path to the zip file on the local file system, and the * resuming one). In such cases we will get a tuple (path to the zip file on
* name of the entry within that zip file). * the local file system, and the name of the entry within that zip file).
* *
* Case 3 and 4, when we're provided a path, are simple. We don't have a choice, * Case 3 and 4, when we're provided a path, are simple. We don't have a choice,
* since we cannot still programmatically construct a File object (we can * since we cannot still programmatically construct a File object (we can
* construct it on the Node.js layer, but it can't then be transferred over the * construct it on the Node.js layer, but it can't then be transferred over the
* IPC boundary). So all our operations use the path itself. * IPC boundary). So all our operations use the path itself.
* *
* Case 2 involves a choice on a use-case basis as neither File nor the path is * Case 2 involves a choice on a use-case basis. Neither File nor the path is a
* a better choice for all use cases. * better choice for all use cases.
* *
* The advantage of the File object is that the browser has already read it into * > The advantage of the File object is that the browser has already read it
* memory for us. The disadvantage comes in the case where we need to * into memory for us. The disadvantage comes in the case where we need to
* communicate with the native Node.js layer of our desktop app. Since this * communicate with the native Node.js layer of our desktop app. Since this
* communication happens over IPC, the File's contents need to be serialized and * communication happens over IPC, the File's contents need to be serialized
* copied, which is a bummer for large videos etc. * and copied, which is a bummer for large videos etc.
*/ */
const readUploadItem = async (uploadItem: UploadItem): Promise<FileStream> => { const readUploadItem = async (uploadItem: UploadItem): Promise<FileStream> => {
let underlyingStream: ReadableStream; let underlyingStream: ReadableStream;