Optionalconfig: Partial<WorkerPoolConfig>Initializes the shared worker pool for matching operations.
A promise that resolves when initialization is complete.
async initialize(): Promise<void> {
if (this.isInitialized) {
return;
}
const pool = getGenericWorkerPool({
maxWorkers: this.config.maxWorkers,
enableWorkers: this.config.enableWorkers,
fallbackToMainThread: this.config.fallbackToMainThread,
});
await pool.initialize();
this.isInitialized = true;
}
Executes a batch manga matching operation using a worker or the main thread.
Source manga entries from Kenmei.
Candidate AniList manga grouped by key.
Partial matching engine configuration.
OptionalprogressCallback: (current: number, total: number, currentTitle?: string) => voidOptional progress callback for UI updates.
OptionaltaskId: stringOptional external task identifier.
Batch execution handle with aggregated promise.
async executeMatchBatch(
kenmeiMangaList: KenmeiManga[],
anilistMangaMap: Map<string, AniListManga[]>,
config: Partial<MatchEngineConfig>,
progressCallback?: (
current: number,
total: number,
currentTitle?: string,
) => void,
taskId?: string,
): Promise<MatchBatchExecution> {
const pool = getGenericWorkerPool();
// Ensure pool is initialized
await pool.ensureInitialized();
const mainTaskId = taskId || generateUUID();
const promise = new Promise<MangaMatchResult[]>((resolve, reject) => {
if (!pool.isAvailable()) {
// Fallback to main thread
this.executeMatchBatchMainThread(
kenmeiMangaList,
anilistMangaMap,
config,
)
.then(resolve)
.catch(reject);
return;
}
const workerIndex = pool.selectWorker();
if (workerIndex === -1) {
// Fallback to main thread
this.executeMatchBatchMainThread(
kenmeiMangaList,
anilistMangaMap,
config,
)
.then(resolve)
.catch(reject);
return;
}
const worker = pool.getWorker(workerIndex);
if (!worker) {
// Fallback to main thread
this.executeMatchBatchMainThread(
kenmeiMangaList,
anilistMangaMap,
config,
)
.then(resolve)
.catch(reject);
return;
}
// Register task
const task = {
taskId: mainTaskId,
type: "matching" as const,
kenmeiManga: kenmeiMangaList,
anilistCandidates: Array.from(anilistMangaMap),
config,
resolve: (result: unknown) => {
// Adapt raw payload to expected shape: extract results array
const adaptedResult =
(result as { results?: MangaMatchResult[] }).results ||
(result as MangaMatchResult[]);
resolve(adaptedResult);
},
reject,
isCancelled: false,
progressCallback,
onProgress: (message: unknown) => {
// Adapt generic message to typed callback
const msgWithType = message as {
type?: string;
payload?: {
current?: number;
total?: number;
currentTitle?: string;
};
};
if (
msgWithType.type === "PROGRESS" &&
progressCallback &&
msgWithType.payload &&
typeof msgWithType.payload.current === "number" &&
typeof msgWithType.payload.total === "number"
) {
const { current, total, currentTitle } = msgWithType.payload;
progressCallback(current, total, currentTitle);
}
},
workerIndex,
};
pool.registerTask(mainTaskId, task);
// Send message to worker
worker.postMessage({
type: "MATCH_BATCH",
payload: {
taskId: mainTaskId,
kenmeiManga: kenmeiMangaList,
anilistCandidates: Array.from(anilistMangaMap),
config,
},
});
console.info(
`[MatchingWorkerPool] 📤 Dispatched batch match to worker ${workerIndex}: ${kenmeiMangaList.length} items`,
);
});
return {
taskId: mainTaskId,
chunkTaskIds: [],
promise,
};
}
Manages manga matching operations using the shared worker pool.
Source