@vlian/framework 1.2.18 → 1.2.25

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (85) hide show
  1. package/dist/analytics.umd.js +1 -1
  2. package/dist/core/index.cjs +0 -1
  3. package/dist/core/index.cjs.map +1 -1
  4. package/dist/core/index.d.ts +1 -2
  5. package/dist/core/index.js +0 -1
  6. package/dist/core/index.js.map +1 -1
  7. package/dist/core/initialization/index.cjs.map +1 -1
  8. package/dist/core/initialization/index.d.ts +1 -1
  9. package/dist/core/initialization/index.js.map +1 -1
  10. package/dist/core/initialization/initialization.cjs +2 -147
  11. package/dist/core/initialization/initialization.cjs.map +1 -1
  12. package/dist/core/initialization/initialization.d.ts +0 -57
  13. package/dist/core/initialization/initialization.js +2 -148
  14. package/dist/core/initialization/initialization.js.map +1 -1
  15. package/dist/core/kernel/startKernel.cjs +1 -2
  16. package/dist/core/kernel/startKernel.cjs.map +1 -1
  17. package/dist/core/kernel/startKernel.js +1 -2
  18. package/dist/core/kernel/startKernel.js.map +1 -1
  19. package/dist/core/plugin.cjs +16 -16
  20. package/dist/core/plugin.cjs.map +1 -1
  21. package/dist/core/plugin.d.ts +5 -1
  22. package/dist/core/plugin.js +17 -17
  23. package/dist/core/plugin.js.map +1 -1
  24. package/dist/core/router/RouterManager.cjs +28 -9
  25. package/dist/core/router/RouterManager.cjs.map +1 -1
  26. package/dist/core/router/RouterManager.d.ts +2 -2
  27. package/dist/core/router/RouterManager.js +28 -9
  28. package/dist/core/router/RouterManager.js.map +1 -1
  29. package/dist/core/router/adapter/react-router/ReactRouterAdapter.cjs +1 -1
  30. package/dist/core/router/adapter/react-router/ReactRouterAdapter.cjs.map +1 -1
  31. package/dist/core/router/adapter/react-router/ReactRouterAdapter.js +1 -1
  32. package/dist/core/router/adapter/react-router/ReactRouterAdapter.js.map +1 -1
  33. package/dist/core/router/types.d.ts +9 -0
  34. package/dist/core/router/types.js.map +1 -1
  35. package/dist/core/router/utils/adapters/react-router/RouteErrorBoundary.cjs +13 -8
  36. package/dist/core/router/utils/adapters/react-router/RouteErrorBoundary.cjs.map +1 -1
  37. package/dist/core/router/utils/adapters/react-router/RouteErrorBoundary.js +13 -8
  38. package/dist/core/router/utils/adapters/react-router/RouteErrorBoundary.js.map +1 -1
  39. package/dist/core/router/utils/adapters/react-router/transform.cjs +11 -6
  40. package/dist/core/router/utils/adapters/react-router/transform.cjs.map +1 -1
  41. package/dist/core/router/utils/adapters/react-router/transform.d.ts +1 -1
  42. package/dist/core/router/utils/adapters/react-router/transform.js +11 -6
  43. package/dist/core/router/utils/adapters/react-router/transform.js.map +1 -1
  44. package/dist/core/router/validation/RouterConfigValidator.d.ts +2 -0
  45. package/dist/core/router/validation/schema.cjs +2 -1
  46. package/dist/core/router/validation/schema.cjs.map +1 -1
  47. package/dist/core/router/validation/schema.d.ts +3 -0
  48. package/dist/core/router/validation/schema.js +2 -1
  49. package/dist/core/router/validation/schema.js.map +1 -1
  50. package/dist/core/startup/startApp.cjs +0 -2
  51. package/dist/core/startup/startApp.cjs.map +1 -1
  52. package/dist/core/startup/startApp.js +0 -2
  53. package/dist/core/startup/startApp.js.map +1 -1
  54. package/dist/core/types.d.ts +1 -5
  55. package/dist/core/types.js.map +1 -1
  56. package/dist/index.umd.js +77 -221
  57. package/dist/index.umd.js.map +1 -1
  58. package/dist/lazy/index.cjs +104 -0
  59. package/dist/lazy/index.cjs.map +1 -0
  60. package/dist/lazy/index.d.ts +19 -0
  61. package/dist/lazy/index.js +24 -0
  62. package/dist/lazy/index.js.map +1 -0
  63. package/dist/library/storage/index.cjs +1 -1
  64. package/dist/library/storage/index.cjs.map +1 -1
  65. package/dist/library/storage/index.d.ts +1 -0
  66. package/dist/library/storage/index.js +1 -1
  67. package/dist/library/storage/index.js.map +1 -1
  68. package/dist/request.umd.js +1 -1
  69. package/dist/state.umd.js +1 -1
  70. package/package.json +96 -2
  71. package/dist/core/ui-adapter/adapters.cjs +0 -45
  72. package/dist/core/ui-adapter/adapters.cjs.map +0 -1
  73. package/dist/core/ui-adapter/adapters.d.ts +0 -4
  74. package/dist/core/ui-adapter/adapters.js +0 -27
  75. package/dist/core/ui-adapter/adapters.js.map +0 -1
  76. package/dist/core/ui-adapter/index.cjs +0 -21
  77. package/dist/core/ui-adapter/index.cjs.map +0 -1
  78. package/dist/core/ui-adapter/index.d.ts +0 -2
  79. package/dist/core/ui-adapter/index.js +0 -3
  80. package/dist/core/ui-adapter/index.js.map +0 -1
  81. package/dist/core/ui-adapter/types.cjs +0 -6
  82. package/dist/core/ui-adapter/types.cjs.map +0 -1
  83. package/dist/core/ui-adapter/types.d.ts +0 -24
  84. package/dist/core/ui-adapter/types.js +0 -3
  85. package/dist/core/ui-adapter/types.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/core/router/types.ts"],"sourcesContent":["import type { AppInstance } from '../startup/AppInstance';\nimport type { createBrowserRouter, createMemoryRouter } from 'react-router-dom';\nimport type { TransformOptions } from './utils/transform';\nimport type { PreloadConfig } from './performance/RoutePreloader';\n\nexport type RouteItemHandle = {\n title: string,\n i18nKey?: string,\n order: number,\n icon?: string,\n // 在菜单中隐藏\n hideInMenu?: boolean,\n // 隐藏尾部\n hideFooter?: boolean,\n // 保活\n keepAlive?: boolean,\n // 是否需要的登录\n needLogin?: boolean,\n // 角色\n roles?: Array<string>,\n // 路由名称,唯一Key\n name?: string,\n // 其他\n [key: string]: unknown,\n}\nexport type RouteItem = {\n // 布局 布局对象的key或动态导入函数\n layout?: string | ComponentImport | null,\n // 页面 页面对象的key或动态导入函数\n page?: string | ComponentImport | null,\n // loading 加载对象的key或动态导入函数\n loading?: string | ComponentImport | null,\n // 错误 组件的key或动态导入函数\n errors?: string | ComponentImport | null,\n // 错误(兼容字段)组件的key或动态导入函数\n error?: string | ComponentImport | null,\n // 路由名称,唯一Key\n name: string,\n // 路由\n path: string | undefined,\n // 是否分组路由\n isGroup?: boolean,\n // 是否开启重定向\n enableRedirection?: boolean,\n // 额外参数\n handle: RouteItemHandle,\n children?: RouteItem[]\n}\n\nexport type RouteMapType = Record<string, () => Promise<any>>;\n\n/**\n * DOM 路由选项类型(从 createBrowserRouter 和 createHashRouter 的参数类型提取)\n */\nexport type DOMRouterOpts = Parameters<typeof createBrowserRouter>[1];\n\n/**\n * Memory 路由选项类型(从 createMemoryRouter 的参数类型提取)\n */\nexport type MemoryRouterOpts = Parameters<typeof createMemoryRouter>[1];\n\n/**\n * 路由元数据(兼容 RouteItemHandle)\n * \n * @deprecated 建议直接使用 RouteItem 和 RouteItemHandle\n */\nexport interface RouteMeta {\n /**\n * 路由标题\n */\n title?: string;\n\n /**\n * 图标\n */\n icon?: string;\n\n /**\n * 排序\n */\n order?: number;\n\n /**\n * 权限标识\n */\n auth?: string | string[];\n\n /**\n * 是否在菜单中隐藏\n */\n hideInMenu?: boolean;\n\n /**\n * 是否启用 KeepAlive\n */\n keepAlive?: boolean;\n\n /**\n * 是否需要登录\n */\n needLogin?: boolean;\n\n /**\n * 角色列表\n */\n roles?: string[];\n\n /**\n * 路由名称(唯一标识)\n */\n name?: string;\n\n /**\n * 其他自定义元数据\n */\n [key: string]: unknown;\n}\n\n/**\n * 动态导入函数类型\n * \n * 用于懒加载组件,返回一个 Promise,resolve 后的值为组件模块对象\n * 组件必须使用默认导出(export default)\n */\nexport type ComponentImport = () => Promise<any>;\n\n/**\n * 路由配置项\n * \n * 与 RouteItem 的区别:\n * - layout、page、loading、error/errors 可以是组件路径字符串(如 \"@/pages/index.ts\")或动态导入函数\n * - 如果使用字符串,系统会自动转换为动态导入函数\n * - 如果使用函数,则直接使用,无需转换\n * - 对应的组件必须默认导出(export default xxxx)\n */\nexport interface RouteConfig {\n /**\n * 布局组件路径(字符串)或动态导入函数\n * \n * 字符串示例: \"@/pages/layout.tsx\" 或 \"../../pages/layout.tsx\"\n * 函数示例: () => import(\"@/pages/layout.tsx\")\n * 组件必须默认导出\n */\n layout?: string | ComponentImport | null;\n\n /**\n * 页面组件路径(字符串)或动态导入函数\n * \n * 字符串示例: \"@/pages/index.tsx\" 或 \"../../pages/index.tsx\"\n * 函数示例: () => import(\"@/pages/index.tsx\")\n * 组件必须默认导出\n */\n page?: string | ComponentImport | null;\n\n /**\n * 加载组件路径(字符串)或动态导入函数\n * \n * 字符串示例: \"@/components/Loading.tsx\"\n * 函数示例: () => import(\"@/components/Loading.tsx\")\n * 组件必须默认导出\n */\n loading?: string | ComponentImport | null;\n\n /**\n * 错误组件路径(字符串)或动态导入函数\n * \n * 字符串示例: \"@/pages/error.tsx\"\n * 函数示例: () => import(\"@/pages/error.tsx\")\n * 组件必须默认导出\n */\n errors?: string | ComponentImport | null;\n\n /**\n * 错误组件路径(字符串)或动态导入函数(兼容字段,优先级高于 errors)\n *\n * 字符串示例: \"@/pages/error.tsx\"\n * 函数示例: () => import(\"@/pages/error.tsx\")\n * 组件必须默认导出\n */\n error?: string | ComponentImport | null;\n\n /**\n * 路由名称(唯一标识)\n */\n name: string;\n\n /**\n * 路由路径\n */\n path: string | undefined;\n\n /**\n * 是否为路由组\n */\n isGroup?: boolean;\n\n /**\n * 是否启用重定向\n */\n enableRedirection?: boolean;\n\n /**\n * 路由元数据\n */\n handle: {\n title: string;\n i18nKey?: string;\n order: number;\n icon?: string;\n hideInMenu?: boolean;\n hideFooter?: boolean;\n keepAlive?: boolean;\n needLogin?: boolean;\n roles?: Array<string>;\n name?: string;\n [key: string]: unknown;\n };\n\n /**\n * 子路由配置\n */\n children?: RouteConfig[];\n}\n\n/**\n * 路由位置信息\n */\nexport interface RouteLocation {\n /**\n * 路径\n */\n path: string;\n\n /**\n * 路径参数\n */\n params?: Record<string, unknown>;\n\n /**\n * 查询参数\n */\n query?: Record<string, unknown>;\n\n /**\n * 路由元数据\n */\n meta?: RouteMeta;\n}\n\n/**\n * 导航选项\n */\nexport interface NavigateOptions {\n /**\n * 是否替换当前历史记录\n */\n replace?: boolean;\n\n /**\n * 状态数据\n */\n state?: unknown;\n\n /**\n * 查询参数\n */\n query?: Record<string, unknown>;\n}\n\n/**\n * 路由生命周期钩子\n */\nexport interface RouteLifecycleHooks {\n /**\n * 路由跳转前钩子\n * \n * @param to - 目标路由\n * @param from - 来源路由\n * @returns 如果返回字符串,则跳转到该路径;如果返回 false,则阻止跳转;返回 true 或 undefined 则继续跳转\n */\n beforeEach?: (to: RouteLocation, from?: RouteLocation) => string | false | void | Promise<string | false | void>;\n\n /**\n * 路由跳转后钩子\n * \n * @param to - 目标路由\n * @param from - 来源路由\n */\n afterEach?: (to: RouteLocation, from?: RouteLocation) => void | Promise<void>;\n}\n\n/**\n * 路由模式\n * \n * 对应 react-router-dom 的路由模式:\n * - `browser`: 使用 BrowserRouter(createBrowserRouter)\n * - `hash`: 使用 HashRouter(createHashRouter)\n * - `memory`: 使用 MemoryRouter(createMemoryRouter)\n */\nexport type RouterMode = 'browser' | 'hash' | 'memory';\n\n/**\n * 应用路由接口\n * \n * 这是框架核心依赖的抽象接口,所有路由实现都必须实现此接口\n */\nexport interface AppRouter {\n /**\n * 挂载到应用实例\n * \n * @param app - 应用实例\n */\n mount(app: AppInstance): void;\n\n /**\n * 路由跳转\n * \n * @param to - 目标路径或路由名称\n * @param options - 导航选项\n */\n navigate(to: string, options?: NavigateOptions): void;\n\n /**\n * 获取当前路由信息\n * \n * @returns 当前路由位置信息\n */\n getCurrentRoute(): RouteLocation;\n\n /**\n * 销毁路由实例(可选)\n */\n destroy?(): void;\n}\n\n/**\n * 路径解析配置\n */\nexport interface PathResolveConfig {\n /**\n * 项目根目录路径\n * \n * 用于解析相对路径的基准目录。\n * 如果不提供,将使用调用框架的项目根目录(通常为 process.cwd())。\n * \n * 注意:路径解析主要由构建工具(如 Vite、Webpack)处理,\n * 此配置主要用于文档和错误提示。\n * \n * @example\n * ```typescript\n * router: {\n * pathResolve: {\n * basePath: '/path/to/project',\n * },\n * }\n * ```\n */\n basePath?: string;\n\n /**\n * 路径别名映射\n * \n * 用于将路径别名(如 @/)映射到实际路径。\n * 如果不提供,将使用构建工具的配置(如 vite.config.ts 中的 resolve.alias)。\n * \n * 注意:路径别名解析主要由构建工具处理,\n * 此配置主要用于文档和错误提示。\n * \n * @example\n * ```typescript\n * router: {\n * pathResolve: {\n * pathAliases: {\n * '@': './src',\n * '@components': './src/components',\n * },\n * },\n * }\n * ```\n */\n pathAliases?: Record<string, string>;\n}\n\n/**\n * 路由配置选项\n */\nexport interface RouterConfig {\n /**\n * 是否启用路由\n * \n * - `true`: 启用内置路由(默认)\n * - `false`: 禁用内置路由,使用自定义路由\n * - `'disabled'`: 完全禁用路由\n * \n * @default true\n */\n enabled?: boolean | 'disabled';\n\n /**\n * 路由配置列表\n * \n * 使用 RouteConfig 类型\n * \n * 注意:RouteConfig 中的 layout、page、loading、error/errors 可以是:\n * - 组件路径字符串:系统会自动转换为动态导入函数\n * - 动态导入函数:直接使用,无需转换\n * \n * 路径字符串可以是:\n * - 相对路径:如 `\"./pages/index.tsx\"`、`\"../components/Layout.tsx\"`\n * - 路径别名:如 `\"@/pages/index.tsx\"`(需要在构建工具中配置,如 vite.config.ts)\n * - 绝对路径:如 `\"/src/pages/index.tsx\"`(不推荐)\n * \n * 动态导入函数示例:\n * - `() => import(\"./pages/index.tsx\")`\n * - `() => import(\"@/pages/index.tsx\")`\n * \n * 路径解析由构建工具(如 Vite、Webpack)处理,框架会在运行时验证组件是否有默认导出。\n */\n routes?: RouteConfig[] | (() => RouteConfig[] | Promise<RouteConfig[]>);\n\n /**\n * 路由模式\n * \n * - `browser`: 使用 BrowserRouter(createBrowserRouter)- 默认\n * - `hash`: 使用 HashRouter(createHashRouter)\n * - `memory`: 使用 MemoryRouter(createMemoryRouter)\n * \n * @default 'browser'\n */\n mode?: RouterMode;\n\n /**\n * 路由选项\n * \n * 传递给 react-router-dom 的路由创建方法的选项\n * - `browser` 和 `hash` 模式使用 `DOMRouterOpts`\n * - `memory` 模式使用 `MemoryRouterOpts`\n */\n options?: DOMRouterOpts | MemoryRouterOpts;\n\n /**\n * 路径解析配置\n * \n * 用于配置路径解析选项,主要用于文档和错误提示。\n * 实际的路径解析由构建工具(如 Vite、Webpack)处理。\n */\n pathResolve?: PathResolveConfig;\n\n /**\n * 转换选项\n * \n * 用于配置转换选项,主要用于转换路由配置。\n */\n transformOptions?: TransformOptions;\n\n /**\n * 路由预加载配置\n *\n * 默认策略为 `none`,即按需懒加载路由组件。\n * 如需预加载,可显式配置 `strategy` 为 `next-level` / `visible` / `all`。\n */\n preload?: PreloadConfig;\n\n /**\n * 路由生命周期钩子\n */\n hooks?: RouteLifecycleHooks;\n\n /**\n * 是否启用配置验证(默认 true)\n * \n * 如果为 false,将跳过路由配置的 Zod 验证\n */\n enableValidation?: boolean;\n\n /**\n * 默认路由错误组件\n * \n * 当路由配置中的 `error`/`errors` 为空时,将使用此组件作为错误边界。\n * 如果不提供,将使用框架内置的 `RouteErrorBoundary` 组件。\n * \n * 组件必须使用默认导出(export default)。\n * \n * @example\n * ```typescript\n * router: {\n * defaultRouteErrorComponent: () => import('./components/CustomErrorBoundary'),\n * routes: [\n * {\n * name: 'home',\n * path: '/',\n * page: './pages/Home',\n * // error/errors 为空时,将使用 defaultRouteErrorComponent\n * },\n * ],\n * },\n * ```\n */\n defaultRouteErrorComponent?: ComponentImport;\n\n /**\n * 默认路由加载组件\n * \n * 当路由配置中的 `loading` 为空时,将使用此组件作为加载指示器。\n * 如果不提供,将使用框架内置 Loading 组件。\n * \n * 组件必须使用默认导出(export default)。\n * \n * @example\n * ```typescript\n * router: {\n * defaultRouteLoadingComponent: () => import('./components/CustomLoading'),\n * routes: [\n * {\n * name: 'home',\n * path: '/',\n * page: './pages/Home',\n * // loading 为空时,将使用 defaultRouteLoadingComponent\n * },\n * ],\n * },\n * ```\n */\n defaultRouteLoadingComponent?: ComponentImport;\n}\n"],"names":[],"mappings":"AA+XA;;CAEC,GACD,WA0IC"}
1
+ {"version":3,"sources":["../../../src/core/router/types.ts"],"sourcesContent":["import type { AppInstance } from '../startup/AppInstance';\nimport type { createBrowserRouter, createMemoryRouter } from 'react-router-dom';\nimport type { TransformOptions } from './utils/transform';\nimport type { PreloadConfig } from './performance/RoutePreloader';\n\nexport type RouteItemHandle = {\n title: string,\n i18nKey?: string,\n order: number,\n icon?: string,\n // 在菜单中隐藏\n hideInMenu?: boolean,\n // 隐藏尾部\n hideFooter?: boolean,\n // 保活\n keepAlive?: boolean,\n // 是否需要的登录\n needLogin?: boolean,\n // 角色\n roles?: Array<string>,\n // 路由名称,唯一Key\n name?: string,\n // 其他\n [key: string]: unknown,\n}\nexport type RouteItem = {\n // 布局 布局对象的key或动态导入函数\n layout?: string | ComponentImport | null,\n // 页面 页面对象的key或动态导入函数\n page?: string | ComponentImport | null,\n // loading 加载对象的key或动态导入函数\n loading?: string | ComponentImport | null,\n // 错误 组件的key或动态导入函数\n errors?: string | ComponentImport | null,\n // 错误(兼容字段)组件的key或动态导入函数\n error?: string | ComponentImport | null,\n // 路由名称,唯一Key\n name: string,\n // 路由\n path: string | undefined,\n // 是否分组路由\n isGroup?: boolean,\n // 是否开启重定向\n enableRedirection?: boolean,\n // 额外参数\n handle: RouteItemHandle,\n children?: RouteItem[]\n}\n\nexport type RouteMapType = Record<string, () => Promise<any>>;\n\n/**\n * DOM 路由选项类型(从 createBrowserRouter 和 createHashRouter 的参数类型提取)\n */\nexport type DOMRouterOpts = Parameters<typeof createBrowserRouter>[1];\n\n/**\n * Memory 路由选项类型(从 createMemoryRouter 的参数类型提取)\n */\nexport type MemoryRouterOpts = Parameters<typeof createMemoryRouter>[1];\n\n/**\n * 路由元数据(兼容 RouteItemHandle)\n * \n * @deprecated 建议直接使用 RouteItem 和 RouteItemHandle\n */\nexport interface RouteMeta {\n /**\n * 路由标题\n */\n title?: string;\n\n /**\n * 图标\n */\n icon?: string;\n\n /**\n * 排序\n */\n order?: number;\n\n /**\n * 权限标识\n */\n auth?: string | string[];\n\n /**\n * 是否在菜单中隐藏\n */\n hideInMenu?: boolean;\n\n /**\n * 是否启用 KeepAlive\n */\n keepAlive?: boolean;\n\n /**\n * 是否需要登录\n */\n needLogin?: boolean;\n\n /**\n * 角色列表\n */\n roles?: string[];\n\n /**\n * 路由名称(唯一标识)\n */\n name?: string;\n\n /**\n * 其他自定义元数据\n */\n [key: string]: unknown;\n}\n\n/**\n * 动态导入函数类型\n * \n * 用于懒加载组件,返回一个 Promise,resolve 后的值为组件模块对象\n * 组件必须使用默认导出(export default)\n */\nexport type ComponentImport = () => Promise<any>;\n\n/**\n * 路由配置项\n * \n * 与 RouteItem 的区别:\n * - layout、page、loading、error/errors 可以是组件路径字符串(如 \"@/pages/index.ts\")或动态导入函数\n * - 如果使用字符串,系统会自动转换为动态导入函数\n * - 如果使用函数,则直接使用,无需转换\n * - 对应的组件必须默认导出(export default xxxx)\n */\nexport interface RouteConfig {\n /**\n * 布局组件路径(字符串)或动态导入函数\n * \n * 字符串示例: \"@/pages/layout.tsx\" 或 \"../../pages/layout.tsx\"\n * 函数示例: () => import(\"@/pages/layout.tsx\")\n * 组件必须默认导出\n */\n layout?: string | ComponentImport | null;\n\n /**\n * 页面组件路径(字符串)或动态导入函数\n * \n * 字符串示例: \"@/pages/index.tsx\" 或 \"../../pages/index.tsx\"\n * 函数示例: () => import(\"@/pages/index.tsx\")\n * 组件必须默认导出\n */\n page?: string | ComponentImport | null;\n\n /**\n * 加载组件路径(字符串)或动态导入函数\n * \n * 字符串示例: \"@/components/Loading.tsx\"\n * 函数示例: () => import(\"@/components/Loading.tsx\")\n * 组件必须默认导出\n */\n loading?: string | ComponentImport | null;\n\n /**\n * 错误组件路径(字符串)或动态导入函数\n * \n * 字符串示例: \"@/pages/error.tsx\"\n * 函数示例: () => import(\"@/pages/error.tsx\")\n * 组件必须默认导出\n */\n errors?: string | ComponentImport | null;\n\n /**\n * 错误组件路径(字符串)或动态导入函数(兼容字段,优先级高于 errors)\n *\n * 字符串示例: \"@/pages/error.tsx\"\n * 函数示例: () => import(\"@/pages/error.tsx\")\n * 组件必须默认导出\n */\n error?: string | ComponentImport | null;\n\n /**\n * 路由名称(唯一标识)\n */\n name: string;\n\n /**\n * 路由路径\n */\n path: string | undefined;\n\n /**\n * 是否为路由组\n */\n isGroup?: boolean;\n\n /**\n * 是否启用重定向\n */\n enableRedirection?: boolean;\n\n /**\n * 路由元数据\n */\n handle: {\n title: string;\n i18nKey?: string;\n order: number;\n icon?: string;\n hideInMenu?: boolean;\n hideFooter?: boolean;\n keepAlive?: boolean;\n needLogin?: boolean;\n roles?: Array<string>;\n name?: string;\n [key: string]: unknown;\n };\n\n /**\n * 子路由配置\n */\n children?: RouteConfig[];\n}\n\n/**\n * 路由位置信息\n */\nexport interface RouteLocation {\n /**\n * 路径\n */\n path: string;\n\n /**\n * 路径参数\n */\n params?: Record<string, unknown>;\n\n /**\n * 查询参数\n */\n query?: Record<string, unknown>;\n\n /**\n * 路由元数据\n */\n meta?: RouteMeta;\n}\n\n/**\n * 导航选项\n */\nexport interface NavigateOptions {\n /**\n * 是否替换当前历史记录\n */\n replace?: boolean;\n\n /**\n * 状态数据\n */\n state?: unknown;\n\n /**\n * 查询参数\n */\n query?: Record<string, unknown>;\n}\n\n/**\n * 路由生命周期钩子\n */\nexport interface RouteLifecycleHooks {\n /**\n * 路由跳转前钩子\n * \n * @param to - 目标路由\n * @param from - 来源路由\n * @returns 如果返回字符串,则跳转到该路径;如果返回 false,则阻止跳转;返回 true 或 undefined 则继续跳转\n */\n beforeEach?: (to: RouteLocation, from?: RouteLocation) => string | false | void | Promise<string | false | void>;\n\n /**\n * 路由跳转后钩子\n * \n * @param to - 目标路由\n * @param from - 来源路由\n */\n afterEach?: (to: RouteLocation, from?: RouteLocation) => void | Promise<void>;\n}\n\n/**\n * 路由模式\n * \n * 对应 react-router-dom 的路由模式:\n * - `browser`: 使用 BrowserRouter(createBrowserRouter)\n * - `hash`: 使用 HashRouter(createHashRouter)\n * - `memory`: 使用 MemoryRouter(createMemoryRouter)\n */\nexport type RouterMode = 'browser' | 'hash' | 'memory';\n\n/**\n * 应用路由接口\n * \n * 这是框架核心依赖的抽象接口,所有路由实现都必须实现此接口\n */\nexport interface AppRouter {\n /**\n * 挂载到应用实例\n * \n * @param app - 应用实例\n */\n mount(app: AppInstance): void;\n\n /**\n * 路由跳转\n * \n * @param to - 目标路径或路由名称\n * @param options - 导航选项\n */\n navigate(to: string, options?: NavigateOptions): void;\n\n /**\n * 获取当前路由信息\n * \n * @returns 当前路由位置信息\n */\n getCurrentRoute(): RouteLocation;\n\n /**\n * 销毁路由实例(可选)\n */\n destroy?(): void;\n}\n\n/**\n * 路径解析配置\n */\nexport interface PathResolveConfig {\n /**\n * 项目根目录路径\n * \n * 用于解析相对路径的基准目录。\n * 如果不提供,将使用调用框架的项目根目录(通常为 process.cwd())。\n * \n * 注意:路径解析主要由构建工具(如 Vite、Webpack)处理,\n * 此配置主要用于文档和错误提示。\n * \n * @example\n * ```typescript\n * router: {\n * pathResolve: {\n * basePath: '/path/to/project',\n * },\n * }\n * ```\n */\n basePath?: string;\n\n /**\n * 路径别名映射\n * \n * 用于将路径别名(如 @/)映射到实际路径。\n * 如果不提供,将使用构建工具的配置(如 vite.config.ts 中的 resolve.alias)。\n * \n * 注意:路径别名解析主要由构建工具处理,\n * 此配置主要用于文档和错误提示。\n * \n * @example\n * ```typescript\n * router: {\n * pathResolve: {\n * pathAliases: {\n * '@': './src',\n * '@components': './src/components',\n * },\n * },\n * }\n * ```\n */\n pathAliases?: Record<string, string>;\n}\n\n/**\n * 路由配置选项\n */\nexport interface RouterConfig {\n /**\n * 是否启用路由\n * \n * - `true`: 启用内置路由(默认)\n * - `false`: 禁用内置路由,使用自定义路由\n * - `'disabled'`: 完全禁用路由\n * \n * @default true\n */\n enabled?: boolean | 'disabled';\n\n /**\n * 路由配置列表\n * \n * 使用 RouteConfig 类型\n * \n * 注意:RouteConfig 中的 layout、page、loading、error/errors 可以是:\n * - 组件路径字符串:系统会自动转换为动态导入函数\n * - 动态导入函数:直接使用,无需转换\n * \n * 路径字符串可以是:\n * - 相对路径:如 `\"./pages/index.tsx\"`、`\"../components/Layout.tsx\"`\n * - 路径别名:如 `\"@/pages/index.tsx\"`(需要在构建工具中配置,如 vite.config.ts)\n * - 绝对路径:如 `\"/src/pages/index.tsx\"`(不推荐)\n * \n * 动态导入函数示例:\n * - `() => import(\"./pages/index.tsx\")`\n * - `() => import(\"@/pages/index.tsx\")`\n * \n * 路径解析由构建工具(如 Vite、Webpack)处理,框架会在运行时验证组件是否有默认导出。\n */\n routes?: RouteConfig[] | (() => RouteConfig[] | Promise<RouteConfig[]>);\n\n /**\n * 路由模式\n * \n * - `browser`: 使用 BrowserRouter(createBrowserRouter)- 默认\n * - `hash`: 使用 HashRouter(createHashRouter)\n * - `memory`: 使用 MemoryRouter(createMemoryRouter)\n * \n * @default 'browser'\n */\n mode?: RouterMode;\n\n /**\n * 路由选项\n * \n * 传递给 react-router-dom 的路由创建方法的选项\n * - `browser` 和 `hash` 模式使用 `DOMRouterOpts`\n * - `memory` 模式使用 `MemoryRouterOpts`\n */\n options?: DOMRouterOpts | MemoryRouterOpts;\n\n /**\n * 路径解析配置\n * \n * 用于配置路径解析选项,主要用于文档和错误提示。\n * 实际的路径解析由构建工具(如 Vite、Webpack)处理。\n */\n pathResolve?: PathResolveConfig;\n\n /**\n * 转换选项\n * \n * 用于配置转换选项,主要用于转换路由配置。\n */\n transformOptions?: TransformOptions;\n\n /**\n * 路由预加载配置\n *\n * 默认策略为 `none`,即按需懒加载路由组件。\n * 如需预加载,可显式配置 `strategy` 为 `next-level` / `visible` / `all`。\n */\n preload?: PreloadConfig;\n\n /**\n * 路由生命周期钩子\n */\n hooks?: RouteLifecycleHooks;\n\n /**\n * 是否启用配置验证(默认 true)\n * \n * 如果为 false,将跳过路由配置的 Zod 验证\n */\n enableValidation?: boolean;\n\n /**\n * 默认路由错误组件\n * \n * 当路由配置中的 `error`/`errors` 为空时,将使用此组件作为错误边界。\n * 如果不提供,将使用框架内置的 `RouteErrorBoundary` 组件。\n * \n * 组件必须使用默认导出(export default)。\n * \n * @example\n * ```typescript\n * router: {\n * defaultRouteErrorComponent: () => import('./components/CustomErrorBoundary'),\n * routes: [\n * {\n * name: 'home',\n * path: '/',\n * page: './pages/Home',\n * // error/errors 为空时,将使用 defaultRouteErrorComponent\n * },\n * ],\n * },\n * ```\n */\n defaultRouteErrorComponent?: ComponentImport;\n\n /**\n * 默认路由加载组件\n * \n * 当路由配置中的 `loading` 为空时,将使用此组件作为加载指示器。\n * 如果不提供,将使用框架内置 Loading 组件。\n * \n * 组件必须使用默认导出(export default)。\n * \n * @example\n * ```typescript\n * router: {\n * defaultRouteLoadingComponent: () => import('./components/CustomLoading'),\n * routes: [\n * {\n * name: 'home',\n * path: '/',\n * page: './pages/Home',\n * // loading 为空时,将使用 defaultRouteLoadingComponent\n * },\n * ],\n * },\n * ```\n */\n defaultRouteLoadingComponent?: ComponentImport;\n\n /**\n * 是否为路由注入 hydrateFallbackElement\n *\n * 默认关闭。仅在 SSR hydration 场景需要时开启。\n * 若未显式配置,会根据 `options.hydrationData` 自动推断。\n *\n * @default false\n */\n enableHydrateFallback?: boolean;\n}\n"],"names":[],"mappings":"AA+XA;;CAEC,GACD,WAoJC"}
@@ -13,8 +13,13 @@ const _react = require("react");
13
13
  const isDevelopment = process.env.NODE_ENV === 'development';
14
14
  const RouteErrorBoundary = ({ error, resetErrorBoundary })=>{
15
15
  const [showDetails, setShowDetails] = (0, _react.useState)(false);
16
- const errorWithCause = error;
17
- const hasCause = 'cause' in error && errorWithCause.cause !== undefined;
16
+ const errorObject = error !== null && typeof error === 'object' ? error : null;
17
+ const errorMessage = typeof errorObject?.message === 'string' && errorObject.message !== '' ? errorObject.message : '未知错误';
18
+ const hasCause = errorObject?.cause !== undefined;
19
+ const isNotFoundError = errorObject?.status === 404 || typeof errorObject?.statusText === 'string' && /not\s*found/i.test(errorObject.statusText) || /no routes matched location|not found|404/i.test(errorMessage);
20
+ const title = isNotFoundError ? '页面不存在(404)' : '出错了,请稍后再试';
21
+ const friendlyMessage = isNotFoundError ? '访问的路由未注册或不存在,请检查访问地址。' : '请稍后再试或联系技术支持';
22
+ const displayMessage = isDevelopment ? errorMessage : friendlyMessage;
18
23
  return /*#__PURE__*/ (0, _jsxruntime.jsx)("div", {
19
24
  role: "alert",
20
25
  style: {
@@ -37,10 +42,10 @@ const RouteErrorBoundary = ({ error, resetErrorBoundary })=>{
37
42
  style: {
38
43
  marginTop: 0
39
44
  },
40
- children: "出错了,请稍后再试"
45
+ children: title
41
46
  }),
42
47
  /*#__PURE__*/ (0, _jsxruntime.jsx)("p", {
43
- children: isDevelopment ? error.message : '请稍后再试或联系技术支持'
48
+ children: displayMessage
44
49
  }),
45
50
  /*#__PURE__*/ (0, _jsxruntime.jsxs)("div", {
46
51
  style: {
@@ -91,10 +96,10 @@ const RouteErrorBoundary = ({ error, resetErrorBoundary })=>{
91
96
  /*#__PURE__*/ (0, _jsxruntime.jsx)("strong", {
92
97
  children: "错误信息:"
93
98
  }),
94
- error.message
99
+ errorMessage
95
100
  ]
96
101
  }),
97
- error.stack && /*#__PURE__*/ (0, _jsxruntime.jsxs)("div", {
102
+ errorObject?.stack && /*#__PURE__*/ (0, _jsxruntime.jsxs)("div", {
98
103
  style: {
99
104
  marginBottom: 10,
100
105
  whiteSpace: 'pre-wrap',
@@ -105,7 +110,7 @@ const RouteErrorBoundary = ({ error, resetErrorBoundary })=>{
105
110
  children: "堆栈:"
106
111
  }),
107
112
  /*#__PURE__*/ (0, _jsxruntime.jsx)("br", {}),
108
- error.stack
113
+ errorObject.stack
109
114
  ]
110
115
  }),
111
116
  hasCause && /*#__PURE__*/ (0, _jsxruntime.jsxs)("div", {
@@ -113,7 +118,7 @@ const RouteErrorBoundary = ({ error, resetErrorBoundary })=>{
113
118
  /*#__PURE__*/ (0, _jsxruntime.jsx)("strong", {
114
119
  children: "原因:"
115
120
  }),
116
- errorWithCause.cause instanceof Error ? errorWithCause.cause.message : String(errorWithCause.cause)
121
+ errorObject?.cause instanceof Error ? errorObject.cause.message : String(errorObject?.cause)
117
122
  ]
118
123
  })
119
124
  ]
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../../src/core/router/utils/adapters/react-router/RouteErrorBoundary.tsx"],"sourcesContent":["import { useState } from 'react';\nimport type { FallbackProps } from 'react-error-boundary';\n\nconst isDevelopment = process.env.NODE_ENV === 'development';\n\ninterface ErrorWithCause extends Error {\n cause?: unknown;\n}\n\nexport const RouteErrorBoundary = ({ error, resetErrorBoundary }: FallbackProps) => {\n const [showDetails, setShowDetails] = useState(false);\n const errorWithCause = error as ErrorWithCause;\n const hasCause = 'cause' in error && errorWithCause.cause !== undefined;\n\n return (\n <div\n role=\"alert\"\n style={{\n minHeight: '100vh',\n display: 'flex',\n justifyContent: 'center',\n alignItems: 'center',\n padding: 24,\n }}\n >\n <div style={{ maxWidth: 760, width: '100%', border: '1px solid #dde5ec', borderRadius: 10, padding: 20 }}>\n <h2 style={{ marginTop: 0 }}>出错了,请稍后再试</h2>\n <p>{isDevelopment ? error.message : '请稍后再试或联系技术支持'}</p>\n <div style={{ display: 'flex', gap: 8, marginBottom: 12 }}>\n <button\n onClick={resetErrorBoundary}\n style={{ border: 'none', background: '#2f80ed', color: '#fff', borderRadius: 6, padding: '8px 12px', cursor: 'pointer' }}\n >\n 刷新重试\n </button>\n {isDevelopment && (\n <button\n onClick={() => setShowDetails(!showDetails)}\n style={{ border: '1px solid #cfd7df', background: '#fff', borderRadius: 6, padding: '8px 12px', cursor: 'pointer' }}\n >\n {showDetails ? '收起详情' : '展开详情'}\n </button>\n )}\n </div>\n\n {isDevelopment && showDetails && (\n <div style={{ background: '#f7fafc', borderRadius: 8, padding: 12, fontSize: 12, fontFamily: 'monospace' }}>\n <div style={{ marginBottom: 10 }}><strong>错误信息:</strong>{error.message}</div>\n {error.stack && (\n <div style={{ marginBottom: 10, whiteSpace: 'pre-wrap', wordBreak: 'break-word' }}>\n <strong>堆栈:</strong>\n <br />\n {error.stack}\n </div>\n )}\n {hasCause && (\n <div><strong>原因:</strong>{errorWithCause.cause instanceof Error ? errorWithCause.cause.message : String(errorWithCause.cause)}</div>\n )}\n </div>\n )}\n </div>\n </div>\n );\n};\n"],"names":["RouteErrorBoundary","isDevelopment","process","env","NODE_ENV","error","resetErrorBoundary","showDetails","setShowDetails","useState","errorWithCause","hasCause","cause","undefined","div","role","style","minHeight","display","justifyContent","alignItems","padding","maxWidth","width","border","borderRadius","h2","marginTop","p","message","gap","marginBottom","button","onClick","background","color","cursor","fontSize","fontFamily","strong","stack","whiteSpace","wordBreak","br","Error","String"],"mappings":";;;;+BASaA;;;eAAAA;;;;uBATY;AAGzB,MAAMC,gBAAgBC,QAAQC,GAAG,CAACC,QAAQ,KAAK;AAMxC,MAAMJ,qBAAqB,CAAC,EAAEK,KAAK,EAAEC,kBAAkB,EAAiB;IAC7E,MAAM,CAACC,aAAaC,eAAe,GAAGC,IAAAA,eAAQ,EAAC;IAC/C,MAAMC,iBAAiBL;IACvB,MAAMM,WAAW,WAAWN,SAASK,eAAeE,KAAK,KAAKC;IAE9D,qBACE,qBAACC;QACCC,MAAK;QACLC,OAAO;YACLC,WAAW;YACXC,SAAS;YACTC,gBAAgB;YAChBC,YAAY;YACZC,SAAS;QACX;kBAEA,cAAA,sBAACP;YAAIE,OAAO;gBAAEM,UAAU;gBAAKC,OAAO;gBAAQC,QAAQ;gBAAqBC,cAAc;gBAAIJ,SAAS;YAAG;;8BACrG,qBAACK;oBAAGV,OAAO;wBAAEW,WAAW;oBAAE;8BAAG;;8BAC7B,qBAACC;8BAAG3B,gBAAgBI,MAAMwB,OAAO,GAAG;;8BACpC,sBAACf;oBAAIE,OAAO;wBAAEE,SAAS;wBAAQY,KAAK;wBAAGC,cAAc;oBAAG;;sCACtD,qBAACC;4BACCC,SAAS3B;4BACTU,OAAO;gCAAEQ,QAAQ;gCAAQU,YAAY;gCAAWC,OAAO;gCAAQV,cAAc;gCAAGJ,SAAS;gCAAYe,QAAQ;4BAAU;sCACxH;;wBAGAnC,+BACC,qBAAC+B;4BACCC,SAAS,IAAMzB,eAAe,CAACD;4BAC/BS,OAAO;gCAAEQ,QAAQ;gCAAqBU,YAAY;gCAAQT,cAAc;gCAAGJ,SAAS;gCAAYe,QAAQ;4BAAU;sCAEjH7B,cAAc,SAAS;;;;gBAK7BN,iBAAiBM,6BAChB,sBAACO;oBAAIE,OAAO;wBAAEkB,YAAY;wBAAWT,cAAc;wBAAGJ,SAAS;wBAAIgB,UAAU;wBAAIC,YAAY;oBAAY;;sCACvG,sBAACxB;4BAAIE,OAAO;gCAAEe,cAAc;4BAAG;;8CAAG,qBAACQ;8CAAO;;gCAAelC,MAAMwB,OAAO;;;wBACrExB,MAAMmC,KAAK,kBACV,sBAAC1B;4BAAIE,OAAO;gCAAEe,cAAc;gCAAIU,YAAY;gCAAYC,WAAW;4BAAa;;8CAC9E,qBAACH;8CAAO;;8CACR,qBAACI;gCACAtC,MAAMmC,KAAK;;;wBAGf7B,0BACC,sBAACG;;8CAAI,qBAACyB;8CAAO;;gCAAa7B,eAAeE,KAAK,YAAYgC,QAAQlC,eAAeE,KAAK,CAACiB,OAAO,GAAGgB,OAAOnC,eAAeE,KAAK;;;;;;;;AAO1I"}
1
+ {"version":3,"sources":["../../../../../../src/core/router/utils/adapters/react-router/RouteErrorBoundary.tsx"],"sourcesContent":["import { useState } from 'react';\nimport type { FallbackProps } from 'react-error-boundary';\n\nconst isDevelopment = process.env.NODE_ENV === 'development';\n\ninterface RouteErrorLike extends Error {\n status?: number;\n statusText?: string;\n data?: unknown;\n cause?: unknown;\n}\n\nexport const RouteErrorBoundary = ({ error, resetErrorBoundary }: FallbackProps) => {\n const [showDetails, setShowDetails] = useState(false);\n const errorObject: RouteErrorLike | null =\n error !== null && typeof error === 'object' ? (error as RouteErrorLike) : null;\n const errorMessage =\n typeof errorObject?.message === 'string' && errorObject.message !== ''\n ? errorObject.message\n : '未知错误';\n const hasCause = errorObject?.cause !== undefined;\n\n const isNotFoundError =\n errorObject?.status === 404 ||\n (typeof errorObject?.statusText === 'string' && /not\\s*found/i.test(errorObject.statusText)) ||\n /no routes matched location|not found|404/i.test(errorMessage);\n\n const title = isNotFoundError ? '页面不存在(404)' : '出错了,请稍后再试';\n const friendlyMessage = isNotFoundError\n ? '访问的路由未注册或不存在,请检查访问地址。'\n : '请稍后再试或联系技术支持';\n const displayMessage = isDevelopment ? errorMessage : friendlyMessage;\n\n return (\n <div\n role=\"alert\"\n style={{\n minHeight: '100vh',\n display: 'flex',\n justifyContent: 'center',\n alignItems: 'center',\n padding: 24,\n }}\n >\n <div style={{ maxWidth: 760, width: '100%', border: '1px solid #dde5ec', borderRadius: 10, padding: 20 }}>\n <h2 style={{ marginTop: 0 }}>{title}</h2>\n <p>{displayMessage}</p>\n <div style={{ display: 'flex', gap: 8, marginBottom: 12 }}>\n <button\n onClick={resetErrorBoundary}\n style={{ border: 'none', background: '#2f80ed', color: '#fff', borderRadius: 6, padding: '8px 12px', cursor: 'pointer' }}\n >\n 刷新重试\n </button>\n {isDevelopment && (\n <button\n onClick={() => setShowDetails(!showDetails)}\n style={{ border: '1px solid #cfd7df', background: '#fff', borderRadius: 6, padding: '8px 12px', cursor: 'pointer' }}\n >\n {showDetails ? '收起详情' : '展开详情'}\n </button>\n )}\n </div>\n\n {isDevelopment && showDetails && (\n <div style={{ background: '#f7fafc', borderRadius: 8, padding: 12, fontSize: 12, fontFamily: 'monospace' }}>\n <div style={{ marginBottom: 10 }}><strong>错误信息:</strong>{errorMessage}</div>\n {errorObject?.stack && (\n <div style={{ marginBottom: 10, whiteSpace: 'pre-wrap', wordBreak: 'break-word' }}>\n <strong>堆栈:</strong>\n <br />\n {errorObject.stack}\n </div>\n )}\n {hasCause && (\n <div>\n <strong>原因:</strong>\n {errorObject?.cause instanceof Error ? errorObject.cause.message : String(errorObject?.cause)}\n </div>\n )}\n </div>\n )}\n </div>\n </div>\n );\n};\n"],"names":["RouteErrorBoundary","isDevelopment","process","env","NODE_ENV","error","resetErrorBoundary","showDetails","setShowDetails","useState","errorObject","errorMessage","message","hasCause","cause","undefined","isNotFoundError","status","statusText","test","title","friendlyMessage","displayMessage","div","role","style","minHeight","display","justifyContent","alignItems","padding","maxWidth","width","border","borderRadius","h2","marginTop","p","gap","marginBottom","button","onClick","background","color","cursor","fontSize","fontFamily","strong","stack","whiteSpace","wordBreak","br","Error","String"],"mappings":";;;;+BAYaA;;;eAAAA;;;;uBAZY;AAGzB,MAAMC,gBAAgBC,QAAQC,GAAG,CAACC,QAAQ,KAAK;AASxC,MAAMJ,qBAAqB,CAAC,EAAEK,KAAK,EAAEC,kBAAkB,EAAiB;IAC7E,MAAM,CAACC,aAAaC,eAAe,GAAGC,IAAAA,eAAQ,EAAC;IAC/C,MAAMC,cACJL,UAAU,QAAQ,OAAOA,UAAU,WAAYA,QAA2B;IAC5E,MAAMM,eACJ,OAAOD,aAAaE,YAAY,YAAYF,YAAYE,OAAO,KAAK,KAChEF,YAAYE,OAAO,GACnB;IACN,MAAMC,WAAWH,aAAaI,UAAUC;IAExC,MAAMC,kBACJN,aAAaO,WAAW,OACvB,OAAOP,aAAaQ,eAAe,YAAY,eAAeC,IAAI,CAACT,YAAYQ,UAAU,KAC1F,4CAA4CC,IAAI,CAACR;IAEnD,MAAMS,QAAQJ,kBAAkB,eAAe;IAC/C,MAAMK,kBAAkBL,kBACpB,0BACA;IACJ,MAAMM,iBAAiBrB,gBAAgBU,eAAeU;IAEtD,qBACE,qBAACE;QACCC,MAAK;QACLC,OAAO;YACLC,WAAW;YACXC,SAAS;YACTC,gBAAgB;YAChBC,YAAY;YACZC,SAAS;QACX;kBAEA,cAAA,sBAACP;YAAIE,OAAO;gBAAEM,UAAU;gBAAKC,OAAO;gBAAQC,QAAQ;gBAAqBC,cAAc;gBAAIJ,SAAS;YAAG;;8BACrG,qBAACK;oBAAGV,OAAO;wBAAEW,WAAW;oBAAE;8BAAIhB;;8BAC9B,qBAACiB;8BAAGf;;8BACJ,sBAACC;oBAAIE,OAAO;wBAAEE,SAAS;wBAAQW,KAAK;wBAAGC,cAAc;oBAAG;;sCACtD,qBAACC;4BACCC,SAASnC;4BACTmB,OAAO;gCAAEQ,QAAQ;gCAAQS,YAAY;gCAAWC,OAAO;gCAAQT,cAAc;gCAAGJ,SAAS;gCAAYc,QAAQ;4BAAU;sCACxH;;wBAGA3C,+BACC,qBAACuC;4BACCC,SAAS,IAAMjC,eAAe,CAACD;4BAC/BkB,OAAO;gCAAEQ,QAAQ;gCAAqBS,YAAY;gCAAQR,cAAc;gCAAGJ,SAAS;gCAAYc,QAAQ;4BAAU;sCAEjHrC,cAAc,SAAS;;;;gBAK7BN,iBAAiBM,6BAChB,sBAACgB;oBAAIE,OAAO;wBAAEiB,YAAY;wBAAWR,cAAc;wBAAGJ,SAAS;wBAAIe,UAAU;wBAAIC,YAAY;oBAAY;;sCACvG,sBAACvB;4BAAIE,OAAO;gCAAEc,cAAc;4BAAG;;8CAAG,qBAACQ;8CAAO;;gCAAepC;;;wBACxDD,aAAasC,uBACZ,sBAACzB;4BAAIE,OAAO;gCAAEc,cAAc;gCAAIU,YAAY;gCAAYC,WAAW;4BAAa;;8CAC9E,qBAACH;8CAAO;;8CACR,qBAACI;gCACAzC,YAAYsC,KAAK;;;wBAGrBnC,0BACC,sBAACU;;8CACC,qBAACwB;8CAAO;;gCACPrC,aAAaI,iBAAiBsC,QAAQ1C,YAAYI,KAAK,CAACF,OAAO,GAAGyC,OAAO3C,aAAaI;;;;;;;;AAQvG"}
@@ -3,8 +3,13 @@ import { useState } from "react";
3
3
  const isDevelopment = process.env.NODE_ENV === 'development';
4
4
  export const RouteErrorBoundary = ({ error, resetErrorBoundary })=>{
5
5
  const [showDetails, setShowDetails] = useState(false);
6
- const errorWithCause = error;
7
- const hasCause = 'cause' in error && errorWithCause.cause !== undefined;
6
+ const errorObject = error !== null && typeof error === 'object' ? error : null;
7
+ const errorMessage = typeof errorObject?.message === 'string' && errorObject.message !== '' ? errorObject.message : '未知错误';
8
+ const hasCause = errorObject?.cause !== undefined;
9
+ const isNotFoundError = errorObject?.status === 404 || typeof errorObject?.statusText === 'string' && /not\s*found/i.test(errorObject.statusText) || /no routes matched location|not found|404/i.test(errorMessage);
10
+ const title = isNotFoundError ? '页面不存在(404)' : '出错了,请稍后再试';
11
+ const friendlyMessage = isNotFoundError ? '访问的路由未注册或不存在,请检查访问地址。' : '请稍后再试或联系技术支持';
12
+ const displayMessage = isDevelopment ? errorMessage : friendlyMessage;
8
13
  return /*#__PURE__*/ _jsx("div", {
9
14
  role: "alert",
10
15
  style: {
@@ -27,10 +32,10 @@ export const RouteErrorBoundary = ({ error, resetErrorBoundary })=>{
27
32
  style: {
28
33
  marginTop: 0
29
34
  },
30
- children: "出错了,请稍后再试"
35
+ children: title
31
36
  }),
32
37
  /*#__PURE__*/ _jsx("p", {
33
- children: isDevelopment ? error.message : '请稍后再试或联系技术支持'
38
+ children: displayMessage
34
39
  }),
35
40
  /*#__PURE__*/ _jsxs("div", {
36
41
  style: {
@@ -81,10 +86,10 @@ export const RouteErrorBoundary = ({ error, resetErrorBoundary })=>{
81
86
  /*#__PURE__*/ _jsx("strong", {
82
87
  children: "错误信息:"
83
88
  }),
84
- error.message
89
+ errorMessage
85
90
  ]
86
91
  }),
87
- error.stack && /*#__PURE__*/ _jsxs("div", {
92
+ errorObject?.stack && /*#__PURE__*/ _jsxs("div", {
88
93
  style: {
89
94
  marginBottom: 10,
90
95
  whiteSpace: 'pre-wrap',
@@ -95,7 +100,7 @@ export const RouteErrorBoundary = ({ error, resetErrorBoundary })=>{
95
100
  children: "堆栈:"
96
101
  }),
97
102
  /*#__PURE__*/ _jsx("br", {}),
98
- error.stack
103
+ errorObject.stack
99
104
  ]
100
105
  }),
101
106
  hasCause && /*#__PURE__*/ _jsxs("div", {
@@ -103,7 +108,7 @@ export const RouteErrorBoundary = ({ error, resetErrorBoundary })=>{
103
108
  /*#__PURE__*/ _jsx("strong", {
104
109
  children: "原因:"
105
110
  }),
106
- errorWithCause.cause instanceof Error ? errorWithCause.cause.message : String(errorWithCause.cause)
111
+ errorObject?.cause instanceof Error ? errorObject.cause.message : String(errorObject?.cause)
107
112
  ]
108
113
  })
109
114
  ]
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../../src/core/router/utils/adapters/react-router/RouteErrorBoundary.tsx"],"sourcesContent":["import { useState } from 'react';\nimport type { FallbackProps } from 'react-error-boundary';\n\nconst isDevelopment = process.env.NODE_ENV === 'development';\n\ninterface ErrorWithCause extends Error {\n cause?: unknown;\n}\n\nexport const RouteErrorBoundary = ({ error, resetErrorBoundary }: FallbackProps) => {\n const [showDetails, setShowDetails] = useState(false);\n const errorWithCause = error as ErrorWithCause;\n const hasCause = 'cause' in error && errorWithCause.cause !== undefined;\n\n return (\n <div\n role=\"alert\"\n style={{\n minHeight: '100vh',\n display: 'flex',\n justifyContent: 'center',\n alignItems: 'center',\n padding: 24,\n }}\n >\n <div style={{ maxWidth: 760, width: '100%', border: '1px solid #dde5ec', borderRadius: 10, padding: 20 }}>\n <h2 style={{ marginTop: 0 }}>出错了,请稍后再试</h2>\n <p>{isDevelopment ? error.message : '请稍后再试或联系技术支持'}</p>\n <div style={{ display: 'flex', gap: 8, marginBottom: 12 }}>\n <button\n onClick={resetErrorBoundary}\n style={{ border: 'none', background: '#2f80ed', color: '#fff', borderRadius: 6, padding: '8px 12px', cursor: 'pointer' }}\n >\n 刷新重试\n </button>\n {isDevelopment && (\n <button\n onClick={() => setShowDetails(!showDetails)}\n style={{ border: '1px solid #cfd7df', background: '#fff', borderRadius: 6, padding: '8px 12px', cursor: 'pointer' }}\n >\n {showDetails ? '收起详情' : '展开详情'}\n </button>\n )}\n </div>\n\n {isDevelopment && showDetails && (\n <div style={{ background: '#f7fafc', borderRadius: 8, padding: 12, fontSize: 12, fontFamily: 'monospace' }}>\n <div style={{ marginBottom: 10 }}><strong>错误信息:</strong>{error.message}</div>\n {error.stack && (\n <div style={{ marginBottom: 10, whiteSpace: 'pre-wrap', wordBreak: 'break-word' }}>\n <strong>堆栈:</strong>\n <br />\n {error.stack}\n </div>\n )}\n {hasCause && (\n <div><strong>原因:</strong>{errorWithCause.cause instanceof Error ? errorWithCause.cause.message : String(errorWithCause.cause)}</div>\n )}\n </div>\n )}\n </div>\n </div>\n );\n};\n"],"names":["useState","isDevelopment","process","env","NODE_ENV","RouteErrorBoundary","error","resetErrorBoundary","showDetails","setShowDetails","errorWithCause","hasCause","cause","undefined","div","role","style","minHeight","display","justifyContent","alignItems","padding","maxWidth","width","border","borderRadius","h2","marginTop","p","message","gap","marginBottom","button","onClick","background","color","cursor","fontSize","fontFamily","strong","stack","whiteSpace","wordBreak","br","Error","String"],"mappings":";AAAA,SAASA,QAAQ,QAAQ,QAAQ;AAGjC,MAAMC,gBAAgBC,QAAQC,GAAG,CAACC,QAAQ,KAAK;AAM/C,OAAO,MAAMC,qBAAqB,CAAC,EAAEC,KAAK,EAAEC,kBAAkB,EAAiB;IAC7E,MAAM,CAACC,aAAaC,eAAe,GAAGT,SAAS;IAC/C,MAAMU,iBAAiBJ;IACvB,MAAMK,WAAW,WAAWL,SAASI,eAAeE,KAAK,KAAKC;IAE9D,qBACE,KAACC;QACCC,MAAK;QACLC,OAAO;YACLC,WAAW;YACXC,SAAS;YACTC,gBAAgB;YAChBC,YAAY;YACZC,SAAS;QACX;kBAEA,cAAA,MAACP;YAAIE,OAAO;gBAAEM,UAAU;gBAAKC,OAAO;gBAAQC,QAAQ;gBAAqBC,cAAc;gBAAIJ,SAAS;YAAG;;8BACrG,KAACK;oBAAGV,OAAO;wBAAEW,WAAW;oBAAE;8BAAG;;8BAC7B,KAACC;8BAAG3B,gBAAgBK,MAAMuB,OAAO,GAAG;;8BACpC,MAACf;oBAAIE,OAAO;wBAAEE,SAAS;wBAAQY,KAAK;wBAAGC,cAAc;oBAAG;;sCACtD,KAACC;4BACCC,SAAS1B;4BACTS,OAAO;gCAAEQ,QAAQ;gCAAQU,YAAY;gCAAWC,OAAO;gCAAQV,cAAc;gCAAGJ,SAAS;gCAAYe,QAAQ;4BAAU;sCACxH;;wBAGAnC,+BACC,KAAC+B;4BACCC,SAAS,IAAMxB,eAAe,CAACD;4BAC/BQ,OAAO;gCAAEQ,QAAQ;gCAAqBU,YAAY;gCAAQT,cAAc;gCAAGJ,SAAS;gCAAYe,QAAQ;4BAAU;sCAEjH5B,cAAc,SAAS;;;;gBAK7BP,iBAAiBO,6BAChB,MAACM;oBAAIE,OAAO;wBAAEkB,YAAY;wBAAWT,cAAc;wBAAGJ,SAAS;wBAAIgB,UAAU;wBAAIC,YAAY;oBAAY;;sCACvG,MAACxB;4BAAIE,OAAO;gCAAEe,cAAc;4BAAG;;8CAAG,KAACQ;8CAAO;;gCAAejC,MAAMuB,OAAO;;;wBACrEvB,MAAMkC,KAAK,kBACV,MAAC1B;4BAAIE,OAAO;gCAAEe,cAAc;gCAAIU,YAAY;gCAAYC,WAAW;4BAAa;;8CAC9E,KAACH;8CAAO;;8CACR,KAACI;gCACArC,MAAMkC,KAAK;;;wBAGf7B,0BACC,MAACG;;8CAAI,KAACyB;8CAAO;;gCAAa7B,eAAeE,KAAK,YAAYgC,QAAQlC,eAAeE,KAAK,CAACiB,OAAO,GAAGgB,OAAOnC,eAAeE,KAAK;;;;;;;;AAO1I,EAAE"}
1
+ {"version":3,"sources":["../../../../../../src/core/router/utils/adapters/react-router/RouteErrorBoundary.tsx"],"sourcesContent":["import { useState } from 'react';\nimport type { FallbackProps } from 'react-error-boundary';\n\nconst isDevelopment = process.env.NODE_ENV === 'development';\n\ninterface RouteErrorLike extends Error {\n status?: number;\n statusText?: string;\n data?: unknown;\n cause?: unknown;\n}\n\nexport const RouteErrorBoundary = ({ error, resetErrorBoundary }: FallbackProps) => {\n const [showDetails, setShowDetails] = useState(false);\n const errorObject: RouteErrorLike | null =\n error !== null && typeof error === 'object' ? (error as RouteErrorLike) : null;\n const errorMessage =\n typeof errorObject?.message === 'string' && errorObject.message !== ''\n ? errorObject.message\n : '未知错误';\n const hasCause = errorObject?.cause !== undefined;\n\n const isNotFoundError =\n errorObject?.status === 404 ||\n (typeof errorObject?.statusText === 'string' && /not\\s*found/i.test(errorObject.statusText)) ||\n /no routes matched location|not found|404/i.test(errorMessage);\n\n const title = isNotFoundError ? '页面不存在(404)' : '出错了,请稍后再试';\n const friendlyMessage = isNotFoundError\n ? '访问的路由未注册或不存在,请检查访问地址。'\n : '请稍后再试或联系技术支持';\n const displayMessage = isDevelopment ? errorMessage : friendlyMessage;\n\n return (\n <div\n role=\"alert\"\n style={{\n minHeight: '100vh',\n display: 'flex',\n justifyContent: 'center',\n alignItems: 'center',\n padding: 24,\n }}\n >\n <div style={{ maxWidth: 760, width: '100%', border: '1px solid #dde5ec', borderRadius: 10, padding: 20 }}>\n <h2 style={{ marginTop: 0 }}>{title}</h2>\n <p>{displayMessage}</p>\n <div style={{ display: 'flex', gap: 8, marginBottom: 12 }}>\n <button\n onClick={resetErrorBoundary}\n style={{ border: 'none', background: '#2f80ed', color: '#fff', borderRadius: 6, padding: '8px 12px', cursor: 'pointer' }}\n >\n 刷新重试\n </button>\n {isDevelopment && (\n <button\n onClick={() => setShowDetails(!showDetails)}\n style={{ border: '1px solid #cfd7df', background: '#fff', borderRadius: 6, padding: '8px 12px', cursor: 'pointer' }}\n >\n {showDetails ? '收起详情' : '展开详情'}\n </button>\n )}\n </div>\n\n {isDevelopment && showDetails && (\n <div style={{ background: '#f7fafc', borderRadius: 8, padding: 12, fontSize: 12, fontFamily: 'monospace' }}>\n <div style={{ marginBottom: 10 }}><strong>错误信息:</strong>{errorMessage}</div>\n {errorObject?.stack && (\n <div style={{ marginBottom: 10, whiteSpace: 'pre-wrap', wordBreak: 'break-word' }}>\n <strong>堆栈:</strong>\n <br />\n {errorObject.stack}\n </div>\n )}\n {hasCause && (\n <div>\n <strong>原因:</strong>\n {errorObject?.cause instanceof Error ? errorObject.cause.message : String(errorObject?.cause)}\n </div>\n )}\n </div>\n )}\n </div>\n </div>\n );\n};\n"],"names":["useState","isDevelopment","process","env","NODE_ENV","RouteErrorBoundary","error","resetErrorBoundary","showDetails","setShowDetails","errorObject","errorMessage","message","hasCause","cause","undefined","isNotFoundError","status","statusText","test","title","friendlyMessage","displayMessage","div","role","style","minHeight","display","justifyContent","alignItems","padding","maxWidth","width","border","borderRadius","h2","marginTop","p","gap","marginBottom","button","onClick","background","color","cursor","fontSize","fontFamily","strong","stack","whiteSpace","wordBreak","br","Error","String"],"mappings":";AAAA,SAASA,QAAQ,QAAQ,QAAQ;AAGjC,MAAMC,gBAAgBC,QAAQC,GAAG,CAACC,QAAQ,KAAK;AAS/C,OAAO,MAAMC,qBAAqB,CAAC,EAAEC,KAAK,EAAEC,kBAAkB,EAAiB;IAC7E,MAAM,CAACC,aAAaC,eAAe,GAAGT,SAAS;IAC/C,MAAMU,cACJJ,UAAU,QAAQ,OAAOA,UAAU,WAAYA,QAA2B;IAC5E,MAAMK,eACJ,OAAOD,aAAaE,YAAY,YAAYF,YAAYE,OAAO,KAAK,KAChEF,YAAYE,OAAO,GACnB;IACN,MAAMC,WAAWH,aAAaI,UAAUC;IAExC,MAAMC,kBACJN,aAAaO,WAAW,OACvB,OAAOP,aAAaQ,eAAe,YAAY,eAAeC,IAAI,CAACT,YAAYQ,UAAU,KAC1F,4CAA4CC,IAAI,CAACR;IAEnD,MAAMS,QAAQJ,kBAAkB,eAAe;IAC/C,MAAMK,kBAAkBL,kBACpB,0BACA;IACJ,MAAMM,iBAAiBrB,gBAAgBU,eAAeU;IAEtD,qBACE,KAACE;QACCC,MAAK;QACLC,OAAO;YACLC,WAAW;YACXC,SAAS;YACTC,gBAAgB;YAChBC,YAAY;YACZC,SAAS;QACX;kBAEA,cAAA,MAACP;YAAIE,OAAO;gBAAEM,UAAU;gBAAKC,OAAO;gBAAQC,QAAQ;gBAAqBC,cAAc;gBAAIJ,SAAS;YAAG;;8BACrG,KAACK;oBAAGV,OAAO;wBAAEW,WAAW;oBAAE;8BAAIhB;;8BAC9B,KAACiB;8BAAGf;;8BACJ,MAACC;oBAAIE,OAAO;wBAAEE,SAAS;wBAAQW,KAAK;wBAAGC,cAAc;oBAAG;;sCACtD,KAACC;4BACCC,SAASlC;4BACTkB,OAAO;gCAAEQ,QAAQ;gCAAQS,YAAY;gCAAWC,OAAO;gCAAQT,cAAc;gCAAGJ,SAAS;gCAAYc,QAAQ;4BAAU;sCACxH;;wBAGA3C,+BACC,KAACuC;4BACCC,SAAS,IAAMhC,eAAe,CAACD;4BAC/BiB,OAAO;gCAAEQ,QAAQ;gCAAqBS,YAAY;gCAAQR,cAAc;gCAAGJ,SAAS;gCAAYc,QAAQ;4BAAU;sCAEjHpC,cAAc,SAAS;;;;gBAK7BP,iBAAiBO,6BAChB,MAACe;oBAAIE,OAAO;wBAAEiB,YAAY;wBAAWR,cAAc;wBAAGJ,SAAS;wBAAIe,UAAU;wBAAIC,YAAY;oBAAY;;sCACvG,MAACvB;4BAAIE,OAAO;gCAAEc,cAAc;4BAAG;;8CAAG,KAACQ;8CAAO;;gCAAepC;;;wBACxDD,aAAasC,uBACZ,MAACzB;4BAAIE,OAAO;gCAAEc,cAAc;gCAAIU,YAAY;gCAAYC,WAAW;4BAAa;;8CAC9E,KAACH;8CAAO;;8CACR,KAACI;gCACAzC,YAAYsC,KAAK;;;wBAGrBnC,0BACC,MAACU;;8CACC,KAACwB;8CAAO;;gCACPrC,aAAaI,iBAAiBsC,QAAQ1C,YAAYI,KAAK,CAACF,OAAO,GAAGyC,OAAO3C,aAAaI;;;;;;;;AAQvG,EAAE"}
@@ -22,7 +22,7 @@ function DefaultRouteHydrateFallback() {
22
22
  children: "Loading..."
23
23
  });
24
24
  }
25
- const transformRoutesToReactRoutes = async (routes, transformResult, defaultRouteErrorComponent, defaultRouteLoadingComponent)=>{
25
+ const transformRoutesToReactRoutes = async (routes, transformResult, defaultRouteErrorComponent, defaultRouteLoadingComponent, enableHydrateFallback = false)=>{
26
26
  /**
27
27
  * 批量处理路由
28
28
  * @param routes 路由组
@@ -158,28 +158,31 @@ const transformRoutesToReactRoutes = async (routes, transformResult, defaultRout
158
158
  }
159
159
  const reactRoute = {
160
160
  children: [],
161
- hydrateFallbackElement: /*#__PURE__*/ (0, _jsxruntime.jsx)(DefaultRouteHydrateFallback, {}),
162
161
  id: name,
163
162
  handle: getHandle(),
164
163
  lazy: async ()=>{
165
164
  const ErrorBoundary = await getErrorComponent();
166
165
  const config = await getConfig();
167
166
  const LoadingComponent = await getLoadingComponent();
167
+ const HydrateFallback = LoadingComponent?.default ?? DefaultRouteHydrateFallback;
168
168
  // 如果配置为空,确保至少返回一个空对象,避免展开 undefined
169
169
  if (!config) {
170
170
  return {
171
171
  ErrorBoundary: ErrorBoundary?.default,
172
- HydrateFallback: LoadingComponent?.default
172
+ HydrateFallback
173
173
  };
174
174
  }
175
175
  return {
176
176
  ErrorBoundary: ErrorBoundary?.default,
177
- HydrateFallback: LoadingComponent?.default,
177
+ HydrateFallback,
178
178
  ...config
179
179
  };
180
180
  },
181
181
  path
182
182
  };
183
+ if (enableHydrateFallback) {
184
+ reactRoute.hydrateFallbackElement = /*#__PURE__*/ (0, _jsxruntime.jsx)(DefaultRouteHydrateFallback, {});
185
+ }
183
186
  // 处理子路由
184
187
  if (children?.length) {
185
188
  reactRoute.children = children.flatMap((child)=>transformRouteToReactRoute(child)).sort((a, b)=>{
@@ -194,9 +197,10 @@ const transformRoutesToReactRoutes = async (routes, transformResult, defaultRout
194
197
  lazy: async ()=>{
195
198
  const ErrorBoundary = await getErrorComponent();
196
199
  const LoadingComponent = await getLoadingComponent();
200
+ const HydrateFallback = LoadingComponent?.default ?? DefaultRouteHydrateFallback;
197
201
  return {
198
202
  ErrorBoundary: ErrorBoundary?.default,
199
- HydrateFallback: LoadingComponent?.default,
203
+ HydrateFallback,
200
204
  ...await getConfig(true)
201
205
  };
202
206
  }
@@ -226,9 +230,10 @@ const transformRoutesToReactRoutes = async (routes, transformResult, defaultRout
226
230
  lazy: async ()=>{
227
231
  const ErrorBoundary = await getErrorComponent();
228
232
  const LoadingComponent = await getLoadingComponent();
233
+ const HydrateFallback = LoadingComponent?.default ?? DefaultRouteHydrateFallback;
229
234
  return {
230
235
  ErrorBoundary: ErrorBoundary?.default,
231
- HydrateFallback: LoadingComponent?.default,
236
+ HydrateFallback,
232
237
  ...await getConfig(true)
233
238
  };
234
239
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../../src/core/router/utils/adapters/react-router/transform.tsx"],"sourcesContent":["import type { RouteConfig } from '../../../types';\nimport {\n type RouteObject,\n Navigate\n} from 'react-router-dom';\nimport type { TransformRoutesResult } from '../../transform';\nimport { RouteErrorBoundary } from './RouteErrorBoundary';\nimport type { ComponentImport } from '../../../types';\nimport { logger } from '../../../../../utils';\n\nfunction DefaultRouteHydrateFallback() {\n return (\n <div style={{ padding: 16, textAlign: 'center', color: '#5f6c7b' }}>\n Loading...\n </div>\n );\n}\n\nexport const transformRoutesToReactRoutes = async (\n routes: RouteConfig[], \n transformResult: TransformRoutesResult,\n defaultRouteErrorComponent?: ComponentImport,\n defaultRouteLoadingComponent?: ComponentImport,\n): Promise<RouteObject[]> => {\n\n /**\n * 批量处理路由\n * @param routes 路由组\n */\n function transformRouteToReactRoutes(routes: RouteConfig[]) {\n return routes.flatMap((route: RouteConfig) => transformRouteToReactRoute(route))\n }\n\n /**\n * 处理单个路由\n * @param route 路由\n */\n function transformRouteToReactRoute(route: RouteConfig): RouteObject {\n const {\n isGroup = false,\n enableRedirection = false,\n name,\n path,\n handle,\n children,\n page,\n layout,\n error,\n errors,\n loading,\n } = route;\n const routeError = error ?? errors;\n\n // 获取错误组件\n async function getErrorComponent() {\n // 如果 error/errors 是函数,直接使用\n if (typeof routeError === 'function') {\n return routeError();\n }\n\n const errorsMap = transformResult.errors;\n\n // 判断 error/errors 是否为 string 且不是空字符串\n if (typeof routeError === 'string' && routeError !== '') {\n // 使用 routeError 作为 key 获取 transformResult.errors 的值\n const errorResolver = errorsMap.get(routeError);\n\n // 如果获取不到,返回 null\n if (!errorResolver) {\n return null;\n }\n\n // 如果获取到,返回对应的值(调用动态导入函数)\n if (typeof errorResolver === 'function') {\n return errorResolver();\n }\n\n return null;\n }\n\n // 如果 errors 为空,使用配置的默认错误组件或内置的 RouteErrorBoundary 组件\n if (defaultRouteErrorComponent) {\n // 如果配置了默认错误组件,使用配置的组件\n return defaultRouteErrorComponent();\n }\n\n // 如果没有配置默认错误组件,使用内置的 RouteErrorBoundary 组件\n // 直接导入而非懒加载,因为:\n // 1. RouteErrorBoundary 是框架核心组件,体积小\n // 2. 错误边界需要快速响应,直接导入速度更快\n // 3. 作为基础设施组件,应该保证可用性\n return { default: RouteErrorBoundary };\n }\n\n // 获取转换配置\n function convertConfig(m: any) {\n if (!m) {\n return null;\n }\n const { action, loader, shouldRevalidate, default: Component } = m;\n\n // 如果 Component 不存在,记录警告\n if (!Component) {\n logger.warn(`路由组件未找到 default 导出: ${name}`, m);\n }\n\n return {\n action, // always use action\n loader, // always use loader\n shouldRevalidate,\n Component\n };\n }\n\n // 获取加载组件\n async function getLoadingComponent() {\n if (typeof loading === 'function') {\n return loading();\n }\n\n if (typeof loading === 'string' && loading !== '') {\n const loadingResolver = transformResult.loadings.get(loading);\n if (typeof loadingResolver === 'function') {\n return loadingResolver();\n }\n }\n\n if (defaultRouteLoadingComponent) {\n return defaultRouteLoadingComponent();\n }\n\n return null;\n }\n\n // 获取配置\n async function getConfig(index: boolean = false) {\n // 如果有layout和不是index,返回布局配置\n if (layout && !index) {\n // 如果 layout 是函数,直接使用\n if (typeof layout === 'function') {\n const config = await layout();\n return convertConfig(config);\n }\n\n // 如果 layout 是字符串,从 Map 中获取\n if (typeof layout === 'string') {\n const layoutResolver = transformResult.layouts.get(layout);\n if (!layoutResolver) {\n throw new Error(`未找到名为 ${layout} 的布局组件`);\n }\n const config = await layoutResolver();\n return convertConfig(config);\n }\n }\n\n let pageName = name;\n\n // 如果是notFound则转成404\n if (pageName === 'notFound') {\n pageName = '404'\n }\n\n if (page && (!children?.length || index)) {\n // 如果 page 是函数,直接使用\n if (typeof page === 'function') {\n const config = await page();\n return convertConfig(config);\n }\n\n // 如果 page 是字符串,从 Map 中获取\n if (typeof page === 'string') {\n const viewResolver = transformResult.pages.get(page);\n if (!viewResolver) {\n throw new Error(`未找到名为 ${page} 的页面组件`);\n }\n const config = await viewResolver();\n return convertConfig(config);\n }\n }\n\n return null;\n }\n\n // 获取处理信息,即额外的配置信息\n function getHandle(index: boolean = false) {\n if ((layout || isGroup) && !index) {\n return null\n }\n return {\n ...handle,\n name,\n path\n }\n }\n\n\n const reactRoute: RouteObject = {\n children: [],\n hydrateFallbackElement: <DefaultRouteHydrateFallback />,\n id: name,\n handle: getHandle(),\n lazy: async () => {\n const ErrorBoundary = await getErrorComponent();\n const config = await getConfig();\n const LoadingComponent = await getLoadingComponent();\n\n // 如果配置为空,确保至少返回一个空对象,避免展开 undefined\n if (!config) {\n return {\n ErrorBoundary: ErrorBoundary?.default,\n HydrateFallback: LoadingComponent?.default,\n };\n }\n\n return {\n ErrorBoundary: ErrorBoundary?.default,\n HydrateFallback: LoadingComponent?.default,\n ...config\n };\n },\n path\n };\n\n // 处理子路由\n if (children?.length) {\n reactRoute.children = children.flatMap(child => transformRouteToReactRoute(child)).sort((a, b) => {\n const orderA = a.handle?.order ?? 99;\n const orderB = b.handle?.order ?? 99;\n return orderA - orderB;\n });\n\n if (page && !isGroup) {\n reactRoute.children.unshift({\n handle: getHandle(true),\n index: true,\n lazy: async () => {\n const ErrorBoundary = await getErrorComponent();\n const LoadingComponent = await getLoadingComponent();\n return {\n ErrorBoundary: ErrorBoundary?.default,\n HydrateFallback: LoadingComponent?.default,\n ...(await getConfig(true))\n };\n }\n });\n }\n\n if (enableRedirection && isGroup) {\n const [firstChild] = reactRoute.children;\n if (firstChild?.path) {\n reactRoute.children.unshift({\n index: true,\n handle: getHandle(true),\n element: <Navigate to={firstChild.path as string} replace />\n });\n }\n }\n\n }\n // 若存在 layout 且没有子路由,但同时声明了 page,则自动生成 index 子路由以渲染页面\n // 场景:/test 使用自定义 layout,且没有 children 时仍应渲染 page\n if ((!children || children.length === 0) && layout && page && !isGroup) {\n reactRoute.children = [{\n handle: getHandle(true),\n index: true,\n lazy: async () => {\n const ErrorBoundary = await getErrorComponent();\n const LoadingComponent = await getLoadingComponent();\n return {\n ErrorBoundary: ErrorBoundary?.default,\n HydrateFallback: LoadingComponent?.default,\n ...(await getConfig(true))\n };\n }\n }];\n }\n\n return reactRoute;\n }\n\n return transformRouteToReactRoutes(routes);\n}\n"],"names":["transformRoutesToReactRoutes","DefaultRouteHydrateFallback","div","style","padding","textAlign","color","routes","transformResult","defaultRouteErrorComponent","defaultRouteLoadingComponent","transformRouteToReactRoutes","flatMap","route","transformRouteToReactRoute","isGroup","enableRedirection","name","path","handle","children","page","layout","error","errors","loading","routeError","getErrorComponent","errorsMap","errorResolver","get","default","RouteErrorBoundary","convertConfig","m","action","loader","shouldRevalidate","Component","logger","warn","getLoadingComponent","loadingResolver","loadings","getConfig","index","config","layoutResolver","layouts","Error","pageName","length","viewResolver","pages","getHandle","reactRoute","hydrateFallbackElement","id","lazy","ErrorBoundary","LoadingComponent","HydrateFallback","child","sort","a","b","orderA","order","orderB","unshift","firstChild","element","Navigate","to","replace"],"mappings":";;;;+BAkBaA;;;eAAAA;;;;gCAdN;oCAE4B;uBAEZ;AAEvB,SAASC;IACL,qBACI,qBAACC;QAAIC,OAAO;YAAEC,SAAS;YAAIC,WAAW;YAAUC,OAAO;QAAU;kBAAG;;AAI5E;AAEO,MAAMN,+BAA+B,OACxCO,QACAC,iBACAC,4BACAC;IAGA;;;KAGC,GACD,SAASC,4BAA4BJ,MAAqB;QACtD,OAAOA,OAAOK,OAAO,CAAC,CAACC,QAAuBC,2BAA2BD;IAC7E;IAEA;;;KAGC,GACD,SAASC,2BAA2BD,KAAkB;QAClD,MAAM,EACFE,UAAU,KAAK,EACfC,oBAAoB,KAAK,EACzBC,IAAI,EACJC,IAAI,EACJC,MAAM,EACNC,QAAQ,EACRC,IAAI,EACJC,MAAM,EACNC,KAAK,EACLC,MAAM,EACNC,OAAO,EACV,GAAGZ;QACJ,MAAMa,aAAaH,SAASC;QAE5B,SAAS;QACT,eAAeG;YACX,2BAA2B;YAC3B,IAAI,OAAOD,eAAe,YAAY;gBAClC,OAAOA;YACX;YAEA,MAAME,YAAYpB,gBAAgBgB,MAAM;YAExC,qCAAqC;YACrC,IAAI,OAAOE,eAAe,YAAYA,eAAe,IAAI;gBACrD,oDAAoD;gBACpD,MAAMG,gBAAgBD,UAAUE,GAAG,CAACJ;gBAEpC,iBAAiB;gBACjB,IAAI,CAACG,eAAe;oBAChB,OAAO;gBACX;gBAEA,yBAAyB;gBACzB,IAAI,OAAOA,kBAAkB,YAAY;oBACrC,OAAOA;gBACX;gBAEA,OAAO;YACX;YAEA,qDAAqD;YACrD,IAAIpB,4BAA4B;gBAC5B,sBAAsB;gBACtB,OAAOA;YACX;YAEA,2CAA2C;YAC3C,gBAAgB;YAChB,oCAAoC;YACpC,yBAAyB;YACzB,sBAAsB;YACtB,OAAO;gBAAEsB,SAASC,sCAAkB;YAAC;QACzC;QAEA,SAAS;QACT,SAASC,cAAcC,CAAM;YACzB,IAAI,CAACA,GAAG;gBACJ,OAAO;YACX;YACA,MAAM,EAAEC,MAAM,EAAEC,MAAM,EAAEC,gBAAgB,EAAEN,SAASO,SAAS,EAAE,GAAGJ;YAEjE,wBAAwB;YACxB,IAAI,CAACI,WAAW;gBACZC,aAAM,CAACC,IAAI,CAAC,CAAC,oBAAoB,EAAEvB,MAAM,EAAEiB;YAC/C;YAEA,OAAO;gBACHC;gBACAC;gBACAC;gBACAC;YACJ;QACJ;QAEA,SAAS;QACT,eAAeG;YACX,IAAI,OAAOhB,YAAY,YAAY;gBAC/B,OAAOA;YACX;YAEA,IAAI,OAAOA,YAAY,YAAYA,YAAY,IAAI;gBAC/C,MAAMiB,kBAAkBlC,gBAAgBmC,QAAQ,CAACb,GAAG,CAACL;gBACrD,IAAI,OAAOiB,oBAAoB,YAAY;oBACvC,OAAOA;gBACX;YACJ;YAEA,IAAIhC,8BAA8B;gBAC9B,OAAOA;YACX;YAEA,OAAO;QACX;QAEA,OAAO;QACP,eAAekC,UAAUC,QAAiB,KAAK;YAC3C,2BAA2B;YAC3B,IAAIvB,UAAU,CAACuB,OAAO;gBAClB,qBAAqB;gBACrB,IAAI,OAAOvB,WAAW,YAAY;oBAC9B,MAAMwB,SAAS,MAAMxB;oBACrB,OAAOW,cAAca;gBACzB;gBAEA,2BAA2B;gBAC3B,IAAI,OAAOxB,WAAW,UAAU;oBAC5B,MAAMyB,iBAAiBvC,gBAAgBwC,OAAO,CAAClB,GAAG,CAACR;oBACnD,IAAI,CAACyB,gBAAgB;wBACjB,MAAM,IAAIE,MAAM,CAAC,MAAM,EAAE3B,OAAO,MAAM,CAAC;oBAC3C;oBACA,MAAMwB,SAAS,MAAMC;oBACrB,OAAOd,cAAca;gBACzB;YACJ;YAEA,IAAII,WAAWjC;YAEf,oBAAoB;YACpB,IAAIiC,aAAa,YAAY;gBACzBA,WAAW;YACf;YAEA,IAAI7B,QAAS,CAAA,CAACD,UAAU+B,UAAUN,KAAI,GAAI;gBACtC,mBAAmB;gBACnB,IAAI,OAAOxB,SAAS,YAAY;oBAC5B,MAAMyB,SAAS,MAAMzB;oBACrB,OAAOY,cAAca;gBACzB;gBAEA,yBAAyB;gBACzB,IAAI,OAAOzB,SAAS,UAAU;oBAC1B,MAAM+B,eAAe5C,gBAAgB6C,KAAK,CAACvB,GAAG,CAACT;oBAC/C,IAAI,CAAC+B,cAAc;wBACf,MAAM,IAAIH,MAAM,CAAC,MAAM,EAAE5B,KAAK,MAAM,CAAC;oBACzC;oBACA,MAAMyB,SAAS,MAAMM;oBACrB,OAAOnB,cAAca;gBACzB;YACJ;YAEA,OAAO;QACX;QAEA,kBAAkB;QAClB,SAASQ,UAAUT,QAAiB,KAAK;YACrC,IAAI,AAACvB,CAAAA,UAAUP,OAAM,KAAM,CAAC8B,OAAO;gBAC/B,OAAO;YACX;YACA,OAAO;gBACH,GAAG1B,MAAM;gBACTF;gBACAC;YACJ;QACJ;QAGA,MAAMqC,aAA0B;YAC5BnC,UAAU,EAAE;YACZoC,sCAAwB,qBAACvD;YACzBwD,IAAIxC;YACJE,QAAQmC;YACRI,MAAM;gBACF,MAAMC,gBAAgB,MAAMhC;gBAC5B,MAAMmB,SAAS,MAAMF;gBACrB,MAAMgB,mBAAmB,MAAMnB;gBAE/B,oCAAoC;gBACpC,IAAI,CAACK,QAAQ;oBACT,OAAO;wBACHa,eAAeA,eAAe5B;wBAC9B8B,iBAAiBD,kBAAkB7B;oBACvC;gBACJ;gBAEA,OAAO;oBACH4B,eAAeA,eAAe5B;oBAC9B8B,iBAAiBD,kBAAkB7B;oBACnC,GAAGe,MAAM;gBACb;YACJ;YACA5B;QACJ;QAEA,QAAQ;QACR,IAAIE,UAAU+B,QAAQ;YAClBI,WAAWnC,QAAQ,GAAGA,SAASR,OAAO,CAACkD,CAAAA,QAAShD,2BAA2BgD,QAAQC,IAAI,CAAC,CAACC,GAAGC;gBACxF,MAAMC,SAASF,EAAE7C,MAAM,EAAEgD,SAAS;gBAClC,MAAMC,SAASH,EAAE9C,MAAM,EAAEgD,SAAS;gBAClC,OAAOD,SAASE;YACpB;YAEA,IAAI/C,QAAQ,CAACN,SAAS;gBAClBwC,WAAWnC,QAAQ,CAACiD,OAAO,CAAC;oBACxBlD,QAAQmC,UAAU;oBAClBT,OAAO;oBACPa,MAAM;wBACF,MAAMC,gBAAgB,MAAMhC;wBAC5B,MAAMiC,mBAAmB,MAAMnB;wBAC/B,OAAO;4BACHkB,eAAeA,eAAe5B;4BAC9B8B,iBAAiBD,kBAAkB7B;4BACnC,GAAI,MAAMa,UAAU,KAAK;wBAC7B;oBACJ;gBACJ;YACJ;YAEA,IAAI5B,qBAAqBD,SAAS;gBAC9B,MAAM,CAACuD,WAAW,GAAGf,WAAWnC,QAAQ;gBACxC,IAAIkD,YAAYpD,MAAM;oBAClBqC,WAAWnC,QAAQ,CAACiD,OAAO,CAAC;wBACxBxB,OAAO;wBACP1B,QAAQmC,UAAU;wBAClBiB,uBAAS,qBAACC,wBAAQ;4BAACC,IAAIH,WAAWpD,IAAI;4BAAYwD,OAAO;;oBAC7D;gBACJ;YACJ;QAEJ;QACA,qDAAqD;QACrD,gDAAgD;QAChD,IAAI,AAAC,CAAA,CAACtD,YAAYA,SAAS+B,MAAM,KAAK,CAAA,KAAM7B,UAAUD,QAAQ,CAACN,SAAS;YACpEwC,WAAWnC,QAAQ,GAAG;gBAAC;oBACnBD,QAAQmC,UAAU;oBAClBT,OAAO;oBACPa,MAAM;wBACF,MAAMC,gBAAgB,MAAMhC;wBAC5B,MAAMiC,mBAAmB,MAAMnB;wBAC/B,OAAO;4BACHkB,eAAeA,eAAe5B;4BAC9B8B,iBAAiBD,kBAAkB7B;4BACnC,GAAI,MAAMa,UAAU,KAAK;wBAC7B;oBACJ;gBACJ;aAAE;QACN;QAEA,OAAOW;IACX;IAEA,OAAO5C,4BAA4BJ;AACvC"}
1
+ {"version":3,"sources":["../../../../../../src/core/router/utils/adapters/react-router/transform.tsx"],"sourcesContent":["import type { RouteConfig } from '../../../types';\nimport {\n type RouteObject,\n Navigate\n} from 'react-router-dom';\nimport type { TransformRoutesResult } from '../../transform';\nimport { RouteErrorBoundary } from './RouteErrorBoundary';\nimport type { ComponentImport } from '../../../types';\nimport { logger } from '../../../../../utils';\n\nfunction DefaultRouteHydrateFallback() {\n return (\n <div style={{ padding: 16, textAlign: 'center', color: '#5f6c7b' }}>\n Loading...\n </div>\n );\n}\n\nexport const transformRoutesToReactRoutes = async (\n routes: RouteConfig[], \n transformResult: TransformRoutesResult,\n defaultRouteErrorComponent?: ComponentImport,\n defaultRouteLoadingComponent?: ComponentImport,\n enableHydrateFallback: boolean = false,\n): Promise<RouteObject[]> => {\n\n /**\n * 批量处理路由\n * @param routes 路由组\n */\n function transformRouteToReactRoutes(routes: RouteConfig[]) {\n return routes.flatMap((route: RouteConfig) => transformRouteToReactRoute(route))\n }\n\n /**\n * 处理单个路由\n * @param route 路由\n */\n function transformRouteToReactRoute(route: RouteConfig): RouteObject {\n const {\n isGroup = false,\n enableRedirection = false,\n name,\n path,\n handle,\n children,\n page,\n layout,\n error,\n errors,\n loading,\n } = route;\n const routeError = error ?? errors;\n\n // 获取错误组件\n async function getErrorComponent() {\n // 如果 error/errors 是函数,直接使用\n if (typeof routeError === 'function') {\n return routeError();\n }\n\n const errorsMap = transformResult.errors;\n\n // 判断 error/errors 是否为 string 且不是空字符串\n if (typeof routeError === 'string' && routeError !== '') {\n // 使用 routeError 作为 key 获取 transformResult.errors 的值\n const errorResolver = errorsMap.get(routeError);\n\n // 如果获取不到,返回 null\n if (!errorResolver) {\n return null;\n }\n\n // 如果获取到,返回对应的值(调用动态导入函数)\n if (typeof errorResolver === 'function') {\n return errorResolver();\n }\n\n return null;\n }\n\n // 如果 errors 为空,使用配置的默认错误组件或内置的 RouteErrorBoundary 组件\n if (defaultRouteErrorComponent) {\n // 如果配置了默认错误组件,使用配置的组件\n return defaultRouteErrorComponent();\n }\n\n // 如果没有配置默认错误组件,使用内置的 RouteErrorBoundary 组件\n // 直接导入而非懒加载,因为:\n // 1. RouteErrorBoundary 是框架核心组件,体积小\n // 2. 错误边界需要快速响应,直接导入速度更快\n // 3. 作为基础设施组件,应该保证可用性\n return { default: RouteErrorBoundary };\n }\n\n // 获取转换配置\n function convertConfig(m: any) {\n if (!m) {\n return null;\n }\n const { action, loader, shouldRevalidate, default: Component } = m;\n\n // 如果 Component 不存在,记录警告\n if (!Component) {\n logger.warn(`路由组件未找到 default 导出: ${name}`, m);\n }\n\n return {\n action, // always use action\n loader, // always use loader\n shouldRevalidate,\n Component\n };\n }\n\n // 获取加载组件\n async function getLoadingComponent() {\n if (typeof loading === 'function') {\n return loading();\n }\n\n if (typeof loading === 'string' && loading !== '') {\n const loadingResolver = transformResult.loadings.get(loading);\n if (typeof loadingResolver === 'function') {\n return loadingResolver();\n }\n }\n\n if (defaultRouteLoadingComponent) {\n return defaultRouteLoadingComponent();\n }\n\n return null;\n }\n\n // 获取配置\n async function getConfig(index: boolean = false) {\n // 如果有layout和不是index,返回布局配置\n if (layout && !index) {\n // 如果 layout 是函数,直接使用\n if (typeof layout === 'function') {\n const config = await layout();\n return convertConfig(config);\n }\n\n // 如果 layout 是字符串,从 Map 中获取\n if (typeof layout === 'string') {\n const layoutResolver = transformResult.layouts.get(layout);\n if (!layoutResolver) {\n throw new Error(`未找到名为 ${layout} 的布局组件`);\n }\n const config = await layoutResolver();\n return convertConfig(config);\n }\n }\n\n let pageName = name;\n\n // 如果是notFound则转成404\n if (pageName === 'notFound') {\n pageName = '404'\n }\n\n if (page && (!children?.length || index)) {\n // 如果 page 是函数,直接使用\n if (typeof page === 'function') {\n const config = await page();\n return convertConfig(config);\n }\n\n // 如果 page 是字符串,从 Map 中获取\n if (typeof page === 'string') {\n const viewResolver = transformResult.pages.get(page);\n if (!viewResolver) {\n throw new Error(`未找到名为 ${page} 的页面组件`);\n }\n const config = await viewResolver();\n return convertConfig(config);\n }\n }\n\n return null;\n }\n\n // 获取处理信息,即额外的配置信息\n function getHandle(index: boolean = false) {\n if ((layout || isGroup) && !index) {\n return null\n }\n return {\n ...handle,\n name,\n path\n }\n }\n\n\n const reactRoute: RouteObject = {\n children: [],\n id: name,\n handle: getHandle(),\n lazy: async () => {\n const ErrorBoundary = await getErrorComponent();\n const config = await getConfig();\n const LoadingComponent = await getLoadingComponent();\n const HydrateFallback = LoadingComponent?.default ?? DefaultRouteHydrateFallback;\n\n // 如果配置为空,确保至少返回一个空对象,避免展开 undefined\n if (!config) {\n return {\n ErrorBoundary: ErrorBoundary?.default,\n HydrateFallback,\n };\n }\n\n return {\n ErrorBoundary: ErrorBoundary?.default,\n HydrateFallback,\n ...config\n };\n },\n path\n };\n\n if (enableHydrateFallback) {\n reactRoute.hydrateFallbackElement = <DefaultRouteHydrateFallback />;\n }\n\n // 处理子路由\n if (children?.length) {\n reactRoute.children = children.flatMap(child => transformRouteToReactRoute(child)).sort((a, b) => {\n const orderA = a.handle?.order ?? 99;\n const orderB = b.handle?.order ?? 99;\n return orderA - orderB;\n });\n\n if (page && !isGroup) {\n reactRoute.children.unshift({\n handle: getHandle(true),\n index: true,\n lazy: async () => {\n const ErrorBoundary = await getErrorComponent();\n const LoadingComponent = await getLoadingComponent();\n const HydrateFallback = LoadingComponent?.default ?? DefaultRouteHydrateFallback;\n return {\n ErrorBoundary: ErrorBoundary?.default,\n HydrateFallback,\n ...(await getConfig(true))\n };\n }\n });\n }\n\n if (enableRedirection && isGroup) {\n const [firstChild] = reactRoute.children;\n if (firstChild?.path) {\n reactRoute.children.unshift({\n index: true,\n handle: getHandle(true),\n element: <Navigate to={firstChild.path as string} replace />\n });\n }\n }\n\n }\n // 若存在 layout 且没有子路由,但同时声明了 page,则自动生成 index 子路由以渲染页面\n // 场景:/test 使用自定义 layout,且没有 children 时仍应渲染 page\n if ((!children || children.length === 0) && layout && page && !isGroup) {\n reactRoute.children = [{\n handle: getHandle(true),\n index: true,\n lazy: async () => {\n const ErrorBoundary = await getErrorComponent();\n const LoadingComponent = await getLoadingComponent();\n const HydrateFallback = LoadingComponent?.default ?? DefaultRouteHydrateFallback;\n return {\n ErrorBoundary: ErrorBoundary?.default,\n HydrateFallback,\n ...(await getConfig(true))\n };\n }\n }];\n }\n\n return reactRoute;\n }\n\n return transformRouteToReactRoutes(routes);\n}\n"],"names":["transformRoutesToReactRoutes","DefaultRouteHydrateFallback","div","style","padding","textAlign","color","routes","transformResult","defaultRouteErrorComponent","defaultRouteLoadingComponent","enableHydrateFallback","transformRouteToReactRoutes","flatMap","route","transformRouteToReactRoute","isGroup","enableRedirection","name","path","handle","children","page","layout","error","errors","loading","routeError","getErrorComponent","errorsMap","errorResolver","get","default","RouteErrorBoundary","convertConfig","m","action","loader","shouldRevalidate","Component","logger","warn","getLoadingComponent","loadingResolver","loadings","getConfig","index","config","layoutResolver","layouts","Error","pageName","length","viewResolver","pages","getHandle","reactRoute","id","lazy","ErrorBoundary","LoadingComponent","HydrateFallback","hydrateFallbackElement","child","sort","a","b","orderA","order","orderB","unshift","firstChild","element","Navigate","to","replace"],"mappings":"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"}
@@ -2,4 +2,4 @@ import type { RouteConfig } from '../../../types';
2
2
  import { type RouteObject } from 'react-router-dom';
3
3
  import type { TransformRoutesResult } from '../../transform';
4
4
  import type { ComponentImport } from '../../../types';
5
- export declare const transformRoutesToReactRoutes: (routes: RouteConfig[], transformResult: TransformRoutesResult, defaultRouteErrorComponent?: ComponentImport, defaultRouteLoadingComponent?: ComponentImport) => Promise<RouteObject[]>;
5
+ export declare const transformRoutesToReactRoutes: (routes: RouteConfig[], transformResult: TransformRoutesResult, defaultRouteErrorComponent?: ComponentImport, defaultRouteLoadingComponent?: ComponentImport, enableHydrateFallback?: boolean) => Promise<RouteObject[]>;
@@ -12,7 +12,7 @@ function DefaultRouteHydrateFallback() {
12
12
  children: "Loading..."
13
13
  });
14
14
  }
15
- export const transformRoutesToReactRoutes = async (routes, transformResult, defaultRouteErrorComponent, defaultRouteLoadingComponent)=>{
15
+ export const transformRoutesToReactRoutes = async (routes, transformResult, defaultRouteErrorComponent, defaultRouteLoadingComponent, enableHydrateFallback = false)=>{
16
16
  /**
17
17
  * 批量处理路由
18
18
  * @param routes 路由组
@@ -148,28 +148,31 @@ export const transformRoutesToReactRoutes = async (routes, transformResult, defa
148
148
  }
149
149
  const reactRoute = {
150
150
  children: [],
151
- hydrateFallbackElement: /*#__PURE__*/ _jsx(DefaultRouteHydrateFallback, {}),
152
151
  id: name,
153
152
  handle: getHandle(),
154
153
  lazy: async ()=>{
155
154
  const ErrorBoundary = await getErrorComponent();
156
155
  const config = await getConfig();
157
156
  const LoadingComponent = await getLoadingComponent();
157
+ const HydrateFallback = LoadingComponent?.default ?? DefaultRouteHydrateFallback;
158
158
  // 如果配置为空,确保至少返回一个空对象,避免展开 undefined
159
159
  if (!config) {
160
160
  return {
161
161
  ErrorBoundary: ErrorBoundary?.default,
162
- HydrateFallback: LoadingComponent?.default
162
+ HydrateFallback
163
163
  };
164
164
  }
165
165
  return {
166
166
  ErrorBoundary: ErrorBoundary?.default,
167
- HydrateFallback: LoadingComponent?.default,
167
+ HydrateFallback,
168
168
  ...config
169
169
  };
170
170
  },
171
171
  path
172
172
  };
173
+ if (enableHydrateFallback) {
174
+ reactRoute.hydrateFallbackElement = /*#__PURE__*/ _jsx(DefaultRouteHydrateFallback, {});
175
+ }
173
176
  // 处理子路由
174
177
  if (children?.length) {
175
178
  reactRoute.children = children.flatMap((child)=>transformRouteToReactRoute(child)).sort((a, b)=>{
@@ -184,9 +187,10 @@ export const transformRoutesToReactRoutes = async (routes, transformResult, defa
184
187
  lazy: async ()=>{
185
188
  const ErrorBoundary = await getErrorComponent();
186
189
  const LoadingComponent = await getLoadingComponent();
190
+ const HydrateFallback = LoadingComponent?.default ?? DefaultRouteHydrateFallback;
187
191
  return {
188
192
  ErrorBoundary: ErrorBoundary?.default,
189
- HydrateFallback: LoadingComponent?.default,
193
+ HydrateFallback,
190
194
  ...await getConfig(true)
191
195
  };
192
196
  }
@@ -216,9 +220,10 @@ export const transformRoutesToReactRoutes = async (routes, transformResult, defa
216
220
  lazy: async ()=>{
217
221
  const ErrorBoundary = await getErrorComponent();
218
222
  const LoadingComponent = await getLoadingComponent();
223
+ const HydrateFallback = LoadingComponent?.default ?? DefaultRouteHydrateFallback;
219
224
  return {
220
225
  ErrorBoundary: ErrorBoundary?.default,
221
- HydrateFallback: LoadingComponent?.default,
226
+ HydrateFallback,
222
227
  ...await getConfig(true)
223
228
  };
224
229
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../../src/core/router/utils/adapters/react-router/transform.tsx"],"sourcesContent":["import type { RouteConfig } from '../../../types';\nimport {\n type RouteObject,\n Navigate\n} from 'react-router-dom';\nimport type { TransformRoutesResult } from '../../transform';\nimport { RouteErrorBoundary } from './RouteErrorBoundary';\nimport type { ComponentImport } from '../../../types';\nimport { logger } from '../../../../../utils';\n\nfunction DefaultRouteHydrateFallback() {\n return (\n <div style={{ padding: 16, textAlign: 'center', color: '#5f6c7b' }}>\n Loading...\n </div>\n );\n}\n\nexport const transformRoutesToReactRoutes = async (\n routes: RouteConfig[], \n transformResult: TransformRoutesResult,\n defaultRouteErrorComponent?: ComponentImport,\n defaultRouteLoadingComponent?: ComponentImport,\n): Promise<RouteObject[]> => {\n\n /**\n * 批量处理路由\n * @param routes 路由组\n */\n function transformRouteToReactRoutes(routes: RouteConfig[]) {\n return routes.flatMap((route: RouteConfig) => transformRouteToReactRoute(route))\n }\n\n /**\n * 处理单个路由\n * @param route 路由\n */\n function transformRouteToReactRoute(route: RouteConfig): RouteObject {\n const {\n isGroup = false,\n enableRedirection = false,\n name,\n path,\n handle,\n children,\n page,\n layout,\n error,\n errors,\n loading,\n } = route;\n const routeError = error ?? errors;\n\n // 获取错误组件\n async function getErrorComponent() {\n // 如果 error/errors 是函数,直接使用\n if (typeof routeError === 'function') {\n return routeError();\n }\n\n const errorsMap = transformResult.errors;\n\n // 判断 error/errors 是否为 string 且不是空字符串\n if (typeof routeError === 'string' && routeError !== '') {\n // 使用 routeError 作为 key 获取 transformResult.errors 的值\n const errorResolver = errorsMap.get(routeError);\n\n // 如果获取不到,返回 null\n if (!errorResolver) {\n return null;\n }\n\n // 如果获取到,返回对应的值(调用动态导入函数)\n if (typeof errorResolver === 'function') {\n return errorResolver();\n }\n\n return null;\n }\n\n // 如果 errors 为空,使用配置的默认错误组件或内置的 RouteErrorBoundary 组件\n if (defaultRouteErrorComponent) {\n // 如果配置了默认错误组件,使用配置的组件\n return defaultRouteErrorComponent();\n }\n\n // 如果没有配置默认错误组件,使用内置的 RouteErrorBoundary 组件\n // 直接导入而非懒加载,因为:\n // 1. RouteErrorBoundary 是框架核心组件,体积小\n // 2. 错误边界需要快速响应,直接导入速度更快\n // 3. 作为基础设施组件,应该保证可用性\n return { default: RouteErrorBoundary };\n }\n\n // 获取转换配置\n function convertConfig(m: any) {\n if (!m) {\n return null;\n }\n const { action, loader, shouldRevalidate, default: Component } = m;\n\n // 如果 Component 不存在,记录警告\n if (!Component) {\n logger.warn(`路由组件未找到 default 导出: ${name}`, m);\n }\n\n return {\n action, // always use action\n loader, // always use loader\n shouldRevalidate,\n Component\n };\n }\n\n // 获取加载组件\n async function getLoadingComponent() {\n if (typeof loading === 'function') {\n return loading();\n }\n\n if (typeof loading === 'string' && loading !== '') {\n const loadingResolver = transformResult.loadings.get(loading);\n if (typeof loadingResolver === 'function') {\n return loadingResolver();\n }\n }\n\n if (defaultRouteLoadingComponent) {\n return defaultRouteLoadingComponent();\n }\n\n return null;\n }\n\n // 获取配置\n async function getConfig(index: boolean = false) {\n // 如果有layout和不是index,返回布局配置\n if (layout && !index) {\n // 如果 layout 是函数,直接使用\n if (typeof layout === 'function') {\n const config = await layout();\n return convertConfig(config);\n }\n\n // 如果 layout 是字符串,从 Map 中获取\n if (typeof layout === 'string') {\n const layoutResolver = transformResult.layouts.get(layout);\n if (!layoutResolver) {\n throw new Error(`未找到名为 ${layout} 的布局组件`);\n }\n const config = await layoutResolver();\n return convertConfig(config);\n }\n }\n\n let pageName = name;\n\n // 如果是notFound则转成404\n if (pageName === 'notFound') {\n pageName = '404'\n }\n\n if (page && (!children?.length || index)) {\n // 如果 page 是函数,直接使用\n if (typeof page === 'function') {\n const config = await page();\n return convertConfig(config);\n }\n\n // 如果 page 是字符串,从 Map 中获取\n if (typeof page === 'string') {\n const viewResolver = transformResult.pages.get(page);\n if (!viewResolver) {\n throw new Error(`未找到名为 ${page} 的页面组件`);\n }\n const config = await viewResolver();\n return convertConfig(config);\n }\n }\n\n return null;\n }\n\n // 获取处理信息,即额外的配置信息\n function getHandle(index: boolean = false) {\n if ((layout || isGroup) && !index) {\n return null\n }\n return {\n ...handle,\n name,\n path\n }\n }\n\n\n const reactRoute: RouteObject = {\n children: [],\n hydrateFallbackElement: <DefaultRouteHydrateFallback />,\n id: name,\n handle: getHandle(),\n lazy: async () => {\n const ErrorBoundary = await getErrorComponent();\n const config = await getConfig();\n const LoadingComponent = await getLoadingComponent();\n\n // 如果配置为空,确保至少返回一个空对象,避免展开 undefined\n if (!config) {\n return {\n ErrorBoundary: ErrorBoundary?.default,\n HydrateFallback: LoadingComponent?.default,\n };\n }\n\n return {\n ErrorBoundary: ErrorBoundary?.default,\n HydrateFallback: LoadingComponent?.default,\n ...config\n };\n },\n path\n };\n\n // 处理子路由\n if (children?.length) {\n reactRoute.children = children.flatMap(child => transformRouteToReactRoute(child)).sort((a, b) => {\n const orderA = a.handle?.order ?? 99;\n const orderB = b.handle?.order ?? 99;\n return orderA - orderB;\n });\n\n if (page && !isGroup) {\n reactRoute.children.unshift({\n handle: getHandle(true),\n index: true,\n lazy: async () => {\n const ErrorBoundary = await getErrorComponent();\n const LoadingComponent = await getLoadingComponent();\n return {\n ErrorBoundary: ErrorBoundary?.default,\n HydrateFallback: LoadingComponent?.default,\n ...(await getConfig(true))\n };\n }\n });\n }\n\n if (enableRedirection && isGroup) {\n const [firstChild] = reactRoute.children;\n if (firstChild?.path) {\n reactRoute.children.unshift({\n index: true,\n handle: getHandle(true),\n element: <Navigate to={firstChild.path as string} replace />\n });\n }\n }\n\n }\n // 若存在 layout 且没有子路由,但同时声明了 page,则自动生成 index 子路由以渲染页面\n // 场景:/test 使用自定义 layout,且没有 children 时仍应渲染 page\n if ((!children || children.length === 0) && layout && page && !isGroup) {\n reactRoute.children = [{\n handle: getHandle(true),\n index: true,\n lazy: async () => {\n const ErrorBoundary = await getErrorComponent();\n const LoadingComponent = await getLoadingComponent();\n return {\n ErrorBoundary: ErrorBoundary?.default,\n HydrateFallback: LoadingComponent?.default,\n ...(await getConfig(true))\n };\n }\n }];\n }\n\n return reactRoute;\n }\n\n return transformRouteToReactRoutes(routes);\n}\n"],"names":["Navigate","RouteErrorBoundary","logger","DefaultRouteHydrateFallback","div","style","padding","textAlign","color","transformRoutesToReactRoutes","routes","transformResult","defaultRouteErrorComponent","defaultRouteLoadingComponent","transformRouteToReactRoutes","flatMap","route","transformRouteToReactRoute","isGroup","enableRedirection","name","path","handle","children","page","layout","error","errors","loading","routeError","getErrorComponent","errorsMap","errorResolver","get","default","convertConfig","m","action","loader","shouldRevalidate","Component","warn","getLoadingComponent","loadingResolver","loadings","getConfig","index","config","layoutResolver","layouts","Error","pageName","length","viewResolver","pages","getHandle","reactRoute","hydrateFallbackElement","id","lazy","ErrorBoundary","LoadingComponent","HydrateFallback","child","sort","a","b","orderA","order","orderB","unshift","firstChild","element","to","replace"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../../../../src/core/router/utils/adapters/react-router/transform.tsx"],"sourcesContent":["import type { RouteConfig } from '../../../types';\nimport {\n type RouteObject,\n Navigate\n} from 'react-router-dom';\nimport type { TransformRoutesResult } from '../../transform';\nimport { RouteErrorBoundary } from './RouteErrorBoundary';\nimport type { ComponentImport } from '../../../types';\nimport { logger } from '../../../../../utils';\n\nfunction DefaultRouteHydrateFallback() {\n return (\n <div style={{ padding: 16, textAlign: 'center', color: '#5f6c7b' }}>\n Loading...\n </div>\n );\n}\n\nexport const transformRoutesToReactRoutes = async (\n routes: RouteConfig[], \n transformResult: TransformRoutesResult,\n defaultRouteErrorComponent?: ComponentImport,\n defaultRouteLoadingComponent?: ComponentImport,\n enableHydrateFallback: boolean = false,\n): Promise<RouteObject[]> => {\n\n /**\n * 批量处理路由\n * @param routes 路由组\n */\n function transformRouteToReactRoutes(routes: RouteConfig[]) {\n return routes.flatMap((route: RouteConfig) => transformRouteToReactRoute(route))\n }\n\n /**\n * 处理单个路由\n * @param route 路由\n */\n function transformRouteToReactRoute(route: RouteConfig): RouteObject {\n const {\n isGroup = false,\n enableRedirection = false,\n name,\n path,\n handle,\n children,\n page,\n layout,\n error,\n errors,\n loading,\n } = route;\n const routeError = error ?? errors;\n\n // 获取错误组件\n async function getErrorComponent() {\n // 如果 error/errors 是函数,直接使用\n if (typeof routeError === 'function') {\n return routeError();\n }\n\n const errorsMap = transformResult.errors;\n\n // 判断 error/errors 是否为 string 且不是空字符串\n if (typeof routeError === 'string' && routeError !== '') {\n // 使用 routeError 作为 key 获取 transformResult.errors 的值\n const errorResolver = errorsMap.get(routeError);\n\n // 如果获取不到,返回 null\n if (!errorResolver) {\n return null;\n }\n\n // 如果获取到,返回对应的值(调用动态导入函数)\n if (typeof errorResolver === 'function') {\n return errorResolver();\n }\n\n return null;\n }\n\n // 如果 errors 为空,使用配置的默认错误组件或内置的 RouteErrorBoundary 组件\n if (defaultRouteErrorComponent) {\n // 如果配置了默认错误组件,使用配置的组件\n return defaultRouteErrorComponent();\n }\n\n // 如果没有配置默认错误组件,使用内置的 RouteErrorBoundary 组件\n // 直接导入而非懒加载,因为:\n // 1. RouteErrorBoundary 是框架核心组件,体积小\n // 2. 错误边界需要快速响应,直接导入速度更快\n // 3. 作为基础设施组件,应该保证可用性\n return { default: RouteErrorBoundary };\n }\n\n // 获取转换配置\n function convertConfig(m: any) {\n if (!m) {\n return null;\n }\n const { action, loader, shouldRevalidate, default: Component } = m;\n\n // 如果 Component 不存在,记录警告\n if (!Component) {\n logger.warn(`路由组件未找到 default 导出: ${name}`, m);\n }\n\n return {\n action, // always use action\n loader, // always use loader\n shouldRevalidate,\n Component\n };\n }\n\n // 获取加载组件\n async function getLoadingComponent() {\n if (typeof loading === 'function') {\n return loading();\n }\n\n if (typeof loading === 'string' && loading !== '') {\n const loadingResolver = transformResult.loadings.get(loading);\n if (typeof loadingResolver === 'function') {\n return loadingResolver();\n }\n }\n\n if (defaultRouteLoadingComponent) {\n return defaultRouteLoadingComponent();\n }\n\n return null;\n }\n\n // 获取配置\n async function getConfig(index: boolean = false) {\n // 如果有layout和不是index,返回布局配置\n if (layout && !index) {\n // 如果 layout 是函数,直接使用\n if (typeof layout === 'function') {\n const config = await layout();\n return convertConfig(config);\n }\n\n // 如果 layout 是字符串,从 Map 中获取\n if (typeof layout === 'string') {\n const layoutResolver = transformResult.layouts.get(layout);\n if (!layoutResolver) {\n throw new Error(`未找到名为 ${layout} 的布局组件`);\n }\n const config = await layoutResolver();\n return convertConfig(config);\n }\n }\n\n let pageName = name;\n\n // 如果是notFound则转成404\n if (pageName === 'notFound') {\n pageName = '404'\n }\n\n if (page && (!children?.length || index)) {\n // 如果 page 是函数,直接使用\n if (typeof page === 'function') {\n const config = await page();\n return convertConfig(config);\n }\n\n // 如果 page 是字符串,从 Map 中获取\n if (typeof page === 'string') {\n const viewResolver = transformResult.pages.get(page);\n if (!viewResolver) {\n throw new Error(`未找到名为 ${page} 的页面组件`);\n }\n const config = await viewResolver();\n return convertConfig(config);\n }\n }\n\n return null;\n }\n\n // 获取处理信息,即额外的配置信息\n function getHandle(index: boolean = false) {\n if ((layout || isGroup) && !index) {\n return null\n }\n return {\n ...handle,\n name,\n path\n }\n }\n\n\n const reactRoute: RouteObject = {\n children: [],\n id: name,\n handle: getHandle(),\n lazy: async () => {\n const ErrorBoundary = await getErrorComponent();\n const config = await getConfig();\n const LoadingComponent = await getLoadingComponent();\n const HydrateFallback = LoadingComponent?.default ?? DefaultRouteHydrateFallback;\n\n // 如果配置为空,确保至少返回一个空对象,避免展开 undefined\n if (!config) {\n return {\n ErrorBoundary: ErrorBoundary?.default,\n HydrateFallback,\n };\n }\n\n return {\n ErrorBoundary: ErrorBoundary?.default,\n HydrateFallback,\n ...config\n };\n },\n path\n };\n\n if (enableHydrateFallback) {\n reactRoute.hydrateFallbackElement = <DefaultRouteHydrateFallback />;\n }\n\n // 处理子路由\n if (children?.length) {\n reactRoute.children = children.flatMap(child => transformRouteToReactRoute(child)).sort((a, b) => {\n const orderA = a.handle?.order ?? 99;\n const orderB = b.handle?.order ?? 99;\n return orderA - orderB;\n });\n\n if (page && !isGroup) {\n reactRoute.children.unshift({\n handle: getHandle(true),\n index: true,\n lazy: async () => {\n const ErrorBoundary = await getErrorComponent();\n const LoadingComponent = await getLoadingComponent();\n const HydrateFallback = LoadingComponent?.default ?? DefaultRouteHydrateFallback;\n return {\n ErrorBoundary: ErrorBoundary?.default,\n HydrateFallback,\n ...(await getConfig(true))\n };\n }\n });\n }\n\n if (enableRedirection && isGroup) {\n const [firstChild] = reactRoute.children;\n if (firstChild?.path) {\n reactRoute.children.unshift({\n index: true,\n handle: getHandle(true),\n element: <Navigate to={firstChild.path as string} replace />\n });\n }\n }\n\n }\n // 若存在 layout 且没有子路由,但同时声明了 page,则自动生成 index 子路由以渲染页面\n // 场景:/test 使用自定义 layout,且没有 children 时仍应渲染 page\n if ((!children || children.length === 0) && layout && page && !isGroup) {\n reactRoute.children = [{\n handle: getHandle(true),\n index: true,\n lazy: async () => {\n const ErrorBoundary = await getErrorComponent();\n const LoadingComponent = await getLoadingComponent();\n const HydrateFallback = LoadingComponent?.default ?? DefaultRouteHydrateFallback;\n return {\n ErrorBoundary: ErrorBoundary?.default,\n HydrateFallback,\n ...(await getConfig(true))\n };\n }\n }];\n }\n\n return reactRoute;\n }\n\n return transformRouteToReactRoutes(routes);\n}\n"],"names":["Navigate","RouteErrorBoundary","logger","DefaultRouteHydrateFallback","div","style","padding","textAlign","color","transformRoutesToReactRoutes","routes","transformResult","defaultRouteErrorComponent","defaultRouteLoadingComponent","enableHydrateFallback","transformRouteToReactRoutes","flatMap","route","transformRouteToReactRoute","isGroup","enableRedirection","name","path","handle","children","page","layout","error","errors","loading","routeError","getErrorComponent","errorsMap","errorResolver","get","default","convertConfig","m","action","loader","shouldRevalidate","Component","warn","getLoadingComponent","loadingResolver","loadings","getConfig","index","config","layoutResolver","layouts","Error","pageName","length","viewResolver","pages","getHandle","reactRoute","id","lazy","ErrorBoundary","LoadingComponent","HydrateFallback","hydrateFallbackElement","child","sort","a","b","orderA","order","orderB","unshift","firstChild","element","to","replace"],"mappings":"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"}
@@ -55,6 +55,7 @@ export declare class RouterConfigValidator {
55
55
  priorityThreshold?: number | undefined;
56
56
  timeout?: number | undefined;
57
57
  } | undefined;
58
+ enableHydrateFallback?: boolean | undefined;
58
59
  };
59
60
  /**
60
61
  * 安全验证路由配置(不抛出异常)
@@ -103,6 +104,7 @@ export declare class RouterConfigValidator {
103
104
  priorityThreshold?: number | undefined;
104
105
  timeout?: number | undefined;
105
106
  } | undefined;
107
+ enableHydrateFallback?: boolean | undefined;
106
108
  }>;
107
109
  /**
108
110
  * 验证路由配置并提供修复建议
@@ -120,7 +120,8 @@ const routerConfigSchema = _zod.z.object({
120
120
  delay: _zod.z.number().int().positive().optional(),
121
121
  priorityThreshold: _zod.z.number().int().nonnegative().optional(),
122
122
  timeout: _zod.z.number().int().positive().optional()
123
- }).optional()
123
+ }).optional(),
124
+ enableHydrateFallback: _zod.z.boolean().optional()
124
125
  }).superRefine((config, ctx)=>{
125
126
  if (!Array.isArray(config.routes)) {
126
127
  return;