• Process a batch of manga updates with rate limiting and progress tracking.

    Parameters

    • entries: AniListMediaEntry[]

      Array of AniList media entries to sync.

    • token: string

      The user's authentication token.

    • OptionalonProgress: (progress: SyncProgress) => void

      Optional callback for progress updates.

    • OptionalabortSignal: AbortSignal

      Optional abort signal to cancel the sync.

    • OptionaldisplayOrderMediaIds: number[]

      Optional array of media IDs to control sync order.

    Returns Promise<SyncReport>

    A promise resolving to a SyncReport object.

    export async function syncMangaBatch(
    entries: AniListMediaEntry[],
    token: string,
    onProgress?: (progress: SyncProgress) => void,
    abortSignal?: AbortSignal,
    displayOrderMediaIds?: number[],
    ): Promise<SyncReport> {
    const errors: { mediaId: number; error: string }[] = [];

    // Organize entries by media ID for handling incremental sync properly
    const entriesByMediaId = organizeEntriesByMediaId(entries);

    // Determine processing order
    const userOrderMediaIds = determineProcessingOrder(
    displayOrderMediaIds,
    entriesByMediaId,
    );

    // Use the original entries length for progress calculation, not media IDs
    const progress: SyncProgress = {
    total: entries.length,
    completed: 0,
    successful: 0,
    failed: 0,
    skipped: 0,
    currentEntry: null,
    currentStep: null,
    totalSteps: null,
    rateLimited: false,
    retryAfter: null,
    };

    if (onProgress) {
    onProgress({ ...progress });
    }

    const apiCallsCompleted = { count: 0 };

    // Process each media ID in order
    for (const mediaIdNum of userOrderMediaIds) {
    if (abortSignal?.aborted) {
    console.log("Sync operation aborted by user");
    break;
    }

    const result = await processMediaEntries(
    mediaIdNum,
    entriesByMediaId,
    token,
    apiCallsCompleted,
    progress,
    onProgress,
    abortSignal,
    );

    // Update progress counters
    progress.completed++;

    if (result.success) {
    progress.successful++;
    } else {
    progress.failed++;
    if (result.error) {
    errors.push({
    mediaId: mediaIdNum,
    error: result.error,
    });
    }
    }

    // Clear current entry info
    progress.currentEntry = null;
    progress.currentStep = null;

    if (onProgress) {
    onProgress({ ...progress });
    }
    }

    return generateSyncReport(entries, progress, errors);
    }