Array of manga match results.
User's existing AniList library indexed by media ID.
Sync configuration with priority settings.
Array of AniList media entries ready for synchronization.
export function prepareAllEntriesToSync(
mangaMatches: MangaMatchResult[],
userLibrary: UserMediaList,
syncConfig: SyncConfig,
): AniListMediaEntry[] {
return mangaMatches
.filter((match) => match.status === "matched" || match.status === "manual")
.filter((match) => match.selectedMatch !== undefined)
.map((match) => {
// Get Kenmei data
const kenmei = match.kenmeiManga;
const anilist = match.selectedMatch!;
const userEntry = userLibrary[anilist.id];
if (
userEntry?.status === "COMPLETED" &&
syncConfig.preserveCompletedStatus
) {
return null;
}
const computeCalculatedStatus = (): MediaListStatus => {
// Reuse existing getEffectiveStatus logic which already handles auto-pause checks
const kenmeiStatusSnapshot: KenmeiMangaData = {
status: kenmei.status,
updatedAt: kenmei.updatedAt,
lastReadAt: kenmei.lastReadAt,
title: kenmei.title,
chaptersRead: kenmei.chaptersRead,
score: kenmei.score,
};
return getEffectiveStatus(kenmeiStatusSnapshot, syncConfig);
};
const calculatedStatus = computeCalculatedStatus();
let shouldSetPrivate: boolean;
if (userEntry) {
if (syncConfig.setPrivate) {
shouldSetPrivate = true;
} else {
shouldSetPrivate = userEntry.private || false;
}
} else {
shouldSetPrivate = syncConfig.setPrivate;
}
const entry: AniListMediaEntry = {
mediaId: anilist.id,
status:
syncConfig.prioritizeAniListStatus && userEntry?.status
? userEntry.status
: calculatedStatus,
progress: (() => {
if (
syncConfig.prioritizeAniListProgress &&
userEntry?.progress &&
userEntry.progress > 0
) {
const kenmeiProgress = kenmei.chaptersRead || 0;
return Math.max(userEntry.progress, kenmeiProgress);
}
return kenmei.chaptersRead || 0;
})(),
private: shouldSetPrivate,
score: (() => {
if (
userEntry &&
syncConfig.prioritizeAniListScore &&
userEntry.score > 0
) {
return userEntry.score;
}
return typeof kenmei.score === "number" ? kenmei.score : 0;
})(),
previousValues: userEntry
? {
status: userEntry.status,
progress:
typeof userEntry.progress === "number" ? userEntry.progress : 0,
score: typeof userEntry.score === "number" ? userEntry.score : 0,
private: userEntry.private || false,
}
: null,
title: anilist.title.romaji || kenmei.title,
coverImage: anilist.coverImage?.large || anilist.coverImage?.medium,
};
entry.private ??= syncConfig.setPrivate || false;
return entry;
})
.filter((entry): entry is AniListMediaEntry => entry !== null);
}
Prepare all entries to sync from matched manga, applying configuration rules. Filters to matched/manual entries and respects preserveCompletedStatus setting.