import { DEFAULT_SEGMENT_KEY } from "../../../shared/lib/segment"; import { matchSegment } from "../match-segments"; import { addRefreshMarkerToActiveParallelSegments } from "./refetch-inactive-parallel-segments"; /** * Deep merge of the two router states. Parallel route keys are preserved if the patch doesn't have them. */ function applyPatch(initialTree, patchTree, flightSegmentPath) { const [initialSegment, initialParallelRoutes] = initialTree; const [patchSegment, patchParallelRoutes] = patchTree; // if the applied patch segment is __DEFAULT__ then it can be ignored in favor of the initial tree // this is because the __DEFAULT__ segment is used as a placeholder on navigation if (patchSegment === DEFAULT_SEGMENT_KEY && initialSegment !== DEFAULT_SEGMENT_KEY) { return initialTree; } if (matchSegment(initialSegment, patchSegment)) { const newParallelRoutes = {}; for(const key in initialParallelRoutes){ const isInPatchTreeParallelRoutes = typeof patchParallelRoutes[key] !== "undefined"; if (isInPatchTreeParallelRoutes) { newParallelRoutes[key] = applyPatch(initialParallelRoutes[key], patchParallelRoutes[key], flightSegmentPath); } else { newParallelRoutes[key] = initialParallelRoutes[key]; } } for(const key in patchParallelRoutes){ if (newParallelRoutes[key]) { continue; } newParallelRoutes[key] = patchParallelRoutes[key]; } const tree = [ initialSegment, newParallelRoutes ]; // Copy over the existing tree if (initialTree[2]) { tree[2] = initialTree[2]; } if (initialTree[3]) { tree[3] = initialTree[3]; } if (initialTree[4]) { tree[4] = initialTree[4]; } return tree; } return patchTree; } /** * Apply the router state from the Flight response, but skip patching default segments. * Useful for patching the router cache when navigating, where we persist the existing default segment if there isn't a new one. * Creates a new router state tree. */ export function applyRouterStatePatchToTree(flightSegmentPath, flightRouterState, treePatch, path) { const [segment, parallelRoutes, url, refetch, isRootLayout] = flightRouterState; // Root refresh if (flightSegmentPath.length === 1) { const tree = applyPatch(flightRouterState, treePatch, flightSegmentPath); addRefreshMarkerToActiveParallelSegments(tree, path); return tree; } const [currentSegment, parallelRouteKey] = flightSegmentPath; // Tree path returned from the server should always match up with the current tree in the browser if (!matchSegment(currentSegment, segment)) { return null; } const lastSegment = flightSegmentPath.length === 2; let parallelRoutePatch; if (lastSegment) { parallelRoutePatch = applyPatch(parallelRoutes[parallelRouteKey], treePatch, flightSegmentPath); } else { parallelRoutePatch = applyRouterStatePatchToTree(flightSegmentPath.slice(2), parallelRoutes[parallelRouteKey], treePatch, path); if (parallelRoutePatch === null) { return null; } } const tree = [ flightSegmentPath[0], { ...parallelRoutes, [parallelRouteKey]: parallelRoutePatch }, url, refetch ]; // Current segment is the root layout if (isRootLayout) { tree[4] = true; } addRefreshMarkerToActiveParallelSegments(tree, path); return tree; } //# sourceMappingURL=apply-router-state-patch-to-tree.js.map