mirror of
				https://github.com/KevinMidboe/immich.git
				synced 2025-10-29 17:40:28 +00:00 
			
		
		
		
	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
This commit is contained in:
		
							
								
								
									
										23
									
								
								web/package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										23
									
								
								web/package-lock.json
									
									
									
										generated
									
									
									
								
							| @@ -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", | ||||
|   | ||||
| @@ -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", | ||||
|   | ||||
| @@ -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<File>(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 <T>(iterable: AsyncIterable<T>) { | ||||
|   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, | ||||
|       }, | ||||
|   | ||||
		Reference in New Issue
	
	Block a user