@vlian/framework 1.2.1 → 1.2.18

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 (456) hide show
  1. package/dist/analytics/index.cjs +24 -0
  2. package/dist/analytics/index.cjs.map +1 -0
  3. package/dist/analytics/index.d.ts +2 -0
  4. package/dist/analytics/index.js +3 -0
  5. package/dist/analytics/index.js.map +1 -0
  6. package/dist/analytics.umd.js +2406 -0
  7. package/dist/analytics.umd.js.map +1 -0
  8. package/dist/components/LocaleSwitch.cjs +118 -0
  9. package/dist/components/LocaleSwitch.cjs.map +1 -0
  10. package/dist/components/LocaleSwitch.d.ts +21 -0
  11. package/dist/components/LocaleSwitch.js +103 -0
  12. package/dist/components/LocaleSwitch.js.map +1 -0
  13. package/dist/components/ThemeSwitch.cjs +117 -0
  14. package/dist/components/ThemeSwitch.cjs.map +1 -0
  15. package/dist/components/ThemeSwitch.d.ts +20 -0
  16. package/dist/components/ThemeSwitch.js +102 -0
  17. package/dist/components/ThemeSwitch.js.map +1 -0
  18. package/dist/components/index.cjs +16 -0
  19. package/dist/components/index.cjs.map +1 -1
  20. package/dist/components/index.d.ts +5 -2
  21. package/dist/components/index.js +2 -1
  22. package/dist/components/index.js.map +1 -1
  23. package/dist/components/persistence.cjs +60 -0
  24. package/dist/components/persistence.cjs.map +1 -0
  25. package/dist/components/persistence.d.ts +12 -0
  26. package/dist/components/persistence.js +39 -0
  27. package/dist/components/persistence.js.map +1 -0
  28. package/dist/core/Test.d.ts +0 -1
  29. package/dist/core/app/AppContext.cjs +36 -30
  30. package/dist/core/app/AppContext.cjs.map +1 -1
  31. package/dist/core/app/AppContext.d.ts +9 -6
  32. package/dist/core/app/AppContext.js +36 -30
  33. package/dist/core/app/AppContext.js.map +1 -1
  34. package/dist/core/app/AppContext.types.d.ts +9 -10
  35. package/dist/core/app/AppContext.types.js.map +1 -1
  36. package/dist/core/app/BasicLayout.cjs +57 -22
  37. package/dist/core/app/BasicLayout.cjs.map +1 -1
  38. package/dist/core/app/BasicLayout.d.ts +7 -5
  39. package/dist/core/app/BasicLayout.js +57 -22
  40. package/dist/core/app/BasicLayout.js.map +1 -1
  41. package/dist/core/app/DefaultApp.cjs +104 -153
  42. package/dist/core/app/DefaultApp.cjs.map +1 -1
  43. package/dist/core/app/DefaultApp.d.ts +0 -21
  44. package/dist/core/app/DefaultApp.js +104 -153
  45. package/dist/core/app/DefaultApp.js.map +1 -1
  46. package/dist/core/app/index.d.ts +0 -1
  47. package/dist/core/config/AppConfig.cjs.map +1 -1
  48. package/dist/core/config/AppConfig.d.ts +3 -4
  49. package/dist/core/config/AppConfig.js.map +1 -1
  50. package/dist/core/config/ConfigLoader.d.ts +0 -1
  51. package/dist/core/config/ConfigValidator.d.ts +0 -1
  52. package/dist/core/config/index.d.ts +0 -1
  53. package/dist/core/dev/DevTools.cjs +141 -287
  54. package/dist/core/dev/DevTools.cjs.map +1 -1
  55. package/dist/core/dev/DevTools.d.ts +1 -32
  56. package/dist/core/dev/DevTools.js +143 -296
  57. package/dist/core/dev/DevTools.js.map +1 -1
  58. package/dist/core/error/ErrorBoundary.cjs +72 -14
  59. package/dist/core/error/ErrorBoundary.cjs.map +1 -1
  60. package/dist/core/error/ErrorBoundary.d.ts +7 -9
  61. package/dist/core/error/ErrorBoundary.js +73 -15
  62. package/dist/core/error/ErrorBoundary.js.map +1 -1
  63. package/dist/core/error/ErrorHandler.d.ts +0 -1
  64. package/dist/core/error/index.d.ts +0 -1
  65. package/dist/core/event/AppEventBus.d.ts +0 -1
  66. package/dist/core/event/frameworkEvents.d.ts +0 -1
  67. package/dist/core/event/hooks.d.ts +0 -1
  68. package/dist/core/event/index.d.ts +0 -1
  69. package/dist/core/event/types.d.ts +0 -1
  70. package/dist/core/event/useEventBus.d.ts +0 -1
  71. package/dist/core/index.cjs +2 -0
  72. package/dist/core/index.cjs.map +1 -1
  73. package/dist/core/index.d.ts +2 -1
  74. package/dist/core/index.js +2 -0
  75. package/dist/core/index.js.map +1 -1
  76. package/dist/core/initialization/InitializationErrorThrower.d.ts +0 -1
  77. package/dist/core/initialization/index.d.ts +0 -1
  78. package/dist/core/initialization/initialization.d.ts +0 -1
  79. package/dist/core/initialization/initializationErrorState.d.ts +0 -1
  80. package/dist/core/kernel/defaultAdapters.cjs +185 -0
  81. package/dist/core/kernel/defaultAdapters.cjs.map +1 -0
  82. package/dist/core/kernel/defaultAdapters.d.ts +2 -0
  83. package/dist/core/kernel/defaultAdapters.js +175 -0
  84. package/dist/core/kernel/defaultAdapters.js.map +1 -0
  85. package/dist/core/kernel/errors.cjs +71 -0
  86. package/dist/core/kernel/errors.cjs.map +1 -0
  87. package/dist/core/kernel/errors.d.ts +18 -0
  88. package/dist/core/kernel/errors.js +53 -0
  89. package/dist/core/kernel/errors.js.map +1 -0
  90. package/dist/core/kernel/index.cjs +22 -0
  91. package/dist/core/kernel/index.cjs.map +1 -0
  92. package/dist/core/kernel/index.d.ts +3 -0
  93. package/dist/core/kernel/index.js +4 -0
  94. package/dist/core/kernel/index.js.map +1 -0
  95. package/dist/core/kernel/startKernel.cjs +203 -0
  96. package/dist/core/kernel/startKernel.cjs.map +1 -0
  97. package/dist/core/kernel/startKernel.d.ts +2 -0
  98. package/dist/core/kernel/startKernel.js +193 -0
  99. package/dist/core/kernel/startKernel.js.map +1 -0
  100. package/dist/core/kernel/types.cjs +6 -0
  101. package/dist/core/kernel/types.cjs.map +1 -0
  102. package/dist/core/kernel/types.d.ts +114 -0
  103. package/dist/core/kernel/types.js +3 -0
  104. package/dist/core/kernel/types.js.map +1 -0
  105. package/dist/core/middleware.d.ts +0 -1
  106. package/dist/core/plugin/PluginEventBus.d.ts +0 -1
  107. package/dist/core/plugin/PluginSandbox.d.ts +0 -1
  108. package/dist/core/plugin.cjs +1 -1
  109. package/dist/core/plugin.cjs.map +1 -1
  110. package/dist/core/plugin.d.ts +0 -1
  111. package/dist/core/plugin.js +1 -1
  112. package/dist/core/plugin.js.map +1 -1
  113. package/dist/core/router/RouterManager.cjs +32 -2
  114. package/dist/core/router/RouterManager.cjs.map +1 -1
  115. package/dist/core/router/RouterManager.d.ts +5 -1
  116. package/dist/core/router/RouterManager.js +33 -3
  117. package/dist/core/router/RouterManager.js.map +1 -1
  118. package/dist/core/router/adapter/AdapterManager.d.ts +0 -1
  119. package/dist/core/router/adapter/index.d.ts +0 -1
  120. package/dist/core/router/adapter/react-router/ReactRouterAdapter.cjs.map +1 -1
  121. package/dist/core/router/adapter/react-router/ReactRouterAdapter.d.ts +0 -1
  122. package/dist/core/router/adapter/react-router/ReactRouterAdapter.js.map +1 -1
  123. package/dist/core/router/adapter/react-router/index.d.ts +0 -1
  124. package/dist/core/router/adapter/types.cjs.map +1 -1
  125. package/dist/core/router/adapter/types.d.ts +1 -2
  126. package/dist/core/router/adapter/types.js.map +1 -1
  127. package/dist/core/router/dev/RouterDevTools.cjs +148 -296
  128. package/dist/core/router/dev/RouterDevTools.cjs.map +1 -1
  129. package/dist/core/router/dev/RouterDevTools.d.ts +1 -6
  130. package/dist/core/router/dev/RouterDevTools.js +149 -301
  131. package/dist/core/router/dev/RouterDevTools.js.map +1 -1
  132. package/dist/core/router/dev/index.d.ts +0 -1
  133. package/dist/core/router/dynamic/DynamicRouteManager.d.ts +0 -1
  134. package/dist/core/router/dynamic/index.d.ts +0 -1
  135. package/dist/core/router/errors/RouterError.d.ts +0 -1
  136. package/dist/core/router/errors/index.d.ts +0 -1
  137. package/dist/core/router/index.d.ts +0 -1
  138. package/dist/core/router/lifecycle/RouterLifecycleManager.d.ts +0 -1
  139. package/dist/core/router/lifecycle/index.d.ts +0 -1
  140. package/dist/core/router/middleware/RouterMiddlewareManager.cjs +24 -4
  141. package/dist/core/router/middleware/RouterMiddlewareManager.cjs.map +1 -1
  142. package/dist/core/router/middleware/RouterMiddlewareManager.d.ts +1 -1
  143. package/dist/core/router/middleware/RouterMiddlewareManager.js +24 -4
  144. package/dist/core/router/middleware/RouterMiddlewareManager.js.map +1 -1
  145. package/dist/core/router/middleware/auth.d.ts +0 -1
  146. package/dist/core/router/middleware/index.d.ts +0 -1
  147. package/dist/core/router/middleware/types.cjs.map +1 -1
  148. package/dist/core/router/middleware/types.d.ts +1 -2
  149. package/dist/core/router/middleware/types.js.map +1 -1
  150. package/dist/core/router/monitoring/RouterMonitoring.d.ts +0 -1
  151. package/dist/core/router/monitoring/index.d.ts +0 -1
  152. package/dist/core/router/navigation/RouterNavigation.cjs +69 -14
  153. package/dist/core/router/navigation/RouterNavigation.cjs.map +1 -1
  154. package/dist/core/router/navigation/RouterNavigation.d.ts +3 -1
  155. package/dist/core/router/navigation/RouterNavigation.js +69 -14
  156. package/dist/core/router/navigation/RouterNavigation.js.map +1 -1
  157. package/dist/core/router/navigation/index.d.ts +0 -1
  158. package/dist/core/router/performance/RouteCache.cjs +34 -13
  159. package/dist/core/router/performance/RouteCache.cjs.map +1 -1
  160. package/dist/core/router/performance/RouteCache.d.ts +8 -3
  161. package/dist/core/router/performance/RouteCache.js +34 -13
  162. package/dist/core/router/performance/RouteCache.js.map +1 -1
  163. package/dist/core/router/performance/RoutePreloader.cjs +89 -22
  164. package/dist/core/router/performance/RoutePreloader.cjs.map +1 -1
  165. package/dist/core/router/performance/RoutePreloader.d.ts +9 -2
  166. package/dist/core/router/performance/RoutePreloader.js +89 -22
  167. package/dist/core/router/performance/RoutePreloader.js.map +1 -1
  168. package/dist/core/router/performance/index.d.ts +0 -1
  169. package/dist/core/router/plugin/RouterPluginManager.d.ts +0 -1
  170. package/dist/core/router/plugin/index.d.ts +0 -1
  171. package/dist/core/router/plugin/types.d.ts +0 -1
  172. package/dist/core/router/types.d.ts +23 -7
  173. package/dist/core/router/types.js.map +1 -1
  174. package/dist/core/router/utils/adapters/react-router/RouteErrorBoundary.cjs +90 -103
  175. package/dist/core/router/utils/adapters/react-router/RouteErrorBoundary.cjs.map +1 -1
  176. package/dist/core/router/utils/adapters/react-router/RouteErrorBoundary.d.ts +0 -1
  177. package/dist/core/router/utils/adapters/react-router/RouteErrorBoundary.js +91 -104
  178. package/dist/core/router/utils/adapters/react-router/RouteErrorBoundary.js.map +1 -1
  179. package/dist/core/router/utils/adapters/react-router/transform.cjs +45 -63
  180. package/dist/core/router/utils/adapters/react-router/transform.cjs.map +1 -1
  181. package/dist/core/router/utils/adapters/react-router/transform.d.ts +0 -1
  182. package/dist/core/router/utils/adapters/react-router/transform.js +46 -59
  183. package/dist/core/router/utils/adapters/react-router/transform.js.map +1 -1
  184. package/dist/core/router/utils/transform.cjs +80 -71
  185. package/dist/core/router/utils/transform.cjs.map +1 -1
  186. package/dist/core/router/utils/transform.d.ts +1 -2
  187. package/dist/core/router/utils/transform.js +81 -72
  188. package/dist/core/router/utils/transform.js.map +1 -1
  189. package/dist/core/router/validation/RouterConfigValidator.d.ts +66 -5
  190. package/dist/core/router/validation/index.d.ts +0 -1
  191. package/dist/core/router/validation/schema.cjs +71 -2
  192. package/dist/core/router/validation/schema.cjs.map +1 -1
  193. package/dist/core/router/validation/schema.d.ts +102 -7
  194. package/dist/core/router/validation/schema.js +71 -2
  195. package/dist/core/router/validation/schema.js.map +1 -1
  196. package/dist/core/router/version/RouteVersionManager.d.ts +0 -1
  197. package/dist/core/router/version/index.d.ts +0 -1
  198. package/dist/core/splash/SplashScreen.cjs +101 -15
  199. package/dist/core/splash/SplashScreen.cjs.map +1 -1
  200. package/dist/core/splash/SplashScreen.d.ts +0 -1
  201. package/dist/core/splash/SplashScreen.js +101 -15
  202. package/dist/core/splash/SplashScreen.js.map +1 -1
  203. package/dist/core/splash/index.d.ts +0 -1
  204. package/dist/core/splash/splashScreenUtils.d.ts +0 -1
  205. package/dist/core/startup/AppInstance.d.ts +0 -1
  206. package/dist/core/startup/environment.d.ts +0 -1
  207. package/dist/core/startup/index.d.ts +0 -1
  208. package/dist/core/startup/initializeServices.d.ts +0 -1
  209. package/dist/core/startup/performanceTracker.d.ts +0 -1
  210. package/dist/core/startup/renderApp.cjs +12 -10
  211. package/dist/core/startup/renderApp.cjs.map +1 -1
  212. package/dist/core/startup/renderApp.d.ts +0 -1
  213. package/dist/core/startup/renderApp.js +12 -10
  214. package/dist/core/startup/renderApp.js.map +1 -1
  215. package/dist/core/startup/startApp.cjs +118 -13
  216. package/dist/core/startup/startApp.cjs.map +1 -1
  217. package/dist/core/startup/startApp.d.ts +0 -1
  218. package/dist/core/startup/startApp.js +118 -13
  219. package/dist/core/startup/startApp.js.map +1 -1
  220. package/dist/core/types.d.ts +34 -21
  221. package/dist/core/types.js.map +1 -1
  222. package/dist/core/ui-adapter/adapters.cjs +45 -0
  223. package/dist/core/ui-adapter/adapters.cjs.map +1 -0
  224. package/dist/core/ui-adapter/adapters.d.ts +4 -0
  225. package/dist/core/ui-adapter/adapters.js +27 -0
  226. package/dist/core/ui-adapter/adapters.js.map +1 -0
  227. package/dist/core/ui-adapter/index.cjs +21 -0
  228. package/dist/core/ui-adapter/index.cjs.map +1 -0
  229. package/dist/core/ui-adapter/index.d.ts +2 -0
  230. package/dist/core/ui-adapter/index.js +3 -0
  231. package/dist/core/ui-adapter/index.js.map +1 -0
  232. package/dist/core/ui-adapter/types.cjs +6 -0
  233. package/dist/core/ui-adapter/types.cjs.map +1 -0
  234. package/dist/core/ui-adapter/types.d.ts +24 -0
  235. package/dist/core/ui-adapter/types.js +3 -0
  236. package/dist/core/ui-adapter/types.js.map +1 -0
  237. package/dist/index.cjs +1 -0
  238. package/dist/index.cjs.map +1 -1
  239. package/dist/index.d.ts +1 -1
  240. package/dist/index.js +1 -0
  241. package/dist/index.js.map +1 -1
  242. package/dist/index.umd.d.ts +0 -1
  243. package/dist/index.umd.js +7684 -6056
  244. package/dist/index.umd.js.map +1 -1
  245. package/dist/library/index.d.ts +0 -1
  246. package/dist/library/locale/index.d.ts +0 -1
  247. package/dist/library/locale/langs/en-us/index.d.ts +0 -1
  248. package/dist/library/locale/langs/zh-cn/index.d.ts +0 -1
  249. package/dist/library/locale/types.d.ts +0 -1
  250. package/dist/library/storage/cache.d.ts +0 -1
  251. package/dist/library/storage/encryption.d.ts +0 -1
  252. package/dist/library/storage/index.d.ts +0 -1
  253. package/dist/request/adapter/RequestAdapter.d.ts +0 -1
  254. package/dist/request/adapter/axiosAdapter.d.ts +0 -1
  255. package/dist/request/adapter/fetchAdapter.d.ts +0 -1
  256. package/dist/request/adapter/index.d.ts +0 -1
  257. package/dist/request/adapter/kyAdapter.d.ts +0 -1
  258. package/dist/request/adapter/undiciAdapter.d.ts +0 -1
  259. package/dist/request/core/RequestClient.d.ts +0 -1
  260. package/dist/request/core/index.d.ts +0 -1
  261. package/dist/request/index.d.ts +0 -1
  262. package/dist/request/plugin/RequestPlugin.d.ts +0 -1
  263. package/dist/request/plugin/cache.d.ts +0 -1
  264. package/dist/request/plugin/csrfPlugin.d.ts +0 -1
  265. package/dist/request/plugin/index.d.ts +0 -1
  266. package/dist/request/plugin/monitoring.d.ts +0 -1
  267. package/dist/request/plugin/queue.d.ts +0 -1
  268. package/dist/request/plugin/retry.d.ts +0 -1
  269. package/dist/request/plugin/validation.d.ts +0 -1
  270. package/dist/request/runtime/RequestContext.d.ts +0 -1
  271. package/dist/request/runtime/index.d.ts +0 -1
  272. package/dist/request/types.d.ts +0 -1
  273. package/dist/request/utils/RequestQueueManager.d.ts +0 -1
  274. package/dist/request/utils/dependencyCheck.d.ts +0 -1
  275. package/dist/request/utils/index.d.ts +0 -1
  276. package/dist/request.umd.js +5392 -0
  277. package/dist/request.umd.js.map +1 -0
  278. package/dist/state/StateManager.d.ts +0 -1
  279. package/dist/state/adapters/AdapterFactory.d.ts +0 -1
  280. package/dist/state/adapters/DefaultAdapter.d.ts +0 -1
  281. package/dist/state/adapters/ReduxAdapter.d.ts +0 -1
  282. package/dist/state/adapters/ZustandAdapter.d.ts +0 -1
  283. package/dist/state/adapters/index.d.ts +0 -1
  284. package/dist/state/adapters/types.d.ts +0 -1
  285. package/dist/state/core/DerivedStateInstance.d.ts +0 -1
  286. package/dist/state/core/StateInstance.d.ts +0 -1
  287. package/dist/state/core/StateRegistry.d.ts +0 -1
  288. package/dist/state/core/StateScope.d.ts +0 -1
  289. package/dist/state/core/index.d.ts +0 -1
  290. package/dist/state/index.d.ts +0 -1
  291. package/dist/state/types.d.ts +0 -1
  292. package/dist/state.umd.js +1414 -0
  293. package/dist/state.umd.js.map +1 -0
  294. package/dist/types.d.ts +0 -1
  295. package/dist/utils/analytics.d.ts +0 -1
  296. package/dist/utils/configSecurity.d.ts +0 -1
  297. package/dist/utils/csrf.d.ts +0 -1
  298. package/dist/utils/errors/ErrorCodes.d.ts +0 -1
  299. package/dist/utils/errors.cjs +44 -1
  300. package/dist/utils/errors.cjs.map +1 -1
  301. package/dist/utils/errors.d.ts +5 -1
  302. package/dist/utils/errors.js +44 -1
  303. package/dist/utils/errors.js.map +1 -1
  304. package/dist/utils/index.d.ts +0 -1
  305. package/dist/utils/logger.d.ts +0 -1
  306. package/dist/utils/logger.types.d.ts +0 -1
  307. package/dist/utils/monitoring.d.ts +0 -1
  308. package/dist/utils/performance.d.ts +0 -1
  309. package/dist/utils/resourceLoader.d.ts +0 -1
  310. package/dist/utils/runtimeSecurity.d.ts +0 -1
  311. package/dist/utils/security.d.ts +0 -1
  312. package/dist/utils/traceId.d.ts +0 -1
  313. package/dist/utils/validation.d.ts +0 -1
  314. package/package.json +24 -9
  315. package/dist/components/index.d.ts.map +0 -1
  316. package/dist/core/Test.d.ts.map +0 -1
  317. package/dist/core/app/AppContext.d.ts.map +0 -1
  318. package/dist/core/app/AppContext.types.d.ts.map +0 -1
  319. package/dist/core/app/BasicLayout.d.ts.map +0 -1
  320. package/dist/core/app/DefaultApp.d.ts.map +0 -1
  321. package/dist/core/app/index.d.ts.map +0 -1
  322. package/dist/core/config/AppConfig.d.ts.map +0 -1
  323. package/dist/core/config/ConfigLoader.d.ts.map +0 -1
  324. package/dist/core/config/ConfigValidator.d.ts.map +0 -1
  325. package/dist/core/config/index.d.ts.map +0 -1
  326. package/dist/core/dev/DevTools.d.ts.map +0 -1
  327. package/dist/core/error/ErrorBoundary.d.ts.map +0 -1
  328. package/dist/core/error/ErrorHandler.d.ts.map +0 -1
  329. package/dist/core/error/index.d.ts.map +0 -1
  330. package/dist/core/event/AppEventBus.d.ts.map +0 -1
  331. package/dist/core/event/frameworkEvents.d.ts.map +0 -1
  332. package/dist/core/event/hooks.d.ts.map +0 -1
  333. package/dist/core/event/index.d.ts.map +0 -1
  334. package/dist/core/event/types.d.ts.map +0 -1
  335. package/dist/core/event/useEventBus.d.ts.map +0 -1
  336. package/dist/core/index.d.ts.map +0 -1
  337. package/dist/core/initialization/InitializationErrorThrower.d.ts.map +0 -1
  338. package/dist/core/initialization/index.d.ts.map +0 -1
  339. package/dist/core/initialization/initialization.d.ts.map +0 -1
  340. package/dist/core/initialization/initializationErrorState.d.ts.map +0 -1
  341. package/dist/core/middleware.d.ts.map +0 -1
  342. package/dist/core/plugin/PluginEventBus.d.ts.map +0 -1
  343. package/dist/core/plugin/PluginSandbox.d.ts.map +0 -1
  344. package/dist/core/plugin.d.ts.map +0 -1
  345. package/dist/core/router/RouterManager.d.ts.map +0 -1
  346. package/dist/core/router/adapter/AdapterManager.d.ts.map +0 -1
  347. package/dist/core/router/adapter/index.d.ts.map +0 -1
  348. package/dist/core/router/adapter/react-router/ReactRouterAdapter.d.ts.map +0 -1
  349. package/dist/core/router/adapter/react-router/index.d.ts.map +0 -1
  350. package/dist/core/router/adapter/types.d.ts.map +0 -1
  351. package/dist/core/router/dev/RouterDevTools.d.ts.map +0 -1
  352. package/dist/core/router/dev/index.d.ts.map +0 -1
  353. package/dist/core/router/dynamic/DynamicRouteManager.d.ts.map +0 -1
  354. package/dist/core/router/dynamic/index.d.ts.map +0 -1
  355. package/dist/core/router/errors/RouterError.d.ts.map +0 -1
  356. package/dist/core/router/errors/index.d.ts.map +0 -1
  357. package/dist/core/router/index.d.ts.map +0 -1
  358. package/dist/core/router/lifecycle/RouterLifecycleManager.d.ts.map +0 -1
  359. package/dist/core/router/lifecycle/index.d.ts.map +0 -1
  360. package/dist/core/router/middleware/RouterMiddlewareManager.d.ts.map +0 -1
  361. package/dist/core/router/middleware/auth.d.ts.map +0 -1
  362. package/dist/core/router/middleware/index.d.ts.map +0 -1
  363. package/dist/core/router/middleware/types.d.ts.map +0 -1
  364. package/dist/core/router/monitoring/RouterMonitoring.d.ts.map +0 -1
  365. package/dist/core/router/monitoring/index.d.ts.map +0 -1
  366. package/dist/core/router/navigation/RouterNavigation.d.ts.map +0 -1
  367. package/dist/core/router/navigation/index.d.ts.map +0 -1
  368. package/dist/core/router/performance/RouteCache.d.ts.map +0 -1
  369. package/dist/core/router/performance/RoutePreloader.d.ts.map +0 -1
  370. package/dist/core/router/performance/index.d.ts.map +0 -1
  371. package/dist/core/router/plugin/RouterPluginManager.d.ts.map +0 -1
  372. package/dist/core/router/plugin/index.d.ts.map +0 -1
  373. package/dist/core/router/plugin/types.d.ts.map +0 -1
  374. package/dist/core/router/types.d.ts.map +0 -1
  375. package/dist/core/router/utils/adapters/react-router/RouteErrorBoundary.d.ts.map +0 -1
  376. package/dist/core/router/utils/adapters/react-router/transform.d.ts.map +0 -1
  377. package/dist/core/router/utils/transform.d.ts.map +0 -1
  378. package/dist/core/router/validation/RouterConfigValidator.d.ts.map +0 -1
  379. package/dist/core/router/validation/index.d.ts.map +0 -1
  380. package/dist/core/router/validation/schema.d.ts.map +0 -1
  381. package/dist/core/router/version/RouteVersionManager.d.ts.map +0 -1
  382. package/dist/core/router/version/index.d.ts.map +0 -1
  383. package/dist/core/splash/SplashScreen.d.ts.map +0 -1
  384. package/dist/core/splash/index.d.ts.map +0 -1
  385. package/dist/core/splash/splashScreenUtils.d.ts.map +0 -1
  386. package/dist/core/startup/AppInstance.d.ts.map +0 -1
  387. package/dist/core/startup/environment.d.ts.map +0 -1
  388. package/dist/core/startup/index.d.ts.map +0 -1
  389. package/dist/core/startup/initializeServices.d.ts.map +0 -1
  390. package/dist/core/startup/performanceTracker.d.ts.map +0 -1
  391. package/dist/core/startup/renderApp.d.ts.map +0 -1
  392. package/dist/core/startup/startApp.d.ts.map +0 -1
  393. package/dist/core/types.d.ts.map +0 -1
  394. package/dist/index.d.ts.map +0 -1
  395. package/dist/index.umd.d.ts.map +0 -1
  396. package/dist/library/index.d.ts.map +0 -1
  397. package/dist/library/locale/index.d.ts.map +0 -1
  398. package/dist/library/locale/langs/en-us/index.d.ts.map +0 -1
  399. package/dist/library/locale/langs/zh-cn/index.d.ts.map +0 -1
  400. package/dist/library/locale/types.d.ts.map +0 -1
  401. package/dist/library/storage/cache.d.ts.map +0 -1
  402. package/dist/library/storage/encryption.d.ts.map +0 -1
  403. package/dist/library/storage/index.d.ts.map +0 -1
  404. package/dist/request/adapter/RequestAdapter.d.ts.map +0 -1
  405. package/dist/request/adapter/axiosAdapter.d.ts.map +0 -1
  406. package/dist/request/adapter/fetchAdapter.d.ts.map +0 -1
  407. package/dist/request/adapter/index.d.ts.map +0 -1
  408. package/dist/request/adapter/kyAdapter.d.ts.map +0 -1
  409. package/dist/request/adapter/undiciAdapter.d.ts.map +0 -1
  410. package/dist/request/core/RequestClient.d.ts.map +0 -1
  411. package/dist/request/core/index.d.ts.map +0 -1
  412. package/dist/request/index.d.ts.map +0 -1
  413. package/dist/request/plugin/RequestPlugin.d.ts.map +0 -1
  414. package/dist/request/plugin/cache.d.ts.map +0 -1
  415. package/dist/request/plugin/csrfPlugin.d.ts.map +0 -1
  416. package/dist/request/plugin/index.d.ts.map +0 -1
  417. package/dist/request/plugin/monitoring.d.ts.map +0 -1
  418. package/dist/request/plugin/queue.d.ts.map +0 -1
  419. package/dist/request/plugin/retry.d.ts.map +0 -1
  420. package/dist/request/plugin/validation.d.ts.map +0 -1
  421. package/dist/request/runtime/RequestContext.d.ts.map +0 -1
  422. package/dist/request/runtime/index.d.ts.map +0 -1
  423. package/dist/request/types.d.ts.map +0 -1
  424. package/dist/request/utils/RequestQueueManager.d.ts.map +0 -1
  425. package/dist/request/utils/dependencyCheck.d.ts.map +0 -1
  426. package/dist/request/utils/index.d.ts.map +0 -1
  427. package/dist/state/StateManager.d.ts.map +0 -1
  428. package/dist/state/adapters/AdapterFactory.d.ts.map +0 -1
  429. package/dist/state/adapters/DefaultAdapter.d.ts.map +0 -1
  430. package/dist/state/adapters/ReduxAdapter.d.ts.map +0 -1
  431. package/dist/state/adapters/ZustandAdapter.d.ts.map +0 -1
  432. package/dist/state/adapters/index.d.ts.map +0 -1
  433. package/dist/state/adapters/types.d.ts.map +0 -1
  434. package/dist/state/core/DerivedStateInstance.d.ts.map +0 -1
  435. package/dist/state/core/StateInstance.d.ts.map +0 -1
  436. package/dist/state/core/StateRegistry.d.ts.map +0 -1
  437. package/dist/state/core/StateScope.d.ts.map +0 -1
  438. package/dist/state/core/index.d.ts.map +0 -1
  439. package/dist/state/index.d.ts.map +0 -1
  440. package/dist/state/types.d.ts.map +0 -1
  441. package/dist/types.d.ts.map +0 -1
  442. package/dist/utils/analytics.d.ts.map +0 -1
  443. package/dist/utils/configSecurity.d.ts.map +0 -1
  444. package/dist/utils/csrf.d.ts.map +0 -1
  445. package/dist/utils/errors/ErrorCodes.d.ts.map +0 -1
  446. package/dist/utils/errors.d.ts.map +0 -1
  447. package/dist/utils/index.d.ts.map +0 -1
  448. package/dist/utils/logger.d.ts.map +0 -1
  449. package/dist/utils/logger.types.d.ts.map +0 -1
  450. package/dist/utils/monitoring.d.ts.map +0 -1
  451. package/dist/utils/performance.d.ts.map +0 -1
  452. package/dist/utils/resourceLoader.d.ts.map +0 -1
  453. package/dist/utils/runtimeSecurity.d.ts.map +0 -1
  454. package/dist/utils/security.d.ts.map +0 -1
  455. package/dist/utils/traceId.d.ts.map +0 -1
  456. package/dist/utils/validation.d.ts.map +0 -1
@@ -1,3 +1,16 @@
1
+ function _define_property(obj, key, value) {
2
+ if (key in obj) {
3
+ Object.defineProperty(obj, key, {
4
+ value: value,
5
+ enumerable: true,
6
+ configurable: true,
7
+ writable: true
8
+ });
9
+ } else {
10
+ obj[key] = value;
11
+ }
12
+ return obj;
13
+ }
1
14
  /**
2
15
  * 路由导航 API
3
16
  * 提供框架级别的路由导航能力,封装 react-router-dom 的导航功能
@@ -7,12 +20,32 @@ import { getRouterMiddlewareManager } from "../middleware";
7
20
  /**
8
21
  * 路由导航器
9
22
  */ export class RouterNavigation {
10
- /**
11
- * 导航到指定路径
12
- *
13
- * @param to - 目标路径或路由名称
14
- * @param options - 导航选项
15
- */ static async navigate(to, options) {
23
+ static buildTargetPath(to, query) {
24
+ const base = typeof window !== 'undefined' && window.location?.origin ? window.location.origin : 'http://localhost';
25
+ const url = new URL(to, base);
26
+ if (query && Object.keys(query).length > 0) {
27
+ const params = new URLSearchParams(url.search);
28
+ Object.entries(query).forEach(([key, value])=>{
29
+ if (value === undefined || value === null) {
30
+ params.delete(key);
31
+ return;
32
+ }
33
+ params.set(key, String(value));
34
+ });
35
+ url.search = params.toString();
36
+ }
37
+ return `${url.pathname}${url.search}${url.hash}`;
38
+ }
39
+ static async navigateInternal(to, options, depth, visited) {
40
+ const startTime = performance.now();
41
+ if (depth > this.MAX_REDIRECTS) {
42
+ throw new Error(`路由重定向次数超过上限(${this.MAX_REDIRECTS}),可能存在循环重定向`);
43
+ }
44
+ const targetPath = this.buildTargetPath(to, options?.query);
45
+ if (visited.has(targetPath)) {
46
+ throw new Error(`检测到循环重定向: ${targetPath}`);
47
+ }
48
+ visited.add(targetPath);
16
49
  const routerManager = await import("../RouterManager").then((m)=>m.getRouterManager());
17
50
  const router = routerManager.getRouter();
18
51
  if (!router) {
@@ -22,12 +55,13 @@ import { getRouterMiddlewareManager } from "../middleware";
22
55
  const currentLocation = this.getCurrentRoute();
23
56
  // 构建目标路由位置
24
57
  const targetLocation = {
25
- path: to,
58
+ path: targetPath,
26
59
  query: options?.query
27
60
  };
28
61
  // 执行生命周期钩子
29
62
  const lifecycleManager = getRouterLifecycleManager();
30
63
  const beforeEachResult = await lifecycleManager.beforeEach(targetLocation, currentLocation);
64
+ let finalPath = targetPath;
31
65
  // 如果 beforeEach 返回 false,阻止导航
32
66
  if (beforeEachResult === false) {
33
67
  logger.debug('路由导航被阻止: beforeEach 返回 false');
@@ -36,14 +70,14 @@ import { getRouterMiddlewareManager } from "../middleware";
36
70
  // 如果 beforeEach 返回字符串,重定向到该路径
37
71
  if (typeof beforeEachResult === 'string') {
38
72
  logger.debug(`路由导航重定向: ${beforeEachResult}`);
39
- to = beforeEachResult;
73
+ finalPath = this.buildTargetPath(beforeEachResult);
40
74
  }
41
75
  // 执行中间件
42
76
  const middlewareManager = getRouterMiddlewareManager();
43
77
  const middlewareContext = {
44
78
  to: {
45
79
  ...targetLocation,
46
- path: to
80
+ path: finalPath
47
81
  },
48
82
  from: currentLocation,
49
83
  options
@@ -53,8 +87,10 @@ import { getRouterMiddlewareManager } from "../middleware";
53
87
  if (!middlewareResult.allow) {
54
88
  if (middlewareResult.redirect) {
55
89
  logger.debug(`路由导航被中间件重定向: ${middlewareResult.redirect}`);
56
- // 递归调用 navigate 进行重定向
57
- return this.navigate(middlewareResult.redirect, options);
90
+ return this.navigateInternal(middlewareResult.redirect, {
91
+ ...options,
92
+ query: undefined
93
+ }, depth + 1, visited);
58
94
  }
59
95
  logger.debug(`路由导航被中间件阻止: ${middlewareResult.reason || '未知原因'}`);
60
96
  return;
@@ -62,30 +98,48 @@ import { getRouterMiddlewareManager } from "../middleware";
62
98
  // 执行导航
63
99
  try {
64
100
  if (options?.replace) {
65
- router.navigate(to, {
101
+ router.navigate(finalPath, {
66
102
  replace: true,
67
103
  state: options.state
68
104
  });
69
105
  } else {
70
- router.navigate(to, {
106
+ router.navigate(finalPath, {
71
107
  state: options?.state
72
108
  });
73
109
  }
74
110
  // 执行 afterEach 钩子
75
111
  await lifecycleManager.afterEach({
76
112
  ...targetLocation,
77
- path: to
113
+ path: finalPath
78
114
  }, currentLocation);
115
+ const duration = performance.now() - startTime;
116
+ routerManager.getMonitoring().trackRoutePerformance(finalPath, {
117
+ totalTime: duration
118
+ });
79
119
  } catch (error) {
80
120
  logger.error('路由导航失败', error);
81
121
  throw error;
82
122
  }
83
123
  }
84
124
  /**
125
+ * 导航到指定路径
126
+ *
127
+ * @param to - 目标路径或路由名称
128
+ * @param options - 导航选项
129
+ */ static async navigate(to, options) {
130
+ return this.navigateInternal(to, options, 0, new Set());
131
+ }
132
+ /**
85
133
  * 获取当前路由信息
86
134
  *
87
135
  * @returns 当前路由位置信息
88
136
  */ static getCurrentRoute() {
137
+ if (typeof window === 'undefined') {
138
+ return {
139
+ path: '/',
140
+ query: {}
141
+ };
142
+ }
89
143
  // 从 window.location 获取当前路由信息
90
144
  const pathname = window.location.pathname;
91
145
  const search = window.location.search;
@@ -133,5 +187,6 @@ import { getRouterMiddlewareManager } from "../middleware";
133
187
  });
134
188
  }
135
189
  }
190
+ _define_property(RouterNavigation, "MAX_REDIRECTS", 10);
136
191
 
137
192
  //# sourceMappingURL=RouterNavigation.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/core/router/navigation/RouterNavigation.ts"],"sourcesContent":["/**\n * 路由导航 API\n * 提供框架级别的路由导航能力,封装 react-router-dom 的导航功能\n */\n\nimport { logger } from '../../../utils';\nimport type { RouteLocation, NavigateOptions } from '../types';\nimport { getRouterLifecycleManager } from '../lifecycle';\nimport { getRouterMiddlewareManager } from '../middleware';\nimport type { RouterMiddlewareContext } from '../middleware/types';\n\n/**\n * 路由导航器\n */\nexport class RouterNavigation {\n /**\n * 导航到指定路径\n * \n * @param to - 目标路径或路由名称\n * @param options - 导航选项\n */\n static async navigate(\n to: string,\n options?: NavigateOptions\n ): Promise<void> {\n const routerManager = await import('../RouterManager').then((m) => m.getRouterManager());\n const router = routerManager.getRouter();\n\n if (!router) {\n throw new Error('路由未初始化,无法导航');\n }\n\n // 获取当前路由信息\n const currentLocation = this.getCurrentRoute();\n\n // 构建目标路由位置\n const targetLocation: RouteLocation = {\n path: to,\n query: options?.query,\n };\n\n // 执行生命周期钩子\n const lifecycleManager = getRouterLifecycleManager();\n const beforeEachResult = await lifecycleManager.beforeEach(\n targetLocation,\n currentLocation\n );\n\n // 如果 beforeEach 返回 false,阻止导航\n if (beforeEachResult === false) {\n logger.debug('路由导航被阻止: beforeEach 返回 false');\n return;\n }\n\n // 如果 beforeEach 返回字符串,重定向到该路径\n if (typeof beforeEachResult === 'string') {\n logger.debug(`路由导航重定向: ${beforeEachResult}`);\n to = beforeEachResult;\n }\n\n // 执行中间件\n const middlewareManager = getRouterMiddlewareManager();\n const middlewareContext: RouterMiddlewareContext = {\n to: {\n ...targetLocation,\n path: to,\n },\n from: currentLocation,\n options,\n };\n\n const middlewareResult = await middlewareManager.execute(middlewareContext);\n\n // 如果中间件阻止导航\n if (!middlewareResult.allow) {\n if (middlewareResult.redirect) {\n logger.debug(`路由导航被中间件重定向: ${middlewareResult.redirect}`);\n // 递归调用 navigate 进行重定向\n return this.navigate(middlewareResult.redirect, options);\n }\n logger.debug(`路由导航被中间件阻止: ${middlewareResult.reason || '未知原因'}`);\n return;\n }\n\n // 执行导航\n try {\n if (options?.replace) {\n router.navigate(to, { replace: true, state: options.state });\n } else {\n router.navigate(to, { state: options?.state });\n }\n\n // 执行 afterEach 钩子\n await lifecycleManager.afterEach(\n {\n ...targetLocation,\n path: to,\n },\n currentLocation\n );\n } catch (error) {\n logger.error('路由导航失败', error);\n throw error;\n }\n }\n\n /**\n * 获取当前路由信息\n * \n * @returns 当前路由位置信息\n */\n static getCurrentRoute(): RouteLocation {\n // 从 window.location 获取当前路由信息\n const pathname = window.location.pathname;\n const search = window.location.search;\n const hash = window.location.hash;\n\n // 解析查询参数\n const query: Record<string, unknown> = {};\n if (search) {\n const params = new URLSearchParams(search);\n params.forEach((value, key) => {\n query[key] = value;\n });\n }\n\n return {\n path: pathname + hash,\n query,\n };\n }\n\n /**\n * 返回上一页\n * \n * @param fallback - 如果没有历史记录,跳转到该路径\n */\n static async goBack(fallback?: string): Promise<void> {\n if (window.history.length > 1) {\n window.history.back();\n } else if (fallback) {\n await this.navigate(fallback);\n } else {\n logger.warn('没有历史记录,无法返回');\n }\n }\n\n /**\n * 前进到下一页\n */\n static goForward(): void {\n window.history.forward();\n }\n\n /**\n * 替换当前路由\n * \n * @param to - 目标路径\n * @param options - 导航选项\n */\n static async replace(\n to: string,\n options?: Omit<NavigateOptions, 'replace'>\n ): Promise<void> {\n return this.navigate(to, { ...options, replace: true });\n }\n}\n"],"names":["logger","getRouterLifecycleManager","getRouterMiddlewareManager","RouterNavigation","navigate","to","options","routerManager","then","m","getRouterManager","router","getRouter","Error","currentLocation","getCurrentRoute","targetLocation","path","query","lifecycleManager","beforeEachResult","beforeEach","debug","middlewareManager","middlewareContext","from","middlewareResult","execute","allow","redirect","reason","replace","state","afterEach","error","pathname","window","location","search","hash","params","URLSearchParams","forEach","value","key","goBack","fallback","history","length","back","warn","goForward","forward"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../../src/core/router/navigation/RouterNavigation.ts"],"sourcesContent":["/**\n * 路由导航 API\n * 提供框架级别的路由导航能力,封装 react-router-dom 的导航功能\n */\n\nimport { logger } from '../../../utils';\nimport type { RouteLocation, NavigateOptions } from '../types';\nimport { getRouterLifecycleManager } from '../lifecycle';\nimport { getRouterMiddlewareManager } from '../middleware';\nimport type { RouterMiddlewareContext } from '../middleware/types';\n\n/**\n * 路由导航器\n */\nexport class RouterNavigation {\n private static readonly MAX_REDIRECTS = 10;\n\n private static buildTargetPath(\n to: string,\n query?: Record<string, unknown>\n ): string {\n const base =\n typeof window !== 'undefined' && window.location?.origin\n ? window.location.origin\n : 'http://localhost';\n\n const url = new URL(to, base);\n\n if (query && Object.keys(query).length > 0) {\n const params = new URLSearchParams(url.search);\n Object.entries(query).forEach(([key, value]) => {\n if (value === undefined || value === null) {\n params.delete(key);\n return;\n }\n params.set(key, String(value));\n });\n url.search = params.toString();\n }\n\n return `${url.pathname}${url.search}${url.hash}`;\n }\n\n private static async navigateInternal(\n to: string,\n options: NavigateOptions | undefined,\n depth: number,\n visited: Set<string>\n ): Promise<void> {\n const startTime = performance.now();\n\n if (depth > this.MAX_REDIRECTS) {\n throw new Error(`路由重定向次数超过上限(${this.MAX_REDIRECTS}),可能存在循环重定向`);\n }\n\n const targetPath = this.buildTargetPath(to, options?.query);\n if (visited.has(targetPath)) {\n throw new Error(`检测到循环重定向: ${targetPath}`);\n }\n visited.add(targetPath);\n\n const routerManager = await import('../RouterManager').then((m) => m.getRouterManager());\n const router = routerManager.getRouter();\n\n if (!router) {\n throw new Error('路由未初始化,无法导航');\n }\n\n // 获取当前路由信息\n const currentLocation = this.getCurrentRoute();\n\n // 构建目标路由位置\n const targetLocation: RouteLocation = {\n path: targetPath,\n query: options?.query,\n };\n\n // 执行生命周期钩子\n const lifecycleManager = getRouterLifecycleManager();\n const beforeEachResult = await lifecycleManager.beforeEach(\n targetLocation,\n currentLocation\n );\n\n let finalPath = targetPath;\n\n // 如果 beforeEach 返回 false,阻止导航\n if (beforeEachResult === false) {\n logger.debug('路由导航被阻止: beforeEach 返回 false');\n return;\n }\n\n // 如果 beforeEach 返回字符串,重定向到该路径\n if (typeof beforeEachResult === 'string') {\n logger.debug(`路由导航重定向: ${beforeEachResult}`);\n finalPath = this.buildTargetPath(beforeEachResult);\n }\n\n // 执行中间件\n const middlewareManager = getRouterMiddlewareManager();\n const middlewareContext: RouterMiddlewareContext = {\n to: {\n ...targetLocation,\n path: finalPath,\n },\n from: currentLocation,\n options,\n };\n\n const middlewareResult = await middlewareManager.execute(middlewareContext);\n\n // 如果中间件阻止导航\n if (!middlewareResult.allow) {\n if (middlewareResult.redirect) {\n logger.debug(`路由导航被中间件重定向: ${middlewareResult.redirect}`);\n return this.navigateInternal(\n middlewareResult.redirect,\n { ...options, query: undefined },\n depth + 1,\n visited\n );\n }\n logger.debug(`路由导航被中间件阻止: ${middlewareResult.reason || '未知原因'}`);\n return;\n }\n\n // 执行导航\n try {\n if (options?.replace) {\n router.navigate(finalPath, { replace: true, state: options.state });\n } else {\n router.navigate(finalPath, { state: options?.state });\n }\n\n // 执行 afterEach 钩子\n await lifecycleManager.afterEach(\n {\n ...targetLocation,\n path: finalPath,\n },\n currentLocation\n );\n\n const duration = performance.now() - startTime;\n routerManager.getMonitoring().trackRoutePerformance(finalPath, {\n totalTime: duration,\n });\n } catch (error) {\n logger.error('路由导航失败', error);\n throw error;\n }\n }\n\n /**\n * 导航到指定路径\n * \n * @param to - 目标路径或路由名称\n * @param options - 导航选项\n */\n static async navigate(\n to: string,\n options?: NavigateOptions\n ): Promise<void> {\n return this.navigateInternal(to, options, 0, new Set());\n }\n\n /**\n * 获取当前路由信息\n * \n * @returns 当前路由位置信息\n */\n static getCurrentRoute(): RouteLocation {\n if (typeof window === 'undefined') {\n return {\n path: '/',\n query: {},\n };\n }\n\n // 从 window.location 获取当前路由信息\n const pathname = window.location.pathname;\n const search = window.location.search;\n const hash = window.location.hash;\n\n // 解析查询参数\n const query: Record<string, unknown> = {};\n if (search) {\n const params = new URLSearchParams(search);\n params.forEach((value, key) => {\n query[key] = value;\n });\n }\n\n return {\n path: pathname + hash,\n query,\n };\n }\n\n /**\n * 返回上一页\n * \n * @param fallback - 如果没有历史记录,跳转到该路径\n */\n static async goBack(fallback?: string): Promise<void> {\n if (window.history.length > 1) {\n window.history.back();\n } else if (fallback) {\n await this.navigate(fallback);\n } else {\n logger.warn('没有历史记录,无法返回');\n }\n }\n\n /**\n * 前进到下一页\n */\n static goForward(): void {\n window.history.forward();\n }\n\n /**\n * 替换当前路由\n * \n * @param to - 目标路径\n * @param options - 导航选项\n */\n static async replace(\n to: string,\n options?: Omit<NavigateOptions, 'replace'>\n ): Promise<void> {\n return this.navigate(to, { ...options, replace: true });\n }\n}\n"],"names":["logger","getRouterLifecycleManager","getRouterMiddlewareManager","RouterNavigation","buildTargetPath","to","query","base","window","location","origin","url","URL","Object","keys","length","params","URLSearchParams","search","entries","forEach","key","value","undefined","delete","set","String","toString","pathname","hash","navigateInternal","options","depth","visited","startTime","performance","now","MAX_REDIRECTS","Error","targetPath","has","add","routerManager","then","m","getRouterManager","router","getRouter","currentLocation","getCurrentRoute","targetLocation","path","lifecycleManager","beforeEachResult","beforeEach","finalPath","debug","middlewareManager","middlewareContext","from","middlewareResult","execute","allow","redirect","reason","replace","navigate","state","afterEach","duration","getMonitoring","trackRoutePerformance","totalTime","error","Set","goBack","fallback","history","back","warn","goForward","forward"],"mappings":";;;;;;;;;;;;;AAAA;;;CAGC,GAED,SAASA,MAAM,QAAQ,iBAAiB;AAExC,SAASC,yBAAyB,QAAQ,eAAe;AACzD,SAASC,0BAA0B,QAAQ,gBAAgB;AAG3D;;CAEC,GACD,OAAO,MAAMC;IAGX,OAAeC,gBACbC,EAAU,EACVC,KAA+B,EACvB;QACR,MAAMC,OACJ,OAAOC,WAAW,eAAeA,OAAOC,QAAQ,EAAEC,SAC9CF,OAAOC,QAAQ,CAACC,MAAM,GACtB;QAEN,MAAMC,MAAM,IAAIC,IAAIP,IAAIE;QAExB,IAAID,SAASO,OAAOC,IAAI,CAACR,OAAOS,MAAM,GAAG,GAAG;YAC1C,MAAMC,SAAS,IAAIC,gBAAgBN,IAAIO,MAAM;YAC7CL,OAAOM,OAAO,CAACb,OAAOc,OAAO,CAAC,CAAC,CAACC,KAAKC,MAAM;gBACzC,IAAIA,UAAUC,aAAaD,UAAU,MAAM;oBACzCN,OAAOQ,MAAM,CAACH;oBACd;gBACF;gBACAL,OAAOS,GAAG,CAACJ,KAAKK,OAAOJ;YACzB;YACAX,IAAIO,MAAM,GAAGF,OAAOW,QAAQ;QAC9B;QAEA,OAAO,GAAGhB,IAAIiB,QAAQ,GAAGjB,IAAIO,MAAM,GAAGP,IAAIkB,IAAI,EAAE;IAClD;IAEA,aAAqBC,iBACnBzB,EAAU,EACV0B,OAAoC,EACpCC,KAAa,EACbC,OAAoB,EACL;QACf,MAAMC,YAAYC,YAAYC,GAAG;QAEjC,IAAIJ,QAAQ,IAAI,CAACK,aAAa,EAAE;YAC9B,MAAM,IAAIC,MAAM,CAAC,YAAY,EAAE,IAAI,CAACD,aAAa,CAAC,WAAW,CAAC;QAChE;QAEA,MAAME,aAAa,IAAI,CAACnC,eAAe,CAACC,IAAI0B,SAASzB;QACrD,IAAI2B,QAAQO,GAAG,CAACD,aAAa;YAC3B,MAAM,IAAID,MAAM,CAAC,UAAU,EAAEC,YAAY;QAC3C;QACAN,QAAQQ,GAAG,CAACF;QAEZ,MAAMG,gBAAgB,MAAM,MAAM,CAAC,oBAAoBC,IAAI,CAAC,CAACC,IAAMA,EAAEC,gBAAgB;QACrF,MAAMC,SAASJ,cAAcK,SAAS;QAEtC,IAAI,CAACD,QAAQ;YACX,MAAM,IAAIR,MAAM;QAClB;QAEA,WAAW;QACX,MAAMU,kBAAkB,IAAI,CAACC,eAAe;QAE5C,WAAW;QACX,MAAMC,iBAAgC;YACpCC,MAAMZ;YACNjC,OAAOyB,SAASzB;QAClB;QAEA,WAAW;QACX,MAAM8C,mBAAmBnD;QACzB,MAAMoD,mBAAmB,MAAMD,iBAAiBE,UAAU,CACxDJ,gBACAF;QAGF,IAAIO,YAAYhB;QAEhB,8BAA8B;QAC9B,IAAIc,qBAAqB,OAAO;YAC9BrD,OAAOwD,KAAK,CAAC;YACb;QACF;QAEA,8BAA8B;QAC9B,IAAI,OAAOH,qBAAqB,UAAU;YACxCrD,OAAOwD,KAAK,CAAC,CAAC,SAAS,EAAEH,kBAAkB;YAC3CE,YAAY,IAAI,CAACnD,eAAe,CAACiD;QACnC;QAEA,QAAQ;QACR,MAAMI,oBAAoBvD;QAC1B,MAAMwD,oBAA6C;YACjDrD,IAAI;gBACF,GAAG6C,cAAc;gBACjBC,MAAMI;YACR;YACAI,MAAMX;YACNjB;QACF;QAEA,MAAM6B,mBAAmB,MAAMH,kBAAkBI,OAAO,CAACH;QAEzD,YAAY;QACZ,IAAI,CAACE,iBAAiBE,KAAK,EAAE;YAC3B,IAAIF,iBAAiBG,QAAQ,EAAE;gBAC7B/D,OAAOwD,KAAK,CAAC,CAAC,aAAa,EAAEI,iBAAiBG,QAAQ,EAAE;gBACxD,OAAO,IAAI,CAACjC,gBAAgB,CAC1B8B,iBAAiBG,QAAQ,EACzB;oBAAE,GAAGhC,OAAO;oBAAEzB,OAAOiB;gBAAU,GAC/BS,QAAQ,GACRC;YAEJ;YACAjC,OAAOwD,KAAK,CAAC,CAAC,YAAY,EAAEI,iBAAiBI,MAAM,IAAI,QAAQ;YAC/D;QACF;QAEA,OAAO;QACP,IAAI;YACF,IAAIjC,SAASkC,SAAS;gBACpBnB,OAAOoB,QAAQ,CAACX,WAAW;oBAAEU,SAAS;oBAAME,OAAOpC,QAAQoC,KAAK;gBAAC;YACnE,OAAO;gBACLrB,OAAOoB,QAAQ,CAACX,WAAW;oBAAEY,OAAOpC,SAASoC;gBAAM;YACrD;YAEA,kBAAkB;YAClB,MAAMf,iBAAiBgB,SAAS,CAC9B;gBACE,GAAGlB,cAAc;gBACjBC,MAAMI;YACR,GACAP;YAGF,MAAMqB,WAAWlC,YAAYC,GAAG,KAAKF;YACrCQ,cAAc4B,aAAa,GAAGC,qBAAqB,CAAChB,WAAW;gBAC7DiB,WAAWH;YACb;QACF,EAAE,OAAOI,OAAO;YACdzE,OAAOyE,KAAK,CAAC,UAAUA;YACvB,MAAMA;QACR;IACF;IAEA;;;;;GAKC,GACD,aAAaP,SACX7D,EAAU,EACV0B,OAAyB,EACV;QACf,OAAO,IAAI,CAACD,gBAAgB,CAACzB,IAAI0B,SAAS,GAAG,IAAI2C;IACnD;IAEA;;;;GAIC,GACD,OAAOzB,kBAAiC;QACtC,IAAI,OAAOzC,WAAW,aAAa;YACjC,OAAO;gBACL2C,MAAM;gBACN7C,OAAO,CAAC;YACV;QACF;QAEA,6BAA6B;QAC7B,MAAMsB,WAAWpB,OAAOC,QAAQ,CAACmB,QAAQ;QACzC,MAAMV,SAASV,OAAOC,QAAQ,CAACS,MAAM;QACrC,MAAMW,OAAOrB,OAAOC,QAAQ,CAACoB,IAAI;QAEjC,SAAS;QACT,MAAMvB,QAAiC,CAAC;QACxC,IAAIY,QAAQ;YACV,MAAMF,SAAS,IAAIC,gBAAgBC;YACnCF,OAAOI,OAAO,CAAC,CAACE,OAAOD;gBACrBf,KAAK,CAACe,IAAI,GAAGC;YACf;QACF;QAEA,OAAO;YACL6B,MAAMvB,WAAWC;YACjBvB;QACF;IACF;IAEA;;;;GAIC,GACD,aAAaqE,OAAOC,QAAiB,EAAiB;QACpD,IAAIpE,OAAOqE,OAAO,CAAC9D,MAAM,GAAG,GAAG;YAC7BP,OAAOqE,OAAO,CAACC,IAAI;QACrB,OAAO,IAAIF,UAAU;YACnB,MAAM,IAAI,CAACV,QAAQ,CAACU;QACtB,OAAO;YACL5E,OAAO+E,IAAI,CAAC;QACd;IACF;IAEA;;GAEC,GACD,OAAOC,YAAkB;QACvBxE,OAAOqE,OAAO,CAACI,OAAO;IACxB;IAEA;;;;;GAKC,GACD,aAAahB,QACX5D,EAAU,EACV0B,OAA0C,EAC3B;QACf,OAAO,IAAI,CAACmC,QAAQ,CAAC7D,IAAI;YAAE,GAAG0B,OAAO;YAAEkC,SAAS;QAAK;IACvD;AACF;AA1NE,iBADW9D,kBACakC,iBAAgB"}
@@ -2,4 +2,3 @@
2
2
  * 路由导航模块入口
3
3
  */
4
4
  export * from './RouterNavigation';
5
- //# sourceMappingURL=index.d.ts.map
@@ -149,8 +149,11 @@ let RouteCache = class RouteCache {
149
149
  /**
150
150
  * 启动定期清理
151
151
  */ startCleanupInterval() {
152
+ if (this.cleanupTimer) {
153
+ clearInterval(this.cleanupTimer);
154
+ }
152
155
  // 每 1 分钟清理一次过期缓存
153
- setInterval(()=>{
156
+ this.cleanupTimer = setInterval(()=>{
154
157
  this.cleanup();
155
158
  }, 60 * 1000);
156
159
  }
@@ -160,15 +163,18 @@ let RouteCache = class RouteCache {
160
163
  const key = this.generateKey(routes);
161
164
  const item = this.cache.get(key);
162
165
  if (!item) {
166
+ this.stats.transformMisses++;
163
167
  return null;
164
168
  }
165
169
  if (this.isExpired(item)) {
166
170
  this.cache.delete(key);
171
+ this.stats.transformMisses++;
167
172
  return null;
168
173
  }
169
174
  // 更新访问信息
170
175
  item.lastAccessedAt = Date.now();
171
176
  item.accessCount++;
177
+ this.stats.transformHits++;
172
178
  return item.value;
173
179
  }
174
180
  /**
@@ -198,15 +204,18 @@ let RouteCache = class RouteCache {
198
204
  */ getMatch(path) {
199
205
  const item = this.matchCache.get(path);
200
206
  if (!item) {
207
+ this.stats.matchMisses++;
201
208
  return undefined;
202
209
  }
203
210
  if (this.isExpired(item)) {
204
211
  this.matchCache.delete(path);
212
+ this.stats.matchMisses++;
205
213
  return undefined;
206
214
  }
207
215
  // 更新访问信息
208
216
  item.lastAccessedAt = Date.now();
209
217
  item.accessCount++;
218
+ this.stats.matchHits++;
210
219
  return item.value;
211
220
  }
212
221
  /**
@@ -229,23 +238,28 @@ let RouteCache = class RouteCache {
229
238
  */ clear() {
230
239
  this.cache.clear();
231
240
  this.matchCache.clear();
241
+ this.stats = {
242
+ transformHits: 0,
243
+ transformMisses: 0,
244
+ matchHits: 0,
245
+ matchMisses: 0
246
+ };
232
247
  _utils.logger.debug('路由缓存已清空');
233
248
  }
234
249
  /**
250
+ * 销毁缓存实例并释放资源
251
+ */ destroy() {
252
+ this.clear();
253
+ if (this.cleanupTimer) {
254
+ clearInterval(this.cleanupTimer);
255
+ this.cleanupTimer = null;
256
+ }
257
+ }
258
+ /**
235
259
  * 获取缓存统计信息
236
260
  */ getStats() {
237
- let totalHits = 0;
238
- let totalAccess = 0;
239
- // 统计转换结果缓存
240
- for (const item of this.cache.values()){
241
- totalHits += item.accessCount;
242
- totalAccess += item.accessCount;
243
- }
244
- // 统计匹配结果缓存
245
- for (const item of this.matchCache.values()){
246
- totalHits += item.accessCount;
247
- totalAccess += item.accessCount;
248
- }
261
+ const totalHits = this.stats.transformHits + this.stats.matchHits;
262
+ const totalAccess = totalHits + this.stats.transformMisses + this.stats.matchMisses;
249
263
  const hitRate = totalAccess > 0 ? totalHits / totalAccess : 0;
250
264
  return {
251
265
  transformCacheSize: this.cache.size,
@@ -259,6 +273,13 @@ let RouteCache = class RouteCache {
259
273
  _define_property(this, "matchCache", new Map());
260
274
  _define_property(this, "config", void 0);
261
275
  _define_property(this, "persistenceEnabled", false);
276
+ _define_property(this, "cleanupTimer", null);
277
+ _define_property(this, "stats", {
278
+ transformHits: 0,
279
+ transformMisses: 0,
280
+ matchHits: 0,
281
+ matchMisses: 0
282
+ });
262
283
  this.config = {
263
284
  maxSize: config.maxSize ?? 50,
264
285
  ttl: config.ttl ?? 5 * 60 * 1000,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/core/router/performance/RouteCache.ts"],"sourcesContent":["/**\n * 路由缓存管理器\n * 提供路由转换结果、匹配结果的缓存功能\n */\n\nimport { logger } from '../../../utils';\nimport type { RouteConfig } from '../types';\nimport type { TransformRoutesResult } from '../utils/transform';\n\n/**\n * 缓存项接口\n */\ninterface CacheItem<T> {\n /**\n * 缓存值\n */\n value: T;\n /**\n * 过期时间戳\n */\n expiresAt: number;\n /**\n * 创建时间戳\n */\n createdAt: number;\n /**\n * 访问次数\n */\n accessCount: number;\n /**\n * 最后访问时间\n */\n lastAccessedAt: number;\n}\n\n/**\n * LRU 缓存配置\n */\nexport interface RouteCacheConfig {\n /**\n * 最大缓存数量\n * @default 50\n */\n maxSize?: number;\n\n /**\n * 缓存过期时间(毫秒)\n * @default 5 * 60 * 1000 (5分钟)\n */\n ttl?: number;\n\n /**\n * 是否启用持久化缓存(使用 IndexedDB)\n * @default false\n */\n enablePersistence?: boolean;\n\n /**\n * 持久化缓存键前缀\n * @default 'router_cache_'\n */\n persistenceKeyPrefix?: string;\n}\n\n/**\n * 路由缓存管理器\n */\nexport class RouteCache {\n private cache: Map<string, CacheItem<TransformRoutesResult>> = new Map();\n private matchCache: Map<string, CacheItem<RouteConfig | null>> = new Map();\n private config: Required<RouteCacheConfig>;\n private persistenceEnabled: boolean = false;\n\n constructor(config: RouteCacheConfig = {}) {\n this.config = {\n maxSize: config.maxSize ?? 50,\n ttl: config.ttl ?? 5 * 60 * 1000,\n enablePersistence: config.enablePersistence ?? false,\n persistenceKeyPrefix: config.persistenceKeyPrefix ?? 'router_cache_',\n };\n\n // 初始化持久化缓存\n if (this.config.enablePersistence && typeof window !== 'undefined' && 'indexedDB' in window) {\n this.initPersistence();\n }\n\n // 定期清理过期缓存\n this.startCleanupInterval();\n }\n\n /**\n * 初始化持久化缓存\n */\n private async initPersistence(): Promise<void> {\n try {\n // 检查 IndexedDB 是否可用\n if (typeof window !== 'undefined' && 'indexedDB' in window) {\n this.persistenceEnabled = true;\n await this.loadFromPersistence();\n logger.debug('路由缓存持久化已启用');\n }\n } catch (error) {\n logger.warn('路由缓存持久化初始化失败', error);\n this.persistenceEnabled = false;\n }\n }\n\n /**\n * 从持久化存储加载缓存\n */\n private async loadFromPersistence(): Promise<void> {\n try {\n // 这里可以实现从 IndexedDB 加载缓存的逻辑\n // 由于 IndexedDB 操作较复杂,这里先留空\n // 实际实现可以使用 idb 库或原生 IndexedDB API\n } catch (error) {\n logger.warn('从持久化存储加载缓存失败', error);\n }\n }\n\n /**\n * 保存到持久化存储\n */\n private async saveToPersistence(_key: string, _value: TransformRoutesResult): Promise<void> {\n if (!this.persistenceEnabled) {\n return;\n }\n\n try {\n // 这里可以实现保存到 IndexedDB 的逻辑\n // 实际实现可以使用 idb 库或原生 IndexedDB API\n } catch (error) {\n logger.warn('保存到持久化存储失败', error);\n }\n }\n\n /**\n * 生成缓存键\n */\n private generateKey(routes: RouteConfig[] | (() => Promise<RouteConfig[]>)): string {\n if (typeof routes === 'function') {\n // 对于函数,使用函数名或随机 ID\n return `fn_${routes.name || Math.random().toString(36).substring(7)}`;\n }\n\n // 对于数组,使用 JSON.stringify 生成键(注意:这可能会很慢)\n // 实际使用中可以考虑使用路由配置的哈希值\n try {\n const routesStr = JSON.stringify(routes, (_key, value) => {\n // 过滤掉函数,避免序列化问题\n if (typeof value === 'function') {\n return '[Function]';\n }\n return value;\n });\n return `routes_${this.hashString(routesStr)}`;\n } catch (error) {\n // 如果序列化失败,使用随机键\n return `routes_${Math.random().toString(36).substring(7)}`;\n }\n }\n\n /**\n * 字符串哈希函数(简单实现)\n */\n private hashString(str: string): string {\n let hash = 0;\n for (let i = 0; i < str.length; i++) {\n const char = str.charCodeAt(i);\n hash = (hash << 5) - hash + char;\n hash = hash & hash; // 转换为 32 位整数\n }\n return Math.abs(hash).toString(36);\n }\n\n /**\n * 检查缓存项是否过期\n */\n private isExpired(item: CacheItem<unknown>): boolean {\n return Date.now() > item.expiresAt;\n }\n\n /**\n * 清理过期缓存\n */\n private cleanup(): void {\n\n // 清理转换结果缓存\n for (const [key, item] of this.cache.entries()) {\n if (this.isExpired(item)) {\n this.cache.delete(key);\n }\n }\n\n // 清理匹配结果缓存\n for (const [key, item] of this.matchCache.entries()) {\n if (this.isExpired(item)) {\n this.matchCache.delete(key);\n }\n }\n\n // 如果缓存超过最大大小,删除最久未访问的项(LRU)\n this.evictLRU();\n }\n\n /**\n * LRU 淘汰策略\n */\n private evictLRU(): void {\n // 清理转换结果缓存\n if (this.cache.size > this.config.maxSize) {\n const sorted = Array.from(this.cache.entries()).sort(\n (a, b) => a[1].lastAccessedAt - b[1].lastAccessedAt\n );\n const toDelete = sorted.slice(0, this.cache.size - this.config.maxSize);\n toDelete.forEach(([key]) => this.cache.delete(key));\n }\n\n // 清理匹配结果缓存\n if (this.matchCache.size > this.config.maxSize) {\n const sorted = Array.from(this.matchCache.entries()).sort(\n (a, b) => a[1].lastAccessedAt - b[1].lastAccessedAt\n );\n const toDelete = sorted.slice(0, this.matchCache.size - this.config.maxSize);\n toDelete.forEach(([key]) => this.matchCache.delete(key));\n }\n }\n\n /**\n * 启动定期清理\n */\n private startCleanupInterval(): void {\n // 每 1 分钟清理一次过期缓存\n setInterval(() => {\n this.cleanup();\n }, 60 * 1000);\n }\n\n /**\n * 获取转换结果缓存\n */\n get(routes: RouteConfig[] | (() => Promise<RouteConfig[]>)): TransformRoutesResult | null {\n const key = this.generateKey(routes);\n const item = this.cache.get(key);\n\n if (!item) {\n return null;\n }\n\n if (this.isExpired(item)) {\n this.cache.delete(key);\n return null;\n }\n\n // 更新访问信息\n item.lastAccessedAt = Date.now();\n item.accessCount++;\n\n return item.value;\n }\n\n /**\n * 设置转换结果缓存\n */\n set(\n routes: RouteConfig[] | (() => Promise<RouteConfig[]>),\n value: TransformRoutesResult\n ): void {\n const key = this.generateKey(routes);\n const now = Date.now();\n\n const item: CacheItem<TransformRoutesResult> = {\n value,\n expiresAt: now + this.config.ttl,\n createdAt: now,\n accessCount: 0,\n lastAccessedAt: now,\n };\n\n this.cache.set(key, item);\n\n // 保存到持久化存储\n if (this.persistenceEnabled) {\n this.saveToPersistence(key, value).catch((error) => {\n logger.warn('保存缓存到持久化存储失败', error);\n });\n }\n\n // 检查是否需要淘汰\n this.evictLRU();\n }\n\n /**\n * 获取路由匹配缓存\n */\n getMatch(path: string): RouteConfig | null | undefined {\n const item = this.matchCache.get(path);\n\n if (!item) {\n return undefined;\n }\n\n if (this.isExpired(item)) {\n this.matchCache.delete(path);\n return undefined;\n }\n\n // 更新访问信息\n item.lastAccessedAt = Date.now();\n item.accessCount++;\n\n return item.value;\n }\n\n /**\n * 设置路由匹配缓存\n */\n setMatch(path: string, route: RouteConfig | null): void {\n const now = Date.now();\n\n const item: CacheItem<RouteConfig | null> = {\n value: route,\n expiresAt: now + this.config.ttl,\n createdAt: now,\n accessCount: 0,\n lastAccessedAt: now,\n };\n\n this.matchCache.set(path, item);\n\n // 检查是否需要淘汰\n this.evictLRU();\n }\n\n /**\n * 清空所有缓存\n */\n clear(): void {\n this.cache.clear();\n this.matchCache.clear();\n logger.debug('路由缓存已清空');\n }\n\n /**\n * 获取缓存统计信息\n */\n getStats(): {\n transformCacheSize: number;\n matchCacheSize: number;\n totalSize: number;\n hitRate: number;\n } {\n let totalHits = 0;\n let totalAccess = 0;\n\n // 统计转换结果缓存\n for (const item of this.cache.values()) {\n totalHits += item.accessCount;\n totalAccess += item.accessCount;\n }\n\n // 统计匹配结果缓存\n for (const item of this.matchCache.values()) {\n totalHits += item.accessCount;\n totalAccess += item.accessCount;\n }\n\n const hitRate = totalAccess > 0 ? totalHits / totalAccess : 0;\n\n return {\n transformCacheSize: this.cache.size,\n matchCacheSize: this.matchCache.size,\n totalSize: this.cache.size + this.matchCache.size,\n hitRate,\n };\n }\n}\n\n/**\n * 获取路由缓存管理器单例\n */\nlet routeCacheInstance: RouteCache | null = null;\n\nexport function getRouteCache(config?: RouteCacheConfig): RouteCache {\n if (!routeCacheInstance) {\n routeCacheInstance = new RouteCache(config);\n }\n return routeCacheInstance;\n}\n"],"names":["RouteCache","getRouteCache","initPersistence","window","persistenceEnabled","loadFromPersistence","logger","debug","error","warn","saveToPersistence","_key","_value","generateKey","routes","name","Math","random","toString","substring","routesStr","JSON","stringify","value","hashString","str","hash","i","length","char","charCodeAt","abs","isExpired","item","Date","now","expiresAt","cleanup","key","cache","entries","delete","matchCache","evictLRU","size","config","maxSize","sorted","Array","from","sort","a","b","lastAccessedAt","toDelete","slice","forEach","startCleanupInterval","setInterval","get","accessCount","set","ttl","createdAt","catch","getMatch","path","undefined","setMatch","route","clear","getStats","totalHits","totalAccess","values","hitRate","transformCacheSize","matchCacheSize","totalSize","Map","enablePersistence","persistenceKeyPrefix","routeCacheInstance"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../../src/core/router/performance/RouteCache.ts"],"sourcesContent":["/**\n * 路由缓存管理器\n * 提供路由转换结果、匹配结果的缓存功能\n */\n\nimport { logger } from '../../../utils';\nimport type { RouteConfig } from '../types';\nimport type { TransformRoutesResult } from '../utils/transform';\n\n/**\n * 缓存项接口\n */\ninterface CacheItem<T> {\n /**\n * 缓存值\n */\n value: T;\n /**\n * 过期时间戳\n */\n expiresAt: number;\n /**\n * 创建时间戳\n */\n createdAt: number;\n /**\n * 访问次数\n */\n accessCount: number;\n /**\n * 最后访问时间\n */\n lastAccessedAt: number;\n}\n\n/**\n * LRU 缓存配置\n */\nexport interface RouteCacheConfig {\n /**\n * 最大缓存数量\n * @default 50\n */\n maxSize?: number;\n\n /**\n * 缓存过期时间(毫秒)\n * @default 5 * 60 * 1000 (5分钟)\n */\n ttl?: number;\n\n /**\n * 是否启用持久化缓存(使用 IndexedDB)\n * @default false\n */\n enablePersistence?: boolean;\n\n /**\n * 持久化缓存键前缀\n * @default 'router_cache_'\n */\n persistenceKeyPrefix?: string;\n}\n\n/**\n * 路由缓存管理器\n */\nexport class RouteCache {\n private cache: Map<string, CacheItem<TransformRoutesResult>> = new Map();\n private matchCache: Map<string, CacheItem<RouteConfig | null>> = new Map();\n private config: Required<RouteCacheConfig>;\n private persistenceEnabled: boolean = false;\n private cleanupTimer: ReturnType<typeof setInterval> | null = null;\n private stats = {\n transformHits: 0,\n transformMisses: 0,\n matchHits: 0,\n matchMisses: 0,\n };\n\n constructor(config: RouteCacheConfig = {}) {\n this.config = {\n maxSize: config.maxSize ?? 50,\n ttl: config.ttl ?? 5 * 60 * 1000,\n enablePersistence: config.enablePersistence ?? false,\n persistenceKeyPrefix: config.persistenceKeyPrefix ?? 'router_cache_',\n };\n\n // 初始化持久化缓存\n if (this.config.enablePersistence && typeof window !== 'undefined' && 'indexedDB' in window) {\n this.initPersistence();\n }\n\n // 定期清理过期缓存\n this.startCleanupInterval();\n }\n\n /**\n * 初始化持久化缓存\n */\n private async initPersistence(): Promise<void> {\n try {\n // 检查 IndexedDB 是否可用\n if (typeof window !== 'undefined' && 'indexedDB' in window) {\n this.persistenceEnabled = true;\n await this.loadFromPersistence();\n logger.debug('路由缓存持久化已启用');\n }\n } catch (error) {\n logger.warn('路由缓存持久化初始化失败', error);\n this.persistenceEnabled = false;\n }\n }\n\n /**\n * 从持久化存储加载缓存\n */\n private async loadFromPersistence(): Promise<void> {\n try {\n // 这里可以实现从 IndexedDB 加载缓存的逻辑\n // 由于 IndexedDB 操作较复杂,这里先留空\n // 实际实现可以使用 idb 库或原生 IndexedDB API\n } catch (error) {\n logger.warn('从持久化存储加载缓存失败', error);\n }\n }\n\n /**\n * 保存到持久化存储\n */\n private async saveToPersistence(_key: string, _value: TransformRoutesResult): Promise<void> {\n if (!this.persistenceEnabled) {\n return;\n }\n\n try {\n // 这里可以实现保存到 IndexedDB 的逻辑\n // 实际实现可以使用 idb 库或原生 IndexedDB API\n } catch (error) {\n logger.warn('保存到持久化存储失败', error);\n }\n }\n\n /**\n * 生成缓存键\n */\n private generateKey(routes: RouteConfig[] | (() => RouteConfig[] | Promise<RouteConfig[]>)): string {\n if (typeof routes === 'function') {\n // 对于函数,使用函数名或随机 ID\n return `fn_${routes.name || Math.random().toString(36).substring(7)}`;\n }\n\n // 对于数组,使用 JSON.stringify 生成键(注意:这可能会很慢)\n // 实际使用中可以考虑使用路由配置的哈希值\n try {\n const routesStr = JSON.stringify(routes, (_key, value) => {\n // 过滤掉函数,避免序列化问题\n if (typeof value === 'function') {\n return '[Function]';\n }\n return value;\n });\n return `routes_${this.hashString(routesStr)}`;\n } catch (error) {\n // 如果序列化失败,使用随机键\n return `routes_${Math.random().toString(36).substring(7)}`;\n }\n }\n\n /**\n * 字符串哈希函数(简单实现)\n */\n private hashString(str: string): string {\n let hash = 0;\n for (let i = 0; i < str.length; i++) {\n const char = str.charCodeAt(i);\n hash = (hash << 5) - hash + char;\n hash = hash & hash; // 转换为 32 位整数\n }\n return Math.abs(hash).toString(36);\n }\n\n /**\n * 检查缓存项是否过期\n */\n private isExpired(item: CacheItem<unknown>): boolean {\n return Date.now() > item.expiresAt;\n }\n\n /**\n * 清理过期缓存\n */\n private cleanup(): void {\n\n // 清理转换结果缓存\n for (const [key, item] of this.cache.entries()) {\n if (this.isExpired(item)) {\n this.cache.delete(key);\n }\n }\n\n // 清理匹配结果缓存\n for (const [key, item] of this.matchCache.entries()) {\n if (this.isExpired(item)) {\n this.matchCache.delete(key);\n }\n }\n\n // 如果缓存超过最大大小,删除最久未访问的项(LRU)\n this.evictLRU();\n }\n\n /**\n * LRU 淘汰策略\n */\n private evictLRU(): void {\n // 清理转换结果缓存\n if (this.cache.size > this.config.maxSize) {\n const sorted = Array.from(this.cache.entries()).sort(\n (a, b) => a[1].lastAccessedAt - b[1].lastAccessedAt\n );\n const toDelete = sorted.slice(0, this.cache.size - this.config.maxSize);\n toDelete.forEach(([key]) => this.cache.delete(key));\n }\n\n // 清理匹配结果缓存\n if (this.matchCache.size > this.config.maxSize) {\n const sorted = Array.from(this.matchCache.entries()).sort(\n (a, b) => a[1].lastAccessedAt - b[1].lastAccessedAt\n );\n const toDelete = sorted.slice(0, this.matchCache.size - this.config.maxSize);\n toDelete.forEach(([key]) => this.matchCache.delete(key));\n }\n }\n\n /**\n * 启动定期清理\n */\n private startCleanupInterval(): void {\n if (this.cleanupTimer) {\n clearInterval(this.cleanupTimer);\n }\n\n // 每 1 分钟清理一次过期缓存\n this.cleanupTimer = setInterval(() => {\n this.cleanup();\n }, 60 * 1000);\n }\n\n /**\n * 获取转换结果缓存\n */\n get(routes: RouteConfig[] | (() => RouteConfig[] | Promise<RouteConfig[]>)): TransformRoutesResult | null {\n const key = this.generateKey(routes);\n const item = this.cache.get(key);\n\n if (!item) {\n this.stats.transformMisses++;\n return null;\n }\n\n if (this.isExpired(item)) {\n this.cache.delete(key);\n this.stats.transformMisses++;\n return null;\n }\n\n // 更新访问信息\n item.lastAccessedAt = Date.now();\n item.accessCount++;\n this.stats.transformHits++;\n\n return item.value;\n }\n\n /**\n * 设置转换结果缓存\n */\n set(\n routes: RouteConfig[] | (() => RouteConfig[] | Promise<RouteConfig[]>),\n value: TransformRoutesResult\n ): void {\n const key = this.generateKey(routes);\n const now = Date.now();\n\n const item: CacheItem<TransformRoutesResult> = {\n value,\n expiresAt: now + this.config.ttl,\n createdAt: now,\n accessCount: 0,\n lastAccessedAt: now,\n };\n\n this.cache.set(key, item);\n\n // 保存到持久化存储\n if (this.persistenceEnabled) {\n this.saveToPersistence(key, value).catch((error) => {\n logger.warn('保存缓存到持久化存储失败', error);\n });\n }\n\n // 检查是否需要淘汰\n this.evictLRU();\n }\n\n /**\n * 获取路由匹配缓存\n */\n getMatch(path: string): RouteConfig | null | undefined {\n const item = this.matchCache.get(path);\n\n if (!item) {\n this.stats.matchMisses++;\n return undefined;\n }\n\n if (this.isExpired(item)) {\n this.matchCache.delete(path);\n this.stats.matchMisses++;\n return undefined;\n }\n\n // 更新访问信息\n item.lastAccessedAt = Date.now();\n item.accessCount++;\n this.stats.matchHits++;\n\n return item.value;\n }\n\n /**\n * 设置路由匹配缓存\n */\n setMatch(path: string, route: RouteConfig | null): void {\n const now = Date.now();\n\n const item: CacheItem<RouteConfig | null> = {\n value: route,\n expiresAt: now + this.config.ttl,\n createdAt: now,\n accessCount: 0,\n lastAccessedAt: now,\n };\n\n this.matchCache.set(path, item);\n\n // 检查是否需要淘汰\n this.evictLRU();\n }\n\n /**\n * 清空所有缓存\n */\n clear(): void {\n this.cache.clear();\n this.matchCache.clear();\n this.stats = {\n transformHits: 0,\n transformMisses: 0,\n matchHits: 0,\n matchMisses: 0,\n };\n logger.debug('路由缓存已清空');\n }\n\n /**\n * 销毁缓存实例并释放资源\n */\n destroy(): void {\n this.clear();\n if (this.cleanupTimer) {\n clearInterval(this.cleanupTimer);\n this.cleanupTimer = null;\n }\n }\n\n /**\n * 获取缓存统计信息\n */\n getStats(): {\n transformCacheSize: number;\n matchCacheSize: number;\n totalSize: number;\n hitRate: number;\n } {\n const totalHits = this.stats.transformHits + this.stats.matchHits;\n const totalAccess =\n totalHits +\n this.stats.transformMisses +\n this.stats.matchMisses;\n\n const hitRate = totalAccess > 0 ? totalHits / totalAccess : 0;\n\n return {\n transformCacheSize: this.cache.size,\n matchCacheSize: this.matchCache.size,\n totalSize: this.cache.size + this.matchCache.size,\n hitRate,\n };\n }\n}\n\n/**\n * 获取路由缓存管理器单例\n */\nlet routeCacheInstance: RouteCache | null = null;\n\nexport function getRouteCache(config?: RouteCacheConfig): RouteCache {\n if (!routeCacheInstance) {\n routeCacheInstance = new RouteCache(config);\n }\n return routeCacheInstance;\n}\n"],"names":["RouteCache","getRouteCache","initPersistence","window","persistenceEnabled","loadFromPersistence","logger","debug","error","warn","saveToPersistence","_key","_value","generateKey","routes","name","Math","random","toString","substring","routesStr","JSON","stringify","value","hashString","str","hash","i","length","char","charCodeAt","abs","isExpired","item","Date","now","expiresAt","cleanup","key","cache","entries","delete","matchCache","evictLRU","size","config","maxSize","sorted","Array","from","sort","a","b","lastAccessedAt","toDelete","slice","forEach","startCleanupInterval","cleanupTimer","clearInterval","setInterval","get","stats","transformMisses","accessCount","transformHits","set","ttl","createdAt","catch","getMatch","path","matchMisses","undefined","matchHits","setMatch","route","clear","destroy","getStats","totalHits","totalAccess","hitRate","transformCacheSize","matchCacheSize","totalSize","Map","enablePersistence","persistenceKeyPrefix","routeCacheInstance"],"mappings":"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"}
@@ -37,6 +37,8 @@ export declare class RouteCache {
37
37
  private matchCache;
38
38
  private config;
39
39
  private persistenceEnabled;
40
+ private cleanupTimer;
41
+ private stats;
40
42
  constructor(config?: RouteCacheConfig);
41
43
  /**
42
44
  * 初始化持久化缓存
@@ -77,11 +79,11 @@ export declare class RouteCache {
77
79
  /**
78
80
  * 获取转换结果缓存
79
81
  */
80
- get(routes: RouteConfig[] | (() => Promise<RouteConfig[]>)): TransformRoutesResult | null;
82
+ get(routes: RouteConfig[] | (() => RouteConfig[] | Promise<RouteConfig[]>)): TransformRoutesResult | null;
81
83
  /**
82
84
  * 设置转换结果缓存
83
85
  */
84
- set(routes: RouteConfig[] | (() => Promise<RouteConfig[]>), value: TransformRoutesResult): void;
86
+ set(routes: RouteConfig[] | (() => RouteConfig[] | Promise<RouteConfig[]>), value: TransformRoutesResult): void;
85
87
  /**
86
88
  * 获取路由匹配缓存
87
89
  */
@@ -94,6 +96,10 @@ export declare class RouteCache {
94
96
  * 清空所有缓存
95
97
  */
96
98
  clear(): void;
99
+ /**
100
+ * 销毁缓存实例并释放资源
101
+ */
102
+ destroy(): void;
97
103
  /**
98
104
  * 获取缓存统计信息
99
105
  */
@@ -105,4 +111,3 @@ export declare class RouteCache {
105
111
  };
106
112
  }
107
113
  export declare function getRouteCache(config?: RouteCacheConfig): RouteCache;
108
- //# sourceMappingURL=RouteCache.d.ts.map
@@ -133,8 +133,11 @@ function _define_property(obj, key, value) {
133
133
  /**
134
134
  * 启动定期清理
135
135
  */ startCleanupInterval() {
136
+ if (this.cleanupTimer) {
137
+ clearInterval(this.cleanupTimer);
138
+ }
136
139
  // 每 1 分钟清理一次过期缓存
137
- setInterval(()=>{
140
+ this.cleanupTimer = setInterval(()=>{
138
141
  this.cleanup();
139
142
  }, 60 * 1000);
140
143
  }
@@ -144,15 +147,18 @@ function _define_property(obj, key, value) {
144
147
  const key = this.generateKey(routes);
145
148
  const item = this.cache.get(key);
146
149
  if (!item) {
150
+ this.stats.transformMisses++;
147
151
  return null;
148
152
  }
149
153
  if (this.isExpired(item)) {
150
154
  this.cache.delete(key);
155
+ this.stats.transformMisses++;
151
156
  return null;
152
157
  }
153
158
  // 更新访问信息
154
159
  item.lastAccessedAt = Date.now();
155
160
  item.accessCount++;
161
+ this.stats.transformHits++;
156
162
  return item.value;
157
163
  }
158
164
  /**
@@ -182,15 +188,18 @@ function _define_property(obj, key, value) {
182
188
  */ getMatch(path) {
183
189
  const item = this.matchCache.get(path);
184
190
  if (!item) {
191
+ this.stats.matchMisses++;
185
192
  return undefined;
186
193
  }
187
194
  if (this.isExpired(item)) {
188
195
  this.matchCache.delete(path);
196
+ this.stats.matchMisses++;
189
197
  return undefined;
190
198
  }
191
199
  // 更新访问信息
192
200
  item.lastAccessedAt = Date.now();
193
201
  item.accessCount++;
202
+ this.stats.matchHits++;
194
203
  return item.value;
195
204
  }
196
205
  /**
@@ -213,23 +222,28 @@ function _define_property(obj, key, value) {
213
222
  */ clear() {
214
223
  this.cache.clear();
215
224
  this.matchCache.clear();
225
+ this.stats = {
226
+ transformHits: 0,
227
+ transformMisses: 0,
228
+ matchHits: 0,
229
+ matchMisses: 0
230
+ };
216
231
  logger.debug('路由缓存已清空');
217
232
  }
218
233
  /**
234
+ * 销毁缓存实例并释放资源
235
+ */ destroy() {
236
+ this.clear();
237
+ if (this.cleanupTimer) {
238
+ clearInterval(this.cleanupTimer);
239
+ this.cleanupTimer = null;
240
+ }
241
+ }
242
+ /**
219
243
  * 获取缓存统计信息
220
244
  */ getStats() {
221
- let totalHits = 0;
222
- let totalAccess = 0;
223
- // 统计转换结果缓存
224
- for (const item of this.cache.values()){
225
- totalHits += item.accessCount;
226
- totalAccess += item.accessCount;
227
- }
228
- // 统计匹配结果缓存
229
- for (const item of this.matchCache.values()){
230
- totalHits += item.accessCount;
231
- totalAccess += item.accessCount;
232
- }
245
+ const totalHits = this.stats.transformHits + this.stats.matchHits;
246
+ const totalAccess = totalHits + this.stats.transformMisses + this.stats.matchMisses;
233
247
  const hitRate = totalAccess > 0 ? totalHits / totalAccess : 0;
234
248
  return {
235
249
  transformCacheSize: this.cache.size,
@@ -243,6 +257,13 @@ function _define_property(obj, key, value) {
243
257
  _define_property(this, "matchCache", new Map());
244
258
  _define_property(this, "config", void 0);
245
259
  _define_property(this, "persistenceEnabled", false);
260
+ _define_property(this, "cleanupTimer", null);
261
+ _define_property(this, "stats", {
262
+ transformHits: 0,
263
+ transformMisses: 0,
264
+ matchHits: 0,
265
+ matchMisses: 0
266
+ });
246
267
  this.config = {
247
268
  maxSize: config.maxSize ?? 50,
248
269
  ttl: config.ttl ?? 5 * 60 * 1000,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/core/router/performance/RouteCache.ts"],"sourcesContent":["/**\n * 路由缓存管理器\n * 提供路由转换结果、匹配结果的缓存功能\n */\n\nimport { logger } from '../../../utils';\nimport type { RouteConfig } from '../types';\nimport type { TransformRoutesResult } from '../utils/transform';\n\n/**\n * 缓存项接口\n */\ninterface CacheItem<T> {\n /**\n * 缓存值\n */\n value: T;\n /**\n * 过期时间戳\n */\n expiresAt: number;\n /**\n * 创建时间戳\n */\n createdAt: number;\n /**\n * 访问次数\n */\n accessCount: number;\n /**\n * 最后访问时间\n */\n lastAccessedAt: number;\n}\n\n/**\n * LRU 缓存配置\n */\nexport interface RouteCacheConfig {\n /**\n * 最大缓存数量\n * @default 50\n */\n maxSize?: number;\n\n /**\n * 缓存过期时间(毫秒)\n * @default 5 * 60 * 1000 (5分钟)\n */\n ttl?: number;\n\n /**\n * 是否启用持久化缓存(使用 IndexedDB)\n * @default false\n */\n enablePersistence?: boolean;\n\n /**\n * 持久化缓存键前缀\n * @default 'router_cache_'\n */\n persistenceKeyPrefix?: string;\n}\n\n/**\n * 路由缓存管理器\n */\nexport class RouteCache {\n private cache: Map<string, CacheItem<TransformRoutesResult>> = new Map();\n private matchCache: Map<string, CacheItem<RouteConfig | null>> = new Map();\n private config: Required<RouteCacheConfig>;\n private persistenceEnabled: boolean = false;\n\n constructor(config: RouteCacheConfig = {}) {\n this.config = {\n maxSize: config.maxSize ?? 50,\n ttl: config.ttl ?? 5 * 60 * 1000,\n enablePersistence: config.enablePersistence ?? false,\n persistenceKeyPrefix: config.persistenceKeyPrefix ?? 'router_cache_',\n };\n\n // 初始化持久化缓存\n if (this.config.enablePersistence && typeof window !== 'undefined' && 'indexedDB' in window) {\n this.initPersistence();\n }\n\n // 定期清理过期缓存\n this.startCleanupInterval();\n }\n\n /**\n * 初始化持久化缓存\n */\n private async initPersistence(): Promise<void> {\n try {\n // 检查 IndexedDB 是否可用\n if (typeof window !== 'undefined' && 'indexedDB' in window) {\n this.persistenceEnabled = true;\n await this.loadFromPersistence();\n logger.debug('路由缓存持久化已启用');\n }\n } catch (error) {\n logger.warn('路由缓存持久化初始化失败', error);\n this.persistenceEnabled = false;\n }\n }\n\n /**\n * 从持久化存储加载缓存\n */\n private async loadFromPersistence(): Promise<void> {\n try {\n // 这里可以实现从 IndexedDB 加载缓存的逻辑\n // 由于 IndexedDB 操作较复杂,这里先留空\n // 实际实现可以使用 idb 库或原生 IndexedDB API\n } catch (error) {\n logger.warn('从持久化存储加载缓存失败', error);\n }\n }\n\n /**\n * 保存到持久化存储\n */\n private async saveToPersistence(_key: string, _value: TransformRoutesResult): Promise<void> {\n if (!this.persistenceEnabled) {\n return;\n }\n\n try {\n // 这里可以实现保存到 IndexedDB 的逻辑\n // 实际实现可以使用 idb 库或原生 IndexedDB API\n } catch (error) {\n logger.warn('保存到持久化存储失败', error);\n }\n }\n\n /**\n * 生成缓存键\n */\n private generateKey(routes: RouteConfig[] | (() => Promise<RouteConfig[]>)): string {\n if (typeof routes === 'function') {\n // 对于函数,使用函数名或随机 ID\n return `fn_${routes.name || Math.random().toString(36).substring(7)}`;\n }\n\n // 对于数组,使用 JSON.stringify 生成键(注意:这可能会很慢)\n // 实际使用中可以考虑使用路由配置的哈希值\n try {\n const routesStr = JSON.stringify(routes, (_key, value) => {\n // 过滤掉函数,避免序列化问题\n if (typeof value === 'function') {\n return '[Function]';\n }\n return value;\n });\n return `routes_${this.hashString(routesStr)}`;\n } catch (error) {\n // 如果序列化失败,使用随机键\n return `routes_${Math.random().toString(36).substring(7)}`;\n }\n }\n\n /**\n * 字符串哈希函数(简单实现)\n */\n private hashString(str: string): string {\n let hash = 0;\n for (let i = 0; i < str.length; i++) {\n const char = str.charCodeAt(i);\n hash = (hash << 5) - hash + char;\n hash = hash & hash; // 转换为 32 位整数\n }\n return Math.abs(hash).toString(36);\n }\n\n /**\n * 检查缓存项是否过期\n */\n private isExpired(item: CacheItem<unknown>): boolean {\n return Date.now() > item.expiresAt;\n }\n\n /**\n * 清理过期缓存\n */\n private cleanup(): void {\n\n // 清理转换结果缓存\n for (const [key, item] of this.cache.entries()) {\n if (this.isExpired(item)) {\n this.cache.delete(key);\n }\n }\n\n // 清理匹配结果缓存\n for (const [key, item] of this.matchCache.entries()) {\n if (this.isExpired(item)) {\n this.matchCache.delete(key);\n }\n }\n\n // 如果缓存超过最大大小,删除最久未访问的项(LRU)\n this.evictLRU();\n }\n\n /**\n * LRU 淘汰策略\n */\n private evictLRU(): void {\n // 清理转换结果缓存\n if (this.cache.size > this.config.maxSize) {\n const sorted = Array.from(this.cache.entries()).sort(\n (a, b) => a[1].lastAccessedAt - b[1].lastAccessedAt\n );\n const toDelete = sorted.slice(0, this.cache.size - this.config.maxSize);\n toDelete.forEach(([key]) => this.cache.delete(key));\n }\n\n // 清理匹配结果缓存\n if (this.matchCache.size > this.config.maxSize) {\n const sorted = Array.from(this.matchCache.entries()).sort(\n (a, b) => a[1].lastAccessedAt - b[1].lastAccessedAt\n );\n const toDelete = sorted.slice(0, this.matchCache.size - this.config.maxSize);\n toDelete.forEach(([key]) => this.matchCache.delete(key));\n }\n }\n\n /**\n * 启动定期清理\n */\n private startCleanupInterval(): void {\n // 每 1 分钟清理一次过期缓存\n setInterval(() => {\n this.cleanup();\n }, 60 * 1000);\n }\n\n /**\n * 获取转换结果缓存\n */\n get(routes: RouteConfig[] | (() => Promise<RouteConfig[]>)): TransformRoutesResult | null {\n const key = this.generateKey(routes);\n const item = this.cache.get(key);\n\n if (!item) {\n return null;\n }\n\n if (this.isExpired(item)) {\n this.cache.delete(key);\n return null;\n }\n\n // 更新访问信息\n item.lastAccessedAt = Date.now();\n item.accessCount++;\n\n return item.value;\n }\n\n /**\n * 设置转换结果缓存\n */\n set(\n routes: RouteConfig[] | (() => Promise<RouteConfig[]>),\n value: TransformRoutesResult\n ): void {\n const key = this.generateKey(routes);\n const now = Date.now();\n\n const item: CacheItem<TransformRoutesResult> = {\n value,\n expiresAt: now + this.config.ttl,\n createdAt: now,\n accessCount: 0,\n lastAccessedAt: now,\n };\n\n this.cache.set(key, item);\n\n // 保存到持久化存储\n if (this.persistenceEnabled) {\n this.saveToPersistence(key, value).catch((error) => {\n logger.warn('保存缓存到持久化存储失败', error);\n });\n }\n\n // 检查是否需要淘汰\n this.evictLRU();\n }\n\n /**\n * 获取路由匹配缓存\n */\n getMatch(path: string): RouteConfig | null | undefined {\n const item = this.matchCache.get(path);\n\n if (!item) {\n return undefined;\n }\n\n if (this.isExpired(item)) {\n this.matchCache.delete(path);\n return undefined;\n }\n\n // 更新访问信息\n item.lastAccessedAt = Date.now();\n item.accessCount++;\n\n return item.value;\n }\n\n /**\n * 设置路由匹配缓存\n */\n setMatch(path: string, route: RouteConfig | null): void {\n const now = Date.now();\n\n const item: CacheItem<RouteConfig | null> = {\n value: route,\n expiresAt: now + this.config.ttl,\n createdAt: now,\n accessCount: 0,\n lastAccessedAt: now,\n };\n\n this.matchCache.set(path, item);\n\n // 检查是否需要淘汰\n this.evictLRU();\n }\n\n /**\n * 清空所有缓存\n */\n clear(): void {\n this.cache.clear();\n this.matchCache.clear();\n logger.debug('路由缓存已清空');\n }\n\n /**\n * 获取缓存统计信息\n */\n getStats(): {\n transformCacheSize: number;\n matchCacheSize: number;\n totalSize: number;\n hitRate: number;\n } {\n let totalHits = 0;\n let totalAccess = 0;\n\n // 统计转换结果缓存\n for (const item of this.cache.values()) {\n totalHits += item.accessCount;\n totalAccess += item.accessCount;\n }\n\n // 统计匹配结果缓存\n for (const item of this.matchCache.values()) {\n totalHits += item.accessCount;\n totalAccess += item.accessCount;\n }\n\n const hitRate = totalAccess > 0 ? totalHits / totalAccess : 0;\n\n return {\n transformCacheSize: this.cache.size,\n matchCacheSize: this.matchCache.size,\n totalSize: this.cache.size + this.matchCache.size,\n hitRate,\n };\n }\n}\n\n/**\n * 获取路由缓存管理器单例\n */\nlet routeCacheInstance: RouteCache | null = null;\n\nexport function getRouteCache(config?: RouteCacheConfig): RouteCache {\n if (!routeCacheInstance) {\n routeCacheInstance = new RouteCache(config);\n }\n return routeCacheInstance;\n}\n"],"names":["logger","RouteCache","initPersistence","window","persistenceEnabled","loadFromPersistence","debug","error","warn","saveToPersistence","_key","_value","generateKey","routes","name","Math","random","toString","substring","routesStr","JSON","stringify","value","hashString","str","hash","i","length","char","charCodeAt","abs","isExpired","item","Date","now","expiresAt","cleanup","key","cache","entries","delete","matchCache","evictLRU","size","config","maxSize","sorted","Array","from","sort","a","b","lastAccessedAt","toDelete","slice","forEach","startCleanupInterval","setInterval","get","accessCount","set","ttl","createdAt","catch","getMatch","path","undefined","setMatch","route","clear","getStats","totalHits","totalAccess","values","hitRate","transformCacheSize","matchCacheSize","totalSize","Map","enablePersistence","persistenceKeyPrefix","routeCacheInstance","getRouteCache"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../../src/core/router/performance/RouteCache.ts"],"sourcesContent":["/**\n * 路由缓存管理器\n * 提供路由转换结果、匹配结果的缓存功能\n */\n\nimport { logger } from '../../../utils';\nimport type { RouteConfig } from '../types';\nimport type { TransformRoutesResult } from '../utils/transform';\n\n/**\n * 缓存项接口\n */\ninterface CacheItem<T> {\n /**\n * 缓存值\n */\n value: T;\n /**\n * 过期时间戳\n */\n expiresAt: number;\n /**\n * 创建时间戳\n */\n createdAt: number;\n /**\n * 访问次数\n */\n accessCount: number;\n /**\n * 最后访问时间\n */\n lastAccessedAt: number;\n}\n\n/**\n * LRU 缓存配置\n */\nexport interface RouteCacheConfig {\n /**\n * 最大缓存数量\n * @default 50\n */\n maxSize?: number;\n\n /**\n * 缓存过期时间(毫秒)\n * @default 5 * 60 * 1000 (5分钟)\n */\n ttl?: number;\n\n /**\n * 是否启用持久化缓存(使用 IndexedDB)\n * @default false\n */\n enablePersistence?: boolean;\n\n /**\n * 持久化缓存键前缀\n * @default 'router_cache_'\n */\n persistenceKeyPrefix?: string;\n}\n\n/**\n * 路由缓存管理器\n */\nexport class RouteCache {\n private cache: Map<string, CacheItem<TransformRoutesResult>> = new Map();\n private matchCache: Map<string, CacheItem<RouteConfig | null>> = new Map();\n private config: Required<RouteCacheConfig>;\n private persistenceEnabled: boolean = false;\n private cleanupTimer: ReturnType<typeof setInterval> | null = null;\n private stats = {\n transformHits: 0,\n transformMisses: 0,\n matchHits: 0,\n matchMisses: 0,\n };\n\n constructor(config: RouteCacheConfig = {}) {\n this.config = {\n maxSize: config.maxSize ?? 50,\n ttl: config.ttl ?? 5 * 60 * 1000,\n enablePersistence: config.enablePersistence ?? false,\n persistenceKeyPrefix: config.persistenceKeyPrefix ?? 'router_cache_',\n };\n\n // 初始化持久化缓存\n if (this.config.enablePersistence && typeof window !== 'undefined' && 'indexedDB' in window) {\n this.initPersistence();\n }\n\n // 定期清理过期缓存\n this.startCleanupInterval();\n }\n\n /**\n * 初始化持久化缓存\n */\n private async initPersistence(): Promise<void> {\n try {\n // 检查 IndexedDB 是否可用\n if (typeof window !== 'undefined' && 'indexedDB' in window) {\n this.persistenceEnabled = true;\n await this.loadFromPersistence();\n logger.debug('路由缓存持久化已启用');\n }\n } catch (error) {\n logger.warn('路由缓存持久化初始化失败', error);\n this.persistenceEnabled = false;\n }\n }\n\n /**\n * 从持久化存储加载缓存\n */\n private async loadFromPersistence(): Promise<void> {\n try {\n // 这里可以实现从 IndexedDB 加载缓存的逻辑\n // 由于 IndexedDB 操作较复杂,这里先留空\n // 实际实现可以使用 idb 库或原生 IndexedDB API\n } catch (error) {\n logger.warn('从持久化存储加载缓存失败', error);\n }\n }\n\n /**\n * 保存到持久化存储\n */\n private async saveToPersistence(_key: string, _value: TransformRoutesResult): Promise<void> {\n if (!this.persistenceEnabled) {\n return;\n }\n\n try {\n // 这里可以实现保存到 IndexedDB 的逻辑\n // 实际实现可以使用 idb 库或原生 IndexedDB API\n } catch (error) {\n logger.warn('保存到持久化存储失败', error);\n }\n }\n\n /**\n * 生成缓存键\n */\n private generateKey(routes: RouteConfig[] | (() => RouteConfig[] | Promise<RouteConfig[]>)): string {\n if (typeof routes === 'function') {\n // 对于函数,使用函数名或随机 ID\n return `fn_${routes.name || Math.random().toString(36).substring(7)}`;\n }\n\n // 对于数组,使用 JSON.stringify 生成键(注意:这可能会很慢)\n // 实际使用中可以考虑使用路由配置的哈希值\n try {\n const routesStr = JSON.stringify(routes, (_key, value) => {\n // 过滤掉函数,避免序列化问题\n if (typeof value === 'function') {\n return '[Function]';\n }\n return value;\n });\n return `routes_${this.hashString(routesStr)}`;\n } catch (error) {\n // 如果序列化失败,使用随机键\n return `routes_${Math.random().toString(36).substring(7)}`;\n }\n }\n\n /**\n * 字符串哈希函数(简单实现)\n */\n private hashString(str: string): string {\n let hash = 0;\n for (let i = 0; i < str.length; i++) {\n const char = str.charCodeAt(i);\n hash = (hash << 5) - hash + char;\n hash = hash & hash; // 转换为 32 位整数\n }\n return Math.abs(hash).toString(36);\n }\n\n /**\n * 检查缓存项是否过期\n */\n private isExpired(item: CacheItem<unknown>): boolean {\n return Date.now() > item.expiresAt;\n }\n\n /**\n * 清理过期缓存\n */\n private cleanup(): void {\n\n // 清理转换结果缓存\n for (const [key, item] of this.cache.entries()) {\n if (this.isExpired(item)) {\n this.cache.delete(key);\n }\n }\n\n // 清理匹配结果缓存\n for (const [key, item] of this.matchCache.entries()) {\n if (this.isExpired(item)) {\n this.matchCache.delete(key);\n }\n }\n\n // 如果缓存超过最大大小,删除最久未访问的项(LRU)\n this.evictLRU();\n }\n\n /**\n * LRU 淘汰策略\n */\n private evictLRU(): void {\n // 清理转换结果缓存\n if (this.cache.size > this.config.maxSize) {\n const sorted = Array.from(this.cache.entries()).sort(\n (a, b) => a[1].lastAccessedAt - b[1].lastAccessedAt\n );\n const toDelete = sorted.slice(0, this.cache.size - this.config.maxSize);\n toDelete.forEach(([key]) => this.cache.delete(key));\n }\n\n // 清理匹配结果缓存\n if (this.matchCache.size > this.config.maxSize) {\n const sorted = Array.from(this.matchCache.entries()).sort(\n (a, b) => a[1].lastAccessedAt - b[1].lastAccessedAt\n );\n const toDelete = sorted.slice(0, this.matchCache.size - this.config.maxSize);\n toDelete.forEach(([key]) => this.matchCache.delete(key));\n }\n }\n\n /**\n * 启动定期清理\n */\n private startCleanupInterval(): void {\n if (this.cleanupTimer) {\n clearInterval(this.cleanupTimer);\n }\n\n // 每 1 分钟清理一次过期缓存\n this.cleanupTimer = setInterval(() => {\n this.cleanup();\n }, 60 * 1000);\n }\n\n /**\n * 获取转换结果缓存\n */\n get(routes: RouteConfig[] | (() => RouteConfig[] | Promise<RouteConfig[]>)): TransformRoutesResult | null {\n const key = this.generateKey(routes);\n const item = this.cache.get(key);\n\n if (!item) {\n this.stats.transformMisses++;\n return null;\n }\n\n if (this.isExpired(item)) {\n this.cache.delete(key);\n this.stats.transformMisses++;\n return null;\n }\n\n // 更新访问信息\n item.lastAccessedAt = Date.now();\n item.accessCount++;\n this.stats.transformHits++;\n\n return item.value;\n }\n\n /**\n * 设置转换结果缓存\n */\n set(\n routes: RouteConfig[] | (() => RouteConfig[] | Promise<RouteConfig[]>),\n value: TransformRoutesResult\n ): void {\n const key = this.generateKey(routes);\n const now = Date.now();\n\n const item: CacheItem<TransformRoutesResult> = {\n value,\n expiresAt: now + this.config.ttl,\n createdAt: now,\n accessCount: 0,\n lastAccessedAt: now,\n };\n\n this.cache.set(key, item);\n\n // 保存到持久化存储\n if (this.persistenceEnabled) {\n this.saveToPersistence(key, value).catch((error) => {\n logger.warn('保存缓存到持久化存储失败', error);\n });\n }\n\n // 检查是否需要淘汰\n this.evictLRU();\n }\n\n /**\n * 获取路由匹配缓存\n */\n getMatch(path: string): RouteConfig | null | undefined {\n const item = this.matchCache.get(path);\n\n if (!item) {\n this.stats.matchMisses++;\n return undefined;\n }\n\n if (this.isExpired(item)) {\n this.matchCache.delete(path);\n this.stats.matchMisses++;\n return undefined;\n }\n\n // 更新访问信息\n item.lastAccessedAt = Date.now();\n item.accessCount++;\n this.stats.matchHits++;\n\n return item.value;\n }\n\n /**\n * 设置路由匹配缓存\n */\n setMatch(path: string, route: RouteConfig | null): void {\n const now = Date.now();\n\n const item: CacheItem<RouteConfig | null> = {\n value: route,\n expiresAt: now + this.config.ttl,\n createdAt: now,\n accessCount: 0,\n lastAccessedAt: now,\n };\n\n this.matchCache.set(path, item);\n\n // 检查是否需要淘汰\n this.evictLRU();\n }\n\n /**\n * 清空所有缓存\n */\n clear(): void {\n this.cache.clear();\n this.matchCache.clear();\n this.stats = {\n transformHits: 0,\n transformMisses: 0,\n matchHits: 0,\n matchMisses: 0,\n };\n logger.debug('路由缓存已清空');\n }\n\n /**\n * 销毁缓存实例并释放资源\n */\n destroy(): void {\n this.clear();\n if (this.cleanupTimer) {\n clearInterval(this.cleanupTimer);\n this.cleanupTimer = null;\n }\n }\n\n /**\n * 获取缓存统计信息\n */\n getStats(): {\n transformCacheSize: number;\n matchCacheSize: number;\n totalSize: number;\n hitRate: number;\n } {\n const totalHits = this.stats.transformHits + this.stats.matchHits;\n const totalAccess =\n totalHits +\n this.stats.transformMisses +\n this.stats.matchMisses;\n\n const hitRate = totalAccess > 0 ? totalHits / totalAccess : 0;\n\n return {\n transformCacheSize: this.cache.size,\n matchCacheSize: this.matchCache.size,\n totalSize: this.cache.size + this.matchCache.size,\n hitRate,\n };\n }\n}\n\n/**\n * 获取路由缓存管理器单例\n */\nlet routeCacheInstance: RouteCache | null = null;\n\nexport function getRouteCache(config?: RouteCacheConfig): RouteCache {\n if (!routeCacheInstance) {\n routeCacheInstance = new RouteCache(config);\n }\n return routeCacheInstance;\n}\n"],"names":["logger","RouteCache","initPersistence","window","persistenceEnabled","loadFromPersistence","debug","error","warn","saveToPersistence","_key","_value","generateKey","routes","name","Math","random","toString","substring","routesStr","JSON","stringify","value","hashString","str","hash","i","length","char","charCodeAt","abs","isExpired","item","Date","now","expiresAt","cleanup","key","cache","entries","delete","matchCache","evictLRU","size","config","maxSize","sorted","Array","from","sort","a","b","lastAccessedAt","toDelete","slice","forEach","startCleanupInterval","cleanupTimer","clearInterval","setInterval","get","stats","transformMisses","accessCount","transformHits","set","ttl","createdAt","catch","getMatch","path","matchMisses","undefined","matchHits","setMatch","route","clear","destroy","getStats","totalHits","totalAccess","hitRate","transformCacheSize","matchCacheSize","totalSize","Map","enablePersistence","persistenceKeyPrefix","routeCacheInstance","getRouteCache"],"mappings":"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"}