@vlian/framework 1.2.19 → 1.2.37
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.
- package/dist/analytics.umd.js +208 -2395
- package/dist/analytics.umd.js.map +1 -1
- package/dist/core/error/ErrorHandler.cjs.map +1 -1
- package/dist/core/error/ErrorHandler.d.ts +1 -1
- package/dist/core/error/ErrorHandler.js.map +1 -1
- package/dist/core/index.cjs +0 -1
- package/dist/core/index.cjs.map +1 -1
- package/dist/core/index.d.ts +1 -2
- package/dist/core/index.js +0 -1
- package/dist/core/index.js.map +1 -1
- package/dist/core/initialization/index.cjs.map +1 -1
- package/dist/core/initialization/index.d.ts +1 -1
- package/dist/core/initialization/index.js.map +1 -1
- package/dist/core/initialization/initialization.cjs +2 -147
- package/dist/core/initialization/initialization.cjs.map +1 -1
- package/dist/core/initialization/initialization.d.ts +0 -57
- package/dist/core/initialization/initialization.js +2 -148
- package/dist/core/initialization/initialization.js.map +1 -1
- package/dist/core/kernel/startKernel.cjs +1 -2
- package/dist/core/kernel/startKernel.cjs.map +1 -1
- package/dist/core/kernel/startKernel.js +1 -2
- package/dist/core/kernel/startKernel.js.map +1 -1
- package/dist/core/plugin.cjs +16 -16
- package/dist/core/plugin.cjs.map +1 -1
- package/dist/core/plugin.d.ts +5 -1
- package/dist/core/plugin.js +17 -17
- package/dist/core/plugin.js.map +1 -1
- package/dist/core/router/monitoring/RouterMonitoring.cjs +1 -1
- package/dist/core/router/monitoring/RouterMonitoring.cjs.map +1 -1
- package/dist/core/router/monitoring/RouterMonitoring.js +1 -1
- package/dist/core/router/monitoring/RouterMonitoring.js.map +1 -1
- package/dist/core/router/utils/adapters/react-router/RouteErrorBoundary.cjs +13 -8
- package/dist/core/router/utils/adapters/react-router/RouteErrorBoundary.cjs.map +1 -1
- package/dist/core/router/utils/adapters/react-router/RouteErrorBoundary.js +13 -8
- package/dist/core/router/utils/adapters/react-router/RouteErrorBoundary.js.map +1 -1
- package/dist/core/router/utils/adapters/react-router/transform.cjs +4 -0
- package/dist/core/router/utils/adapters/react-router/transform.cjs.map +1 -1
- package/dist/core/router/utils/adapters/react-router/transform.js +4 -0
- package/dist/core/router/utils/adapters/react-router/transform.js.map +1 -1
- package/dist/core/startup/initializeServices.cjs +1 -1
- package/dist/core/startup/initializeServices.cjs.map +1 -1
- package/dist/core/startup/initializeServices.d.ts +1 -1
- package/dist/core/startup/initializeServices.js +1 -1
- package/dist/core/startup/initializeServices.js.map +1 -1
- package/dist/core/startup/performanceTracker.cjs.map +1 -1
- package/dist/core/startup/performanceTracker.d.ts +1 -1
- package/dist/core/startup/performanceTracker.js.map +1 -1
- package/dist/core/startup/renderApp.cjs +1 -1
- package/dist/core/startup/renderApp.cjs.map +1 -1
- package/dist/core/startup/renderApp.d.ts +1 -1
- package/dist/core/startup/renderApp.js +1 -1
- package/dist/core/startup/renderApp.js.map +1 -1
- package/dist/core/startup/startApp.cjs +2 -4
- package/dist/core/startup/startApp.cjs.map +1 -1
- package/dist/core/startup/startApp.js +3 -5
- package/dist/core/startup/startApp.js.map +1 -1
- package/dist/core/types.d.ts +2 -6
- package/dist/core/types.js.map +1 -1
- package/dist/index.cjs +15 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +6 -4
- package/dist/index.js +5 -4
- package/dist/index.js.map +1 -1
- package/dist/index.umd.js +11758 -32895
- package/dist/index.umd.js.map +1 -1
- package/dist/kernel/constants.cjs +67 -0
- package/dist/kernel/constants.cjs.map +1 -0
- package/dist/kernel/constants.d.ts +5 -0
- package/dist/kernel/constants.js +43 -0
- package/dist/kernel/constants.js.map +1 -0
- package/dist/kernel/index.cjs +40 -0
- package/dist/kernel/index.cjs.map +1 -0
- package/dist/kernel/index.d.ts +3 -0
- package/dist/kernel/index.js +4 -0
- package/dist/kernel/index.js.map +1 -0
- package/dist/kernel/kernel.cjs +296 -0
- package/dist/kernel/kernel.cjs.map +1 -0
- package/dist/kernel/kernel.d.ts +40 -0
- package/dist/kernel/kernel.js +272 -0
- package/dist/kernel/kernel.js.map +1 -0
- package/dist/kernel/manager/cacheManager.cjs +46 -0
- package/dist/kernel/manager/cacheManager.cjs.map +1 -0
- package/dist/kernel/manager/cacheManager.d.ts +6 -0
- package/dist/kernel/manager/cacheManager.js +36 -0
- package/dist/kernel/manager/cacheManager.js.map +1 -0
- package/dist/kernel/manager/i18nManager.cjs +68 -0
- package/dist/kernel/manager/i18nManager.cjs.map +1 -0
- package/dist/kernel/manager/i18nManager.d.ts +8 -0
- package/dist/kernel/manager/i18nManager.js +58 -0
- package/dist/kernel/manager/i18nManager.js.map +1 -0
- package/dist/kernel/manager/index.cjs +30 -0
- package/dist/kernel/manager/index.cjs.map +1 -0
- package/dist/kernel/manager/index.d.ts +4 -0
- package/dist/kernel/manager/index.js +6 -0
- package/dist/kernel/manager/index.js.map +1 -0
- package/dist/kernel/manager/loggerManager.cjs +70 -0
- package/dist/kernel/manager/loggerManager.cjs.map +1 -0
- package/dist/kernel/manager/loggerManager.d.ts +14 -0
- package/dist/kernel/manager/loggerManager.js +60 -0
- package/dist/kernel/manager/loggerManager.js.map +1 -0
- package/dist/kernel/manager/persistence.cjs +93 -0
- package/dist/kernel/manager/persistence.cjs.map +1 -0
- package/dist/kernel/manager/persistence.d.ts +3 -0
- package/dist/kernel/manager/persistence.js +75 -0
- package/dist/kernel/manager/persistence.js.map +1 -0
- package/dist/kernel/manager/themeManager.cjs +85 -0
- package/dist/kernel/manager/themeManager.cjs.map +1 -0
- package/dist/kernel/manager/themeManager.d.ts +9 -0
- package/dist/kernel/manager/themeManager.js +75 -0
- package/dist/kernel/manager/themeManager.js.map +1 -0
- package/dist/kernel/types.cjs.map +1 -0
- package/dist/kernel/types.d.ts +72 -0
- package/dist/kernel/types.js.map +1 -0
- package/dist/library/storage/index.cjs +1 -1
- package/dist/library/storage/index.cjs.map +1 -1
- package/dist/library/storage/index.d.ts +1 -0
- package/dist/library/storage/index.js +1 -1
- package/dist/library/storage/index.js.map +1 -1
- package/dist/request/adapter.d.ts +1 -0
- package/dist/request/core.d.ts +1 -0
- package/dist/request/index.d.ts +1 -42
- package/dist/request/plugin/csrfPlugin.d.ts +2 -2
- package/dist/request/plugin/queue.d.ts +2 -2
- package/dist/request/plugin.d.ts +1 -0
- package/dist/request/runtime.d.ts +1 -0
- package/dist/request/types.d.ts +1 -394
- package/dist/request/utils.d.ts +1 -0
- package/dist/state.umd.js +1 -1
- package/dist/utils/csrf.cjs +13 -152
- package/dist/utils/csrf.cjs.map +1 -1
- package/dist/utils/csrf.d.ts +1 -72
- package/dist/utils/csrf.js +1 -142
- package/dist/utils/csrf.js.map +1 -1
- package/dist/utils/errors/ErrorCodes.cjs +6 -76
- package/dist/utils/errors/ErrorCodes.cjs.map +1 -1
- package/dist/utils/errors/ErrorCodes.d.ts +1 -45
- package/dist/utils/errors/ErrorCodes.js +1 -84
- package/dist/utils/errors/ErrorCodes.js.map +1 -1
- package/dist/utils/errors.cjs +15 -344
- package/dist/utils/errors.cjs.map +1 -1
- package/dist/utils/errors.d.ts +1 -183
- package/dist/utils/errors.js +1 -352
- package/dist/utils/errors.js.map +1 -1
- package/dist/utils/logger.cjs +5 -374
- package/dist/utils/logger.cjs.map +1 -1
- package/dist/utils/logger.d.ts +2 -189
- package/dist/utils/logger.js +1 -379
- package/dist/utils/logger.js.map +1 -1
- package/dist/utils/logger.types.cjs +3 -12
- package/dist/utils/logger.types.cjs.map +1 -1
- package/dist/utils/logger.types.d.ts +2 -57
- package/dist/utils/logger.types.js +1 -10
- package/dist/utils/logger.types.js.map +1 -1
- package/dist/utils/monitoring.cjs +11 -302
- package/dist/utils/monitoring.cjs.map +1 -1
- package/dist/utils/monitoring.d.ts +1 -163
- package/dist/utils/monitoring.js +1 -294
- package/dist/utils/monitoring.js.map +1 -1
- package/dist/utils/performance.cjs +5 -352
- package/dist/utils/performance.cjs.map +1 -1
- package/dist/utils/performance.d.ts +2 -246
- package/dist/utils/performance.js +1 -354
- package/dist/utils/performance.js.map +1 -1
- package/dist/utils/resourceLoader.cjs +5 -303
- package/dist/utils/resourceLoader.cjs.map +1 -1
- package/dist/utils/resourceLoader.d.ts +2 -130
- package/dist/utils/resourceLoader.js +1 -305
- package/dist/utils/resourceLoader.js.map +1 -1
- package/dist/utils/runtimeSecurity.cjs +2 -140
- package/dist/utils/runtimeSecurity.cjs.map +1 -1
- package/dist/utils/runtimeSecurity.d.ts +2 -104
- package/dist/utils/runtimeSecurity.js +1 -141
- package/dist/utils/runtimeSecurity.js.map +1 -1
- package/dist/utils/security.cjs +3 -314
- package/dist/utils/security.cjs.map +1 -1
- package/dist/utils/security.d.ts +2 -80
- package/dist/utils/security.js +1 -311
- package/dist/utils/security.js.map +1 -1
- package/dist/utils/traceId.cjs +10 -111
- package/dist/utils/traceId.cjs.map +1 -1
- package/dist/utils/traceId.d.ts +1 -63
- package/dist/utils/traceId.js +1 -116
- package/dist/utils/traceId.js.map +1 -1
- package/dist/utils/validation.cjs +3 -173
- package/dist/utils/validation.cjs.map +1 -1
- package/dist/utils/validation.d.ts +2 -110
- package/dist/utils/validation.js +1 -175
- package/dist/utils/validation.js.map +1 -1
- package/package.json +98 -13
- package/dist/core/ui-adapter/adapters.cjs +0 -45
- package/dist/core/ui-adapter/adapters.cjs.map +0 -1
- package/dist/core/ui-adapter/adapters.d.ts +0 -4
- package/dist/core/ui-adapter/adapters.js +0 -27
- package/dist/core/ui-adapter/adapters.js.map +0 -1
- package/dist/core/ui-adapter/index.cjs +0 -21
- package/dist/core/ui-adapter/index.cjs.map +0 -1
- package/dist/core/ui-adapter/index.d.ts +0 -2
- package/dist/core/ui-adapter/index.js +0 -3
- package/dist/core/ui-adapter/index.js.map +0 -1
- package/dist/core/ui-adapter/types.cjs.map +0 -1
- package/dist/core/ui-adapter/types.d.ts +0 -24
- package/dist/core/ui-adapter/types.js.map +0 -1
- package/dist/request/adapter/RequestAdapter.cjs +0 -78
- package/dist/request/adapter/RequestAdapter.cjs.map +0 -1
- package/dist/request/adapter/axiosAdapter.cjs +0 -164
- package/dist/request/adapter/axiosAdapter.cjs.map +0 -1
- package/dist/request/adapter/fetchAdapter.cjs +0 -134
- package/dist/request/adapter/fetchAdapter.cjs.map +0 -1
- package/dist/request/adapter/index.cjs +0 -80
- package/dist/request/adapter/index.cjs.map +0 -1
- package/dist/request/adapter/kyAdapter.cjs +0 -191
- package/dist/request/adapter/kyAdapter.cjs.map +0 -1
- package/dist/request/adapter/undiciAdapter.cjs +0 -213
- package/dist/request/adapter/undiciAdapter.cjs.map +0 -1
- package/dist/request/core/RequestClient.cjs +0 -558
- package/dist/request/core/RequestClient.cjs.map +0 -1
- package/dist/request/core/index.cjs +0 -15
- package/dist/request/core/index.cjs.map +0 -1
- package/dist/request/index.cjs +0 -149
- package/dist/request/index.cjs.map +0 -1
- package/dist/request/plugin/RequestPlugin.cjs +0 -218
- package/dist/request/plugin/RequestPlugin.cjs.map +0 -1
- package/dist/request/plugin/cache.cjs +0 -269
- package/dist/request/plugin/cache.cjs.map +0 -1
- package/dist/request/plugin/csrfPlugin.cjs +0 -40
- package/dist/request/plugin/csrfPlugin.cjs.map +0 -1
- package/dist/request/plugin/index.cjs +0 -53
- package/dist/request/plugin/index.cjs.map +0 -1
- package/dist/request/plugin/monitoring.cjs +0 -216
- package/dist/request/plugin/monitoring.cjs.map +0 -1
- package/dist/request/plugin/queue.cjs +0 -140
- package/dist/request/plugin/queue.cjs.map +0 -1
- package/dist/request/plugin/retry.cjs +0 -98
- package/dist/request/plugin/retry.cjs.map +0 -1
- package/dist/request/plugin/validation.cjs +0 -121
- package/dist/request/plugin/validation.cjs.map +0 -1
- package/dist/request/runtime/RequestContext.cjs +0 -77
- package/dist/request/runtime/RequestContext.cjs.map +0 -1
- package/dist/request/runtime/index.cjs +0 -32
- package/dist/request/runtime/index.cjs.map +0 -1
- package/dist/request/types.cjs +0 -112
- package/dist/request/types.cjs.map +0 -1
- package/dist/request/utils/RequestQueueManager.cjs +0 -168
- package/dist/request/utils/RequestQueueManager.cjs.map +0 -1
- package/dist/request/utils/dependencyCheck.cjs +0 -237
- package/dist/request/utils/dependencyCheck.cjs.map +0 -1
- package/dist/request/utils/index.cjs +0 -30
- package/dist/request/utils/index.cjs.map +0 -1
- package/dist/request.umd.js +0 -5392
- package/dist/request.umd.js.map +0 -1
- /package/dist/{core/ui-adapter → kernel}/types.cjs +0 -0
- /package/dist/{core/ui-adapter → kernel}/types.js +0 -0
|
@@ -3,8 +3,13 @@ import { useState } from "react";
|
|
|
3
3
|
const isDevelopment = process.env.NODE_ENV === 'development';
|
|
4
4
|
export const RouteErrorBoundary = ({ error, resetErrorBoundary })=>{
|
|
5
5
|
const [showDetails, setShowDetails] = useState(false);
|
|
6
|
-
const
|
|
7
|
-
const
|
|
6
|
+
const errorObject = error !== null && typeof error === 'object' ? error : null;
|
|
7
|
+
const errorMessage = typeof errorObject?.message === 'string' && errorObject.message !== '' ? errorObject.message : '未知错误';
|
|
8
|
+
const hasCause = errorObject?.cause !== undefined;
|
|
9
|
+
const isNotFoundError = errorObject?.status === 404 || typeof errorObject?.statusText === 'string' && /not\s*found/i.test(errorObject.statusText) || /no routes matched location|not found|404/i.test(errorMessage);
|
|
10
|
+
const title = isNotFoundError ? '页面不存在(404)' : '出错了,请稍后再试';
|
|
11
|
+
const friendlyMessage = isNotFoundError ? '访问的路由未注册或不存在,请检查访问地址。' : '请稍后再试或联系技术支持';
|
|
12
|
+
const displayMessage = isDevelopment ? errorMessage : friendlyMessage;
|
|
8
13
|
return /*#__PURE__*/ _jsx("div", {
|
|
9
14
|
role: "alert",
|
|
10
15
|
style: {
|
|
@@ -27,10 +32,10 @@ export const RouteErrorBoundary = ({ error, resetErrorBoundary })=>{
|
|
|
27
32
|
style: {
|
|
28
33
|
marginTop: 0
|
|
29
34
|
},
|
|
30
|
-
children:
|
|
35
|
+
children: title
|
|
31
36
|
}),
|
|
32
37
|
/*#__PURE__*/ _jsx("p", {
|
|
33
|
-
children:
|
|
38
|
+
children: displayMessage
|
|
34
39
|
}),
|
|
35
40
|
/*#__PURE__*/ _jsxs("div", {
|
|
36
41
|
style: {
|
|
@@ -81,10 +86,10 @@ export const RouteErrorBoundary = ({ error, resetErrorBoundary })=>{
|
|
|
81
86
|
/*#__PURE__*/ _jsx("strong", {
|
|
82
87
|
children: "错误信息:"
|
|
83
88
|
}),
|
|
84
|
-
|
|
89
|
+
errorMessage
|
|
85
90
|
]
|
|
86
91
|
}),
|
|
87
|
-
|
|
92
|
+
errorObject?.stack && /*#__PURE__*/ _jsxs("div", {
|
|
88
93
|
style: {
|
|
89
94
|
marginBottom: 10,
|
|
90
95
|
whiteSpace: 'pre-wrap',
|
|
@@ -95,7 +100,7 @@ export const RouteErrorBoundary = ({ error, resetErrorBoundary })=>{
|
|
|
95
100
|
children: "堆栈:"
|
|
96
101
|
}),
|
|
97
102
|
/*#__PURE__*/ _jsx("br", {}),
|
|
98
|
-
|
|
103
|
+
errorObject.stack
|
|
99
104
|
]
|
|
100
105
|
}),
|
|
101
106
|
hasCause && /*#__PURE__*/ _jsxs("div", {
|
|
@@ -103,7 +108,7 @@ export const RouteErrorBoundary = ({ error, resetErrorBoundary })=>{
|
|
|
103
108
|
/*#__PURE__*/ _jsx("strong", {
|
|
104
109
|
children: "原因:"
|
|
105
110
|
}),
|
|
106
|
-
|
|
111
|
+
errorObject?.cause instanceof Error ? errorObject.cause.message : String(errorObject?.cause)
|
|
107
112
|
]
|
|
108
113
|
})
|
|
109
114
|
]
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../../src/core/router/utils/adapters/react-router/RouteErrorBoundary.tsx"],"sourcesContent":["import { useState } from 'react';\nimport type { FallbackProps } from 'react-error-boundary';\n\nconst isDevelopment = process.env.NODE_ENV === 'development';\n\ninterface
|
|
1
|
+
{"version":3,"sources":["../../../../../../src/core/router/utils/adapters/react-router/RouteErrorBoundary.tsx"],"sourcesContent":["import { useState } from 'react';\nimport type { FallbackProps } from 'react-error-boundary';\n\nconst isDevelopment = process.env.NODE_ENV === 'development';\n\ninterface RouteErrorLike extends Error {\n status?: number;\n statusText?: string;\n data?: unknown;\n cause?: unknown;\n}\n\nexport const RouteErrorBoundary = ({ error, resetErrorBoundary }: FallbackProps) => {\n const [showDetails, setShowDetails] = useState(false);\n const errorObject: RouteErrorLike | null =\n error !== null && typeof error === 'object' ? (error as RouteErrorLike) : null;\n const errorMessage =\n typeof errorObject?.message === 'string' && errorObject.message !== ''\n ? errorObject.message\n : '未知错误';\n const hasCause = errorObject?.cause !== undefined;\n\n const isNotFoundError =\n errorObject?.status === 404 ||\n (typeof errorObject?.statusText === 'string' && /not\\s*found/i.test(errorObject.statusText)) ||\n /no routes matched location|not found|404/i.test(errorMessage);\n\n const title = isNotFoundError ? '页面不存在(404)' : '出错了,请稍后再试';\n const friendlyMessage = isNotFoundError\n ? '访问的路由未注册或不存在,请检查访问地址。'\n : '请稍后再试或联系技术支持';\n const displayMessage = isDevelopment ? errorMessage : friendlyMessage;\n\n return (\n <div\n role=\"alert\"\n style={{\n minHeight: '100vh',\n display: 'flex',\n justifyContent: 'center',\n alignItems: 'center',\n padding: 24,\n }}\n >\n <div style={{ maxWidth: 760, width: '100%', border: '1px solid #dde5ec', borderRadius: 10, padding: 20 }}>\n <h2 style={{ marginTop: 0 }}>{title}</h2>\n <p>{displayMessage}</p>\n <div style={{ display: 'flex', gap: 8, marginBottom: 12 }}>\n <button\n onClick={resetErrorBoundary}\n style={{ border: 'none', background: '#2f80ed', color: '#fff', borderRadius: 6, padding: '8px 12px', cursor: 'pointer' }}\n >\n 刷新重试\n </button>\n {isDevelopment && (\n <button\n onClick={() => setShowDetails(!showDetails)}\n style={{ border: '1px solid #cfd7df', background: '#fff', borderRadius: 6, padding: '8px 12px', cursor: 'pointer' }}\n >\n {showDetails ? '收起详情' : '展开详情'}\n </button>\n )}\n </div>\n\n {isDevelopment && showDetails && (\n <div style={{ background: '#f7fafc', borderRadius: 8, padding: 12, fontSize: 12, fontFamily: 'monospace' }}>\n <div style={{ marginBottom: 10 }}><strong>错误信息:</strong>{errorMessage}</div>\n {errorObject?.stack && (\n <div style={{ marginBottom: 10, whiteSpace: 'pre-wrap', wordBreak: 'break-word' }}>\n <strong>堆栈:</strong>\n <br />\n {errorObject.stack}\n </div>\n )}\n {hasCause && (\n <div>\n <strong>原因:</strong>\n {errorObject?.cause instanceof Error ? errorObject.cause.message : String(errorObject?.cause)}\n </div>\n )}\n </div>\n )}\n </div>\n </div>\n );\n};\n"],"names":["useState","isDevelopment","process","env","NODE_ENV","RouteErrorBoundary","error","resetErrorBoundary","showDetails","setShowDetails","errorObject","errorMessage","message","hasCause","cause","undefined","isNotFoundError","status","statusText","test","title","friendlyMessage","displayMessage","div","role","style","minHeight","display","justifyContent","alignItems","padding","maxWidth","width","border","borderRadius","h2","marginTop","p","gap","marginBottom","button","onClick","background","color","cursor","fontSize","fontFamily","strong","stack","whiteSpace","wordBreak","br","Error","String"],"mappings":";AAAA,SAASA,QAAQ,QAAQ,QAAQ;AAGjC,MAAMC,gBAAgBC,QAAQC,GAAG,CAACC,QAAQ,KAAK;AAS/C,OAAO,MAAMC,qBAAqB,CAAC,EAAEC,KAAK,EAAEC,kBAAkB,EAAiB;IAC7E,MAAM,CAACC,aAAaC,eAAe,GAAGT,SAAS;IAC/C,MAAMU,cACJJ,UAAU,QAAQ,OAAOA,UAAU,WAAYA,QAA2B;IAC5E,MAAMK,eACJ,OAAOD,aAAaE,YAAY,YAAYF,YAAYE,OAAO,KAAK,KAChEF,YAAYE,OAAO,GACnB;IACN,MAAMC,WAAWH,aAAaI,UAAUC;IAExC,MAAMC,kBACJN,aAAaO,WAAW,OACvB,OAAOP,aAAaQ,eAAe,YAAY,eAAeC,IAAI,CAACT,YAAYQ,UAAU,KAC1F,4CAA4CC,IAAI,CAACR;IAEnD,MAAMS,QAAQJ,kBAAkB,eAAe;IAC/C,MAAMK,kBAAkBL,kBACpB,0BACA;IACJ,MAAMM,iBAAiBrB,gBAAgBU,eAAeU;IAEtD,qBACE,KAACE;QACCC,MAAK;QACLC,OAAO;YACLC,WAAW;YACXC,SAAS;YACTC,gBAAgB;YAChBC,YAAY;YACZC,SAAS;QACX;kBAEA,cAAA,MAACP;YAAIE,OAAO;gBAAEM,UAAU;gBAAKC,OAAO;gBAAQC,QAAQ;gBAAqBC,cAAc;gBAAIJ,SAAS;YAAG;;8BACrG,KAACK;oBAAGV,OAAO;wBAAEW,WAAW;oBAAE;8BAAIhB;;8BAC9B,KAACiB;8BAAGf;;8BACJ,MAACC;oBAAIE,OAAO;wBAAEE,SAAS;wBAAQW,KAAK;wBAAGC,cAAc;oBAAG;;sCACtD,KAACC;4BACCC,SAASlC;4BACTkB,OAAO;gCAAEQ,QAAQ;gCAAQS,YAAY;gCAAWC,OAAO;gCAAQT,cAAc;gCAAGJ,SAAS;gCAAYc,QAAQ;4BAAU;sCACxH;;wBAGA3C,+BACC,KAACuC;4BACCC,SAAS,IAAMhC,eAAe,CAACD;4BAC/BiB,OAAO;gCAAEQ,QAAQ;gCAAqBS,YAAY;gCAAQR,cAAc;gCAAGJ,SAAS;gCAAYc,QAAQ;4BAAU;sCAEjHpC,cAAc,SAAS;;;;gBAK7BP,iBAAiBO,6BAChB,MAACe;oBAAIE,OAAO;wBAAEiB,YAAY;wBAAWR,cAAc;wBAAGJ,SAAS;wBAAIe,UAAU;wBAAIC,YAAY;oBAAY;;sCACvG,MAACvB;4BAAIE,OAAO;gCAAEc,cAAc;4BAAG;;8CAAG,KAACQ;8CAAO;;gCAAepC;;;wBACxDD,aAAasC,uBACZ,MAACzB;4BAAIE,OAAO;gCAAEc,cAAc;gCAAIU,YAAY;gCAAYC,WAAW;4BAAa;;8CAC9E,KAACH;8CAAO;;8CACR,KAACI;gCACAzC,YAAYsC,KAAK;;;wBAGrBnC,0BACC,MAACU;;8CACC,KAACwB;8CAAO;;gCACPrC,aAAaI,iBAAiBsC,QAAQ1C,YAAYI,KAAK,CAACF,OAAO,GAAGyC,OAAO3C,aAAaI;;;;;;;;AAQvG,EAAE"}
|
|
@@ -198,9 +198,11 @@ const transformRoutesToReactRoutes = async (routes, transformResult, defaultRout
|
|
|
198
198
|
const ErrorBoundary = await getErrorComponent();
|
|
199
199
|
const LoadingComponent = await getLoadingComponent();
|
|
200
200
|
const HydrateFallback = LoadingComponent?.default ?? DefaultRouteHydrateFallback;
|
|
201
|
+
const Component = page;
|
|
201
202
|
return {
|
|
202
203
|
ErrorBoundary: ErrorBoundary?.default,
|
|
203
204
|
HydrateFallback,
|
|
205
|
+
Component,
|
|
204
206
|
...await getConfig(true)
|
|
205
207
|
};
|
|
206
208
|
}
|
|
@@ -231,9 +233,11 @@ const transformRoutesToReactRoutes = async (routes, transformResult, defaultRout
|
|
|
231
233
|
const ErrorBoundary = await getErrorComponent();
|
|
232
234
|
const LoadingComponent = await getLoadingComponent();
|
|
233
235
|
const HydrateFallback = LoadingComponent?.default ?? DefaultRouteHydrateFallback;
|
|
236
|
+
const Component = page;
|
|
234
237
|
return {
|
|
235
238
|
ErrorBoundary: ErrorBoundary?.default,
|
|
236
239
|
HydrateFallback,
|
|
240
|
+
Component,
|
|
237
241
|
...await getConfig(true)
|
|
238
242
|
};
|
|
239
243
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../../src/core/router/utils/adapters/react-router/transform.tsx"],"sourcesContent":["import type { RouteConfig } from '../../../types';\nimport {\n type RouteObject,\n Navigate\n} from 'react-router-dom';\nimport type { TransformRoutesResult } from '../../transform';\nimport { RouteErrorBoundary } from './RouteErrorBoundary';\nimport type { ComponentImport } from '../../../types';\nimport { logger } from '../../../../../utils';\n\nfunction DefaultRouteHydrateFallback() {\n return (\n <div style={{ padding: 16, textAlign: 'center', color: '#5f6c7b' }}>\n Loading...\n </div>\n );\n}\n\nexport const transformRoutesToReactRoutes = async (\n routes: RouteConfig[], \n transformResult: TransformRoutesResult,\n defaultRouteErrorComponent?: ComponentImport,\n defaultRouteLoadingComponent?: ComponentImport,\n enableHydrateFallback: boolean = false,\n): Promise<RouteObject[]> => {\n\n /**\n * 批量处理路由\n * @param routes 路由组\n */\n function transformRouteToReactRoutes(routes: RouteConfig[]) {\n return routes.flatMap((route: RouteConfig) => transformRouteToReactRoute(route))\n }\n\n /**\n * 处理单个路由\n * @param route 路由\n */\n function transformRouteToReactRoute(route: RouteConfig): RouteObject {\n const {\n isGroup = false,\n enableRedirection = false,\n name,\n path,\n handle,\n children,\n page,\n layout,\n error,\n errors,\n loading,\n } = route;\n const routeError = error ?? errors;\n\n // 获取错误组件\n async function getErrorComponent() {\n // 如果 error/errors 是函数,直接使用\n if (typeof routeError === 'function') {\n return routeError();\n }\n\n const errorsMap = transformResult.errors;\n\n // 判断 error/errors 是否为 string 且不是空字符串\n if (typeof routeError === 'string' && routeError !== '') {\n // 使用 routeError 作为 key 获取 transformResult.errors 的值\n const errorResolver = errorsMap.get(routeError);\n\n // 如果获取不到,返回 null\n if (!errorResolver) {\n return null;\n }\n\n // 如果获取到,返回对应的值(调用动态导入函数)\n if (typeof errorResolver === 'function') {\n return errorResolver();\n }\n\n return null;\n }\n\n // 如果 errors 为空,使用配置的默认错误组件或内置的 RouteErrorBoundary 组件\n if (defaultRouteErrorComponent) {\n // 如果配置了默认错误组件,使用配置的组件\n return defaultRouteErrorComponent();\n }\n\n // 如果没有配置默认错误组件,使用内置的 RouteErrorBoundary 组件\n // 直接导入而非懒加载,因为:\n // 1. RouteErrorBoundary 是框架核心组件,体积小\n // 2. 错误边界需要快速响应,直接导入速度更快\n // 3. 作为基础设施组件,应该保证可用性\n return { default: RouteErrorBoundary };\n }\n\n // 获取转换配置\n function convertConfig(m: any) {\n if (!m) {\n return null;\n }\n const { action, loader, shouldRevalidate, default: Component } = m;\n\n // 如果 Component 不存在,记录警告\n if (!Component) {\n logger.warn(`路由组件未找到 default 导出: ${name}`, m);\n }\n\n return {\n action, // always use action\n loader, // always use loader\n shouldRevalidate,\n Component\n };\n }\n\n // 获取加载组件\n async function getLoadingComponent() {\n if (typeof loading === 'function') {\n return loading();\n }\n\n if (typeof loading === 'string' && loading !== '') {\n const loadingResolver = transformResult.loadings.get(loading);\n if (typeof loadingResolver === 'function') {\n return loadingResolver();\n }\n }\n\n if (defaultRouteLoadingComponent) {\n return defaultRouteLoadingComponent();\n }\n\n return null;\n }\n\n // 获取配置\n async function getConfig(index: boolean = false) {\n // 如果有layout和不是index,返回布局配置\n if (layout && !index) {\n // 如果 layout 是函数,直接使用\n if (typeof layout === 'function') {\n const config = await layout();\n return convertConfig(config);\n }\n\n // 如果 layout 是字符串,从 Map 中获取\n if (typeof layout === 'string') {\n const layoutResolver = transformResult.layouts.get(layout);\n if (!layoutResolver) {\n throw new Error(`未找到名为 ${layout} 的布局组件`);\n }\n const config = await layoutResolver();\n return convertConfig(config);\n }\n }\n\n let pageName = name;\n\n // 如果是notFound则转成404\n if (pageName === 'notFound') {\n pageName = '404'\n }\n\n if (page && (!children?.length || index)) {\n // 如果 page 是函数,直接使用\n if (typeof page === 'function') {\n const config = await page();\n return convertConfig(config);\n }\n\n // 如果 page 是字符串,从 Map 中获取\n if (typeof page === 'string') {\n const viewResolver = transformResult.pages.get(page);\n if (!viewResolver) {\n throw new Error(`未找到名为 ${page} 的页面组件`);\n }\n const config = await viewResolver();\n return convertConfig(config);\n }\n }\n\n return null;\n }\n\n // 获取处理信息,即额外的配置信息\n function getHandle(index: boolean = false) {\n if ((layout || isGroup) && !index) {\n return null\n }\n return {\n ...handle,\n name,\n path\n }\n }\n\n\n const reactRoute: RouteObject = {\n children: [],\n id: name,\n handle: getHandle(),\n lazy: async () => {\n const ErrorBoundary = await getErrorComponent();\n const config = await getConfig();\n const LoadingComponent = await getLoadingComponent();\n const HydrateFallback = LoadingComponent?.default ?? DefaultRouteHydrateFallback;\n\n // 如果配置为空,确保至少返回一个空对象,避免展开 undefined\n if (!config) {\n return {\n ErrorBoundary: ErrorBoundary?.default,\n HydrateFallback,\n };\n }\n\n return {\n ErrorBoundary: ErrorBoundary?.default,\n HydrateFallback,\n ...config\n };\n },\n path\n };\n\n if (enableHydrateFallback) {\n reactRoute.hydrateFallbackElement = <DefaultRouteHydrateFallback />;\n }\n\n // 处理子路由\n if (children?.length) {\n reactRoute.children = children.flatMap(child => transformRouteToReactRoute(child)).sort((a, b) => {\n const orderA = a.handle?.order ?? 99;\n const orderB = b.handle?.order ?? 99;\n return orderA - orderB;\n });\n\n if (page && !isGroup) {\n reactRoute.children.unshift({\n handle: getHandle(true),\n index: true,\n lazy: async () => {\n const ErrorBoundary = await getErrorComponent();\n const LoadingComponent = await getLoadingComponent();\n const HydrateFallback = LoadingComponent?.default ?? DefaultRouteHydrateFallback;\n return {\n ErrorBoundary: ErrorBoundary?.default,\n HydrateFallback,\n ...(await getConfig(true))\n };\n }\n });\n }\n\n if (enableRedirection && isGroup) {\n const [firstChild] = reactRoute.children;\n if (firstChild?.path) {\n reactRoute.children.unshift({\n index: true,\n handle: getHandle(true),\n element: <Navigate to={firstChild.path as string} replace />\n });\n }\n }\n\n }\n // 若存在 layout 且没有子路由,但同时声明了 page,则自动生成 index 子路由以渲染页面\n // 场景:/test 使用自定义 layout,且没有 children 时仍应渲染 page\n if ((!children || children.length === 0) && layout && page && !isGroup) {\n reactRoute.children = [{\n handle: getHandle(true),\n index: true,\n lazy: async () => {\n const ErrorBoundary = await getErrorComponent();\n const LoadingComponent = await getLoadingComponent();\n const HydrateFallback = LoadingComponent?.default ?? DefaultRouteHydrateFallback;\n return {\n ErrorBoundary: ErrorBoundary?.default,\n HydrateFallback,\n ...(await getConfig(true))\n };\n }\n }];\n }\n\n return reactRoute;\n }\n\n return transformRouteToReactRoutes(routes);\n}\n"],"names":["transformRoutesToReactRoutes","DefaultRouteHydrateFallback","div","style","padding","textAlign","color","routes","transformResult","defaultRouteErrorComponent","defaultRouteLoadingComponent","enableHydrateFallback","transformRouteToReactRoutes","flatMap","route","transformRouteToReactRoute","isGroup","enableRedirection","name","path","handle","children","page","layout","error","errors","loading","routeError","getErrorComponent","errorsMap","errorResolver","get","default","RouteErrorBoundary","convertConfig","m","action","loader","shouldRevalidate","Component","logger","warn","getLoadingComponent","loadingResolver","loadings","getConfig","index","config","layoutResolver","layouts","Error","pageName","length","viewResolver","pages","getHandle","reactRoute","id","lazy","ErrorBoundary","LoadingComponent","HydrateFallback","hydrateFallbackElement","child","sort","a","b","orderA","order","orderB","unshift","firstChild","element","Navigate","to","replace"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../../../../src/core/router/utils/adapters/react-router/transform.tsx"],"sourcesContent":["import type { RouteConfig } from '../../../types';\nimport {\n type RouteObject,\n Navigate\n} from 'react-router-dom';\nimport type { TransformRoutesResult } from '../../transform';\nimport { RouteErrorBoundary } from './RouteErrorBoundary';\nimport type { ComponentImport } from '../../../types';\nimport { logger } from '../../../../../utils';\n\nfunction DefaultRouteHydrateFallback() {\n return (\n <div style={{ padding: 16, textAlign: 'center', color: '#5f6c7b' }}>\n Loading...\n </div>\n );\n}\n\nexport const transformRoutesToReactRoutes = async (\n routes: RouteConfig[],\n transformResult: TransformRoutesResult,\n defaultRouteErrorComponent?: ComponentImport,\n defaultRouteLoadingComponent?: ComponentImport,\n enableHydrateFallback: boolean = false,\n): Promise<RouteObject[]> => {\n\n /**\n * 批量处理路由\n * @param routes 路由组\n */\n function transformRouteToReactRoutes(routes: RouteConfig[]) {\n return routes.flatMap((route: RouteConfig) => transformRouteToReactRoute(route))\n }\n\n /**\n * 处理单个路由\n * @param route 路由\n */\n function transformRouteToReactRoute(route: RouteConfig): RouteObject {\n const {\n isGroup = false,\n enableRedirection = false,\n name,\n path,\n handle,\n children,\n page,\n layout,\n error,\n errors,\n loading,\n } = route;\n const routeError = error ?? errors;\n\n // 获取错误组件\n async function getErrorComponent() {\n // 如果 error/errors 是函数,直接使用\n if (typeof routeError === 'function') {\n return routeError();\n }\n\n const errorsMap = transformResult.errors;\n\n // 判断 error/errors 是否为 string 且不是空字符串\n if (typeof routeError === 'string' && routeError !== '') {\n // 使用 routeError 作为 key 获取 transformResult.errors 的值\n const errorResolver = errorsMap.get(routeError);\n\n // 如果获取不到,返回 null\n if (!errorResolver) {\n return null;\n }\n\n // 如果获取到,返回对应的值(调用动态导入函数)\n if (typeof errorResolver === 'function') {\n return errorResolver();\n }\n\n return null;\n }\n\n // 如果 errors 为空,使用配置的默认错误组件或内置的 RouteErrorBoundary 组件\n if (defaultRouteErrorComponent) {\n // 如果配置了默认错误组件,使用配置的组件\n return defaultRouteErrorComponent();\n }\n\n // 如果没有配置默认错误组件,使用内置的 RouteErrorBoundary 组件\n // 直接导入而非懒加载,因为:\n // 1. RouteErrorBoundary 是框架核心组件,体积小\n // 2. 错误边界需要快速响应,直接导入速度更快\n // 3. 作为基础设施组件,应该保证可用性\n return { default: RouteErrorBoundary };\n }\n\n // 获取转换配置\n function convertConfig(m: any) {\n if (!m) {\n return null;\n }\n const { action, loader, shouldRevalidate, default: Component } = m;\n\n // 如果 Component 不存在,记录警告\n if (!Component) {\n logger.warn(`路由组件未找到 default 导出: ${name}`, m);\n }\n\n return {\n action, // always use action\n loader, // always use loader\n shouldRevalidate,\n Component\n };\n }\n\n // 获取加载组件\n async function getLoadingComponent() {\n if (typeof loading === 'function') {\n return loading();\n }\n\n if (typeof loading === 'string' && loading !== '') {\n const loadingResolver = transformResult.loadings.get(loading);\n if (typeof loadingResolver === 'function') {\n return loadingResolver();\n }\n }\n\n if (defaultRouteLoadingComponent) {\n return defaultRouteLoadingComponent();\n }\n\n return null;\n }\n\n // 获取配置\n async function getConfig(index: boolean = false) {\n // 如果有layout和不是index,返回布局配置\n if (layout && !index) {\n // 如果 layout 是函数,直接使用\n if (typeof layout === 'function') {\n const config = await layout();\n return convertConfig(config);\n }\n\n // 如果 layout 是字符串,从 Map 中获取\n if (typeof layout === 'string') {\n const layoutResolver = transformResult.layouts.get(layout);\n if (!layoutResolver) {\n throw new Error(`未找到名为 ${layout} 的布局组件`);\n }\n const config = await layoutResolver();\n return convertConfig(config);\n }\n }\n\n let pageName = name;\n\n // 如果是notFound则转成404\n if (pageName === 'notFound') {\n pageName = '404'\n }\n\n if (page && (!children?.length || index)) {\n // 如果 page 是函数,直接使用\n if (typeof page === 'function') {\n const config = await page();\n return convertConfig(config);\n }\n\n // 如果 page 是字符串,从 Map 中获取\n if (typeof page === 'string') {\n const viewResolver = transformResult.pages.get(page);\n if (!viewResolver) {\n throw new Error(`未找到名为 ${page} 的页面组件`);\n }\n const config = await viewResolver();\n return convertConfig(config);\n }\n }\n\n return null;\n }\n\n // 获取处理信息,即额外的配置信息\n function getHandle(index: boolean = false) {\n if ((layout || isGroup) && !index) {\n return null\n }\n return {\n ...handle,\n name,\n path\n }\n }\n\n\n const reactRoute: RouteObject = {\n children: [],\n id: name,\n handle: getHandle(),\n lazy: async () => {\n const ErrorBoundary = await getErrorComponent();\n const config = await getConfig();\n const LoadingComponent = await getLoadingComponent();\n const HydrateFallback = LoadingComponent?.default ?? DefaultRouteHydrateFallback;\n\n // 如果配置为空,确保至少返回一个空对象,避免展开 undefined\n if (!config) {\n return {\n ErrorBoundary: ErrorBoundary?.default,\n HydrateFallback,\n };\n }\n\n return {\n ErrorBoundary: ErrorBoundary?.default,\n HydrateFallback,\n ...config\n };\n },\n path\n };\n\n if (enableHydrateFallback) {\n reactRoute.hydrateFallbackElement = <DefaultRouteHydrateFallback />;\n }\n\n // 处理子路由\n if (children?.length) {\n reactRoute.children = children.flatMap(child => transformRouteToReactRoute(child)).sort((a, b) => {\n const orderA = a.handle?.order ?? 99;\n const orderB = b.handle?.order ?? 99;\n return orderA - orderB;\n });\n\n if (page && !isGroup) {\n reactRoute.children.unshift({\n handle: getHandle(true),\n index: true,\n lazy: async () => {\n const ErrorBoundary = await getErrorComponent();\n const LoadingComponent = await getLoadingComponent();\n const HydrateFallback = LoadingComponent?.default ?? DefaultRouteHydrateFallback;\n const Component = page;\n return {\n ErrorBoundary: ErrorBoundary?.default,\n HydrateFallback,\n Component,\n ...(await getConfig(true))\n };\n }\n });\n }\n\n if (enableRedirection && isGroup) {\n const [firstChild] = reactRoute.children;\n if (firstChild?.path) {\n reactRoute.children.unshift({\n index: true,\n handle: getHandle(true),\n element: <Navigate to={firstChild.path as string} replace />\n });\n }\n }\n\n }\n // 若存在 layout 且没有子路由,但同时声明了 page,则自动生成 index 子路由以渲染页面\n // 场景:/test 使用自定义 layout,且没有 children 时仍应渲染 page\n if ((!children || children.length === 0) && layout && page && !isGroup) {\n reactRoute.children = [{\n handle: getHandle(true),\n index: true,\n lazy: async () => {\n const ErrorBoundary = await getErrorComponent();\n const LoadingComponent = await getLoadingComponent();\n const HydrateFallback = LoadingComponent?.default ?? DefaultRouteHydrateFallback;\n const Component = page;\n return {\n ErrorBoundary: ErrorBoundary?.default,\n HydrateFallback,\n Component,\n ...(await getConfig(true))\n };\n }\n }];\n }\n\n return reactRoute;\n }\n\n return transformRouteToReactRoutes(routes);\n}\n"],"names":["transformRoutesToReactRoutes","DefaultRouteHydrateFallback","div","style","padding","textAlign","color","routes","transformResult","defaultRouteErrorComponent","defaultRouteLoadingComponent","enableHydrateFallback","transformRouteToReactRoutes","flatMap","route","transformRouteToReactRoute","isGroup","enableRedirection","name","path","handle","children","page","layout","error","errors","loading","routeError","getErrorComponent","errorsMap","errorResolver","get","default","RouteErrorBoundary","convertConfig","m","action","loader","shouldRevalidate","Component","logger","warn","getLoadingComponent","loadingResolver","loadings","getConfig","index","config","layoutResolver","layouts","Error","pageName","length","viewResolver","pages","getHandle","reactRoute","id","lazy","ErrorBoundary","LoadingComponent","HydrateFallback","hydrateFallbackElement","child","sort","a","b","orderA","order","orderB","unshift","firstChild","element","Navigate","to","replace"],"mappings":"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"}
|
|
@@ -188,9 +188,11 @@ export const transformRoutesToReactRoutes = async (routes, transformResult, defa
|
|
|
188
188
|
const ErrorBoundary = await getErrorComponent();
|
|
189
189
|
const LoadingComponent = await getLoadingComponent();
|
|
190
190
|
const HydrateFallback = LoadingComponent?.default ?? DefaultRouteHydrateFallback;
|
|
191
|
+
const Component = page;
|
|
191
192
|
return {
|
|
192
193
|
ErrorBoundary: ErrorBoundary?.default,
|
|
193
194
|
HydrateFallback,
|
|
195
|
+
Component,
|
|
194
196
|
...await getConfig(true)
|
|
195
197
|
};
|
|
196
198
|
}
|
|
@@ -221,9 +223,11 @@ export const transformRoutesToReactRoutes = async (routes, transformResult, defa
|
|
|
221
223
|
const ErrorBoundary = await getErrorComponent();
|
|
222
224
|
const LoadingComponent = await getLoadingComponent();
|
|
223
225
|
const HydrateFallback = LoadingComponent?.default ?? DefaultRouteHydrateFallback;
|
|
226
|
+
const Component = page;
|
|
224
227
|
return {
|
|
225
228
|
ErrorBoundary: ErrorBoundary?.default,
|
|
226
229
|
HydrateFallback,
|
|
230
|
+
Component,
|
|
227
231
|
...await getConfig(true)
|
|
228
232
|
};
|
|
229
233
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../../src/core/router/utils/adapters/react-router/transform.tsx"],"sourcesContent":["import type { RouteConfig } from '../../../types';\nimport {\n type RouteObject,\n Navigate\n} from 'react-router-dom';\nimport type { TransformRoutesResult } from '../../transform';\nimport { RouteErrorBoundary } from './RouteErrorBoundary';\nimport type { ComponentImport } from '../../../types';\nimport { logger } from '../../../../../utils';\n\nfunction DefaultRouteHydrateFallback() {\n return (\n <div style={{ padding: 16, textAlign: 'center', color: '#5f6c7b' }}>\n Loading...\n </div>\n );\n}\n\nexport const transformRoutesToReactRoutes = async (\n routes: RouteConfig[], \n transformResult: TransformRoutesResult,\n defaultRouteErrorComponent?: ComponentImport,\n defaultRouteLoadingComponent?: ComponentImport,\n enableHydrateFallback: boolean = false,\n): Promise<RouteObject[]> => {\n\n /**\n * 批量处理路由\n * @param routes 路由组\n */\n function transformRouteToReactRoutes(routes: RouteConfig[]) {\n return routes.flatMap((route: RouteConfig) => transformRouteToReactRoute(route))\n }\n\n /**\n * 处理单个路由\n * @param route 路由\n */\n function transformRouteToReactRoute(route: RouteConfig): RouteObject {\n const {\n isGroup = false,\n enableRedirection = false,\n name,\n path,\n handle,\n children,\n page,\n layout,\n error,\n errors,\n loading,\n } = route;\n const routeError = error ?? errors;\n\n // 获取错误组件\n async function getErrorComponent() {\n // 如果 error/errors 是函数,直接使用\n if (typeof routeError === 'function') {\n return routeError();\n }\n\n const errorsMap = transformResult.errors;\n\n // 判断 error/errors 是否为 string 且不是空字符串\n if (typeof routeError === 'string' && routeError !== '') {\n // 使用 routeError 作为 key 获取 transformResult.errors 的值\n const errorResolver = errorsMap.get(routeError);\n\n // 如果获取不到,返回 null\n if (!errorResolver) {\n return null;\n }\n\n // 如果获取到,返回对应的值(调用动态导入函数)\n if (typeof errorResolver === 'function') {\n return errorResolver();\n }\n\n return null;\n }\n\n // 如果 errors 为空,使用配置的默认错误组件或内置的 RouteErrorBoundary 组件\n if (defaultRouteErrorComponent) {\n // 如果配置了默认错误组件,使用配置的组件\n return defaultRouteErrorComponent();\n }\n\n // 如果没有配置默认错误组件,使用内置的 RouteErrorBoundary 组件\n // 直接导入而非懒加载,因为:\n // 1. RouteErrorBoundary 是框架核心组件,体积小\n // 2. 错误边界需要快速响应,直接导入速度更快\n // 3. 作为基础设施组件,应该保证可用性\n return { default: RouteErrorBoundary };\n }\n\n // 获取转换配置\n function convertConfig(m: any) {\n if (!m) {\n return null;\n }\n const { action, loader, shouldRevalidate, default: Component } = m;\n\n // 如果 Component 不存在,记录警告\n if (!Component) {\n logger.warn(`路由组件未找到 default 导出: ${name}`, m);\n }\n\n return {\n action, // always use action\n loader, // always use loader\n shouldRevalidate,\n Component\n };\n }\n\n // 获取加载组件\n async function getLoadingComponent() {\n if (typeof loading === 'function') {\n return loading();\n }\n\n if (typeof loading === 'string' && loading !== '') {\n const loadingResolver = transformResult.loadings.get(loading);\n if (typeof loadingResolver === 'function') {\n return loadingResolver();\n }\n }\n\n if (defaultRouteLoadingComponent) {\n return defaultRouteLoadingComponent();\n }\n\n return null;\n }\n\n // 获取配置\n async function getConfig(index: boolean = false) {\n // 如果有layout和不是index,返回布局配置\n if (layout && !index) {\n // 如果 layout 是函数,直接使用\n if (typeof layout === 'function') {\n const config = await layout();\n return convertConfig(config);\n }\n\n // 如果 layout 是字符串,从 Map 中获取\n if (typeof layout === 'string') {\n const layoutResolver = transformResult.layouts.get(layout);\n if (!layoutResolver) {\n throw new Error(`未找到名为 ${layout} 的布局组件`);\n }\n const config = await layoutResolver();\n return convertConfig(config);\n }\n }\n\n let pageName = name;\n\n // 如果是notFound则转成404\n if (pageName === 'notFound') {\n pageName = '404'\n }\n\n if (page && (!children?.length || index)) {\n // 如果 page 是函数,直接使用\n if (typeof page === 'function') {\n const config = await page();\n return convertConfig(config);\n }\n\n // 如果 page 是字符串,从 Map 中获取\n if (typeof page === 'string') {\n const viewResolver = transformResult.pages.get(page);\n if (!viewResolver) {\n throw new Error(`未找到名为 ${page} 的页面组件`);\n }\n const config = await viewResolver();\n return convertConfig(config);\n }\n }\n\n return null;\n }\n\n // 获取处理信息,即额外的配置信息\n function getHandle(index: boolean = false) {\n if ((layout || isGroup) && !index) {\n return null\n }\n return {\n ...handle,\n name,\n path\n }\n }\n\n\n const reactRoute: RouteObject = {\n children: [],\n id: name,\n handle: getHandle(),\n lazy: async () => {\n const ErrorBoundary = await getErrorComponent();\n const config = await getConfig();\n const LoadingComponent = await getLoadingComponent();\n const HydrateFallback = LoadingComponent?.default ?? DefaultRouteHydrateFallback;\n\n // 如果配置为空,确保至少返回一个空对象,避免展开 undefined\n if (!config) {\n return {\n ErrorBoundary: ErrorBoundary?.default,\n HydrateFallback,\n };\n }\n\n return {\n ErrorBoundary: ErrorBoundary?.default,\n HydrateFallback,\n ...config\n };\n },\n path\n };\n\n if (enableHydrateFallback) {\n reactRoute.hydrateFallbackElement = <DefaultRouteHydrateFallback />;\n }\n\n // 处理子路由\n if (children?.length) {\n reactRoute.children = children.flatMap(child => transformRouteToReactRoute(child)).sort((a, b) => {\n const orderA = a.handle?.order ?? 99;\n const orderB = b.handle?.order ?? 99;\n return orderA - orderB;\n });\n\n if (page && !isGroup) {\n reactRoute.children.unshift({\n handle: getHandle(true),\n index: true,\n lazy: async () => {\n const ErrorBoundary = await getErrorComponent();\n const LoadingComponent = await getLoadingComponent();\n const HydrateFallback = LoadingComponent?.default ?? DefaultRouteHydrateFallback;\n return {\n ErrorBoundary: ErrorBoundary?.default,\n HydrateFallback,\n ...(await getConfig(true))\n };\n }\n });\n }\n\n if (enableRedirection && isGroup) {\n const [firstChild] = reactRoute.children;\n if (firstChild?.path) {\n reactRoute.children.unshift({\n index: true,\n handle: getHandle(true),\n element: <Navigate to={firstChild.path as string} replace />\n });\n }\n }\n\n }\n // 若存在 layout 且没有子路由,但同时声明了 page,则自动生成 index 子路由以渲染页面\n // 场景:/test 使用自定义 layout,且没有 children 时仍应渲染 page\n if ((!children || children.length === 0) && layout && page && !isGroup) {\n reactRoute.children = [{\n handle: getHandle(true),\n index: true,\n lazy: async () => {\n const ErrorBoundary = await getErrorComponent();\n const LoadingComponent = await getLoadingComponent();\n const HydrateFallback = LoadingComponent?.default ?? DefaultRouteHydrateFallback;\n return {\n ErrorBoundary: ErrorBoundary?.default,\n HydrateFallback,\n ...(await getConfig(true))\n };\n }\n }];\n }\n\n return reactRoute;\n }\n\n return transformRouteToReactRoutes(routes);\n}\n"],"names":["Navigate","RouteErrorBoundary","logger","DefaultRouteHydrateFallback","div","style","padding","textAlign","color","transformRoutesToReactRoutes","routes","transformResult","defaultRouteErrorComponent","defaultRouteLoadingComponent","enableHydrateFallback","transformRouteToReactRoutes","flatMap","route","transformRouteToReactRoute","isGroup","enableRedirection","name","path","handle","children","page","layout","error","errors","loading","routeError","getErrorComponent","errorsMap","errorResolver","get","default","convertConfig","m","action","loader","shouldRevalidate","Component","warn","getLoadingComponent","loadingResolver","loadings","getConfig","index","config","layoutResolver","layouts","Error","pageName","length","viewResolver","pages","getHandle","reactRoute","id","lazy","ErrorBoundary","LoadingComponent","HydrateFallback","hydrateFallbackElement","child","sort","a","b","orderA","order","orderB","unshift","firstChild","element","to","replace"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../../../../src/core/router/utils/adapters/react-router/transform.tsx"],"sourcesContent":["import type { RouteConfig } from '../../../types';\nimport {\n type RouteObject,\n Navigate\n} from 'react-router-dom';\nimport type { TransformRoutesResult } from '../../transform';\nimport { RouteErrorBoundary } from './RouteErrorBoundary';\nimport type { ComponentImport } from '../../../types';\nimport { logger } from '../../../../../utils';\n\nfunction DefaultRouteHydrateFallback() {\n return (\n <div style={{ padding: 16, textAlign: 'center', color: '#5f6c7b' }}>\n Loading...\n </div>\n );\n}\n\nexport const transformRoutesToReactRoutes = async (\n routes: RouteConfig[],\n transformResult: TransformRoutesResult,\n defaultRouteErrorComponent?: ComponentImport,\n defaultRouteLoadingComponent?: ComponentImport,\n enableHydrateFallback: boolean = false,\n): Promise<RouteObject[]> => {\n\n /**\n * 批量处理路由\n * @param routes 路由组\n */\n function transformRouteToReactRoutes(routes: RouteConfig[]) {\n return routes.flatMap((route: RouteConfig) => transformRouteToReactRoute(route))\n }\n\n /**\n * 处理单个路由\n * @param route 路由\n */\n function transformRouteToReactRoute(route: RouteConfig): RouteObject {\n const {\n isGroup = false,\n enableRedirection = false,\n name,\n path,\n handle,\n children,\n page,\n layout,\n error,\n errors,\n loading,\n } = route;\n const routeError = error ?? errors;\n\n // 获取错误组件\n async function getErrorComponent() {\n // 如果 error/errors 是函数,直接使用\n if (typeof routeError === 'function') {\n return routeError();\n }\n\n const errorsMap = transformResult.errors;\n\n // 判断 error/errors 是否为 string 且不是空字符串\n if (typeof routeError === 'string' && routeError !== '') {\n // 使用 routeError 作为 key 获取 transformResult.errors 的值\n const errorResolver = errorsMap.get(routeError);\n\n // 如果获取不到,返回 null\n if (!errorResolver) {\n return null;\n }\n\n // 如果获取到,返回对应的值(调用动态导入函数)\n if (typeof errorResolver === 'function') {\n return errorResolver();\n }\n\n return null;\n }\n\n // 如果 errors 为空,使用配置的默认错误组件或内置的 RouteErrorBoundary 组件\n if (defaultRouteErrorComponent) {\n // 如果配置了默认错误组件,使用配置的组件\n return defaultRouteErrorComponent();\n }\n\n // 如果没有配置默认错误组件,使用内置的 RouteErrorBoundary 组件\n // 直接导入而非懒加载,因为:\n // 1. RouteErrorBoundary 是框架核心组件,体积小\n // 2. 错误边界需要快速响应,直接导入速度更快\n // 3. 作为基础设施组件,应该保证可用性\n return { default: RouteErrorBoundary };\n }\n\n // 获取转换配置\n function convertConfig(m: any) {\n if (!m) {\n return null;\n }\n const { action, loader, shouldRevalidate, default: Component } = m;\n\n // 如果 Component 不存在,记录警告\n if (!Component) {\n logger.warn(`路由组件未找到 default 导出: ${name}`, m);\n }\n\n return {\n action, // always use action\n loader, // always use loader\n shouldRevalidate,\n Component\n };\n }\n\n // 获取加载组件\n async function getLoadingComponent() {\n if (typeof loading === 'function') {\n return loading();\n }\n\n if (typeof loading === 'string' && loading !== '') {\n const loadingResolver = transformResult.loadings.get(loading);\n if (typeof loadingResolver === 'function') {\n return loadingResolver();\n }\n }\n\n if (defaultRouteLoadingComponent) {\n return defaultRouteLoadingComponent();\n }\n\n return null;\n }\n\n // 获取配置\n async function getConfig(index: boolean = false) {\n // 如果有layout和不是index,返回布局配置\n if (layout && !index) {\n // 如果 layout 是函数,直接使用\n if (typeof layout === 'function') {\n const config = await layout();\n return convertConfig(config);\n }\n\n // 如果 layout 是字符串,从 Map 中获取\n if (typeof layout === 'string') {\n const layoutResolver = transformResult.layouts.get(layout);\n if (!layoutResolver) {\n throw new Error(`未找到名为 ${layout} 的布局组件`);\n }\n const config = await layoutResolver();\n return convertConfig(config);\n }\n }\n\n let pageName = name;\n\n // 如果是notFound则转成404\n if (pageName === 'notFound') {\n pageName = '404'\n }\n\n if (page && (!children?.length || index)) {\n // 如果 page 是函数,直接使用\n if (typeof page === 'function') {\n const config = await page();\n return convertConfig(config);\n }\n\n // 如果 page 是字符串,从 Map 中获取\n if (typeof page === 'string') {\n const viewResolver = transformResult.pages.get(page);\n if (!viewResolver) {\n throw new Error(`未找到名为 ${page} 的页面组件`);\n }\n const config = await viewResolver();\n return convertConfig(config);\n }\n }\n\n return null;\n }\n\n // 获取处理信息,即额外的配置信息\n function getHandle(index: boolean = false) {\n if ((layout || isGroup) && !index) {\n return null\n }\n return {\n ...handle,\n name,\n path\n }\n }\n\n\n const reactRoute: RouteObject = {\n children: [],\n id: name,\n handle: getHandle(),\n lazy: async () => {\n const ErrorBoundary = await getErrorComponent();\n const config = await getConfig();\n const LoadingComponent = await getLoadingComponent();\n const HydrateFallback = LoadingComponent?.default ?? DefaultRouteHydrateFallback;\n\n // 如果配置为空,确保至少返回一个空对象,避免展开 undefined\n if (!config) {\n return {\n ErrorBoundary: ErrorBoundary?.default,\n HydrateFallback,\n };\n }\n\n return {\n ErrorBoundary: ErrorBoundary?.default,\n HydrateFallback,\n ...config\n };\n },\n path\n };\n\n if (enableHydrateFallback) {\n reactRoute.hydrateFallbackElement = <DefaultRouteHydrateFallback />;\n }\n\n // 处理子路由\n if (children?.length) {\n reactRoute.children = children.flatMap(child => transformRouteToReactRoute(child)).sort((a, b) => {\n const orderA = a.handle?.order ?? 99;\n const orderB = b.handle?.order ?? 99;\n return orderA - orderB;\n });\n\n if (page && !isGroup) {\n reactRoute.children.unshift({\n handle: getHandle(true),\n index: true,\n lazy: async () => {\n const ErrorBoundary = await getErrorComponent();\n const LoadingComponent = await getLoadingComponent();\n const HydrateFallback = LoadingComponent?.default ?? DefaultRouteHydrateFallback;\n const Component = page;\n return {\n ErrorBoundary: ErrorBoundary?.default,\n HydrateFallback,\n Component,\n ...(await getConfig(true))\n };\n }\n });\n }\n\n if (enableRedirection && isGroup) {\n const [firstChild] = reactRoute.children;\n if (firstChild?.path) {\n reactRoute.children.unshift({\n index: true,\n handle: getHandle(true),\n element: <Navigate to={firstChild.path as string} replace />\n });\n }\n }\n\n }\n // 若存在 layout 且没有子路由,但同时声明了 page,则自动生成 index 子路由以渲染页面\n // 场景:/test 使用自定义 layout,且没有 children 时仍应渲染 page\n if ((!children || children.length === 0) && layout && page && !isGroup) {\n reactRoute.children = [{\n handle: getHandle(true),\n index: true,\n lazy: async () => {\n const ErrorBoundary = await getErrorComponent();\n const LoadingComponent = await getLoadingComponent();\n const HydrateFallback = LoadingComponent?.default ?? DefaultRouteHydrateFallback;\n const Component = page;\n return {\n ErrorBoundary: ErrorBoundary?.default,\n HydrateFallback,\n Component,\n ...(await getConfig(true))\n };\n }\n }];\n }\n\n return reactRoute;\n }\n\n return transformRouteToReactRoutes(routes);\n}\n"],"names":["Navigate","RouteErrorBoundary","logger","DefaultRouteHydrateFallback","div","style","padding","textAlign","color","transformRoutesToReactRoutes","routes","transformResult","defaultRouteErrorComponent","defaultRouteLoadingComponent","enableHydrateFallback","transformRouteToReactRoutes","flatMap","route","transformRouteToReactRoute","isGroup","enableRedirection","name","path","handle","children","page","layout","error","errors","loading","routeError","getErrorComponent","errorsMap","errorResolver","get","default","convertConfig","m","action","loader","shouldRevalidate","Component","warn","getLoadingComponent","loadingResolver","loadings","getConfig","index","config","layoutResolver","layouts","Error","pageName","length","viewResolver","pages","getHandle","reactRoute","id","lazy","ErrorBoundary","LoadingComponent","HydrateFallback","hydrateFallbackElement","child","sort","a","b","orderA","order","orderB","unshift","firstChild","element","to","replace"],"mappings":"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"}
|
|
@@ -12,7 +12,7 @@ Object.defineProperty(exports, "initializeServices", {
|
|
|
12
12
|
}
|
|
13
13
|
});
|
|
14
14
|
const _utils = require("../../utils");
|
|
15
|
-
const _monitoring = require("
|
|
15
|
+
const _monitoring = require("@vlian/monitoring");
|
|
16
16
|
const _performance = require("../../utils/performance");
|
|
17
17
|
const _library = require("../../library");
|
|
18
18
|
const _state = require("../../state");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/core/startup/initializeServices.ts"],"sourcesContent":["/**\n * 服务初始化模块\n * 负责初始化框架所需的各种服务\n */\n\nimport { logger } from '../../utils';\nimport { initMonitoring } from '../../utils/monitoring';\nimport type { MonitoringService } from '../../utils/monitoring';\nimport { PerformanceMonitor } from '../../utils/performance';\nimport { storage } from '../../library';\nimport { StateManager } from '../../state';\nimport type { StartOptions } from '../types';\nimport { AppEventBus } from '../event/AppEventBus';\nimport type { AppEventBusConfig } from '../event/types';\n\n/**\n * 重试配置\n */\nexport interface RetryConfig {\n /**\n * 最大重试次数\n * @default 3\n */\n maxRetries?: number;\n /**\n * 重试延迟(毫秒)\n * @default 1000\n */\n retryDelay?: number;\n /**\n * 是否启用指数退避\n * @default true\n */\n exponentialBackoff?: boolean;\n}\n\n/**\n * 服务初始化结果\n */\nexport interface ServicesInitResult {\n /**\n * 监控服务实例\n */\n monitoring: MonitoringService;\n\n /**\n * 性能监控实例\n */\n performanceMonitor: PerformanceMonitor;\n\n /**\n * 状态管理器实例\n */\n stateManager: StateManager;\n\n /**\n * 事件总线实例\n */\n eventBus: AppEventBus;\n\n /**\n * 延迟初始化非关键服务的函数\n * 在应用渲染后调用,使用 requestIdleCallback 在空闲时初始化\n */\n initializeNonCriticalServices?: () => Promise<void>;\n}\n\n/**\n * 带重试的异步函数执行器\n */\nasync function withRetry<T>(\n fn: () => Promise<T>,\n config: RetryConfig = {},\n serviceName: string\n): Promise<T> {\n const maxRetries = config.maxRetries ?? 3;\n const retryDelay = config.retryDelay ?? 1000;\n const exponentialBackoff = config.exponentialBackoff ?? true;\n\n let lastError: unknown;\n \n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n try {\n return await fn();\n } catch (error) {\n lastError = error;\n \n if (attempt < maxRetries) {\n const delay = exponentialBackoff \n ? retryDelay * Math.pow(2, attempt)\n : retryDelay;\n \n logger.warn(\n `${serviceName} 初始化失败(尝试 ${attempt + 1}/${maxRetries + 1}),${delay}ms 后重试...`,\n error\n );\n \n await new Promise(resolve => setTimeout(resolve, delay));\n }\n }\n }\n \n logger.error(`${serviceName} 初始化失败,已重试 ${maxRetries} 次`);\n throw lastError;\n}\n\n/**\n * 初始化所有服务\n * \n * 优化:\n * 1. 区分关键服务和非关键服务\n * 2. 关键服务并行初始化,缩短首屏时间\n * 3. 非关键服务延迟到应用渲染后初始化,使用 requestIdleCallback 在空闲时初始化\n * 4. 实现服务初始化失败重试机制,提高启动成功率\n * \n * @param options - 启动配置选项\n * @returns 服务初始化结果\n */\nexport async function initializeServices(\n options: StartOptions = {}\n): Promise<ServicesInitResult> {\n const startTime = performance.now();\n \n // 重试配置\n const retryConfig: RetryConfig = {\n maxRetries: options.serviceRetry?.maxRetries ?? 3,\n retryDelay: options.serviceRetry?.retryDelay ?? 1000,\n exponentialBackoff: options.serviceRetry?.exponentialBackoff ?? true,\n };\n\n // ========== 关键服务:必须在应用渲染前初始化 ==========\n // 这些服务是应用运行的基础,必须并行初始化完成\n\n // 1. 监控服务(必须最先初始化,因为其他服务可能依赖它)\n const monitoringPromise = withRetry(\n () => Promise.resolve(initMonitoring({\n ...options.errorMonitor,\n onError: (error) => {\n logger.error('监控服务捕获到错误:', error);\n options.errorMonitor?.onError?.(error);\n },\n })),\n retryConfig,\n '监控服务'\n );\n\n // 2. 存储服务(关键服务,应用可能需要立即使用存储)\n const storagePromise = withRetry(\n () => Promise.resolve().then(() => {\n storage.initialize(options.storageOptions);\n return storage;\n }),\n retryConfig,\n '存储服务'\n );\n\n // 3. 状态管理器(关键服务,应用状态管理的基础)\n const stateManagerPromise = withRetry(\n () => Promise.resolve().then(() => {\n if (options.stateManager !== undefined) {\n return new StateManager(options.stateManager);\n } else {\n // 默认初始化状态管理器\n return new StateManager({\n enableRegistry: true,\n defaultScope: 'app',\n });\n }\n }),\n retryConfig,\n '状态管理器'\n );\n\n // 4. 事件总线(关键服务,用于应用内部通信)\n const eventBusPromise = withRetry(\n () => Promise.resolve().then(() => {\n const eventBusConfig: AppEventBusConfig = {\n enableTracking: options.eventBus?.enableTracking ?? (process.env.NODE_ENV === 'development'),\n maxHistorySize: options.eventBus?.maxHistorySize ?? 100,\n enableValidation: options.eventBus?.enableValidation ?? false,\n enablePerformanceMonitoring: options.eventBus?.enablePerformanceMonitoring ?? (process.env.NODE_ENV === 'development'),\n namespacePrefix: options.eventBus?.namespacePrefix,\n instanceId: options.eventBus?.instanceId,\n enableSecurityMode: options.eventBus?.enableSecurityMode ?? false,\n allowedSources: options.eventBus?.allowedSources,\n };\n return new AppEventBus(eventBusConfig);\n }),\n retryConfig,\n '事件总线'\n );\n\n // 并行执行关键服务初始化\n const [monitoring, , stateManager, eventBus] = await Promise.all([\n monitoringPromise,\n storagePromise,\n stateManagerPromise,\n eventBusPromise,\n ]);\n\n logger.info('关键服务初始化完成');\n\n // 初始化性能监控(依赖监控服务,必须在监控服务初始化后)\n const performanceMonitor = new PerformanceMonitor({\n ...options.performanceMonitor,\n onReport: (metrics) => {\n monitoring.reportPerformance(metrics);\n options.performanceMonitor?.onReport?.(metrics);\n },\n });\n\n // 在页面卸载时清理性能监控\n if (typeof window !== 'undefined') {\n const cleanupHandler = () => {\n performanceMonitor.disconnect();\n window.removeEventListener('beforeunload', cleanupHandler);\n };\n window.addEventListener('beforeunload', cleanupHandler);\n }\n\n const criticalServicesDuration = performance.now() - startTime;\n logger.debug(`关键服务初始化完成,耗时: ${criticalServicesDuration.toFixed(2)}ms`);\n\n // ========== 非关键服务:延迟到应用渲染后初始化 ==========\n // 这些服务不影响首屏渲染,可以在空闲时初始化\n\n /**\n * 延迟初始化非关键服务\n * 在应用渲染后调用,使用 requestIdleCallback 在空闲时初始化\n */\n const initializeNonCriticalServices = async (): Promise<void> => {\n const nonCriticalStartTime = performance.now();\n \n // 使用 requestIdleCallback 在浏览器空闲时初始化非关键服务\n // 如果不支持 requestIdleCallback,则使用 setTimeout 延迟执行\n const scheduleInit = (callback: () => void) => {\n if (typeof window !== 'undefined' && 'requestIdleCallback' in window) {\n window.requestIdleCallback(callback, { timeout: 5000 });\n } else {\n setTimeout(callback, 100);\n }\n };\n\n return new Promise<void>((resolve) => {\n scheduleInit(async () => {\n try {\n // 1. 分析服务(可选,非关键)\n if (options.analytics) {\n try {\n await withRetry(\n () => import('../../utils/analytics').then(({ initAnalytics }) => {\n initAnalytics(options.analytics!);\n return true;\n }),\n retryConfig,\n '分析服务'\n );\n logger.debug('分析服务初始化完成');\n } catch (error) {\n logger.warn('分析服务初始化失败(不影响应用运行):', error);\n }\n }\n\n // 2. 运行时安全服务(可选,非关键)\n if (options.runtimeSecurity) {\n try {\n await withRetry(\n () => import('../../utils/runtimeSecurity').then(({ RuntimeSecurity }) => {\n RuntimeSecurity.initialize(options.runtimeSecurity!);\n return true;\n }),\n retryConfig,\n '运行时安全服务'\n );\n logger.debug('运行时安全服务初始化完成');\n } catch (error) {\n logger.warn('运行时安全服务初始化失败(不影响应用运行):', error);\n }\n }\n\n const nonCriticalDuration = performance.now() - nonCriticalStartTime;\n logger.debug(`非关键服务初始化完成,耗时: ${nonCriticalDuration.toFixed(2)}ms`);\n } catch (error) {\n logger.warn('非关键服务初始化过程中出现错误:', error);\n } finally {\n resolve();\n }\n });\n });\n };\n\n // 记录关键服务初始化性能指标\n if (monitoring.reportPerformance) {\n monitoring.reportPerformance({\n serviceInitDuration: criticalServicesDuration,\n } as any);\n }\n\n return {\n monitoring,\n performanceMonitor,\n stateManager,\n eventBus,\n initializeNonCriticalServices,\n };\n}\n"],"names":["initializeServices","withRetry","fn","config","serviceName","maxRetries","retryDelay","exponentialBackoff","lastError","attempt","error","delay","Math","pow","logger","warn","Promise","resolve","setTimeout","options","startTime","performance","now","retryConfig","serviceRetry","monitoringPromise","initMonitoring","errorMonitor","onError","storagePromise","then","storage","initialize","storageOptions","stateManagerPromise","stateManager","undefined","StateManager","enableRegistry","defaultScope","eventBusPromise","eventBusConfig","enableTracking","eventBus","process","env","NODE_ENV","maxHistorySize","enableValidation","enablePerformanceMonitoring","namespacePrefix","instanceId","enableSecurityMode","allowedSources","AppEventBus","monitoring","all","info","performanceMonitor","PerformanceMonitor","onReport","metrics","reportPerformance","window","cleanupHandler","disconnect","removeEventListener","addEventListener","criticalServicesDuration","debug","toFixed","initializeNonCriticalServices","nonCriticalStartTime","scheduleInit","callback","requestIdleCallback","timeout","analytics","initAnalytics","runtimeSecurity","RuntimeSecurity","nonCriticalDuration","serviceInitDuration"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../src/core/startup/initializeServices.ts"],"sourcesContent":["/**\n * 服务初始化模块\n * 负责初始化框架所需的各种服务\n */\n\nimport { logger } from '../../utils';\nimport { initMonitoring } from '@vlian/monitoring';\nimport type { MonitoringService } from '@vlian/monitoring';\nimport { PerformanceMonitor } from '../../utils/performance';\nimport { storage } from '../../library';\nimport { StateManager } from '../../state';\nimport type { StartOptions } from '../types';\nimport { AppEventBus } from '../event/AppEventBus';\nimport type { AppEventBusConfig } from '../event/types';\n\n/**\n * 重试配置\n */\nexport interface RetryConfig {\n /**\n * 最大重试次数\n * @default 3\n */\n maxRetries?: number;\n /**\n * 重试延迟(毫秒)\n * @default 1000\n */\n retryDelay?: number;\n /**\n * 是否启用指数退避\n * @default true\n */\n exponentialBackoff?: boolean;\n}\n\n/**\n * 服务初始化结果\n */\nexport interface ServicesInitResult {\n /**\n * 监控服务实例\n */\n monitoring: MonitoringService;\n\n /**\n * 性能监控实例\n */\n performanceMonitor: PerformanceMonitor;\n\n /**\n * 状态管理器实例\n */\n stateManager: StateManager;\n\n /**\n * 事件总线实例\n */\n eventBus: AppEventBus;\n\n /**\n * 延迟初始化非关键服务的函数\n * 在应用渲染后调用,使用 requestIdleCallback 在空闲时初始化\n */\n initializeNonCriticalServices?: () => Promise<void>;\n}\n\n/**\n * 带重试的异步函数执行器\n */\nasync function withRetry<T>(\n fn: () => Promise<T>,\n config: RetryConfig = {},\n serviceName: string\n): Promise<T> {\n const maxRetries = config.maxRetries ?? 3;\n const retryDelay = config.retryDelay ?? 1000;\n const exponentialBackoff = config.exponentialBackoff ?? true;\n\n let lastError: unknown;\n \n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n try {\n return await fn();\n } catch (error) {\n lastError = error;\n \n if (attempt < maxRetries) {\n const delay = exponentialBackoff \n ? retryDelay * Math.pow(2, attempt)\n : retryDelay;\n \n logger.warn(\n `${serviceName} 初始化失败(尝试 ${attempt + 1}/${maxRetries + 1}),${delay}ms 后重试...`,\n error\n );\n \n await new Promise(resolve => setTimeout(resolve, delay));\n }\n }\n }\n \n logger.error(`${serviceName} 初始化失败,已重试 ${maxRetries} 次`);\n throw lastError;\n}\n\n/**\n * 初始化所有服务\n * \n * 优化:\n * 1. 区分关键服务和非关键服务\n * 2. 关键服务并行初始化,缩短首屏时间\n * 3. 非关键服务延迟到应用渲染后初始化,使用 requestIdleCallback 在空闲时初始化\n * 4. 实现服务初始化失败重试机制,提高启动成功率\n * \n * @param options - 启动配置选项\n * @returns 服务初始化结果\n */\nexport async function initializeServices(\n options: StartOptions = {}\n): Promise<ServicesInitResult> {\n const startTime = performance.now();\n \n // 重试配置\n const retryConfig: RetryConfig = {\n maxRetries: options.serviceRetry?.maxRetries ?? 3,\n retryDelay: options.serviceRetry?.retryDelay ?? 1000,\n exponentialBackoff: options.serviceRetry?.exponentialBackoff ?? true,\n };\n\n // ========== 关键服务:必须在应用渲染前初始化 ==========\n // 这些服务是应用运行的基础,必须并行初始化完成\n\n // 1. 监控服务(必须最先初始化,因为其他服务可能依赖它)\n const monitoringPromise = withRetry(\n () => Promise.resolve(initMonitoring({\n ...options.errorMonitor,\n onError: (error) => {\n logger.error('监控服务捕获到错误:', error);\n options.errorMonitor?.onError?.(error);\n },\n })),\n retryConfig,\n '监控服务'\n );\n\n // 2. 存储服务(关键服务,应用可能需要立即使用存储)\n const storagePromise = withRetry(\n () => Promise.resolve().then(() => {\n storage.initialize(options.storageOptions);\n return storage;\n }),\n retryConfig,\n '存储服务'\n );\n\n // 3. 状态管理器(关键服务,应用状态管理的基础)\n const stateManagerPromise = withRetry(\n () => Promise.resolve().then(() => {\n if (options.stateManager !== undefined) {\n return new StateManager(options.stateManager);\n } else {\n // 默认初始化状态管理器\n return new StateManager({\n enableRegistry: true,\n defaultScope: 'app',\n });\n }\n }),\n retryConfig,\n '状态管理器'\n );\n\n // 4. 事件总线(关键服务,用于应用内部通信)\n const eventBusPromise = withRetry(\n () => Promise.resolve().then(() => {\n const eventBusConfig: AppEventBusConfig = {\n enableTracking: options.eventBus?.enableTracking ?? (process.env.NODE_ENV === 'development'),\n maxHistorySize: options.eventBus?.maxHistorySize ?? 100,\n enableValidation: options.eventBus?.enableValidation ?? false,\n enablePerformanceMonitoring: options.eventBus?.enablePerformanceMonitoring ?? (process.env.NODE_ENV === 'development'),\n namespacePrefix: options.eventBus?.namespacePrefix,\n instanceId: options.eventBus?.instanceId,\n enableSecurityMode: options.eventBus?.enableSecurityMode ?? false,\n allowedSources: options.eventBus?.allowedSources,\n };\n return new AppEventBus(eventBusConfig);\n }),\n retryConfig,\n '事件总线'\n );\n\n // 并行执行关键服务初始化\n const [monitoring, , stateManager, eventBus] = await Promise.all([\n monitoringPromise,\n storagePromise,\n stateManagerPromise,\n eventBusPromise,\n ]);\n\n logger.info('关键服务初始化完成');\n\n // 初始化性能监控(依赖监控服务,必须在监控服务初始化后)\n const performanceMonitor = new PerformanceMonitor({\n ...options.performanceMonitor,\n onReport: (metrics) => {\n monitoring.reportPerformance(metrics);\n options.performanceMonitor?.onReport?.(metrics);\n },\n });\n\n // 在页面卸载时清理性能监控\n if (typeof window !== 'undefined') {\n const cleanupHandler = () => {\n performanceMonitor.disconnect();\n window.removeEventListener('beforeunload', cleanupHandler);\n };\n window.addEventListener('beforeunload', cleanupHandler);\n }\n\n const criticalServicesDuration = performance.now() - startTime;\n logger.debug(`关键服务初始化完成,耗时: ${criticalServicesDuration.toFixed(2)}ms`);\n\n // ========== 非关键服务:延迟到应用渲染后初始化 ==========\n // 这些服务不影响首屏渲染,可以在空闲时初始化\n\n /**\n * 延迟初始化非关键服务\n * 在应用渲染后调用,使用 requestIdleCallback 在空闲时初始化\n */\n const initializeNonCriticalServices = async (): Promise<void> => {\n const nonCriticalStartTime = performance.now();\n \n // 使用 requestIdleCallback 在浏览器空闲时初始化非关键服务\n // 如果不支持 requestIdleCallback,则使用 setTimeout 延迟执行\n const scheduleInit = (callback: () => void) => {\n if (typeof window !== 'undefined' && 'requestIdleCallback' in window) {\n window.requestIdleCallback(callback, { timeout: 5000 });\n } else {\n setTimeout(callback, 100);\n }\n };\n\n return new Promise<void>((resolve) => {\n scheduleInit(async () => {\n try {\n // 1. 分析服务(可选,非关键)\n if (options.analytics) {\n try {\n await withRetry(\n () => import('../../utils/analytics').then(({ initAnalytics }) => {\n initAnalytics(options.analytics!);\n return true;\n }),\n retryConfig,\n '分析服务'\n );\n logger.debug('分析服务初始化完成');\n } catch (error) {\n logger.warn('分析服务初始化失败(不影响应用运行):', error);\n }\n }\n\n // 2. 运行时安全服务(可选,非关键)\n if (options.runtimeSecurity) {\n try {\n await withRetry(\n () => import('../../utils/runtimeSecurity').then(({ RuntimeSecurity }) => {\n RuntimeSecurity.initialize(options.runtimeSecurity!);\n return true;\n }),\n retryConfig,\n '运行时安全服务'\n );\n logger.debug('运行时安全服务初始化完成');\n } catch (error) {\n logger.warn('运行时安全服务初始化失败(不影响应用运行):', error);\n }\n }\n\n const nonCriticalDuration = performance.now() - nonCriticalStartTime;\n logger.debug(`非关键服务初始化完成,耗时: ${nonCriticalDuration.toFixed(2)}ms`);\n } catch (error) {\n logger.warn('非关键服务初始化过程中出现错误:', error);\n } finally {\n resolve();\n }\n });\n });\n };\n\n // 记录关键服务初始化性能指标\n if (monitoring.reportPerformance) {\n monitoring.reportPerformance({\n serviceInitDuration: criticalServicesDuration,\n } as any);\n }\n\n return {\n monitoring,\n performanceMonitor,\n stateManager,\n eventBus,\n initializeNonCriticalServices,\n };\n}\n"],"names":["initializeServices","withRetry","fn","config","serviceName","maxRetries","retryDelay","exponentialBackoff","lastError","attempt","error","delay","Math","pow","logger","warn","Promise","resolve","setTimeout","options","startTime","performance","now","retryConfig","serviceRetry","monitoringPromise","initMonitoring","errorMonitor","onError","storagePromise","then","storage","initialize","storageOptions","stateManagerPromise","stateManager","undefined","StateManager","enableRegistry","defaultScope","eventBusPromise","eventBusConfig","enableTracking","eventBus","process","env","NODE_ENV","maxHistorySize","enableValidation","enablePerformanceMonitoring","namespacePrefix","instanceId","enableSecurityMode","allowedSources","AppEventBus","monitoring","all","info","performanceMonitor","PerformanceMonitor","onReport","metrics","reportPerformance","window","cleanupHandler","disconnect","removeEventListener","addEventListener","criticalServicesDuration","debug","toFixed","initializeNonCriticalServices","nonCriticalStartTime","scheduleInit","callback","requestIdleCallback","timeout","analytics","initAnalytics","runtimeSecurity","RuntimeSecurity","nonCriticalDuration","serviceInitDuration"],"mappings":"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"}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* 服务初始化模块
|
|
3
3
|
* 负责初始化框架所需的各种服务
|
|
4
4
|
*/
|
|
5
|
-
import type { MonitoringService } from '
|
|
5
|
+
import type { MonitoringService } from '@vlian/monitoring';
|
|
6
6
|
import { PerformanceMonitor } from '../../utils/performance';
|
|
7
7
|
import { StateManager } from '../../state';
|
|
8
8
|
import type { StartOptions } from '../types';
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* 服务初始化模块
|
|
3
3
|
* 负责初始化框架所需的各种服务
|
|
4
4
|
*/ import { logger } from "../../utils";
|
|
5
|
-
import { initMonitoring } from "
|
|
5
|
+
import { initMonitoring } from "@vlian/monitoring";
|
|
6
6
|
import { PerformanceMonitor } from "../../utils/performance";
|
|
7
7
|
import { storage } from "../../library";
|
|
8
8
|
import { StateManager } from "../../state";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/core/startup/initializeServices.ts"],"sourcesContent":["/**\n * 服务初始化模块\n * 负责初始化框架所需的各种服务\n */\n\nimport { logger } from '../../utils';\nimport { initMonitoring } from '../../utils/monitoring';\nimport type { MonitoringService } from '../../utils/monitoring';\nimport { PerformanceMonitor } from '../../utils/performance';\nimport { storage } from '../../library';\nimport { StateManager } from '../../state';\nimport type { StartOptions } from '../types';\nimport { AppEventBus } from '../event/AppEventBus';\nimport type { AppEventBusConfig } from '../event/types';\n\n/**\n * 重试配置\n */\nexport interface RetryConfig {\n /**\n * 最大重试次数\n * @default 3\n */\n maxRetries?: number;\n /**\n * 重试延迟(毫秒)\n * @default 1000\n */\n retryDelay?: number;\n /**\n * 是否启用指数退避\n * @default true\n */\n exponentialBackoff?: boolean;\n}\n\n/**\n * 服务初始化结果\n */\nexport interface ServicesInitResult {\n /**\n * 监控服务实例\n */\n monitoring: MonitoringService;\n\n /**\n * 性能监控实例\n */\n performanceMonitor: PerformanceMonitor;\n\n /**\n * 状态管理器实例\n */\n stateManager: StateManager;\n\n /**\n * 事件总线实例\n */\n eventBus: AppEventBus;\n\n /**\n * 延迟初始化非关键服务的函数\n * 在应用渲染后调用,使用 requestIdleCallback 在空闲时初始化\n */\n initializeNonCriticalServices?: () => Promise<void>;\n}\n\n/**\n * 带重试的异步函数执行器\n */\nasync function withRetry<T>(\n fn: () => Promise<T>,\n config: RetryConfig = {},\n serviceName: string\n): Promise<T> {\n const maxRetries = config.maxRetries ?? 3;\n const retryDelay = config.retryDelay ?? 1000;\n const exponentialBackoff = config.exponentialBackoff ?? true;\n\n let lastError: unknown;\n \n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n try {\n return await fn();\n } catch (error) {\n lastError = error;\n \n if (attempt < maxRetries) {\n const delay = exponentialBackoff \n ? retryDelay * Math.pow(2, attempt)\n : retryDelay;\n \n logger.warn(\n `${serviceName} 初始化失败(尝试 ${attempt + 1}/${maxRetries + 1}),${delay}ms 后重试...`,\n error\n );\n \n await new Promise(resolve => setTimeout(resolve, delay));\n }\n }\n }\n \n logger.error(`${serviceName} 初始化失败,已重试 ${maxRetries} 次`);\n throw lastError;\n}\n\n/**\n * 初始化所有服务\n * \n * 优化:\n * 1. 区分关键服务和非关键服务\n * 2. 关键服务并行初始化,缩短首屏时间\n * 3. 非关键服务延迟到应用渲染后初始化,使用 requestIdleCallback 在空闲时初始化\n * 4. 实现服务初始化失败重试机制,提高启动成功率\n * \n * @param options - 启动配置选项\n * @returns 服务初始化结果\n */\nexport async function initializeServices(\n options: StartOptions = {}\n): Promise<ServicesInitResult> {\n const startTime = performance.now();\n \n // 重试配置\n const retryConfig: RetryConfig = {\n maxRetries: options.serviceRetry?.maxRetries ?? 3,\n retryDelay: options.serviceRetry?.retryDelay ?? 1000,\n exponentialBackoff: options.serviceRetry?.exponentialBackoff ?? true,\n };\n\n // ========== 关键服务:必须在应用渲染前初始化 ==========\n // 这些服务是应用运行的基础,必须并行初始化完成\n\n // 1. 监控服务(必须最先初始化,因为其他服务可能依赖它)\n const monitoringPromise = withRetry(\n () => Promise.resolve(initMonitoring({\n ...options.errorMonitor,\n onError: (error) => {\n logger.error('监控服务捕获到错误:', error);\n options.errorMonitor?.onError?.(error);\n },\n })),\n retryConfig,\n '监控服务'\n );\n\n // 2. 存储服务(关键服务,应用可能需要立即使用存储)\n const storagePromise = withRetry(\n () => Promise.resolve().then(() => {\n storage.initialize(options.storageOptions);\n return storage;\n }),\n retryConfig,\n '存储服务'\n );\n\n // 3. 状态管理器(关键服务,应用状态管理的基础)\n const stateManagerPromise = withRetry(\n () => Promise.resolve().then(() => {\n if (options.stateManager !== undefined) {\n return new StateManager(options.stateManager);\n } else {\n // 默认初始化状态管理器\n return new StateManager({\n enableRegistry: true,\n defaultScope: 'app',\n });\n }\n }),\n retryConfig,\n '状态管理器'\n );\n\n // 4. 事件总线(关键服务,用于应用内部通信)\n const eventBusPromise = withRetry(\n () => Promise.resolve().then(() => {\n const eventBusConfig: AppEventBusConfig = {\n enableTracking: options.eventBus?.enableTracking ?? (process.env.NODE_ENV === 'development'),\n maxHistorySize: options.eventBus?.maxHistorySize ?? 100,\n enableValidation: options.eventBus?.enableValidation ?? false,\n enablePerformanceMonitoring: options.eventBus?.enablePerformanceMonitoring ?? (process.env.NODE_ENV === 'development'),\n namespacePrefix: options.eventBus?.namespacePrefix,\n instanceId: options.eventBus?.instanceId,\n enableSecurityMode: options.eventBus?.enableSecurityMode ?? false,\n allowedSources: options.eventBus?.allowedSources,\n };\n return new AppEventBus(eventBusConfig);\n }),\n retryConfig,\n '事件总线'\n );\n\n // 并行执行关键服务初始化\n const [monitoring, , stateManager, eventBus] = await Promise.all([\n monitoringPromise,\n storagePromise,\n stateManagerPromise,\n eventBusPromise,\n ]);\n\n logger.info('关键服务初始化完成');\n\n // 初始化性能监控(依赖监控服务,必须在监控服务初始化后)\n const performanceMonitor = new PerformanceMonitor({\n ...options.performanceMonitor,\n onReport: (metrics) => {\n monitoring.reportPerformance(metrics);\n options.performanceMonitor?.onReport?.(metrics);\n },\n });\n\n // 在页面卸载时清理性能监控\n if (typeof window !== 'undefined') {\n const cleanupHandler = () => {\n performanceMonitor.disconnect();\n window.removeEventListener('beforeunload', cleanupHandler);\n };\n window.addEventListener('beforeunload', cleanupHandler);\n }\n\n const criticalServicesDuration = performance.now() - startTime;\n logger.debug(`关键服务初始化完成,耗时: ${criticalServicesDuration.toFixed(2)}ms`);\n\n // ========== 非关键服务:延迟到应用渲染后初始化 ==========\n // 这些服务不影响首屏渲染,可以在空闲时初始化\n\n /**\n * 延迟初始化非关键服务\n * 在应用渲染后调用,使用 requestIdleCallback 在空闲时初始化\n */\n const initializeNonCriticalServices = async (): Promise<void> => {\n const nonCriticalStartTime = performance.now();\n \n // 使用 requestIdleCallback 在浏览器空闲时初始化非关键服务\n // 如果不支持 requestIdleCallback,则使用 setTimeout 延迟执行\n const scheduleInit = (callback: () => void) => {\n if (typeof window !== 'undefined' && 'requestIdleCallback' in window) {\n window.requestIdleCallback(callback, { timeout: 5000 });\n } else {\n setTimeout(callback, 100);\n }\n };\n\n return new Promise<void>((resolve) => {\n scheduleInit(async () => {\n try {\n // 1. 分析服务(可选,非关键)\n if (options.analytics) {\n try {\n await withRetry(\n () => import('../../utils/analytics').then(({ initAnalytics }) => {\n initAnalytics(options.analytics!);\n return true;\n }),\n retryConfig,\n '分析服务'\n );\n logger.debug('分析服务初始化完成');\n } catch (error) {\n logger.warn('分析服务初始化失败(不影响应用运行):', error);\n }\n }\n\n // 2. 运行时安全服务(可选,非关键)\n if (options.runtimeSecurity) {\n try {\n await withRetry(\n () => import('../../utils/runtimeSecurity').then(({ RuntimeSecurity }) => {\n RuntimeSecurity.initialize(options.runtimeSecurity!);\n return true;\n }),\n retryConfig,\n '运行时安全服务'\n );\n logger.debug('运行时安全服务初始化完成');\n } catch (error) {\n logger.warn('运行时安全服务初始化失败(不影响应用运行):', error);\n }\n }\n\n const nonCriticalDuration = performance.now() - nonCriticalStartTime;\n logger.debug(`非关键服务初始化完成,耗时: ${nonCriticalDuration.toFixed(2)}ms`);\n } catch (error) {\n logger.warn('非关键服务初始化过程中出现错误:', error);\n } finally {\n resolve();\n }\n });\n });\n };\n\n // 记录关键服务初始化性能指标\n if (monitoring.reportPerformance) {\n monitoring.reportPerformance({\n serviceInitDuration: criticalServicesDuration,\n } as any);\n }\n\n return {\n monitoring,\n performanceMonitor,\n stateManager,\n eventBus,\n initializeNonCriticalServices,\n };\n}\n"],"names":["logger","initMonitoring","PerformanceMonitor","storage","StateManager","AppEventBus","withRetry","fn","config","serviceName","maxRetries","retryDelay","exponentialBackoff","lastError","attempt","error","delay","Math","pow","warn","Promise","resolve","setTimeout","initializeServices","options","startTime","performance","now","retryConfig","serviceRetry","monitoringPromise","errorMonitor","onError","storagePromise","then","initialize","storageOptions","stateManagerPromise","stateManager","undefined","enableRegistry","defaultScope","eventBusPromise","eventBusConfig","enableTracking","eventBus","process","env","NODE_ENV","maxHistorySize","enableValidation","enablePerformanceMonitoring","namespacePrefix","instanceId","enableSecurityMode","allowedSources","monitoring","all","info","performanceMonitor","onReport","metrics","reportPerformance","window","cleanupHandler","disconnect","removeEventListener","addEventListener","criticalServicesDuration","debug","toFixed","initializeNonCriticalServices","nonCriticalStartTime","scheduleInit","callback","requestIdleCallback","timeout","analytics","initAnalytics","runtimeSecurity","RuntimeSecurity","nonCriticalDuration","serviceInitDuration"],"mappings":"AAAA;;;CAGC,GAED,SAASA,MAAM,QAAQ,cAAc;AACrC,SAASC,cAAc,QAAQ,yBAAyB;AAExD,SAASC,kBAAkB,QAAQ,0BAA0B;AAC7D,SAASC,OAAO,QAAQ,gBAAgB;AACxC,SAASC,YAAY,QAAQ,cAAc;AAE3C,SAASC,WAAW,QAAQ,uBAAuB;AAuDnD;;CAEC,GACD,eAAeC,UACbC,EAAoB,EACpBC,SAAsB,CAAC,CAAC,EACxBC,WAAmB;IAEnB,MAAMC,aAAaF,OAAOE,UAAU,IAAI;IACxC,MAAMC,aAAaH,OAAOG,UAAU,IAAI;IACxC,MAAMC,qBAAqBJ,OAAOI,kBAAkB,IAAI;IAExD,IAAIC;IAEJ,IAAK,IAAIC,UAAU,GAAGA,WAAWJ,YAAYI,UAAW;QACtD,IAAI;YACF,OAAO,MAAMP;QACf,EAAE,OAAOQ,OAAO;YACdF,YAAYE;YAEZ,IAAID,UAAUJ,YAAY;gBACxB,MAAMM,QAAQJ,qBACVD,aAAaM,KAAKC,GAAG,CAAC,GAAGJ,WACzBH;gBAEJX,OAAOmB,IAAI,CACT,GAAGV,YAAY,UAAU,EAAEK,UAAU,EAAE,CAAC,EAAEJ,aAAa,EAAE,EAAE,EAAEM,MAAM,SAAS,CAAC,EAC7ED;gBAGF,MAAM,IAAIK,QAAQC,CAAAA,UAAWC,WAAWD,SAASL;YACnD;QACF;IACF;IAEAhB,OAAOe,KAAK,CAAC,GAAGN,YAAY,WAAW,EAAEC,WAAW,EAAE,CAAC;IACvD,MAAMG;AACR;AAEA;;;;;;;;;;;CAWC,GACD,OAAO,eAAeU,mBACpBC,UAAwB,CAAC,CAAC;IAE1B,MAAMC,YAAYC,YAAYC,GAAG;IAEjC,OAAO;IACP,MAAMC,cAA2B;QAC/BlB,YAAYc,QAAQK,YAAY,EAAEnB,cAAc;QAChDC,YAAYa,QAAQK,YAAY,EAAElB,cAAc;QAChDC,oBAAoBY,QAAQK,YAAY,EAAEjB,sBAAsB;IAClE;IAEA,yCAAyC;IACzC,yBAAyB;IAEzB,+BAA+B;IAC/B,MAAMkB,oBAAoBxB,UACxB,IAAMc,QAAQC,OAAO,CAACpB,eAAe;YACnC,GAAGuB,QAAQO,YAAY;YACvBC,SAAS,CAACjB;gBACRf,OAAOe,KAAK,CAAC,cAAcA;gBAC3BS,QAAQO,YAAY,EAAEC,UAAUjB;YAClC;QACF,KACAa,aACA;IAGF,6BAA6B;IAC7B,MAAMK,iBAAiB3B,UACrB,IAAMc,QAAQC,OAAO,GAAGa,IAAI,CAAC;YAC3B/B,QAAQgC,UAAU,CAACX,QAAQY,cAAc;YACzC,OAAOjC;QACT,IACAyB,aACA;IAGF,2BAA2B;IAC3B,MAAMS,sBAAsB/B,UAC1B,IAAMc,QAAQC,OAAO,GAAGa,IAAI,CAAC;YAC3B,IAAIV,QAAQc,YAAY,KAAKC,WAAW;gBACtC,OAAO,IAAInC,aAAaoB,QAAQc,YAAY;YAC9C,OAAO;gBACL,aAAa;gBACb,OAAO,IAAIlC,aAAa;oBACtBoC,gBAAgB;oBAChBC,cAAc;gBAChB;YACF;QACF,IACAb,aACA;IAGF,yBAAyB;IACzB,MAAMc,kBAAkBpC,UACtB,IAAMc,QAAQC,OAAO,GAAGa,IAAI,CAAC;YAC3B,MAAMS,iBAAoC;gBACxCC,gBAAgBpB,QAAQqB,QAAQ,EAAED,kBAAmBE,QAAQC,GAAG,CAACC,QAAQ,KAAK;gBAC9EC,gBAAgBzB,QAAQqB,QAAQ,EAAEI,kBAAkB;gBACpDC,kBAAkB1B,QAAQqB,QAAQ,EAAEK,oBAAoB;gBACxDC,6BAA6B3B,QAAQqB,QAAQ,EAAEM,+BAAgCL,QAAQC,GAAG,CAACC,QAAQ,KAAK;gBACxGI,iBAAiB5B,QAAQqB,QAAQ,EAAEO;gBACnCC,YAAY7B,QAAQqB,QAAQ,EAAEQ;gBAC9BC,oBAAoB9B,QAAQqB,QAAQ,EAAES,sBAAsB;gBAC5DC,gBAAgB/B,QAAQqB,QAAQ,EAAEU;YACpC;YACA,OAAO,IAAIlD,YAAYsC;QACzB,IACAf,aACA;IAGF,cAAc;IACd,MAAM,CAAC4B,cAAclB,cAAcO,SAAS,GAAG,MAAMzB,QAAQqC,GAAG,CAAC;QAC/D3B;QACAG;QACAI;QACAK;KACD;IAED1C,OAAO0D,IAAI,CAAC;IAEZ,8BAA8B;IAC9B,MAAMC,qBAAqB,IAAIzD,mBAAmB;QAChD,GAAGsB,QAAQmC,kBAAkB;QAC7BC,UAAU,CAACC;YACTL,WAAWM,iBAAiB,CAACD;YAC7BrC,QAAQmC,kBAAkB,EAAEC,WAAWC;QACzC;IACF;IAEA,eAAe;IACf,IAAI,OAAOE,WAAW,aAAa;QACjC,MAAMC,iBAAiB;YACrBL,mBAAmBM,UAAU;YAC7BF,OAAOG,mBAAmB,CAAC,gBAAgBF;QAC7C;QACAD,OAAOI,gBAAgB,CAAC,gBAAgBH;IAC1C;IAEA,MAAMI,2BAA2B1C,YAAYC,GAAG,KAAKF;IACrDzB,OAAOqE,KAAK,CAAC,CAAC,cAAc,EAAED,yBAAyBE,OAAO,CAAC,GAAG,EAAE,CAAC;IAErE,0CAA0C;IAC1C,wBAAwB;IAExB;;;GAGC,GACD,MAAMC,gCAAgC;QACpC,MAAMC,uBAAuB9C,YAAYC,GAAG;QAE5C,yCAAyC;QACzC,gDAAgD;QAChD,MAAM8C,eAAe,CAACC;YACpB,IAAI,OAAOX,WAAW,eAAe,yBAAyBA,QAAQ;gBACpEA,OAAOY,mBAAmB,CAACD,UAAU;oBAAEE,SAAS;gBAAK;YACvD,OAAO;gBACLtD,WAAWoD,UAAU;YACvB;QACF;QAEA,OAAO,IAAItD,QAAc,CAACC;YACxBoD,aAAa;gBACX,IAAI;oBACF,kBAAkB;oBAClB,IAAIjD,QAAQqD,SAAS,EAAE;wBACrB,IAAI;4BACF,MAAMvE,UACJ,IAAM,MAAM,CAAC,yBAAyB4B,IAAI,CAAC,CAAC,EAAE4C,aAAa,EAAE;oCAC3DA,cAActD,QAAQqD,SAAS;oCAC/B,OAAO;gCACT,IACAjD,aACA;4BAEF5B,OAAOqE,KAAK,CAAC;wBACf,EAAE,OAAOtD,OAAO;4BACdf,OAAOmB,IAAI,CAAC,uBAAuBJ;wBACrC;oBACF;oBAEA,qBAAqB;oBACrB,IAAIS,QAAQuD,eAAe,EAAE;wBAC3B,IAAI;4BACF,MAAMzE,UACJ,IAAM,MAAM,CAAC,+BAA+B4B,IAAI,CAAC,CAAC,EAAE8C,eAAe,EAAE;oCACnEA,gBAAgB7C,UAAU,CAACX,QAAQuD,eAAe;oCAClD,OAAO;gCACT,IACAnD,aACA;4BAEF5B,OAAOqE,KAAK,CAAC;wBACf,EAAE,OAAOtD,OAAO;4BACdf,OAAOmB,IAAI,CAAC,0BAA0BJ;wBACxC;oBACF;oBAEA,MAAMkE,sBAAsBvD,YAAYC,GAAG,KAAK6C;oBAChDxE,OAAOqE,KAAK,CAAC,CAAC,eAAe,EAAEY,oBAAoBX,OAAO,CAAC,GAAG,EAAE,CAAC;gBACnE,EAAE,OAAOvD,OAAO;oBACdf,OAAOmB,IAAI,CAAC,oBAAoBJ;gBAClC,SAAU;oBACRM;gBACF;YACF;QACF;IACF;IAEA,gBAAgB;IAChB,IAAImC,WAAWM,iBAAiB,EAAE;QAChCN,WAAWM,iBAAiB,CAAC;YAC3BoB,qBAAqBd;QACvB;IACF;IAEA,OAAO;QACLZ;QACAG;QACArB;QACAO;QACA0B;IACF;AACF"}
|
|
1
|
+
{"version":3,"sources":["../../../src/core/startup/initializeServices.ts"],"sourcesContent":["/**\n * 服务初始化模块\n * 负责初始化框架所需的各种服务\n */\n\nimport { logger } from '../../utils';\nimport { initMonitoring } from '@vlian/monitoring';\nimport type { MonitoringService } from '@vlian/monitoring';\nimport { PerformanceMonitor } from '../../utils/performance';\nimport { storage } from '../../library';\nimport { StateManager } from '../../state';\nimport type { StartOptions } from '../types';\nimport { AppEventBus } from '../event/AppEventBus';\nimport type { AppEventBusConfig } from '../event/types';\n\n/**\n * 重试配置\n */\nexport interface RetryConfig {\n /**\n * 最大重试次数\n * @default 3\n */\n maxRetries?: number;\n /**\n * 重试延迟(毫秒)\n * @default 1000\n */\n retryDelay?: number;\n /**\n * 是否启用指数退避\n * @default true\n */\n exponentialBackoff?: boolean;\n}\n\n/**\n * 服务初始化结果\n */\nexport interface ServicesInitResult {\n /**\n * 监控服务实例\n */\n monitoring: MonitoringService;\n\n /**\n * 性能监控实例\n */\n performanceMonitor: PerformanceMonitor;\n\n /**\n * 状态管理器实例\n */\n stateManager: StateManager;\n\n /**\n * 事件总线实例\n */\n eventBus: AppEventBus;\n\n /**\n * 延迟初始化非关键服务的函数\n * 在应用渲染后调用,使用 requestIdleCallback 在空闲时初始化\n */\n initializeNonCriticalServices?: () => Promise<void>;\n}\n\n/**\n * 带重试的异步函数执行器\n */\nasync function withRetry<T>(\n fn: () => Promise<T>,\n config: RetryConfig = {},\n serviceName: string\n): Promise<T> {\n const maxRetries = config.maxRetries ?? 3;\n const retryDelay = config.retryDelay ?? 1000;\n const exponentialBackoff = config.exponentialBackoff ?? true;\n\n let lastError: unknown;\n \n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n try {\n return await fn();\n } catch (error) {\n lastError = error;\n \n if (attempt < maxRetries) {\n const delay = exponentialBackoff \n ? retryDelay * Math.pow(2, attempt)\n : retryDelay;\n \n logger.warn(\n `${serviceName} 初始化失败(尝试 ${attempt + 1}/${maxRetries + 1}),${delay}ms 后重试...`,\n error\n );\n \n await new Promise(resolve => setTimeout(resolve, delay));\n }\n }\n }\n \n logger.error(`${serviceName} 初始化失败,已重试 ${maxRetries} 次`);\n throw lastError;\n}\n\n/**\n * 初始化所有服务\n * \n * 优化:\n * 1. 区分关键服务和非关键服务\n * 2. 关键服务并行初始化,缩短首屏时间\n * 3. 非关键服务延迟到应用渲染后初始化,使用 requestIdleCallback 在空闲时初始化\n * 4. 实现服务初始化失败重试机制,提高启动成功率\n * \n * @param options - 启动配置选项\n * @returns 服务初始化结果\n */\nexport async function initializeServices(\n options: StartOptions = {}\n): Promise<ServicesInitResult> {\n const startTime = performance.now();\n \n // 重试配置\n const retryConfig: RetryConfig = {\n maxRetries: options.serviceRetry?.maxRetries ?? 3,\n retryDelay: options.serviceRetry?.retryDelay ?? 1000,\n exponentialBackoff: options.serviceRetry?.exponentialBackoff ?? true,\n };\n\n // ========== 关键服务:必须在应用渲染前初始化 ==========\n // 这些服务是应用运行的基础,必须并行初始化完成\n\n // 1. 监控服务(必须最先初始化,因为其他服务可能依赖它)\n const monitoringPromise = withRetry(\n () => Promise.resolve(initMonitoring({\n ...options.errorMonitor,\n onError: (error) => {\n logger.error('监控服务捕获到错误:', error);\n options.errorMonitor?.onError?.(error);\n },\n })),\n retryConfig,\n '监控服务'\n );\n\n // 2. 存储服务(关键服务,应用可能需要立即使用存储)\n const storagePromise = withRetry(\n () => Promise.resolve().then(() => {\n storage.initialize(options.storageOptions);\n return storage;\n }),\n retryConfig,\n '存储服务'\n );\n\n // 3. 状态管理器(关键服务,应用状态管理的基础)\n const stateManagerPromise = withRetry(\n () => Promise.resolve().then(() => {\n if (options.stateManager !== undefined) {\n return new StateManager(options.stateManager);\n } else {\n // 默认初始化状态管理器\n return new StateManager({\n enableRegistry: true,\n defaultScope: 'app',\n });\n }\n }),\n retryConfig,\n '状态管理器'\n );\n\n // 4. 事件总线(关键服务,用于应用内部通信)\n const eventBusPromise = withRetry(\n () => Promise.resolve().then(() => {\n const eventBusConfig: AppEventBusConfig = {\n enableTracking: options.eventBus?.enableTracking ?? (process.env.NODE_ENV === 'development'),\n maxHistorySize: options.eventBus?.maxHistorySize ?? 100,\n enableValidation: options.eventBus?.enableValidation ?? false,\n enablePerformanceMonitoring: options.eventBus?.enablePerformanceMonitoring ?? (process.env.NODE_ENV === 'development'),\n namespacePrefix: options.eventBus?.namespacePrefix,\n instanceId: options.eventBus?.instanceId,\n enableSecurityMode: options.eventBus?.enableSecurityMode ?? false,\n allowedSources: options.eventBus?.allowedSources,\n };\n return new AppEventBus(eventBusConfig);\n }),\n retryConfig,\n '事件总线'\n );\n\n // 并行执行关键服务初始化\n const [monitoring, , stateManager, eventBus] = await Promise.all([\n monitoringPromise,\n storagePromise,\n stateManagerPromise,\n eventBusPromise,\n ]);\n\n logger.info('关键服务初始化完成');\n\n // 初始化性能监控(依赖监控服务,必须在监控服务初始化后)\n const performanceMonitor = new PerformanceMonitor({\n ...options.performanceMonitor,\n onReport: (metrics) => {\n monitoring.reportPerformance(metrics);\n options.performanceMonitor?.onReport?.(metrics);\n },\n });\n\n // 在页面卸载时清理性能监控\n if (typeof window !== 'undefined') {\n const cleanupHandler = () => {\n performanceMonitor.disconnect();\n window.removeEventListener('beforeunload', cleanupHandler);\n };\n window.addEventListener('beforeunload', cleanupHandler);\n }\n\n const criticalServicesDuration = performance.now() - startTime;\n logger.debug(`关键服务初始化完成,耗时: ${criticalServicesDuration.toFixed(2)}ms`);\n\n // ========== 非关键服务:延迟到应用渲染后初始化 ==========\n // 这些服务不影响首屏渲染,可以在空闲时初始化\n\n /**\n * 延迟初始化非关键服务\n * 在应用渲染后调用,使用 requestIdleCallback 在空闲时初始化\n */\n const initializeNonCriticalServices = async (): Promise<void> => {\n const nonCriticalStartTime = performance.now();\n \n // 使用 requestIdleCallback 在浏览器空闲时初始化非关键服务\n // 如果不支持 requestIdleCallback,则使用 setTimeout 延迟执行\n const scheduleInit = (callback: () => void) => {\n if (typeof window !== 'undefined' && 'requestIdleCallback' in window) {\n window.requestIdleCallback(callback, { timeout: 5000 });\n } else {\n setTimeout(callback, 100);\n }\n };\n\n return new Promise<void>((resolve) => {\n scheduleInit(async () => {\n try {\n // 1. 分析服务(可选,非关键)\n if (options.analytics) {\n try {\n await withRetry(\n () => import('../../utils/analytics').then(({ initAnalytics }) => {\n initAnalytics(options.analytics!);\n return true;\n }),\n retryConfig,\n '分析服务'\n );\n logger.debug('分析服务初始化完成');\n } catch (error) {\n logger.warn('分析服务初始化失败(不影响应用运行):', error);\n }\n }\n\n // 2. 运行时安全服务(可选,非关键)\n if (options.runtimeSecurity) {\n try {\n await withRetry(\n () => import('../../utils/runtimeSecurity').then(({ RuntimeSecurity }) => {\n RuntimeSecurity.initialize(options.runtimeSecurity!);\n return true;\n }),\n retryConfig,\n '运行时安全服务'\n );\n logger.debug('运行时安全服务初始化完成');\n } catch (error) {\n logger.warn('运行时安全服务初始化失败(不影响应用运行):', error);\n }\n }\n\n const nonCriticalDuration = performance.now() - nonCriticalStartTime;\n logger.debug(`非关键服务初始化完成,耗时: ${nonCriticalDuration.toFixed(2)}ms`);\n } catch (error) {\n logger.warn('非关键服务初始化过程中出现错误:', error);\n } finally {\n resolve();\n }\n });\n });\n };\n\n // 记录关键服务初始化性能指标\n if (monitoring.reportPerformance) {\n monitoring.reportPerformance({\n serviceInitDuration: criticalServicesDuration,\n } as any);\n }\n\n return {\n monitoring,\n performanceMonitor,\n stateManager,\n eventBus,\n initializeNonCriticalServices,\n };\n}\n"],"names":["logger","initMonitoring","PerformanceMonitor","storage","StateManager","AppEventBus","withRetry","fn","config","serviceName","maxRetries","retryDelay","exponentialBackoff","lastError","attempt","error","delay","Math","pow","warn","Promise","resolve","setTimeout","initializeServices","options","startTime","performance","now","retryConfig","serviceRetry","monitoringPromise","errorMonitor","onError","storagePromise","then","initialize","storageOptions","stateManagerPromise","stateManager","undefined","enableRegistry","defaultScope","eventBusPromise","eventBusConfig","enableTracking","eventBus","process","env","NODE_ENV","maxHistorySize","enableValidation","enablePerformanceMonitoring","namespacePrefix","instanceId","enableSecurityMode","allowedSources","monitoring","all","info","performanceMonitor","onReport","metrics","reportPerformance","window","cleanupHandler","disconnect","removeEventListener","addEventListener","criticalServicesDuration","debug","toFixed","initializeNonCriticalServices","nonCriticalStartTime","scheduleInit","callback","requestIdleCallback","timeout","analytics","initAnalytics","runtimeSecurity","RuntimeSecurity","nonCriticalDuration","serviceInitDuration"],"mappings":"AAAA;;;CAGC,GAED,SAASA,MAAM,QAAQ,cAAc;AACrC,SAASC,cAAc,QAAQ,oBAAoB;AAEnD,SAASC,kBAAkB,QAAQ,0BAA0B;AAC7D,SAASC,OAAO,QAAQ,gBAAgB;AACxC,SAASC,YAAY,QAAQ,cAAc;AAE3C,SAASC,WAAW,QAAQ,uBAAuB;AAuDnD;;CAEC,GACD,eAAeC,UACbC,EAAoB,EACpBC,SAAsB,CAAC,CAAC,EACxBC,WAAmB;IAEnB,MAAMC,aAAaF,OAAOE,UAAU,IAAI;IACxC,MAAMC,aAAaH,OAAOG,UAAU,IAAI;IACxC,MAAMC,qBAAqBJ,OAAOI,kBAAkB,IAAI;IAExD,IAAIC;IAEJ,IAAK,IAAIC,UAAU,GAAGA,WAAWJ,YAAYI,UAAW;QACtD,IAAI;YACF,OAAO,MAAMP;QACf,EAAE,OAAOQ,OAAO;YACdF,YAAYE;YAEZ,IAAID,UAAUJ,YAAY;gBACxB,MAAMM,QAAQJ,qBACVD,aAAaM,KAAKC,GAAG,CAAC,GAAGJ,WACzBH;gBAEJX,OAAOmB,IAAI,CACT,GAAGV,YAAY,UAAU,EAAEK,UAAU,EAAE,CAAC,EAAEJ,aAAa,EAAE,EAAE,EAAEM,MAAM,SAAS,CAAC,EAC7ED;gBAGF,MAAM,IAAIK,QAAQC,CAAAA,UAAWC,WAAWD,SAASL;YACnD;QACF;IACF;IAEAhB,OAAOe,KAAK,CAAC,GAAGN,YAAY,WAAW,EAAEC,WAAW,EAAE,CAAC;IACvD,MAAMG;AACR;AAEA;;;;;;;;;;;CAWC,GACD,OAAO,eAAeU,mBACpBC,UAAwB,CAAC,CAAC;IAE1B,MAAMC,YAAYC,YAAYC,GAAG;IAEjC,OAAO;IACP,MAAMC,cAA2B;QAC/BlB,YAAYc,QAAQK,YAAY,EAAEnB,cAAc;QAChDC,YAAYa,QAAQK,YAAY,EAAElB,cAAc;QAChDC,oBAAoBY,QAAQK,YAAY,EAAEjB,sBAAsB;IAClE;IAEA,yCAAyC;IACzC,yBAAyB;IAEzB,+BAA+B;IAC/B,MAAMkB,oBAAoBxB,UACxB,IAAMc,QAAQC,OAAO,CAACpB,eAAe;YACnC,GAAGuB,QAAQO,YAAY;YACvBC,SAAS,CAACjB;gBACRf,OAAOe,KAAK,CAAC,cAAcA;gBAC3BS,QAAQO,YAAY,EAAEC,UAAUjB;YAClC;QACF,KACAa,aACA;IAGF,6BAA6B;IAC7B,MAAMK,iBAAiB3B,UACrB,IAAMc,QAAQC,OAAO,GAAGa,IAAI,CAAC;YAC3B/B,QAAQgC,UAAU,CAACX,QAAQY,cAAc;YACzC,OAAOjC;QACT,IACAyB,aACA;IAGF,2BAA2B;IAC3B,MAAMS,sBAAsB/B,UAC1B,IAAMc,QAAQC,OAAO,GAAGa,IAAI,CAAC;YAC3B,IAAIV,QAAQc,YAAY,KAAKC,WAAW;gBACtC,OAAO,IAAInC,aAAaoB,QAAQc,YAAY;YAC9C,OAAO;gBACL,aAAa;gBACb,OAAO,IAAIlC,aAAa;oBACtBoC,gBAAgB;oBAChBC,cAAc;gBAChB;YACF;QACF,IACAb,aACA;IAGF,yBAAyB;IACzB,MAAMc,kBAAkBpC,UACtB,IAAMc,QAAQC,OAAO,GAAGa,IAAI,CAAC;YAC3B,MAAMS,iBAAoC;gBACxCC,gBAAgBpB,QAAQqB,QAAQ,EAAED,kBAAmBE,QAAQC,GAAG,CAACC,QAAQ,KAAK;gBAC9EC,gBAAgBzB,QAAQqB,QAAQ,EAAEI,kBAAkB;gBACpDC,kBAAkB1B,QAAQqB,QAAQ,EAAEK,oBAAoB;gBACxDC,6BAA6B3B,QAAQqB,QAAQ,EAAEM,+BAAgCL,QAAQC,GAAG,CAACC,QAAQ,KAAK;gBACxGI,iBAAiB5B,QAAQqB,QAAQ,EAAEO;gBACnCC,YAAY7B,QAAQqB,QAAQ,EAAEQ;gBAC9BC,oBAAoB9B,QAAQqB,QAAQ,EAAES,sBAAsB;gBAC5DC,gBAAgB/B,QAAQqB,QAAQ,EAAEU;YACpC;YACA,OAAO,IAAIlD,YAAYsC;QACzB,IACAf,aACA;IAGF,cAAc;IACd,MAAM,CAAC4B,cAAclB,cAAcO,SAAS,GAAG,MAAMzB,QAAQqC,GAAG,CAAC;QAC/D3B;QACAG;QACAI;QACAK;KACD;IAED1C,OAAO0D,IAAI,CAAC;IAEZ,8BAA8B;IAC9B,MAAMC,qBAAqB,IAAIzD,mBAAmB;QAChD,GAAGsB,QAAQmC,kBAAkB;QAC7BC,UAAU,CAACC;YACTL,WAAWM,iBAAiB,CAACD;YAC7BrC,QAAQmC,kBAAkB,EAAEC,WAAWC;QACzC;IACF;IAEA,eAAe;IACf,IAAI,OAAOE,WAAW,aAAa;QACjC,MAAMC,iBAAiB;YACrBL,mBAAmBM,UAAU;YAC7BF,OAAOG,mBAAmB,CAAC,gBAAgBF;QAC7C;QACAD,OAAOI,gBAAgB,CAAC,gBAAgBH;IAC1C;IAEA,MAAMI,2BAA2B1C,YAAYC,GAAG,KAAKF;IACrDzB,OAAOqE,KAAK,CAAC,CAAC,cAAc,EAAED,yBAAyBE,OAAO,CAAC,GAAG,EAAE,CAAC;IAErE,0CAA0C;IAC1C,wBAAwB;IAExB;;;GAGC,GACD,MAAMC,gCAAgC;QACpC,MAAMC,uBAAuB9C,YAAYC,GAAG;QAE5C,yCAAyC;QACzC,gDAAgD;QAChD,MAAM8C,eAAe,CAACC;YACpB,IAAI,OAAOX,WAAW,eAAe,yBAAyBA,QAAQ;gBACpEA,OAAOY,mBAAmB,CAACD,UAAU;oBAAEE,SAAS;gBAAK;YACvD,OAAO;gBACLtD,WAAWoD,UAAU;YACvB;QACF;QAEA,OAAO,IAAItD,QAAc,CAACC;YACxBoD,aAAa;gBACX,IAAI;oBACF,kBAAkB;oBAClB,IAAIjD,QAAQqD,SAAS,EAAE;wBACrB,IAAI;4BACF,MAAMvE,UACJ,IAAM,MAAM,CAAC,yBAAyB4B,IAAI,CAAC,CAAC,EAAE4C,aAAa,EAAE;oCAC3DA,cAActD,QAAQqD,SAAS;oCAC/B,OAAO;gCACT,IACAjD,aACA;4BAEF5B,OAAOqE,KAAK,CAAC;wBACf,EAAE,OAAOtD,OAAO;4BACdf,OAAOmB,IAAI,CAAC,uBAAuBJ;wBACrC;oBACF;oBAEA,qBAAqB;oBACrB,IAAIS,QAAQuD,eAAe,EAAE;wBAC3B,IAAI;4BACF,MAAMzE,UACJ,IAAM,MAAM,CAAC,+BAA+B4B,IAAI,CAAC,CAAC,EAAE8C,eAAe,EAAE;oCACnEA,gBAAgB7C,UAAU,CAACX,QAAQuD,eAAe;oCAClD,OAAO;gCACT,IACAnD,aACA;4BAEF5B,OAAOqE,KAAK,CAAC;wBACf,EAAE,OAAOtD,OAAO;4BACdf,OAAOmB,IAAI,CAAC,0BAA0BJ;wBACxC;oBACF;oBAEA,MAAMkE,sBAAsBvD,YAAYC,GAAG,KAAK6C;oBAChDxE,OAAOqE,KAAK,CAAC,CAAC,eAAe,EAAEY,oBAAoBX,OAAO,CAAC,GAAG,EAAE,CAAC;gBACnE,EAAE,OAAOvD,OAAO;oBACdf,OAAOmB,IAAI,CAAC,oBAAoBJ;gBAClC,SAAU;oBACRM;gBACF;YACF;QACF;IACF;IAEA,gBAAgB;IAChB,IAAImC,WAAWM,iBAAiB,EAAE;QAChCN,WAAWM,iBAAiB,CAAC;YAC3BoB,qBAAqBd;QACvB;IACF;IAEA,OAAO;QACLZ;QACAG;QACArB;QACAO;QACA0B;IACF;AACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/core/startup/performanceTracker.ts"],"sourcesContent":["/**\n * 性能追踪模块\n * 负责收集和上报启动性能指标\n */\n\nimport type { MonitoringService } from '
|
|
1
|
+
{"version":3,"sources":["../../../src/core/startup/performanceTracker.ts"],"sourcesContent":["/**\n * 性能追踪模块\n * 负责收集和上报启动性能指标\n */\n\nimport type { MonitoringService } from '@vlian/monitoring';\n\n/**\n * 启动性能指标单位常量\n */\nexport const STARTUP_METRIC_UNITS = {\n /**\n * 毫秒单位\n */\n ms: 'ms',\n /**\n * 无单位(分数)\n */\n none: '',\n} as const;\n\n/**\n * 启动性能指标\n */\nexport interface StartupPerformanceMetrics {\n /**\n * 服务初始化耗时\n * 单位:毫秒(ms)\n */\n serviceInitDuration?: number;\n\n /**\n * 初始化耗时\n * 单位:毫秒(ms)\n */\n initializationDuration?: number;\n\n /**\n * 首次渲染耗时\n * 单位:毫秒(ms)\n */\n firstRenderDuration?: number;\n\n /**\n * 总启动耗时\n * 单位:毫秒(ms)\n */\n totalStartupDuration?: number;\n\n /**\n * 首次内容绘制时间(FCP)\n * 单位:毫秒(ms)\n */\n fcp?: number;\n\n /**\n * 最大内容绘制时间(LCP)\n * 单位:毫秒(ms)\n */\n lcp?: number;\n\n /**\n * 首次输入延迟(FID)\n * 单位:毫秒(ms)\n */\n fid?: number;\n\n /**\n * 累积布局偏移(CLS)\n * 单位:无(分数)\n */\n cls?: number;\n}\n\n/**\n * 性能追踪器\n */\nexport class PerformanceTracker {\n private monitoring: MonitoringService;\n private metrics: StartupPerformanceMetrics = {};\n private startTime: number;\n\n constructor(monitoring: MonitoringService) {\n this.monitoring = monitoring;\n this.startTime = performance.now();\n }\n\n /**\n * 记录服务初始化耗时\n */\n recordServiceInit(duration: number): void {\n this.metrics.serviceInitDuration = duration;\n }\n\n /**\n * 记录初始化耗时\n */\n recordInitialization(duration: number): void {\n this.metrics.initializationDuration = duration;\n }\n\n /**\n * 记录首次渲染耗时\n */\n recordFirstRender(duration: number): void {\n this.metrics.firstRenderDuration = duration;\n }\n\n /**\n * 记录总启动耗时\n */\n recordTotalStartup(duration: number): void {\n this.metrics.totalStartupDuration = duration;\n }\n\n /**\n * 收集Web Vitals指标\n */\n collectWebVitals(): void {\n if (typeof window === 'undefined') {\n return;\n }\n\n // 收集FCP(首次内容绘制)\n if ('PerformanceObserver' in window) {\n try {\n const fcpObserver = new PerformanceObserver((list) => {\n for (const entry of list.getEntries()) {\n if (entry.name === 'first-contentful-paint') {\n this.metrics.fcp = entry.startTime;\n this.report();\n }\n }\n });\n fcpObserver.observe({ entryTypes: ['paint'] });\n } catch (e) {\n // 忽略错误\n }\n }\n\n // 收集LCP(最大内容绘制)\n if ('PerformanceObserver' in window) {\n try {\n const lcpObserver = new PerformanceObserver((list) => {\n const entries = list.getEntries();\n const lastEntry = entries[entries.length - 1];\n this.metrics.lcp = lastEntry.startTime;\n this.report();\n });\n lcpObserver.observe({ entryTypes: ['largest-contentful-paint'] });\n } catch (e) {\n // 忽略错误\n }\n }\n\n // 收集FID(首次输入延迟)\n if ('PerformanceObserver' in window) {\n try {\n const fidObserver = new PerformanceObserver((list) => {\n for (const entry of list.getEntries()) {\n // PerformanceEventTiming 类型检查\n if ('processingStart' in entry && 'startTime' in entry) {\n const eventEntry = entry as PerformanceEventTiming;\n this.metrics.fid = eventEntry.processingStart - eventEntry.startTime;\n this.report();\n }\n }\n });\n fidObserver.observe({ entryTypes: ['first-input'] });\n } catch (e) {\n // 忽略错误\n }\n }\n\n // 收集CLS(累积布局偏移)\n if ('PerformanceObserver' in window) {\n try {\n let clsValue = 0;\n const clsObserver = new PerformanceObserver((list) => {\n for (const entry of list.getEntries()) {\n if (!(entry as any).hadRecentInput) {\n clsValue += (entry as any).value;\n }\n }\n this.metrics.cls = clsValue;\n this.report();\n });\n clsObserver.observe({ entryTypes: ['layout-shift'] });\n } catch (e) {\n // 忽略错误\n }\n }\n }\n\n /**\n * 上报性能指标\n */\n report(): void {\n if (this.monitoring.reportPerformance) {\n this.monitoring.reportPerformance(this.metrics);\n }\n }\n\n /**\n * 获取所有指标\n */\n getMetrics(): StartupPerformanceMetrics {\n return { ...this.metrics };\n }\n\n /**\n * 获取总启动耗时\n */\n getTotalDuration(): number {\n return performance.now() - this.startTime;\n }\n}\n"],"names":["PerformanceTracker","STARTUP_METRIC_UNITS","ms","none","recordServiceInit","duration","metrics","serviceInitDuration","recordInitialization","initializationDuration","recordFirstRender","firstRenderDuration","recordTotalStartup","totalStartupDuration","collectWebVitals","window","fcpObserver","PerformanceObserver","list","entry","getEntries","name","fcp","startTime","report","observe","entryTypes","e","lcpObserver","entries","lastEntry","length","lcp","fidObserver","eventEntry","fid","processingStart","clsValue","clsObserver","hadRecentInput","value","cls","monitoring","reportPerformance","getMetrics","getTotalDuration","performance","now"],"mappings":"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"}
|