From 8045fd3f14d674d48089490a2cfc1ffabb83336a Mon Sep 17 00:00:00 2001 From: Thomas <9749173+uhthomas@users.noreply.github.com> Date: Mon, 17 Jul 2023 17:22:29 +0100 Subject: [PATCH] fix(web): remove dependency on rxjs (#3301) The dependency on rxjs has been removed in favour of iterators as it's clearer and the nature of the workload is inherently non-reactive. The uncaught error when the list of files is empty has also been implicitly fixed by this change. Fixes: #3300 --- web/package-lock.json | 23 +++------------- web/package.json | 1 - web/src/lib/utils/file-uploader.ts | 42 +++++++++++++++++++++--------- 3 files changed, 33 insertions(+), 33 deletions(-) diff --git a/web/package-lock.json b/web/package-lock.json index 5896ca8c91..d0f920b771 100644 --- a/web/package-lock.json +++ b/web/package-lock.json @@ -19,7 +19,6 @@ "leaflet.markercluster": "^1.5.3", "lodash-es": "^4.17.21", "luxon": "^3.2.1", - "rxjs": "^7.8.0", "socket.io-client": "^4.6.1", "svelte-local-storage-store": "^0.5.0", "svelte-material-icons": "^3.0.5", @@ -10526,14 +10525,6 @@ "queue-microtask": "^1.2.2" } }, - "node_modules/rxjs": { - "version": "7.8.1", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", - "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", - "dependencies": { - "tslib": "^2.1.0" - } - }, "node_modules/sade": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/sade/-/sade-1.8.1.tgz", @@ -11447,7 +11438,8 @@ "node_modules/tslib": { "version": "2.5.3", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.3.tgz", - "integrity": "sha512-mSxlJJwl3BMEQCUNnxXBU9jP4JBktcEGhURcPR6VQVlnP0FdDEsIaz0C35dXNGLyRfrATNofF0F5p2KPxQgB+w==" + "integrity": "sha512-mSxlJJwl3BMEQCUNnxXBU9jP4JBktcEGhURcPR6VQVlnP0FdDEsIaz0C35dXNGLyRfrATNofF0F5p2KPxQgB+w==", + "dev": true }, "node_modules/tsutils": { "version": "3.21.0", @@ -19522,14 +19514,6 @@ "queue-microtask": "^1.2.2" } }, - "rxjs": { - "version": "7.8.1", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", - "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", - "requires": { - "tslib": "^2.1.0" - } - }, "sade": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/sade/-/sade-1.8.1.tgz", @@ -20184,7 +20168,8 @@ "tslib": { "version": "2.5.3", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.3.tgz", - "integrity": "sha512-mSxlJJwl3BMEQCUNnxXBU9jP4JBktcEGhURcPR6VQVlnP0FdDEsIaz0C35dXNGLyRfrATNofF0F5p2KPxQgB+w==" + "integrity": "sha512-mSxlJJwl3BMEQCUNnxXBU9jP4JBktcEGhURcPR6VQVlnP0FdDEsIaz0C35dXNGLyRfrATNofF0F5p2KPxQgB+w==", + "dev": true }, "tsutils": { "version": "3.21.0", diff --git a/web/package.json b/web/package.json index 9fe3fc5b33..805b2d12b0 100644 --- a/web/package.json +++ b/web/package.json @@ -70,7 +70,6 @@ "leaflet.markercluster": "^1.5.3", "lodash-es": "^4.17.21", "luxon": "^3.2.1", - "rxjs": "^7.8.0", "socket.io-client": "^4.6.1", "svelte-local-storage-store": "^0.5.0", "svelte-material-icons": "^3.0.5", diff --git a/web/src/lib/utils/file-uploader.ts b/web/src/lib/utils/file-uploader.ts index badfd690c8..4f7bc07b5e 100644 --- a/web/src/lib/utils/file-uploader.ts +++ b/web/src/lib/utils/file-uploader.ts @@ -1,8 +1,7 @@ import { uploadAssetsStore } from '$lib/stores/upload'; -import { addAssetsToAlbum, getFilenameExtension } from '$lib/utils/asset-utils'; +import { addAssetsToAlbum } from '$lib/utils/asset-utils'; import type { AssetFileUploadResponseDto } from '@api'; import axios from 'axios'; -import { combineLatestAll, filter, firstValueFrom, from, mergeMap, of } from 'rxjs'; import { notificationController, NotificationType } from './../components/shared-components/notification/notification'; const extensions = [ @@ -70,9 +69,9 @@ export const openFileUploadDialog = async ( if (!target.files) { return; } - const files = Array.from(target.files); + const files = Array.from(target.files); - resolve(await fileUploadHandler(files, albumId, sharedKey)); + resolve(fileUploadHandler(files, albumId, sharedKey)); }; fileSelector.click(); @@ -88,16 +87,33 @@ export const fileUploadHandler = async ( albumId: string | undefined = undefined, sharedKey: string | undefined = undefined, ) => { - return firstValueFrom( - from(files).pipe( - filter((file) => extensions.includes('.' + getFilenameExtension(file.name))), - mergeMap(async (file) => of(await fileUploader(file, albumId, sharedKey)), 2), - combineLatestAll(), - ), - ); + const iterable = { + files: files.filter((file) => extensions.some((ext) => file.name.endsWith(ext)))[Symbol.iterator](), + + async *[Symbol.asyncIterator]() { + for (const file of this.files) { + yield fileUploader(file, albumId, sharedKey); + } + }, + }; + + const concurrency = 2; + // TODO: use Array.fromAsync instead when it's available universally. + return Promise.all([...Array(concurrency)].map(() => fromAsync(iterable))).then((res) => res.flat()); }; -//TODO: should probably use the @api SDK +// polyfill for Array.fromAsync. +// +// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/fromAsync +const fromAsync = async function (iterable: AsyncIterable) { + const result = []; + for await (const value of iterable) { + result.push(value); + } + return result; +}; + +// TODO: should probably use the @api SDK async function fileUploader( asset: File, albumId: string | undefined = undefined, @@ -122,7 +138,7 @@ async function fileUploader( progress: 0, }); - const response = await axios.post(`/api/asset/upload`, formData, { + const response = await axios.post('/api/asset/upload', formData, { params: { key: sharedKey, },