@tanstack/router-plugin
Version:
Modern and scalable routing for React applications
1 lines • 4.95 kB
Source Map (JSON)
{"version":3,"file":"handle-route-update.cjs","names":[],"sources":["../../../../src/core/hmr/handle-route-update.ts"],"sourcesContent":["import type { AnyRoute, AnyRouter } from '@tanstack/router-core'\n\ntype AnyRouteWithPrivateProps = AnyRoute & {\n options: Record<string, unknown>\n parentRoute: AnyRoute\n _lazy?: Promise<void> | true\n update: (options: Record<string, unknown>) => unknown\n _path: string\n _id: string\n _fullPath: string\n _to: string\n}\n\ntype AnyRouterWithPrivateState = AnyRouter & {\n routesById: Record<string, AnyRoute>\n buildRouteTree: () => Parameters<AnyRouter['setRoutes']>[0]\n setRoutes: AnyRouter['setRoutes']\n _refreshRoute?: () => Promise<void>\n _replaceRouteChunk: (route: AnyRoute, lazyFn: AnyRoute['lazyFn']) => void\n}\n\nfunction handleRouteUpdate(\n routeId: string,\n newRoute: AnyRouteWithPrivateProps,\n) {\n const router = window.__TSR_ROUTER__ as AnyRouterWithPrivateState\n const oldRoute = router.routesById[routeId] as\n | AnyRouteWithPrivateProps\n | undefined\n\n if (!oldRoute) {\n return\n }\n\n // Generated route-tree options are not present on the freshly imported route\n // module, but they must stay on the live route before rebuilding indexes.\n const generatedRouteOptionKeys = new Set(['id', 'path', 'getParentRoute'])\n const generatedRouteOptions: Record<string, unknown> = {}\n generatedRouteOptionKeys.forEach((key) => {\n if (key in oldRoute.options) {\n generatedRouteOptions[key] = oldRoute.options[key]\n }\n })\n\n const oldHasShellComponent = 'shellComponent' in oldRoute.options\n const newHasShellComponent = 'shellComponent' in newRoute.options\n const preserveComponentIdentity =\n oldHasShellComponent === newHasShellComponent\n\n // Keys whose identity must remain stable to prevent React from\n // unmounting/remounting the component tree. React Fast Refresh already\n // handles hot-updating the function bodies of these components — our job\n // is only to update non-component route options (loader, head, etc.).\n // For code-split (splittable) routes, the lazyRouteComponent wrapper is\n // already cached in the bundler hot data so its identity is stable.\n // For unsplittable routes (e.g. root routes), the component is a plain\n // function reference that gets recreated on every module re-execution,\n // so we must explicitly preserve the old reference.\n // Preserve component identity so React doesn't remount.\n // React Fast Refresh patches the function bodies in-place.\n const componentKeys = '__TSR_COMPONENT_TYPES__' as unknown as Array<string>\n if (preserveComponentIdentity) {\n componentKeys.forEach((key) => {\n if (key in oldRoute.options && key in newRoute.options) {\n newRoute.options[key] = oldRoute.options[key]\n }\n })\n }\n\n const nextOptions = {\n ...newRoute.options,\n ...generatedRouteOptions,\n }\n\n oldRoute.options = nextOptions\n oldRoute.update(nextOptions)\n router._replaceRouteChunk(oldRoute, newRoute.lazyFn)\n\n router.setRoutes(router.buildRouteTree())\n syncHotRouteExport(oldRoute)\n router.resolvePathCache.clear()\n void router._refreshRoute?.()\n\n function syncHotRouteExport(liveRoute: AnyRouteWithPrivateProps) {\n // routeTree.gen.ts mutates the original module export with generated\n // routing state. Mirror that state onto the fresh HMR export too, so\n // aliased route imports keep working after the module is hot-reloaded.\n newRoute.options = liveRoute.options\n newRoute.parentRoute = liveRoute.parentRoute\n newRoute._path = liveRoute._path\n newRoute._id = liveRoute._id\n newRoute._fullPath = liveRoute._fullPath\n newRoute._to = liveRoute._to\n }\n}\n\nconst handleRouteUpdateStr = handleRouteUpdate.toString()\n\nexport function getHandleRouteUpdateCode(stableRouteOptionKeys: Array<string>) {\n return handleRouteUpdateStr.replace(\n /['\"]__TSR_COMPONENT_TYPES__['\"]/,\n JSON.stringify(stableRouteOptionKeys),\n )\n}\n"],"mappings":";AAqBA,SAAS,kBACP,SACA,UACA;CACA,MAAM,SAAS,OAAO;CACtB,MAAM,WAAW,OAAO,WAAW;CAInC,IAAI,CAAC,UACH;CAKF,MAAM,2BAA2B,IAAI,IAAI;EAAC;EAAM;EAAQ;CAAgB,CAAC;CACzE,MAAM,wBAAiD,CAAC;CACxD,yBAAyB,SAAS,QAAQ;EACxC,IAAI,OAAO,SAAS,SAClB,sBAAsB,OAAO,SAAS,QAAQ;CAElD,CAAC;CAID,MAAM,4BAFuB,oBAAoB,SAAS,YAC7B,oBAAoB,SAAS;CAe1D,MAAM,gBAAgB;CACtB,IAAI,2BACF,cAAc,SAAS,QAAQ;EAC7B,IAAI,OAAO,SAAS,WAAW,OAAO,SAAS,SAC7C,SAAS,QAAQ,OAAO,SAAS,QAAQ;CAE7C,CAAC;CAGH,MAAM,cAAc;EAClB,GAAG,SAAS;EACZ,GAAG;CACL;CAEA,SAAS,UAAU;CACnB,SAAS,OAAO,WAAW;CAC3B,OAAO,mBAAmB,UAAU,SAAS,MAAM;CAEnD,OAAO,UAAU,OAAO,eAAe,CAAC;CACxC,mBAAmB,QAAQ;CAC3B,OAAO,iBAAiB,MAAM;CAC9B,OAAY,gBAAgB;CAE5B,SAAS,mBAAmB,WAAqC;EAI/D,SAAS,UAAU,UAAU;EAC7B,SAAS,cAAc,UAAU;EACjC,SAAS,QAAQ,UAAU;EAC3B,SAAS,MAAM,UAAU;EACzB,SAAS,YAAY,UAAU;EAC/B,SAAS,MAAM,UAAU;CAC3B;AACF;AAEA,IAAM,uBAAuB,kBAAkB,SAAS;AAExD,SAAgB,yBAAyB,uBAAsC;CAC7E,OAAO,qBAAqB,QAC1B,mCACA,KAAK,UAAU,qBAAqB,CACtC;AACF"}