import { getRouterContext } from "../router-context.js";
import { debugLog, debugWarn } from "../logging.js";
/**
 * Creates background revalidation middleware
 *
 * If cache was stale (state.shouldRevalidate === true):
 * - Triggers background resolution via waitUntil
 * - Observes segments but doesn't modify them
 * - Updates cache with fresh segments after revalidation completes
 */
export function withBackgroundRevalidation(ctx, state) {
    return async function* (source) {
        // Pass through all segments unchanged
        for await (const segment of source) {
            yield segment;
        }
        // Only trigger background revalidation if:
        // 1. Cache was hit and stale
        // 2. Cache scope exists
        if (!state.shouldRevalidate || !state.cacheHit || !ctx.cacheScope) {
            return;
        }
        const { getRequestContext, createHandleStore, resolveAllSegmentsWithRevalidation, resolveAllSegments, resolveInterceptEntry, } = getRouterContext();
        const requestCtx = getRequestContext();
        const cacheScope = ctx.cacheScope;
        requestCtx?.waitUntil(async () => {
            debugLog("backgroundRevalidation", "revalidating stale route", {
                pathname: ctx.pathname,
                fullMatch: ctx.isFullMatch,
            });
            try {
                // Create a fresh handleStore for background revalidation
                // to avoid polluting the current response's handle stream
                if (requestCtx) {
                    requestCtx._handleStore = createHandleStore();
                }
                let freshSegments;
                if (ctx.isFullMatch) {
                    // Full match (document request) - simple resolution
                    freshSegments = await resolveAllSegments(ctx.entries, ctx.routeKey, ctx.matched.params, ctx.handlerContext, ctx.loaderPromises);
                }
                else {
                    // Partial match (navigation) - resolution with revalidation
                    const freshResult = await resolveAllSegmentsWithRevalidation(ctx.entries, ctx.routeKey, ctx.matched.params, ctx.handlerContext, ctx.clientSegmentSet, ctx.prevParams, ctx.request, ctx.prevUrl, ctx.url, ctx.loaderPromises, ctx.actionContext, ctx.interceptResult, ctx.localRouteName, ctx.pathname);
                    freshSegments = freshResult.segments;
                    // For intercept revalidation, also resolve fresh intercept segments
                    if (ctx.interceptResult) {
                        const freshInterceptSegments = await resolveInterceptEntry(ctx.interceptResult.intercept, ctx.interceptResult.entry, ctx.matched.params, ctx.handlerContext, true, {
                            clientSegmentIds: ctx.clientSegmentSet,
                            prevParams: ctx.prevParams,
                            request: ctx.request,
                            prevUrl: ctx.prevUrl,
                            nextUrl: ctx.url,
                            routeKey: ctx.routeKey,
                            actionContext: ctx.actionContext,
                            stale: false,
                        });
                        freshSegments = [...freshSegments, ...freshInterceptSegments];
                    }
                }
                await cacheScope.cacheRoute(ctx.pathname, ctx.matched.params, freshSegments, ctx.isIntercept);
                debugLog("backgroundRevalidation", "revalidation complete", {
                    pathname: ctx.pathname,
                });
            }
            catch (error) {
                debugWarn("backgroundRevalidation", "revalidation failed", {
                    pathname: ctx.pathname,
                    error: String(error),
                });
            }
        });
    };
}
//# sourceMappingURL=background-revalidation.js.map