@vlian/framework 1.2.59 → 1.2.60

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 (154) hide show
  1. package/dist/analytics/index.cjs +1 -22
  2. package/dist/analytics.umd.js +1 -1
  3. package/dist/components/LocaleSwitch.cjs +1 -116
  4. package/dist/components/ThemeSwitch.cjs +1 -115
  5. package/dist/components/index.cjs +1 -20
  6. package/dist/components/persistence.cjs +1 -58
  7. package/dist/core/Test.cjs +1 -64
  8. package/dist/core/app/AppContext.cjs +1 -348
  9. package/dist/core/app/AppContext.types.cjs +1 -4
  10. package/dist/core/app/BasicLayout.cjs +1 -122
  11. package/dist/core/app/DefaultApp.cjs +1 -150
  12. package/dist/core/app/index.cjs +1 -41
  13. package/dist/core/config/AppConfig.cjs +1 -139
  14. package/dist/core/config/ConfigLoader.cjs +1 -323
  15. package/dist/core/config/ConfigValidator.cjs +2 -133
  16. package/dist/core/config/index.cjs +1 -28
  17. package/dist/core/dev/DevTools.cjs +1 -226
  18. package/dist/core/error/ErrorBoundary.cjs +1 -401
  19. package/dist/core/error/ErrorHandler.cjs +1 -275
  20. package/dist/core/error/index.cjs +1 -34
  21. package/dist/core/event/AppEventBus.cjs +1 -444
  22. package/dist/core/event/frameworkEvents.cjs +1 -141
  23. package/dist/core/event/hooks.cjs +1 -69
  24. package/dist/core/event/index.cjs +1 -41
  25. package/dist/core/event/types.cjs +1 -62
  26. package/dist/core/event/useEventBus.cjs +1 -25
  27. package/dist/core/index.cjs +1 -140
  28. package/dist/core/initialization/InitializationErrorThrower.cjs +1 -75
  29. package/dist/core/initialization/index.cjs +1 -26
  30. package/dist/core/initialization/initialization.cjs +1 -64
  31. package/dist/core/initialization/initializationErrorState.cjs +1 -66
  32. package/dist/core/kernel/defaultAdapters.cjs +1 -184
  33. package/dist/core/kernel/errors.cjs +1 -69
  34. package/dist/core/kernel/index.cjs +1 -20
  35. package/dist/core/kernel/startKernel.cjs +1 -200
  36. package/dist/core/kernel/types.cjs +1 -4
  37. package/dist/core/middleware.cjs +1 -73
  38. package/dist/core/plugin/PluginEventBus.cjs +1 -298
  39. package/dist/core/plugin/PluginSandbox.cjs +1 -137
  40. package/dist/core/plugin.cjs +1 -494
  41. package/dist/core/router/RouterManager.cjs +1 -286
  42. package/dist/core/router/adapter/AdapterManager.cjs +1 -235
  43. package/dist/core/router/adapter/index.cjs +1 -22
  44. package/dist/core/router/adapter/react-router/ReactRouterAdapter.cjs +1 -128
  45. package/dist/core/router/adapter/react-router/index.cjs +1 -20
  46. package/dist/core/router/adapter/types.cjs +1 -6
  47. package/dist/core/router/dev/RouterDevTools.cjs +1 -260
  48. package/dist/core/router/dev/index.cjs +1 -20
  49. package/dist/core/router/dynamic/DynamicRouteManager.cjs +1 -193
  50. package/dist/core/router/dynamic/index.cjs +1 -20
  51. package/dist/core/router/errors/RouterError.cjs +1 -61
  52. package/dist/core/router/errors/index.cjs +1 -20
  53. package/dist/core/router/index.cjs +1 -36
  54. package/dist/core/router/lifecycle/RouterLifecycleManager.cjs +1 -144
  55. package/dist/core/router/lifecycle/index.cjs +1 -20
  56. package/dist/core/router/middleware/RouterMiddlewareManager.cjs +1 -193
  57. package/dist/core/router/middleware/auth.cjs +1 -66
  58. package/dist/core/router/middleware/index.cjs +1 -22
  59. package/dist/core/router/middleware/types.cjs +1 -6
  60. package/dist/core/router/monitoring/RouterMonitoring.cjs +1 -227
  61. package/dist/core/router/monitoring/index.cjs +1 -20
  62. package/dist/core/router/navigation/RouterNavigation.cjs +1 -239
  63. package/dist/core/router/navigation/index.cjs +1 -20
  64. package/dist/core/router/performance/RouteCache.cjs +1 -305
  65. package/dist/core/router/performance/RoutePreloader.cjs +1 -292
  66. package/dist/core/router/performance/index.cjs +1 -21
  67. package/dist/core/router/plugin/RouterPluginManager.cjs +1 -262
  68. package/dist/core/router/plugin/index.cjs +1 -21
  69. package/dist/core/router/plugin/types.cjs +1 -39
  70. package/dist/core/router/types.cjs +1 -4
  71. package/dist/core/router/utils/adapters/react-router/RouteErrorBoundary.cjs +1 -129
  72. package/dist/core/router/utils/adapters/react-router/transform.cjs +1 -250
  73. package/dist/core/router/utils/transform.cjs +1 -780
  74. package/dist/core/router/validation/RouterConfigValidator.cjs +2 -83
  75. package/dist/core/router/validation/index.cjs +1 -21
  76. package/dist/core/router/validation/schema.cjs +1 -159
  77. package/dist/core/router/version/RouteVersionManager.cjs +1 -205
  78. package/dist/core/router/version/index.cjs +1 -20
  79. package/dist/core/splash/SplashScreen.cjs +1 -341
  80. package/dist/core/splash/index.cjs +1 -22
  81. package/dist/core/splash/splashScreenUtils.cjs +1 -38
  82. package/dist/core/startup/AppInstance.cjs +1 -239
  83. package/dist/core/startup/environment.cjs +1 -169
  84. package/dist/core/startup/index.cjs +1 -23
  85. package/dist/core/startup/initializeServices.cjs +1 -226
  86. package/dist/core/startup/performanceTracker.cjs +1 -179
  87. package/dist/core/startup/renderApp.cjs +1 -314
  88. package/dist/core/startup/startApp.cjs +1 -317
  89. package/dist/core/types.cjs +1 -4
  90. package/dist/index.cjs +1 -52
  91. package/dist/index.umd.cjs +1 -27
  92. package/dist/index.umd.js +1 -1
  93. package/dist/kernel/constants.cjs +1 -65
  94. package/dist/kernel/index.cjs +1 -38
  95. package/dist/kernel/kernel.cjs +1 -295
  96. package/dist/kernel/manager/cacheManager.cjs +1 -46
  97. package/dist/kernel/manager/i18n/I18nManager.cjs +1 -91
  98. package/dist/kernel/manager/i18n/i18n.persistence.cjs +1 -60
  99. package/dist/kernel/manager/i18n/i18n.schema.cjs +1 -86
  100. package/dist/kernel/manager/i18n/index.cjs +1 -11
  101. package/dist/kernel/manager/i18nManager.cjs +1 -11
  102. package/dist/kernel/manager/index.cjs +1 -28
  103. package/dist/kernel/manager/logger/LoggerManager.cjs +1 -107
  104. package/dist/kernel/manager/logger/index.cjs +1 -11
  105. package/dist/kernel/manager/logger/logger.persistence.cjs +1 -62
  106. package/dist/kernel/manager/logger/logger.schema.cjs +1 -74
  107. package/dist/kernel/manager/loggerManager.cjs +1 -11
  108. package/dist/kernel/manager/theme/ThemeManager.cjs +1 -84
  109. package/dist/kernel/manager/theme/index.cjs +1 -11
  110. package/dist/kernel/manager/theme/theme.dom.cjs +1 -61
  111. package/dist/kernel/manager/theme/theme.persistence.cjs +1 -57
  112. package/dist/kernel/manager/theme/theme.schema.cjs +1 -122
  113. package/dist/kernel/manager/themeManager.cjs +1 -11
  114. package/dist/kernel/types.cjs +1 -4
  115. package/dist/library/index.cjs +1 -19
  116. package/dist/library/locale/index.cjs +1 -39
  117. package/dist/library/locale/langs/en-us/index.cjs +1 -32
  118. package/dist/library/locale/langs/zh-cn/index.cjs +1 -32
  119. package/dist/library/locale/types.cjs +1 -4
  120. package/dist/library/storage/cache.cjs +1 -243
  121. package/dist/library/storage/encryption.cjs +1 -147
  122. package/dist/library/storage/index.cjs +1 -124
  123. package/dist/state/StateManager.cjs +1 -166
  124. package/dist/state/adapters/AdapterFactory.cjs +1 -89
  125. package/dist/state/adapters/DefaultAdapter.cjs +1 -75
  126. package/dist/state/adapters/ReduxAdapter.cjs +1 -443
  127. package/dist/state/adapters/ZustandAdapter.cjs +1 -69
  128. package/dist/state/adapters/index.cjs +1 -44
  129. package/dist/state/adapters/types.cjs +1 -20
  130. package/dist/state/core/DerivedStateInstance.cjs +1 -174
  131. package/dist/state/core/StateInstance.cjs +1 -170
  132. package/dist/state/core/StateRegistry.cjs +1 -110
  133. package/dist/state/core/StateScope.cjs +1 -137
  134. package/dist/state/core/index.cjs +1 -30
  135. package/dist/state/index.cjs +1 -30
  136. package/dist/state/types.cjs +1 -12
  137. package/dist/state.umd.js +1 -1
  138. package/dist/types.cjs +1 -4
  139. package/dist/utils/analytics.cjs +1 -217
  140. package/dist/utils/configSecurity.cjs +3 -182
  141. package/dist/utils/csrf.cjs +1 -18
  142. package/dist/utils/errors/ErrorCodes.cjs +1 -25
  143. package/dist/utils/errors.cjs +1 -111
  144. package/dist/utils/index.cjs +1 -135
  145. package/dist/utils/logger.cjs +1 -25
  146. package/dist/utils/logger.types.cjs +1 -11
  147. package/dist/utils/monitoring.cjs +1 -18
  148. package/dist/utils/performance.cjs +1 -22
  149. package/dist/utils/resourceLoader.cjs +1 -22
  150. package/dist/utils/runtimeSecurity.cjs +1 -11
  151. package/dist/utils/security.cjs +1 -19
  152. package/dist/utils/traceId.cjs +1 -37
  153. package/dist/utils/validation.cjs +1 -19
  154. package/package.json +7 -3
@@ -1,305 +1 @@
1
- /**
2
- * 路由缓存管理器
3
- * 提供路由转换结果、匹配结果的缓存功能
4
- */ "use strict";
5
- Object.defineProperty(exports, "__esModule", {
6
- value: true
7
- });
8
- function _export(target, all) {
9
- for(var name in all)Object.defineProperty(target, name, {
10
- enumerable: true,
11
- get: Object.getOwnPropertyDescriptor(all, name).get
12
- });
13
- }
14
- _export(exports, {
15
- get RouteCache () {
16
- return RouteCache;
17
- },
18
- get getRouteCache () {
19
- return getRouteCache;
20
- }
21
- });
22
- const _logger = require("@vlian/logger");
23
- function _define_property(obj, key, value) {
24
- if (key in obj) {
25
- Object.defineProperty(obj, key, {
26
- value: value,
27
- enumerable: true,
28
- configurable: true,
29
- writable: true
30
- });
31
- } else {
32
- obj[key] = value;
33
- }
34
- return obj;
35
- }
36
- let RouteCache = class RouteCache {
37
- /**
38
- * 初始化持久化缓存
39
- */ async initPersistence() {
40
- try {
41
- // 检查 IndexedDB 是否可用
42
- if (typeof window !== 'undefined' && 'indexedDB' in window) {
43
- this.persistenceEnabled = true;
44
- await this.loadFromPersistence();
45
- _logger.logger.debug('路由缓存持久化已启用');
46
- }
47
- } catch (error) {
48
- _logger.logger.warn('路由缓存持久化初始化失败', error);
49
- this.persistenceEnabled = false;
50
- }
51
- }
52
- /**
53
- * 从持久化存储加载缓存
54
- */ async loadFromPersistence() {
55
- try {
56
- // 这里可以实现从 IndexedDB 加载缓存的逻辑
57
- // 由于 IndexedDB 操作较复杂,这里先留空
58
- // 实际实现可以使用 idb 库或原生 IndexedDB API
59
- } catch (error) {
60
- _logger.logger.warn('从持久化存储加载缓存失败', error);
61
- }
62
- }
63
- /**
64
- * 保存到持久化存储
65
- */ async saveToPersistence(_key, _value) {
66
- if (!this.persistenceEnabled) {
67
- return;
68
- }
69
- try {
70
- // 这里可以实现保存到 IndexedDB 的逻辑
71
- // 实际实现可以使用 idb 库或原生 IndexedDB API
72
- } catch (error) {
73
- _logger.logger.warn('保存到持久化存储失败', error);
74
- }
75
- }
76
- /**
77
- * 生成缓存键
78
- */ generateKey(routes) {
79
- if (typeof routes === 'function') {
80
- // 对于函数,使用函数名或随机 ID
81
- return `fn_${routes.name || Math.random().toString(36).substring(7)}`;
82
- }
83
- // 对于数组,使用 JSON.stringify 生成键(注意:这可能会很慢)
84
- // 实际使用中可以考虑使用路由配置的哈希值
85
- try {
86
- const routesStr = JSON.stringify(routes, (_key, value)=>{
87
- // 过滤掉函数,避免序列化问题
88
- if (typeof value === 'function') {
89
- return '[Function]';
90
- }
91
- return value;
92
- });
93
- return `routes_${this.hashString(routesStr)}`;
94
- } catch (error) {
95
- // 如果序列化失败,使用随机键
96
- return `routes_${Math.random().toString(36).substring(7)}`;
97
- }
98
- }
99
- /**
100
- * 字符串哈希函数(简单实现)
101
- */ hashString(str) {
102
- let hash = 0;
103
- for(let i = 0; i < str.length; i++){
104
- const char = str.charCodeAt(i);
105
- hash = (hash << 5) - hash + char;
106
- hash = hash & hash; // 转换为 32 位整数
107
- }
108
- return Math.abs(hash).toString(36);
109
- }
110
- /**
111
- * 检查缓存项是否过期
112
- */ isExpired(item) {
113
- return Date.now() > item.expiresAt;
114
- }
115
- /**
116
- * 清理过期缓存
117
- */ cleanup() {
118
- // 清理转换结果缓存
119
- for (const [key, item] of this.cache.entries()){
120
- if (this.isExpired(item)) {
121
- this.cache.delete(key);
122
- }
123
- }
124
- // 清理匹配结果缓存
125
- for (const [key, item] of this.matchCache.entries()){
126
- if (this.isExpired(item)) {
127
- this.matchCache.delete(key);
128
- }
129
- }
130
- // 如果缓存超过最大大小,删除最久未访问的项(LRU)
131
- this.evictLRU();
132
- }
133
- /**
134
- * LRU 淘汰策略
135
- */ evictLRU() {
136
- // 清理转换结果缓存
137
- if (this.cache.size > this.config.maxSize) {
138
- const sorted = Array.from(this.cache.entries()).sort((a, b)=>a[1].lastAccessedAt - b[1].lastAccessedAt);
139
- const toDelete = sorted.slice(0, this.cache.size - this.config.maxSize);
140
- toDelete.forEach(([key])=>this.cache.delete(key));
141
- }
142
- // 清理匹配结果缓存
143
- if (this.matchCache.size > this.config.maxSize) {
144
- const sorted = Array.from(this.matchCache.entries()).sort((a, b)=>a[1].lastAccessedAt - b[1].lastAccessedAt);
145
- const toDelete = sorted.slice(0, this.matchCache.size - this.config.maxSize);
146
- toDelete.forEach(([key])=>this.matchCache.delete(key));
147
- }
148
- }
149
- /**
150
- * 启动定期清理
151
- */ startCleanupInterval() {
152
- if (this.cleanupTimer) {
153
- clearInterval(this.cleanupTimer);
154
- }
155
- // 每 1 分钟清理一次过期缓存
156
- this.cleanupTimer = setInterval(()=>{
157
- this.cleanup();
158
- }, 60 * 1000);
159
- }
160
- /**
161
- * 获取转换结果缓存
162
- */ get(routes) {
163
- const key = this.generateKey(routes);
164
- const item = this.cache.get(key);
165
- if (!item) {
166
- this.stats.transformMisses++;
167
- return null;
168
- }
169
- if (this.isExpired(item)) {
170
- this.cache.delete(key);
171
- this.stats.transformMisses++;
172
- return null;
173
- }
174
- // 更新访问信息
175
- item.lastAccessedAt = Date.now();
176
- item.accessCount++;
177
- this.stats.transformHits++;
178
- return item.value;
179
- }
180
- /**
181
- * 设置转换结果缓存
182
- */ set(routes, value) {
183
- const key = this.generateKey(routes);
184
- const now = Date.now();
185
- const item = {
186
- value,
187
- expiresAt: now + this.config.ttl,
188
- createdAt: now,
189
- accessCount: 0,
190
- lastAccessedAt: now
191
- };
192
- this.cache.set(key, item);
193
- // 保存到持久化存储
194
- if (this.persistenceEnabled) {
195
- this.saveToPersistence(key, value).catch((error)=>{
196
- _logger.logger.warn('保存缓存到持久化存储失败', error);
197
- });
198
- }
199
- // 检查是否需要淘汰
200
- this.evictLRU();
201
- }
202
- /**
203
- * 获取路由匹配缓存
204
- */ getMatch(path) {
205
- const item = this.matchCache.get(path);
206
- if (!item) {
207
- this.stats.matchMisses++;
208
- return undefined;
209
- }
210
- if (this.isExpired(item)) {
211
- this.matchCache.delete(path);
212
- this.stats.matchMisses++;
213
- return undefined;
214
- }
215
- // 更新访问信息
216
- item.lastAccessedAt = Date.now();
217
- item.accessCount++;
218
- this.stats.matchHits++;
219
- return item.value;
220
- }
221
- /**
222
- * 设置路由匹配缓存
223
- */ setMatch(path, route) {
224
- const now = Date.now();
225
- const item = {
226
- value: route,
227
- expiresAt: now + this.config.ttl,
228
- createdAt: now,
229
- accessCount: 0,
230
- lastAccessedAt: now
231
- };
232
- this.matchCache.set(path, item);
233
- // 检查是否需要淘汰
234
- this.evictLRU();
235
- }
236
- /**
237
- * 清空所有缓存
238
- */ clear() {
239
- this.cache.clear();
240
- this.matchCache.clear();
241
- this.stats = {
242
- transformHits: 0,
243
- transformMisses: 0,
244
- matchHits: 0,
245
- matchMisses: 0
246
- };
247
- _logger.logger.debug('路由缓存已清空');
248
- }
249
- /**
250
- * 销毁缓存实例并释放资源
251
- */ destroy() {
252
- this.clear();
253
- if (this.cleanupTimer) {
254
- clearInterval(this.cleanupTimer);
255
- this.cleanupTimer = null;
256
- }
257
- }
258
- /**
259
- * 获取缓存统计信息
260
- */ getStats() {
261
- const totalHits = this.stats.transformHits + this.stats.matchHits;
262
- const totalAccess = totalHits + this.stats.transformMisses + this.stats.matchMisses;
263
- const hitRate = totalAccess > 0 ? totalHits / totalAccess : 0;
264
- return {
265
- transformCacheSize: this.cache.size,
266
- matchCacheSize: this.matchCache.size,
267
- totalSize: this.cache.size + this.matchCache.size,
268
- hitRate
269
- };
270
- }
271
- constructor(config = {}){
272
- _define_property(this, "cache", new Map());
273
- _define_property(this, "matchCache", new Map());
274
- _define_property(this, "config", void 0);
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
- });
283
- this.config = {
284
- maxSize: config.maxSize ?? 50,
285
- ttl: config.ttl ?? 5 * 60 * 1000,
286
- enablePersistence: config.enablePersistence ?? false,
287
- persistenceKeyPrefix: config.persistenceKeyPrefix ?? 'router_cache_'
288
- };
289
- // 初始化持久化缓存
290
- if (this.config.enablePersistence && typeof window !== 'undefined' && 'indexedDB' in window) {
291
- this.initPersistence();
292
- }
293
- // 定期清理过期缓存
294
- this.startCleanupInterval();
295
- }
296
- };
297
- /**
298
- * 获取路由缓存管理器单例
299
- */ let routeCacheInstance = null;
300
- function getRouteCache(config) {
301
- if (!routeCacheInstance) {
302
- routeCacheInstance = new RouteCache(config);
303
- }
304
- return routeCacheInstance;
305
- }
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:true});function _export(target,all){for(var name in all)Object.defineProperty(target,name,{enumerable:true,get:Object.getOwnPropertyDescriptor(all,name).get})}_export(exports,{get RouteCache(){return RouteCache},get getRouteCache(){return getRouteCache}});const _logger=require("@vlian/logger");function _define_property(obj,key,value){if(key in obj){Object.defineProperty(obj,key,{value:value,enumerable:true,configurable:true,writable:true})}else{obj[key]=value}return obj}let RouteCache=class RouteCache{async initPersistence(){try{if(typeof window!=="undefined"&&"indexedDB"in window){this.persistenceEnabled=true;await this.loadFromPersistence();_logger.logger.debug("路由缓存持久化已启用")}}catch(error){_logger.logger.warn("路由缓存持久化初始化失败",error);this.persistenceEnabled=false}}async loadFromPersistence(){try{}catch(error){_logger.logger.warn("从持久化存储加载缓存失败",error)}}async saveToPersistence(_key,_value){if(!this.persistenceEnabled){return}try{}catch(error){_logger.logger.warn("保存到持久化存储失败",error)}}generateKey(routes){if(typeof routes==="function"){return`fn_${routes.name||Math.random().toString(36).substring(7)}`}try{const routesStr=JSON.stringify(routes,(_key,value)=>{if(typeof value==="function"){return"[Function]"}return value});return`routes_${this.hashString(routesStr)}`}catch(error){return`routes_${Math.random().toString(36).substring(7)}`}}hashString(str){let hash=0;for(let i=0;i<str.length;i++){const char=str.charCodeAt(i);hash=(hash<<5)-hash+char;hash=hash&hash}return Math.abs(hash).toString(36)}isExpired(item){return Date.now()>item.expiresAt}cleanup(){for(const[key,item]of this.cache.entries()){if(this.isExpired(item)){this.cache.delete(key)}}for(const[key,item]of this.matchCache.entries()){if(this.isExpired(item)){this.matchCache.delete(key)}}this.evictLRU()}evictLRU(){if(this.cache.size>this.config.maxSize){const sorted=Array.from(this.cache.entries()).sort((a,b)=>a[1].lastAccessedAt-b[1].lastAccessedAt);const toDelete=sorted.slice(0,this.cache.size-this.config.maxSize);toDelete.forEach(([key])=>this.cache.delete(key))}if(this.matchCache.size>this.config.maxSize){const sorted=Array.from(this.matchCache.entries()).sort((a,b)=>a[1].lastAccessedAt-b[1].lastAccessedAt);const toDelete=sorted.slice(0,this.matchCache.size-this.config.maxSize);toDelete.forEach(([key])=>this.matchCache.delete(key))}}startCleanupInterval(){if(this.cleanupTimer){clearInterval(this.cleanupTimer)}this.cleanupTimer=setInterval(()=>{this.cleanup()},60*1e3)}get(routes){const key=this.generateKey(routes);const item=this.cache.get(key);if(!item){this.stats.transformMisses++;return null}if(this.isExpired(item)){this.cache.delete(key);this.stats.transformMisses++;return null}item.lastAccessedAt=Date.now();item.accessCount++;this.stats.transformHits++;return item.value}set(routes,value){const key=this.generateKey(routes);const now=Date.now();const item={value,expiresAt:now+this.config.ttl,createdAt:now,accessCount:0,lastAccessedAt:now};this.cache.set(key,item);if(this.persistenceEnabled){this.saveToPersistence(key,value).catch(error=>{_logger.logger.warn("保存缓存到持久化存储失败",error)})}this.evictLRU()}getMatch(path){const item=this.matchCache.get(path);if(!item){this.stats.matchMisses++;return undefined}if(this.isExpired(item)){this.matchCache.delete(path);this.stats.matchMisses++;return undefined}item.lastAccessedAt=Date.now();item.accessCount++;this.stats.matchHits++;return item.value}setMatch(path,route){const now=Date.now();const item={value:route,expiresAt:now+this.config.ttl,createdAt:now,accessCount:0,lastAccessedAt:now};this.matchCache.set(path,item);this.evictLRU()}clear(){this.cache.clear();this.matchCache.clear();this.stats={transformHits:0,transformMisses:0,matchHits:0,matchMisses:0};_logger.logger.debug("路由缓存已清空")}destroy(){this.clear();if(this.cleanupTimer){clearInterval(this.cleanupTimer);this.cleanupTimer=null}}getStats(){const totalHits=this.stats.transformHits+this.stats.matchHits;const totalAccess=totalHits+this.stats.transformMisses+this.stats.matchMisses;const hitRate=totalAccess>0?totalHits/totalAccess:0;return{transformCacheSize:this.cache.size,matchCacheSize:this.matchCache.size,totalSize:this.cache.size+this.matchCache.size,hitRate}}constructor(config={}){_define_property(this,"cache",new Map);_define_property(this,"matchCache",new Map);_define_property(this,"config",void 0);_define_property(this,"persistenceEnabled",false);_define_property(this,"cleanupTimer",null);_define_property(this,"stats",{transformHits:0,transformMisses:0,matchHits:0,matchMisses:0});this.config={maxSize:config.maxSize??50,ttl:config.ttl??5*60*1e3,enablePersistence:config.enablePersistence??false,persistenceKeyPrefix:config.persistenceKeyPrefix??"router_cache_"};if(this.config.enablePersistence&&typeof window!=="undefined"&&"indexedDB"in window){this.initPersistence()}this.startCleanupInterval()}};let routeCacheInstance=null;function getRouteCache(config){if(!routeCacheInstance){routeCacheInstance=new RouteCache(config)}return routeCacheInstance}
@@ -1,292 +1 @@
1
- /**
2
- * 路由预加载管理器
3
- * 提供路由组件的预加载功能
4
- */ "use strict";
5
- Object.defineProperty(exports, "__esModule", {
6
- value: true
7
- });
8
- function _export(target, all) {
9
- for(var name in all)Object.defineProperty(target, name, {
10
- enumerable: true,
11
- get: Object.getOwnPropertyDescriptor(all, name).get
12
- });
13
- }
14
- _export(exports, {
15
- get PreloadStrategy () {
16
- return PreloadStrategy;
17
- },
18
- get RoutePreloader () {
19
- return RoutePreloader;
20
- },
21
- get getRoutePreloader () {
22
- return getRoutePreloader;
23
- }
24
- });
25
- const _logger = require("@vlian/logger");
26
- function _define_property(obj, key, value) {
27
- if (key in obj) {
28
- Object.defineProperty(obj, key, {
29
- value: value,
30
- enumerable: true,
31
- configurable: true,
32
- writable: true
33
- });
34
- } else {
35
- obj[key] = value;
36
- }
37
- return obj;
38
- }
39
- var PreloadStrategy = /*#__PURE__*/ function(PreloadStrategy) {
40
- /**
41
- * 不预加载
42
- */ PreloadStrategy["NONE"] = "none";
43
- /**
44
- * 预加载当前路由的下一级路由
45
- */ PreloadStrategy["NEXT_LEVEL"] = "next-level";
46
- /**
47
- * 预加载所有路由
48
- */ PreloadStrategy["ALL"] = "all";
49
- /**
50
- * 预加载可见路由(根据路由配置的优先级)
51
- */ PreloadStrategy["VISIBLE"] = "visible";
52
- return PreloadStrategy;
53
- }({});
54
- let RoutePreloader = class RoutePreloader {
55
- /**
56
- * 更新预加载配置
57
- */ updateConfig(config = {}) {
58
- this.config = {
59
- strategy: config.strategy ?? "none",
60
- delay: config.delay ?? 1000,
61
- priorityThreshold: config.priorityThreshold ?? 10,
62
- timeout: config.timeout ?? 5000
63
- };
64
- }
65
- shouldRegister(priority) {
66
- if (this.config.strategy === "none") {
67
- return false;
68
- }
69
- if (this.config.strategy === "visible" && priority > this.config.priorityThreshold) {
70
- return false;
71
- }
72
- return true;
73
- }
74
- registerTask(key, importFn, routeName, priority) {
75
- if (!this.shouldRegister(priority)) {
76
- return;
77
- }
78
- this.tasks.set(key, {
79
- importFn,
80
- routeName,
81
- priority,
82
- status: 'pending'
83
- });
84
- }
85
- /**
86
- * 注册路由用于预加载
87
- */ registerRoute(route) {
88
- if (!route.page && !route.layout) {
89
- return;
90
- }
91
- const priority = route.handle?.order ?? 999;
92
- // 注册页面组件
93
- if (route.page && typeof route.page === 'function') {
94
- this.registerTask(`${route.name}_page`, route.page, route.name, priority);
95
- }
96
- // 注册布局组件
97
- if (route.layout && typeof route.layout === 'function') {
98
- this.registerTask(`${route.name}_layout`, route.layout, route.name, priority);
99
- }
100
- // 递归注册子路由
101
- if (route.children) {
102
- route.children.forEach((child)=>this.registerRoute(child));
103
- }
104
- }
105
- /**
106
- * 注册多个路由
107
- */ registerRoutes(routes, resolvers) {
108
- const priorityByPath = new Map();
109
- const nameByPath = new Map();
110
- const collectPriority = (route)=>{
111
- const priority = route.handle?.order ?? 999;
112
- const routeName = route.name;
113
- const record = (value)=>{
114
- if (typeof value !== 'string') {
115
- return;
116
- }
117
- if (!priorityByPath.has(value) || (priorityByPath.get(value) ?? 999) > priority) {
118
- priorityByPath.set(value, priority);
119
- nameByPath.set(value, routeName);
120
- }
121
- };
122
- record(route.page);
123
- record(route.layout);
124
- record(route.error ?? route.errors);
125
- record(route.loading);
126
- route.children?.forEach(collectPriority);
127
- };
128
- routes.forEach(collectPriority);
129
- routes.forEach((route)=>this.registerRoute(route));
130
- if (!resolvers) {
131
- return;
132
- }
133
- const registerResolverMap = (map, type)=>{
134
- for (const [path, importFn] of map.entries()){
135
- const routeName = nameByPath.get(path) ?? path;
136
- const priority = priorityByPath.get(path) ?? 999;
137
- this.registerTask(`${routeName}_${type}_${path}`, importFn, routeName, priority);
138
- }
139
- };
140
- registerResolverMap(resolvers.pages, 'page');
141
- registerResolverMap(resolvers.layouts, 'layout');
142
- registerResolverMap(resolvers.errors, 'error');
143
- registerResolverMap(resolvers.loadings, 'loading');
144
- }
145
- /**
146
- * 预加载指定路由
147
- */ async preloadRoute(routeName) {
148
- const tasks = Array.from(this.tasks.values()).filter((task)=>task.routeName === routeName && task.status === 'pending');
149
- if (tasks.length === 0) {
150
- return;
151
- }
152
- await Promise.all(tasks.map((task)=>this.preloadTask(task)));
153
- }
154
- /**
155
- * 预加载任务
156
- */ async preloadTask(task) {
157
- if (task.status !== 'pending') {
158
- return;
159
- }
160
- task.status = 'loading';
161
- task.startTime = Date.now();
162
- let timeoutId = null;
163
- try {
164
- // 设置超时
165
- const timeoutPromise = new Promise((_, reject)=>{
166
- timeoutId = setTimeout(()=>reject(new Error('预加载超时')), this.config.timeout);
167
- });
168
- // 执行预加载
169
- await Promise.race([
170
- task.importFn(),
171
- timeoutPromise
172
- ]);
173
- task.status = 'loaded';
174
- const duration = Date.now() - (task.startTime || 0);
175
- _logger.logger.debug(`路由组件预加载成功: ${task.routeName} (${duration}ms)`);
176
- } catch (error) {
177
- task.status = 'failed';
178
- _logger.logger.warn(`路由组件预加载失败: ${task.routeName}`, error);
179
- } finally{
180
- if (timeoutId) {
181
- clearTimeout(timeoutId);
182
- }
183
- }
184
- }
185
- /**
186
- * 开始预加载(根据策略)
187
- */ startPreload() {
188
- if (this.config.strategy === "none") {
189
- return;
190
- }
191
- this.stopPreload();
192
- // 延迟预加载,避免影响初始渲染
193
- this.preloadTimer = setTimeout(()=>{
194
- const browserWindow = typeof window !== 'undefined' ? window : undefined;
195
- if (browserWindow?.requestIdleCallback) {
196
- this.idleHandle = browserWindow.requestIdleCallback(()=>{
197
- this.executePreload();
198
- });
199
- return;
200
- }
201
- this.executePreload();
202
- }, this.config.delay);
203
- }
204
- /**
205
- * 执行预加载
206
- */ async executePreload() {
207
- const tasks = Array.from(this.tasks.values()).filter((task)=>task.status === 'pending').sort((a, b)=>a.priority - b.priority);
208
- if (tasks.length === 0) {
209
- return;
210
- }
211
- _logger.logger.debug(`开始预加载 ${tasks.length} 个路由组件`);
212
- // 根据策略决定预加载哪些任务
213
- let tasksToPreload = [];
214
- switch(this.config.strategy){
215
- case "all":
216
- tasksToPreload = tasks;
217
- break;
218
- case "next-level":
219
- // 只预加载优先级最低的(最可能访问的)
220
- tasksToPreload = tasks.slice(0, Math.min(5, tasks.length));
221
- break;
222
- case "visible":
223
- tasksToPreload = tasks.filter((task)=>task.priority <= this.config.priorityThreshold);
224
- break;
225
- default:
226
- return;
227
- }
228
- // 并行预加载(限制并发数)
229
- const concurrency = 3;
230
- for(let i = 0; i < tasksToPreload.length; i += concurrency){
231
- const batch = tasksToPreload.slice(i, i + concurrency);
232
- await Promise.all(batch.map((task)=>this.preloadTask(task)));
233
- }
234
- _logger.logger.debug('路由组件预加载完成');
235
- }
236
- /**
237
- * 停止预加载
238
- */ stopPreload() {
239
- const browserWindow = typeof window !== 'undefined' ? window : undefined;
240
- if (this.preloadTimer) {
241
- clearTimeout(this.preloadTimer);
242
- this.preloadTimer = null;
243
- }
244
- if (this.idleHandle !== null && browserWindow?.cancelIdleCallback) {
245
- browserWindow.cancelIdleCallback(this.idleHandle);
246
- this.idleHandle = null;
247
- }
248
- }
249
- /**
250
- * 清空所有任务
251
- */ clear() {
252
- this.tasks.clear();
253
- this.stopPreload();
254
- _logger.logger.debug('路由预加载任务已清空');
255
- }
256
- /**
257
- * 获取预加载统计信息
258
- */ getStats() {
259
- const stats = {
260
- total: this.tasks.size,
261
- pending: 0,
262
- loading: 0,
263
- loaded: 0,
264
- failed: 0
265
- };
266
- for (const task of this.tasks.values()){
267
- stats[task.status]++;
268
- }
269
- return stats;
270
- }
271
- constructor(config = {}){
272
- _define_property(this, "tasks", new Map());
273
- _define_property(this, "config", void 0);
274
- _define_property(this, "preloadTimer", null);
275
- _define_property(this, "idleHandle", null);
276
- this.config = {
277
- strategy: config.strategy ?? "none",
278
- delay: config.delay ?? 1000,
279
- priorityThreshold: config.priorityThreshold ?? 10,
280
- timeout: config.timeout ?? 5000
281
- };
282
- }
283
- };
284
- /**
285
- * 获取路由预加载管理器单例
286
- */ let routePreloaderInstance = null;
287
- function getRoutePreloader(config) {
288
- if (!routePreloaderInstance) {
289
- routePreloaderInstance = new RoutePreloader(config);
290
- }
291
- return routePreloaderInstance;
292
- }
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:true});function _export(target,all){for(var name in all)Object.defineProperty(target,name,{enumerable:true,get:Object.getOwnPropertyDescriptor(all,name).get})}_export(exports,{get PreloadStrategy(){return PreloadStrategy},get RoutePreloader(){return RoutePreloader},get getRoutePreloader(){return getRoutePreloader}});const _logger=require("@vlian/logger");function _define_property(obj,key,value){if(key in obj){Object.defineProperty(obj,key,{value:value,enumerable:true,configurable:true,writable:true})}else{obj[key]=value}return obj}var PreloadStrategy=/*#__PURE__*/function(PreloadStrategy){PreloadStrategy["NONE"]="none";PreloadStrategy["NEXT_LEVEL"]="next-level";PreloadStrategy["ALL"]="all";PreloadStrategy["VISIBLE"]="visible";return PreloadStrategy}({});let RoutePreloader=class RoutePreloader{updateConfig(config={}){this.config={strategy:config.strategy??"none",delay:config.delay??1e3,priorityThreshold:config.priorityThreshold??10,timeout:config.timeout??5e3}}shouldRegister(priority){if(this.config.strategy==="none"){return false}if(this.config.strategy==="visible"&&priority>this.config.priorityThreshold){return false}return true}registerTask(key,importFn,routeName,priority){if(!this.shouldRegister(priority)){return}this.tasks.set(key,{importFn,routeName,priority,status:"pending"})}registerRoute(route){if(!route.page&&!route.layout){return}const priority=route.handle?.order??999;if(route.page&&typeof route.page==="function"){this.registerTask(`${route.name}_page`,route.page,route.name,priority)}if(route.layout&&typeof route.layout==="function"){this.registerTask(`${route.name}_layout`,route.layout,route.name,priority)}if(route.children){route.children.forEach(child=>this.registerRoute(child))}}registerRoutes(routes,resolvers){const priorityByPath=new Map;const nameByPath=new Map;const collectPriority=route=>{const priority=route.handle?.order??999;const routeName=route.name;const record=value=>{if(typeof value!=="string"){return}if(!priorityByPath.has(value)||(priorityByPath.get(value)??999)>priority){priorityByPath.set(value,priority);nameByPath.set(value,routeName)}};record(route.page);record(route.layout);record(route.error??route.errors);record(route.loading);route.children?.forEach(collectPriority)};routes.forEach(collectPriority);routes.forEach(route=>this.registerRoute(route));if(!resolvers){return}const registerResolverMap=(map,type)=>{for(const[path,importFn]of map.entries()){const routeName=nameByPath.get(path)??path;const priority=priorityByPath.get(path)??999;this.registerTask(`${routeName}_${type}_${path}`,importFn,routeName,priority)}};registerResolverMap(resolvers.pages,"page");registerResolverMap(resolvers.layouts,"layout");registerResolverMap(resolvers.errors,"error");registerResolverMap(resolvers.loadings,"loading")}async preloadRoute(routeName){const tasks=Array.from(this.tasks.values()).filter(task=>task.routeName===routeName&&task.status==="pending");if(tasks.length===0){return}await Promise.all(tasks.map(task=>this.preloadTask(task)))}async preloadTask(task){if(task.status!=="pending"){return}task.status="loading";task.startTime=Date.now();let timeoutId=null;try{const timeoutPromise=new Promise((_,reject)=>{timeoutId=setTimeout(()=>reject(new Error("预加载超时")),this.config.timeout)});await Promise.race([task.importFn(),timeoutPromise]);task.status="loaded";const duration=Date.now()-(task.startTime||0);_logger.logger.debug(`路由组件预加载成功: ${task.routeName} (${duration}ms)`)}catch(error){task.status="failed";_logger.logger.warn(`路由组件预加载失败: ${task.routeName}`,error)}finally{if(timeoutId){clearTimeout(timeoutId)}}}startPreload(){if(this.config.strategy==="none"){return}this.stopPreload();this.preloadTimer=setTimeout(()=>{const browserWindow=typeof window!=="undefined"?window:undefined;if(browserWindow?.requestIdleCallback){this.idleHandle=browserWindow.requestIdleCallback(()=>{this.executePreload()});return}this.executePreload()},this.config.delay)}async executePreload(){const tasks=Array.from(this.tasks.values()).filter(task=>task.status==="pending").sort((a,b)=>a.priority-b.priority);if(tasks.length===0){return}_logger.logger.debug(`开始预加载 ${tasks.length} 个路由组件`);let tasksToPreload=[];switch(this.config.strategy){case"all":tasksToPreload=tasks;break;case"next-level":tasksToPreload=tasks.slice(0,Math.min(5,tasks.length));break;case"visible":tasksToPreload=tasks.filter(task=>task.priority<=this.config.priorityThreshold);break;default:return}const concurrency=3;for(let i=0;i<tasksToPreload.length;i+=concurrency){const batch=tasksToPreload.slice(i,i+concurrency);await Promise.all(batch.map(task=>this.preloadTask(task)))}_logger.logger.debug("路由组件预加载完成")}stopPreload(){const browserWindow=typeof window!=="undefined"?window:undefined;if(this.preloadTimer){clearTimeout(this.preloadTimer);this.preloadTimer=null}if(this.idleHandle!==null&&browserWindow?.cancelIdleCallback){browserWindow.cancelIdleCallback(this.idleHandle);this.idleHandle=null}}clear(){this.tasks.clear();this.stopPreload();_logger.logger.debug("路由预加载任务已清空")}getStats(){const stats={total:this.tasks.size,pending:0,loading:0,loaded:0,failed:0};for(const task of this.tasks.values()){stats[task.status]++}return stats}constructor(config={}){_define_property(this,"tasks",new Map);_define_property(this,"config",void 0);_define_property(this,"preloadTimer",null);_define_property(this,"idleHandle",null);this.config={strategy:config.strategy??"none",delay:config.delay??1e3,priorityThreshold:config.priorityThreshold??10,timeout:config.timeout??5e3}}};let routePreloaderInstance=null;function getRoutePreloader(config){if(!routePreloaderInstance){routePreloaderInstance=new RoutePreloader(config)}return routePreloaderInstance}
@@ -1,21 +1 @@
1
- /**
2
- * 路由性能优化模块入口
3
- */ "use strict";
4
- Object.defineProperty(exports, "__esModule", {
5
- value: true
6
- });
7
- _export_star(require("./RouteCache"), exports);
8
- _export_star(require("./RoutePreloader"), exports);
9
- function _export_star(from, to) {
10
- Object.keys(from).forEach(function(k) {
11
- if (k !== "default" && !Object.prototype.hasOwnProperty.call(to, k)) {
12
- Object.defineProperty(to, k, {
13
- enumerable: true,
14
- get: function() {
15
- return from[k];
16
- }
17
- });
18
- }
19
- });
20
- return from;
21
- }
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:true});_export_star(require("./RouteCache"),exports);_export_star(require("./RoutePreloader"),exports);function _export_star(from,to){Object.keys(from).forEach(function(k){if(k!=="default"&&!Object.prototype.hasOwnProperty.call(to,k)){Object.defineProperty(to,k,{enumerable:true,get:function(){return from[k]}})}});return from}