/**
 * Merge partial loader data from server with cached loader data.
 *
 * During partial revalidation (stale or action), the server may return only
 * some loaders that pass the revalidation check. The component still needs
 * all loader data, so we merge fresh data with cached data.
 *
 * @param fromServer - Segment returned from server with partial loaders
 * @param fromCache - Cached segment with full loader data
 * @returns Merged segment with complete loader data
 */
export function mergeSegmentLoaders(fromServer, fromCache) {
    const serverLoaderIds = fromServer.loaderIds || [];
    const cachedLoaderIds = fromCache.loaderIds || [];
    console.log(`[Browser] Merging partial loaders: server has ${serverLoaderIds.join(", ")}, cache has ${cachedLoaderIds.join(", ")}`);
    return {
        ...fromCache,
        // Keep cached component (server's might be a fresh Promise that needs the loaders)
        component: fromCache.component,
        // Merge loader data - await both and combine
        loaderDataPromise: Promise.all([
            fromServer.loaderDataPromise,
            fromCache.loaderDataPromise,
        ]).then(([newData, cachedData]) => {
            // Build merged array: use new data for updated loaders, cached for rest
            return cachedLoaderIds.map((id, i) => {
                const newIndex = serverLoaderIds.indexOf(id);
                if (newIndex !== -1) {
                    return newData[newIndex]; // Use fresh data
                }
                return cachedData[i]; // Use cached data
            });
        }),
        // Keep all loader IDs from cache
        loaderIds: fromCache.loaderIds,
    };
}
/**
 * Check if segments need loader merging during partial revalidation.
 *
 * Returns true when:
 * - Server returned fewer loaders than cached (partial revalidation)
 * - Both segments have loader data promises
 */
export function needsLoaderMerge(fromServer, fromCache) {
    return !!(fromCache &&
        fromServer.loaderIds &&
        fromCache.loaderIds &&
        fromServer.loaderIds.length < fromCache.loaderIds.length &&
        fromServer.loaderDataPromise &&
        fromCache.loaderDataPromise);
}
/**
 * Insert diff segments that aren't in the matched array into allSegments.
 *
 * During consolidation fetch for concurrent actions, loader segments may be
 * excluded from the request. The server returns them in the diff but not in
 * the matched array. This function inserts them at the correct position
 * (after their parent layout segment).
 *
 * Loader segment IDs follow the pattern: {parentLayoutId}D{index}.{loaderId}
 * Example: M9L0L1D0.actionCounter has parent layout M9L0L1
 *
 * @param allSegments - Mutable array of segments to insert into
 * @param diff - Array of segment IDs that changed (from server response)
 * @param matchedIdSet - Set of segment IDs from matched array
 * @param newSegmentMap - Map of segment ID to segment data from server
 */
export function insertMissingDiffSegments(allSegments, diff, matchedIdSet, newSegmentMap) {
    if (!diff || diff.length === 0)
        return;
    diff.forEach((diffId) => {
        if (!matchedIdSet.has(diffId)) {
            const fromServer = newSegmentMap.get(diffId);
            if (fromServer) {
                // Loader segment IDs have pattern like M9L0L1D0.actionCounter
                // Parent layout ID is the prefix before D\d+ (e.g., M9L0L1)
                const loaderMatch = diffId.match(/^(.+?)D\d+\./);
                if (loaderMatch) {
                    const parentLayoutId = loaderMatch[1];
                    const parentIndex = allSegments.findIndex((s) => s.id === parentLayoutId);
                    if (parentIndex !== -1) {
                        // Insert loader segment right after its parent layout
                        allSegments.splice(parentIndex + 1, 0, fromServer);
                        console.log(`[Browser] Inserted diff segment ${diffId} after ${parentLayoutId}`);
                    }
                    else {
                        // Fallback: append to end if parent not found
                        allSegments.push(fromServer);
                        console.warn(`[Browser] Appended diff segment ${diffId} (parent ${parentLayoutId} not found)`);
                    }
                }
                else {
                    // Non-loader diff segment not in matched - append to end
                    allSegments.push(fromServer);
                    console.log(`[Browser] Appended diff segment ${diffId}`);
                }
            }
        }
    });
}
//# sourceMappingURL=merge-segment-loaders.js.map