/* * Copyright (C) Contributors to the Suwayomi project * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ import { findDuplicatesByTitle } from '@/modules/library/util/LibraryDuplicates.util.ts'; import { LibraryDuplicatesDescriptionWorkerInput, LibraryDuplicatesWorkerInput, TMangaDuplicate, TMangaDuplicates, } from '@/modules/library/Library.types.ts'; import { Queue } from '@/lib/Queue.ts'; import { ControlledPromise } from '@/lib/ControlledPromise.ts'; import { enhancedCleanup } from '@/util/Strings.ts'; const queue = new Queue((navigator.hardwareConcurrency ?? 5) - 1); const MANGAS_PER_CHUNK = 200; // eslint-disable-next-line no-restricted-globals self.onmessage = async (event: MessageEvent) => { const { mangas, checkAlternativeTitles } = event.data; if (!checkAlternativeTitles) { postMessage(findDuplicatesByTitle(mangas)); return; } const chunkPromises: Promise>[] = []; for (let chunkStart = 0; chunkStart < mangas.length; chunkStart += MANGAS_PER_CHUNK) { chunkPromises.push( queue.enqueue(chunkStart.toString(), () => { const workerPromise = new ControlledPromise>(); const worker = new Worker(new URL('LibraryDuplicatesDescriptionWorker.ts', import.meta.url), { type: 'module', }); worker.onmessage = (subWorkerEvent: MessageEvent>) => workerPromise.resolve(subWorkerEvent.data); worker.postMessage({ mangas, mangasToCheck: mangas.slice(chunkStart, chunkStart + MANGAS_PER_CHUNK), } satisfies LibraryDuplicatesDescriptionWorkerInput); return workerPromise.promise; }).promise, ); } const chunkedResults = await Promise.all(chunkPromises); const mergedResult: TMangaDuplicates = {}; const cleanedUpTitleToOriginalTitle: Record = {}; chunkedResults.forEach((chunkedResult) => Object.entries(chunkedResult).forEach(([title, duplicates]) => { const cleanedTitle = enhancedCleanup(title); cleanedUpTitleToOriginalTitle[cleanedTitle] ??= title; const originalTitle = cleanedUpTitleToOriginalTitle[cleanedTitle]; // ignore duplicated results for a title from other chunked results mergedResult[originalTitle] ??= duplicates; }), ); postMessage(mergedResult); };