@4399ywkf/core 5.1.4 → 5.1.6

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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/runtime/bootstrap.tsx","../../src/runtime/providers.tsx","../../src/runtime/context.tsx","../../src/runtime/error-boundary.tsx"],"sourcesContent":["import { createRoot, type Root } from \"react-dom/client\";\nimport { RootProvider } from \"./providers.js\";\nimport type { AppConfig, MicroAppConfig } from \"./types.js\";\n\nlet root: Root | null = null;\n\n/**\n * 解析应用配置,处理约定式路由\n */\nasync function resolveAppConfig(config: AppConfig): Promise<AppConfig> {\n // 如果已有 router 或未启用约定式路由,直接返回\n if (config.router || !config.conventionalRoutes) {\n return config;\n }\n\n try {\n // 动态导入约定式路由\n // @ts-expect-error @ywkf/routes 是编译时生成的模块\n const routesModule = await import(\"@ywkf/routes\");\n const createRouter = routesModule.createRouter || routesModule.default?.createRouter;\n\n if (typeof createRouter === \"function\") {\n const router = createRouter(config.basename);\n console.log(\"[ywkf] 已自动注入约定式路由\");\n return { ...config, router };\n } else {\n console.warn(\"[ywkf] @ywkf/routes 未导出 createRouter 函数\");\n }\n } catch (error) {\n console.error(\"[ywkf] 加载约定式路由失败:\", error);\n console.warn(\"[ywkf] 请确保已启用约定式路由且 src/pages 目录存在\");\n }\n\n return config;\n}\n\n/**\n * 启动应用\n */\nexport async function bootstrap(config: AppConfig): Promise<void> {\n const { rootId = \"root\", lifecycle } = config;\n\n // 解析约定式路由\n const resolvedConfig = await resolveAppConfig(config);\n\n // 执行挂载前钩子\n if (lifecycle?.onBeforeMount) {\n await lifecycle.onBeforeMount();\n }\n\n // 获取根元素\n const rootElement = document.getElementById(rootId);\n\n if (!rootElement) {\n throw new Error(`找不到根元素 #${rootId}`);\n }\n\n // 创建 React Root\n root = createRoot(rootElement);\n\n // 渲染应用\n root.render(<RootProvider config={resolvedConfig} />);\n\n // 执行挂载后钩子\n if (lifecycle?.onMounted) {\n // 使用 setTimeout 确保 React 渲染完成\n setTimeout(() => {\n lifecycle.onMounted?.();\n }, 0);\n }\n\n // 注册卸载钩子\n if (lifecycle?.onUnmount) {\n window.addEventListener(\"beforeunload\", () => {\n lifecycle.onUnmount?.();\n });\n }\n}\n\n/**\n * 卸载应用\n */\nexport function unmount(): void {\n if (root) {\n root.unmount();\n root = null;\n }\n}\n\n/**\n * 创建微前端应用入口\n *\n * 用于 qiankun/garfish 等微前端框架\n */\nexport function createMicroApp(getConfig: (props?: MicroAppConfig) => AppConfig) {\n let microRoot: Root | null = null;\n\n return {\n /**\n * 微前端 bootstrap 生命周期\n */\n async bootstrap() {\n console.log(\"[MicroApp] bootstrap\");\n },\n\n /**\n * 微前端 mount 生命周期\n */\n async mount(props?: MicroAppConfig) {\n console.log(\"[MicroApp] mount\", props);\n\n const config = getConfig(props);\n // 解析约定式路由\n const resolvedConfig = await resolveAppConfig(config);\n\n const container = props?.masterProps?.container as Element | undefined;\n const rootId = resolvedConfig.rootId || \"root\";\n\n // 获取根元素(优先使用微前端容器)\n const rootElement = container\n ? container.querySelector(`#${rootId}`)\n : document.getElementById(rootId);\n\n if (!rootElement) {\n throw new Error(`[MicroApp] 找不到根元素 #${rootId}`);\n }\n\n // 执行挂载前钩子\n if (resolvedConfig.lifecycle?.onBeforeMount) {\n await resolvedConfig.lifecycle.onBeforeMount();\n }\n\n // 创建 React Root\n microRoot = createRoot(rootElement);\n microRoot.render(<RootProvider config={resolvedConfig} />);\n\n // 执行挂载后钩子\n if (resolvedConfig.lifecycle?.onMounted) {\n setTimeout(() => {\n resolvedConfig.lifecycle?.onMounted?.();\n }, 0);\n }\n },\n\n /**\n * 微前端 unmount 生命周期\n */\n async unmount(props?: MicroAppConfig) {\n console.log(\"[MicroApp] unmount\", props);\n\n const config = getConfig(props);\n\n // 执行卸载钩子\n if (config.lifecycle?.onUnmount) {\n config.lifecycle.onUnmount();\n }\n\n if (microRoot) {\n microRoot.unmount();\n microRoot = null;\n }\n },\n\n /**\n * 微前端 update 生命周期(可选)\n */\n async update(props?: MicroAppConfig) {\n console.log(\"[MicroApp] update\", props);\n },\n };\n}\n\n/**\n * Garfish 子应用 provider\n *\n * Garfish 要求子应用导出 provider 函数,接收 { dom, basename, props },\n * 返回 { render, destroy } 对象。\n */\nexport function createGarfishProvider(getConfig: (overrides?: Partial<AppConfig>) => AppConfig) {\n let garfishRoot: Root | null = null;\n\n return function provider(providerContext: {\n dom: Element;\n basename: string;\n props?: Record<string, unknown>;\n }) {\n const { dom, basename } = providerContext;\n\n return {\n render() {\n const config = getConfig({ basename });\n const resolvedConfig = { ...config, basename };\n const rootId = resolvedConfig.rootId || \"root\";\n\n let rootElement = dom.querySelector(`#${rootId}`);\n if (!rootElement) {\n rootElement = document.createElement(\"div\");\n rootElement.id = rootId;\n dom.appendChild(rootElement);\n }\n\n garfishRoot = createRoot(rootElement);\n garfishRoot.render(<RootProvider config={resolvedConfig} />);\n\n if (resolvedConfig.lifecycle?.onMounted) {\n setTimeout(() => resolvedConfig.lifecycle?.onMounted?.(), 0);\n }\n },\n\n destroy() {\n if (garfishRoot) {\n garfishRoot.unmount();\n garfishRoot = null;\n }\n },\n };\n };\n}\n\n/**\n * 判断是否在微前端环境中运行\n */\nexport function isMicroAppEnv(): boolean {\n // qiankun\n if ((window as unknown as Record<string, unknown>).__POWERED_BY_QIANKUN__) {\n return true;\n }\n\n // garfish\n if ((window as unknown as Record<string, unknown>).__GARFISH__) {\n return true;\n }\n\n return false;\n}\n\n/**\n * 获取微前端公共路径\n */\nexport function getMicroAppPublicPath(): string {\n // qiankun 注入的公共路径\n if ((window as unknown as Record<string, string>).__INJECTED_PUBLIC_PATH_BY_QIANKUN__) {\n return (window as unknown as Record<string, string>).__INJECTED_PUBLIC_PATH_BY_QIANKUN__;\n }\n\n return \"/\";\n}\n","import { ConfigProvider } from \"antd\";\nimport zhCN from \"antd/locale/zh_CN.js\";\nimport { type ComponentType, type ReactNode, StrictMode, Suspense } from \"react\";\nimport { RouterProvider } from \"react-router\";\nimport { AppContextProvider } from \"./context.js\";\nimport { ErrorBoundary } from \"./error-boundary.js\";\nimport type { AppConfig, AppContextValue, ProviderConfig } from \"./types.js\";\n\n/**\n * 默认加载中组件\n */\nfunction DefaultLoading() {\n return (\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n height: \"100vh\",\n fontSize: 16,\n color: \"#999\",\n }}\n >\n 加载中...\n </div>\n );\n}\n\n/**\n * 组合多个 Provider\n */\nfunction composeProviders(providers: ProviderConfig[]): ComponentType<{ children: ReactNode }> {\n const sortedProviders = [...providers].sort((a, b) => (a.order ?? 100) - (b.order ?? 100));\n\n return function ComposedProviders({ children }: { children: ReactNode }) {\n return sortedProviders.reduceRight((acc, { component: Provider, props }) => {\n return <Provider {...props}>{acc}</Provider>;\n }, children);\n };\n}\n\nexport interface RootProviderProps {\n config: AppConfig;\n children?: ReactNode;\n}\n\n/**\n * 根 Provider 组件\n * 自动组合所有必要的 Provider\n */\nexport function RootProvider({ config, children }: RootProviderProps) {\n const {\n appName = \"app\",\n router,\n basename = \"/\",\n strictMode = true,\n antd = { enabled: true },\n providers = [],\n lifecycle,\n } = config;\n\n // 构建应用上下文\n const appContextValue: Partial<AppContextValue> = {\n appName,\n basename,\n isDev: process.env.NODE_ENV === \"development\",\n env: typeof process !== \"undefined\" ? (process.env as Record<string, string>) : {},\n };\n\n // 构建 Provider 列表\n const allProviders: ProviderConfig[] = [\n // 应用上下文 Provider(最外层)\n {\n component: AppContextProvider as ComponentType<{ children: ReactNode }>,\n props: { value: appContextValue },\n order: 0,\n },\n // Ant Design ConfigProvider\n ...(antd.enabled !== false\n ? [\n {\n component: ConfigProvider as ComponentType<{ children: ReactNode }>,\n props: {\n locale: antd.locale || zhCN,\n theme: antd.theme,\n ...antd.configProvider,\n },\n order: 10,\n },\n ]\n : []),\n // 用户自定义 Providers\n ...providers.map((p) => ({ ...p, order: p.order ?? 50 })),\n ];\n\n const ComposedProviders = composeProviders(allProviders);\n\n // 内容:路由或自定义 children\n const content = router ? (\n <Suspense fallback={<DefaultLoading />}>\n <RouterProvider router={router} />\n </Suspense>\n ) : (\n children\n );\n\n // 组装最终结构\n const app = (\n <ErrorBoundary onError={lifecycle?.onError}>\n <ComposedProviders>{content}</ComposedProviders>\n </ErrorBoundary>\n );\n\n // 严格模式包装\n if (strictMode) {\n return <StrictMode>{app}</StrictMode>;\n }\n\n return app;\n}\n\n/**\n * 创建自定义 Provider 配置的辅助函数\n */\nexport function createProvider<P extends Record<string, unknown>>(\n component: ComponentType<P & { children: ReactNode }>,\n props?: Omit<P, \"children\">,\n order?: number,\n): ProviderConfig {\n return {\n component: component as ComponentType<{ children: ReactNode }>,\n props,\n order,\n };\n}\n","import { createContext, type ReactNode, useContext } from \"react\";\nimport type { AppContextValue } from \"./types.js\";\n\n/**\n * 默认上下文值\n */\nconst defaultContextValue: AppContextValue = {\n appName: \"app\",\n basename: \"/\",\n isDev: process.env.NODE_ENV === \"development\",\n env: {},\n};\n\n/**\n * 应用上下文\n */\nexport const AppContext = createContext<AppContextValue>(defaultContextValue);\n\n/**\n * 应用上下文 Provider\n */\nexport interface AppContextProviderProps {\n value: Partial<AppContextValue>;\n children: ReactNode;\n}\n\nexport function AppContextProvider({ value, children }: AppContextProviderProps) {\n const contextValue: AppContextValue = {\n ...defaultContextValue,\n ...value,\n env: {\n ...defaultContextValue.env,\n ...value.env,\n },\n };\n\n return <AppContext.Provider value={contextValue}>{children}</AppContext.Provider>;\n}\n\n/**\n * 获取应用上下文的 Hook\n */\nexport function useApp(): AppContextValue {\n const context = useContext(AppContext);\n\n if (!context) {\n throw new Error(\"useApp must be used within AppContextProvider\");\n }\n\n return context;\n}\n\n/**\n * 获取应用名称\n */\nexport function useAppName(): string {\n return useApp().appName;\n}\n\n/**\n * 获取路由 basename\n */\nexport function useBasename(): string {\n return useApp().basename;\n}\n\n/**\n * 获取环境变量\n */\nexport function useEnv(): Record<string, string | undefined> {\n return useApp().env;\n}\n\n/**\n * 判断是否开发环境\n */\nexport function useIsDev(): boolean {\n return useApp().isDev;\n}\n","import { Component, type ErrorInfo, type ReactNode } from \"react\";\n\nexport interface ErrorBoundaryProps {\n /** 子组件 */\n children: ReactNode;\n /** 错误回退 UI */\n fallback?: ReactNode | ((error: Error, reset: () => void) => ReactNode);\n /** 错误回调 */\n onError?: (error: Error, errorInfo: ErrorInfo) => void;\n}\n\ninterface ErrorBoundaryState {\n hasError: boolean;\n error: Error | null;\n}\n\n/**\n * 错误边界组件\n */\nexport class ErrorBoundary extends Component<ErrorBoundaryProps, ErrorBoundaryState> {\n constructor(props: ErrorBoundaryProps) {\n super(props);\n this.state = { hasError: false, error: null };\n }\n\n static getDerivedStateFromError(error: Error): ErrorBoundaryState {\n return { hasError: true, error };\n }\n\n componentDidCatch(error: Error, errorInfo: ErrorInfo): void {\n console.error(\"[ErrorBoundary] Caught error:\", error, errorInfo);\n this.props.onError?.(error, errorInfo);\n }\n\n reset = (): void => {\n this.setState({ hasError: false, error: null });\n };\n\n render(): ReactNode {\n const { hasError, error } = this.state;\n const { children, fallback } = this.props;\n\n if (hasError && error) {\n if (typeof fallback === \"function\") {\n return fallback(error, this.reset);\n }\n\n if (fallback) {\n return fallback;\n }\n\n return <DefaultErrorFallback error={error} onReset={this.reset} />;\n }\n\n return children;\n }\n}\n\n/**\n * 默认错误回退 UI\n */\ninterface DefaultErrorFallbackProps {\n error: Error;\n onReset: () => void;\n}\n\nfunction DefaultErrorFallback({ error, onReset }: DefaultErrorFallbackProps) {\n const isDev = process.env.NODE_ENV === \"development\";\n\n return (\n <div\n style={{\n padding: 24,\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n justifyContent: \"center\",\n minHeight: \"100vh\",\n backgroundColor: \"#f5f5f5\",\n }}\n >\n <div\n style={{\n maxWidth: 600,\n padding: 32,\n backgroundColor: \"#fff\",\n borderRadius: 8,\n boxShadow: \"0 2px 8px rgba(0,0,0,0.1)\",\n }}\n >\n <h1 style={{ color: \"#ff4d4f\", marginBottom: 16 }}>页面出错了</h1>\n <p style={{ color: \"#666\", marginBottom: 16 }}>\n 抱歉,页面遇到了一些问题。请尝试刷新页面或联系管理员。\n </p>\n\n {isDev && (\n <details\n style={{\n marginBottom: 16,\n padding: 12,\n backgroundColor: \"#fff2f0\",\n borderRadius: 4,\n border: \"1px solid #ffccc7\",\n }}\n >\n <summary style={{ cursor: \"pointer\", fontWeight: \"bold\" }}>\n 错误详情(仅开发环境可见)\n </summary>\n <pre\n style={{\n marginTop: 8,\n padding: 8,\n backgroundColor: \"#fff\",\n borderRadius: 4,\n overflow: \"auto\",\n fontSize: 12,\n }}\n >\n {error.message}\n {\"\\n\\n\"}\n {error.stack}\n </pre>\n </details>\n )}\n\n <div style={{ display: \"flex\", gap: 8 }}>\n <button\n onClick={onReset}\n style={{\n padding: \"8px 16px\",\n backgroundColor: \"#1890ff\",\n color: \"#fff\",\n border: \"none\",\n borderRadius: 4,\n cursor: \"pointer\",\n }}\n >\n 重试\n </button>\n <button\n onClick={() => window.location.reload()}\n style={{\n padding: \"8px 16px\",\n backgroundColor: \"#fff\",\n color: \"#666\",\n border: \"1px solid #d9d9d9\",\n borderRadius: 4,\n cursor: \"pointer\",\n }}\n >\n 刷新页面\n </button>\n </div>\n </div>\n </div>\n );\n}\n"],"mappings":"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","names":["jsx","jsx","jsx"]}
1
+ {"version":3,"sources":["../../src/runtime/chunk-recovery.ts","../../src/runtime/bootstrap.tsx","../../src/runtime/providers.tsx","../../src/runtime/context.tsx","../../src/runtime/error-boundary.tsx"],"sourcesContent":["import type {\n ChunkRecoveryConfig,\n ChunkRecoveryEvent,\n ChunkRecoveryOutcome,\n ChunkRecoverySource,\n} from \"./types.js\";\n\nexport const DEFAULT_CHUNK_RECOVERY_COOLDOWN_MS = 30_000;\nexport const CHUNK_RECOVERY_STORAGE_KEY = \"@4399ywkf/core:chunk-recovery-attempt\";\nexport const CHUNK_RECOVERY_CACHE_BUST_PARAM = \"__ywkf_chunk_retry\";\nexport const CHUNK_RECOVERY_ACTIVE_SYMBOL = Symbol.for(\n \"@4399ywkf/core/chunk-recovery-active\",\n);\nconst CHUNK_RECOVERY_REGISTRY_SYMBOL = Symbol.for(\n \"@4399ywkf/core/chunk-recovery-registry\",\n);\n\nconst CHUNK_LOAD_ERROR_PATTERNS = [\n /\\bChunkLoadError\\b/i,\n /\\bLoading (?:CSS )?chunk\\s+\\S+\\s+failed\\b/i,\n /\\bFailed to fetch dynamically imported module\\b/i,\n /\\bImporting a module script failed\\b/i,\n /\\berror loading dynamically imported module\\b/i,\n /\\bUnable to preload CSS for\\b/i,\n /\\bFailed to load module script\\b/i,\n];\n\nexport interface ChunkRecoveryStorage {\n getItem(key: string): string | null;\n setItem(key: string, value: string): void;\n}\n\nexport type ChunkRecoveryClaim =\n | { claimed: true; attemptedAt: number }\n | {\n claimed: false;\n reason: \"already-attempted\" | \"cooldown\" | \"storage-unavailable\";\n attemptedAt?: number;\n };\n\nexport interface ClaimChunkRecoveryAttemptOptions {\n cooldownMs?: number;\n now: number;\n recoveryId: string;\n storageKey?: string;\n}\n\nexport interface ChunkRecoveryPolicyContext {\n isProduction: boolean;\n isMicroApp: boolean;\n}\n\nexport interface ChunkRecoveryPolicy {\n enabled: boolean;\n disabledReason?: \"configuration\" | \"environment\" | \"micro-app\";\n cooldownMs: number;\n globalHandlers: boolean;\n}\n\nexport interface HandleChunkRecoveryOptions {\n source: ChunkRecoverySource;\n config?: boolean | ChunkRecoveryConfig;\n isMicroApp?: boolean;\n onError?: (error: Error) => void;\n onRecoveryEvent?: (event: ChunkRecoveryEvent) => void;\n}\n\nexport interface GlobalChunkRecoveryHandlersOptions {\n config?: boolean | ChunkRecoveryConfig;\n isMicroApp?: boolean;\n onError?: (error: Error) => void;\n onRecoveryEvent?: (event: ChunkRecoveryEvent) => void;\n}\n\nfunction getErrorLikeValue(\n error: unknown,\n key: \"cause\" | \"code\" | \"message\" | \"name\" | \"request\",\n): unknown {\n if ((typeof error !== \"object\" || error === null) && typeof error !== \"function\") {\n return undefined;\n }\n\n try {\n return (error as Record<string, unknown>)[key];\n } catch {\n return undefined;\n }\n}\n\nfunction matchesChunkLoadError(error: unknown, depth: number): boolean {\n if (depth > 3) {\n return false;\n }\n\n if (typeof error === \"string\") {\n return CHUNK_LOAD_ERROR_PATTERNS.some(pattern => pattern.test(error));\n }\n\n const name = getErrorLikeValue(error, \"name\");\n const message = getErrorLikeValue(error, \"message\");\n const code = getErrorLikeValue(error, \"code\");\n const signature = [name, message].filter(value => typeof value === \"string\").join(\": \");\n\n if (\n code === \"CSS_CHUNK_LOAD_FAILED\" ||\n CHUNK_LOAD_ERROR_PATTERNS.some(pattern => pattern.test(signature))\n ) {\n return true;\n }\n\n const cause = getErrorLikeValue(error, \"cause\");\n return cause !== undefined && cause !== error && matchesChunkLoadError(cause, depth + 1);\n}\n\n/** 仅匹配 Rspack/Webpack/Vite 的高置信度异步 chunk 加载错误。 */\nexport function isChunkLoadError(error: unknown): boolean {\n return matchesChunkLoadError(error, 0);\n}\n\nfunction hashRecoveryIdentity(value: string): string {\n let hash = 2_166_136_261;\n\n for (let index = 0; index < value.length; index += 1) {\n hash ^= value.charCodeAt(index);\n hash = Math.imul(hash, 16_777_619);\n }\n\n return (hash >>> 0).toString(36);\n}\n\nfunction getFrameworkBuildId(): string {\n const buildId = (\n globalThis as typeof globalThis & { __YWKF_BUILD_ID__?: unknown }\n ).__YWKF_BUILD_ID__;\n return typeof buildId === \"string\" ? buildId.trim() : \"\";\n}\n\nfunction resolveRecoveryId(error: unknown, config: boolean | ChunkRecoveryConfig | undefined): string {\n const configuredBuildId =\n typeof config === \"object\" && typeof config.buildId === \"string\" ? config.buildId.trim() : \"\";\n const buildId = configuredBuildId || getFrameworkBuildId();\n if (buildId) {\n return `build-${hashRecoveryIdentity(buildId)}`;\n }\n\n const request = getErrorLikeValue(error, \"request\");\n const name = getErrorLikeValue(error, \"name\");\n const message = getErrorLikeValue(error, \"message\");\n const signature = [request, name, message]\n .filter(value => typeof value === \"string\")\n .join(\": \");\n\n return `error-${hashRecoveryIdentity(signature || String(error))}`;\n}\n\nfunction toError(error: unknown, fallbackMessage = \"Chunk loading failed\"): Error {\n if (error instanceof Error) {\n return error;\n }\n\n if (typeof error === \"string\") {\n return new Error(error);\n }\n\n const message = getErrorLikeValue(error, \"message\");\n const name = getErrorLikeValue(error, \"name\");\n const normalizedError = new Error(typeof message === \"string\" ? message : fallbackMessage);\n\n if (typeof name === \"string\") {\n normalizedError.name = name;\n }\n\n return normalizedError;\n}\n\nfunction normalizeCooldownMs(value: number | undefined): number {\n if (typeof value !== \"number\" || !Number.isFinite(value) || value < 1_000) {\n return DEFAULT_CHUNK_RECOVERY_COOLDOWN_MS;\n }\n\n return value;\n}\n\n/** 将配置解析成与运行环境无关、可测试的恢复策略。 */\nexport function resolveChunkRecoveryPolicy(\n config: boolean | ChunkRecoveryConfig | undefined,\n context: ChunkRecoveryPolicyContext,\n): ChunkRecoveryPolicy {\n const options = typeof config === \"object\" ? config : undefined;\n const configuredEnabled = typeof config === \"boolean\" ? config : options?.enabled;\n const enabledForEnvironment = configuredEnabled ?? context.isProduction;\n\n if (!enabledForEnvironment) {\n return {\n enabled: false,\n disabledReason: configuredEnabled === false ? \"configuration\" : \"environment\",\n cooldownMs: normalizeCooldownMs(options?.cooldownMs),\n globalHandlers: options?.globalHandlers === true,\n };\n }\n\n if (context.isMicroApp && options?.allowInMicroApp !== true) {\n return {\n enabled: false,\n disabledReason: \"micro-app\",\n cooldownMs: normalizeCooldownMs(options?.cooldownMs),\n globalHandlers: options?.globalHandlers === true,\n };\n }\n\n return {\n enabled: true,\n cooldownMs: normalizeCooldownMs(options?.cooldownMs),\n globalHandlers: options?.globalHandlers === true,\n };\n}\n\ninterface StoredChunkRecoveryAttempt {\n attemptedAt: number;\n recoveryId: string;\n}\n\ninterface StoredChunkRecoveryState {\n attempts: StoredChunkRecoveryAttempt[];\n lastAttemptAt?: number;\n}\n\nfunction parseStoredChunkRecoveryState(value: string | null): StoredChunkRecoveryState {\n if (value === null) {\n return { attempts: [] };\n }\n\n const parsed = JSON.parse(value) as Partial<StoredChunkRecoveryState>;\n if (!Array.isArray(parsed.attempts)) {\n throw new Error(\"Invalid chunk recovery state\");\n }\n\n const attempts = parsed.attempts.map(attempt => {\n if (\n typeof attempt !== \"object\" ||\n attempt === null ||\n typeof attempt.recoveryId !== \"string\" ||\n typeof attempt.attemptedAt !== \"number\" ||\n !Number.isFinite(attempt.attemptedAt)\n ) {\n throw new Error(\"Invalid chunk recovery attempt\");\n }\n\n return attempt;\n });\n\n if (\n parsed.lastAttemptAt !== undefined &&\n (typeof parsed.lastAttemptAt !== \"number\" || !Number.isFinite(parsed.lastAttemptAt))\n ) {\n throw new Error(\"Invalid chunk recovery timestamp\");\n }\n\n return { attempts, lastAttemptAt: parsed.lastAttemptAt };\n}\n\n/**\n * 同步检查并预占本次刷新额度。\n * 一次 setItem 同时提交 build 尝试集合与全局冷却时间;读写或数据校验失败时 fail closed。\n */\nexport function claimChunkRecoveryAttempt(\n storage: ChunkRecoveryStorage,\n options: ClaimChunkRecoveryAttemptOptions,\n): ChunkRecoveryClaim {\n const {\n cooldownMs = DEFAULT_CHUNK_RECOVERY_COOLDOWN_MS,\n now,\n recoveryId,\n storageKey = CHUNK_RECOVERY_STORAGE_KEY,\n } = options;\n\n let state: StoredChunkRecoveryState;\n try {\n state = parseStoredChunkRecoveryState(storage.getItem(storageKey));\n } catch {\n return { claimed: false, reason: \"storage-unavailable\" };\n }\n\n const existingAttempt = state.attempts.find(attempt => attempt.recoveryId === recoveryId);\n if (existingAttempt) {\n return {\n claimed: false,\n reason: \"already-attempted\",\n attemptedAt: existingAttempt.attemptedAt,\n };\n }\n\n const inCooldown =\n state.lastAttemptAt !== undefined &&\n (state.lastAttemptAt > now || now - state.lastAttemptAt < cooldownMs);\n if (inCooldown) {\n return { claimed: false, reason: \"cooldown\", attemptedAt: state.lastAttemptAt };\n }\n\n try {\n storage.setItem(\n storageKey,\n JSON.stringify({\n attempts: [...state.attempts, { attemptedAt: now, recoveryId }],\n lastAttemptAt: now,\n } satisfies StoredChunkRecoveryState),\n );\n } catch {\n return { claimed: false, reason: \"storage-unavailable\" };\n }\n\n return { claimed: true, attemptedAt: now };\n}\n\n/** 判断当前页面是否运行在已知微前端容器中。 */\nexport function isMicroAppRuntime(): boolean {\n if (typeof window === \"undefined\") {\n return false;\n }\n\n const runtimeWindow = window as unknown as Record<PropertyKey, unknown>;\n return Boolean(runtimeWindow.__POWERED_BY_QIANKUN__ || runtimeWindow.__GARFISH__);\n}\n\nfunction getSessionStorage(): ChunkRecoveryStorage | null {\n if (typeof window === \"undefined\") {\n return null;\n }\n\n try {\n return window.sessionStorage;\n } catch {\n return null;\n }\n}\n\nfunction invokeSafely(callback: (() => void) | undefined, label: string): void {\n if (!callback) {\n return;\n }\n\n try {\n callback();\n } catch (error) {\n console.error(`[ywkf] ${label} 执行失败:`, error);\n }\n}\n\nfunction schedulePageReplace(timestamp: number): void {\n setTimeout(() => {\n try {\n const reloadUrl = new URL(window.location.href);\n reloadUrl.searchParams.set(CHUNK_RECOVERY_CACHE_BUST_PARAM, String(timestamp));\n window.location.replace(reloadUrl.toString());\n } catch (error) {\n console.error(\"[ywkf] chunk 恢复刷新失败:\", error);\n }\n }, 0);\n}\n\n/** 在新文档启动后移除内部 cache-bust 参数,不污染业务分享 URL。 */\nexport function clearChunkRecoveryCacheBustParam(): void {\n if (typeof window === \"undefined\") {\n return;\n }\n\n try {\n const currentUrl = new URL(window.location.href);\n if (!currentUrl.searchParams.has(CHUNK_RECOVERY_CACHE_BUST_PARAM)) {\n return;\n }\n\n currentUrl.searchParams.delete(CHUNK_RECOVERY_CACHE_BUST_PARAM);\n window.history.replaceState(window.history.state, \"\", currentUrl.toString());\n } catch (error) {\n console.error(\"[ywkf] 清理 chunk 恢复参数失败:\", error);\n }\n}\n\n/**\n * 处理一次潜在的 chunk 错误。\n * 返回 null 表示它不是 chunk 错误;发生自动刷新时会先预占、再回调、最后异步导航。\n */\nfunction handleChunkLoadErrorInternal(\n reason: unknown,\n options: HandleChunkRecoveryOptions,\n trustedChunkEvent: boolean,\n): ChunkRecoveryEvent | null {\n if (!trustedChunkEvent && !isChunkLoadError(reason)) {\n return null;\n }\n\n const error = toError(reason);\n const timestamp = Date.now();\n const recoveryId = resolveRecoveryId(reason, options.config);\n const isMicroApp = options.isMicroApp ?? isMicroAppRuntime();\n const policy = resolveChunkRecoveryPolicy(options.config, {\n isProduction: process.env.NODE_ENV === \"production\",\n isMicroApp,\n });\n\n let outcome: ChunkRecoveryOutcome;\n\n if (!policy.enabled) {\n outcome =\n policy.disabledReason === \"micro-app\"\n ? \"reload-skipped-micro-app\"\n : \"reload-skipped-disabled\";\n } else {\n const storage = getSessionStorage();\n const claim = storage\n ? claimChunkRecoveryAttempt(storage, {\n cooldownMs: policy.cooldownMs,\n now: timestamp,\n recoveryId,\n })\n : ({ claimed: false, reason: \"storage-unavailable\" } as const);\n\n if (claim.claimed) {\n outcome = \"reload-scheduled\";\n } else if (claim.reason === \"already-attempted\") {\n outcome = \"reload-skipped-already-attempted\";\n } else if (claim.reason === \"cooldown\") {\n outcome = \"reload-skipped-cooldown\";\n } else {\n outcome = \"reload-skipped-storage-unavailable\";\n }\n }\n\n const event: ChunkRecoveryEvent = {\n error,\n source: options.source,\n outcome,\n timestamp,\n cooldownMs: policy.cooldownMs,\n recoveryId,\n };\n\n invokeSafely(() => options.onError?.(error), \"onError\");\n invokeSafely(() => options.onRecoveryEvent?.(event), \"onRecoveryEvent\");\n\n if (outcome === \"reload-scheduled\") {\n schedulePageReplace(timestamp);\n }\n\n return event;\n}\n\nexport function handleChunkLoadError(\n reason: unknown,\n options: HandleChunkRecoveryOptions,\n): ChunkRecoveryEvent | null {\n return handleChunkLoadErrorInternal(reason, options, false);\n}\n\ninterface GlobalChunkRecoverySubscriber extends GlobalChunkRecoveryHandlersOptions {\n isMicroApp: boolean;\n}\n\ninterface GlobalChunkRecoveryRegistry {\n handleUnhandledRejection: (event: PromiseRejectionEvent) => void;\n handleVitePreloadError: (event: Event) => void;\n subscribers: Map<symbol, GlobalChunkRecoverySubscriber>;\n}\n\nfunction getLatestSubscriber(\n registry: GlobalChunkRecoveryRegistry,\n): GlobalChunkRecoverySubscriber | undefined {\n let latest: GlobalChunkRecoverySubscriber | undefined;\n for (const subscriber of registry.subscribers.values()) {\n latest = subscriber;\n }\n return latest;\n}\n\nfunction createGlobalChunkRecoveryRegistry(): GlobalChunkRecoveryRegistry {\n const registry = {\n subscribers: new Map<symbol, GlobalChunkRecoverySubscriber>(),\n } as GlobalChunkRecoveryRegistry;\n\n registry.handleUnhandledRejection = event => {\n const subscriber = getLatestSubscriber(registry);\n if (!subscriber) return;\n\n const recoveryEvent = handleChunkLoadError(event.reason, {\n ...subscriber,\n source: \"unhandled-rejection\",\n });\n\n if (recoveryEvent?.outcome === \"reload-scheduled\") {\n event.preventDefault();\n }\n };\n\n registry.handleVitePreloadError = event => {\n const subscriber = getLatestSubscriber(registry);\n if (!subscriber) return;\n\n const payload = (event as Event & { payload?: unknown }).payload;\n const recoveryEvent = handleChunkLoadErrorInternal(\n payload,\n {\n ...subscriber,\n source: \"vite-preload-error\",\n },\n true,\n );\n\n if (recoveryEvent?.outcome === \"reload-scheduled\") {\n event.preventDefault();\n }\n };\n\n return registry;\n}\n\n/**\n * 可选的全局 chunk 错误监听。仅当 globalHandlers: true 且恢复策略启用时安装。\n * 多个 core 实例共享一组 DOM listener;后注册的实例优先,卸载后自动回退到前一个实例。\n */\nexport function installGlobalChunkRecoveryHandlers(\n options: GlobalChunkRecoveryHandlersOptions,\n): () => void {\n if (typeof window === \"undefined\") {\n return () => {};\n }\n\n const isMicroApp = options.isMicroApp ?? isMicroAppRuntime();\n const policy = resolveChunkRecoveryPolicy(options.config, {\n isProduction: process.env.NODE_ENV === \"production\",\n isMicroApp,\n });\n\n if (!policy.enabled || !policy.globalHandlers) {\n return () => {};\n }\n\n const runtimeWindow = window as unknown as Record<PropertyKey, unknown>;\n let registry = runtimeWindow[CHUNK_RECOVERY_REGISTRY_SYMBOL] as\n | GlobalChunkRecoveryRegistry\n | undefined;\n\n // 与尚未使用共享注册表的旧版 core 共存时,不重复安装 DOM listener。\n if (!registry && runtimeWindow[CHUNK_RECOVERY_ACTIVE_SYMBOL] === true) {\n return () => {};\n }\n\n if (!registry) {\n registry = createGlobalChunkRecoveryRegistry();\n runtimeWindow[CHUNK_RECOVERY_REGISTRY_SYMBOL] = registry;\n runtimeWindow[CHUNK_RECOVERY_ACTIVE_SYMBOL] = true;\n window.addEventListener(\"unhandledrejection\", registry.handleUnhandledRejection);\n window.addEventListener(\"vite:preloadError\", registry.handleVitePreloadError);\n }\n\n const subscriberId = Symbol(\"chunk-recovery-subscriber\");\n registry.subscribers.set(subscriberId, { ...options, isMicroApp });\n let disposed = false;\n\n return () => {\n if (disposed) return;\n disposed = true;\n registry.subscribers.delete(subscriberId);\n\n if (registry.subscribers.size > 0) return;\n\n window.removeEventListener(\"unhandledrejection\", registry.handleUnhandledRejection);\n window.removeEventListener(\"vite:preloadError\", registry.handleVitePreloadError);\n\n if (runtimeWindow[CHUNK_RECOVERY_REGISTRY_SYMBOL] === registry) {\n delete runtimeWindow[CHUNK_RECOVERY_REGISTRY_SYMBOL];\n delete runtimeWindow[CHUNK_RECOVERY_ACTIVE_SYMBOL];\n }\n };\n}\n","import { createRoot, type Root } from \"react-dom/client\";\nimport {\n clearChunkRecoveryCacheBustParam,\n installGlobalChunkRecoveryHandlers,\n} from \"./chunk-recovery.js\";\nimport { RootProvider } from \"./providers.js\";\nimport type { AppConfig, MicroAppConfig } from \"./types.js\";\n\nlet root: Root | null = null;\nlet disposeChunkRecoveryHandlers: (() => void) | null = null;\n\n/**\n * 解析应用配置,处理约定式路由\n */\nasync function resolveAppConfig(config: AppConfig): Promise<AppConfig> {\n // 如果已有 router 或未启用约定式路由,直接返回\n if (config.router || !config.conventionalRoutes) {\n return config;\n }\n\n try {\n // 动态导入约定式路由\n // @ts-expect-error @ywkf/routes 是编译时生成的模块\n const routesModule = await import(\"@ywkf/routes\");\n const createRouter = routesModule.createRouter || routesModule.default?.createRouter;\n\n if (typeof createRouter === \"function\") {\n const router = createRouter(config.basename);\n console.log(\"[ywkf] 已自动注入约定式路由\");\n return { ...config, router };\n } else {\n console.warn(\"[ywkf] @ywkf/routes 未导出 createRouter 函数\");\n }\n } catch (error) {\n console.error(\"[ywkf] 加载约定式路由失败:\", error);\n console.warn(\"[ywkf] 请确保已启用约定式路由且 src/pages 目录存在\");\n }\n\n return config;\n}\n\n/**\n * 启动应用\n */\nexport async function bootstrap(config: AppConfig): Promise<void> {\n const { rootId = \"root\", lifecycle } = config;\n const isMicroApp = isMicroAppEnv();\n\n if (!isMicroApp) {\n clearChunkRecoveryCacheBustParam();\n }\n\n // 解析约定式路由\n const resolvedConfig = await resolveAppConfig(config);\n\n // 执行挂载前钩子\n if (lifecycle?.onBeforeMount) {\n await lifecycle.onBeforeMount();\n }\n\n // 获取根元素\n const rootElement = document.getElementById(rootId);\n\n if (!rootElement) {\n throw new Error(`找不到根元素 #${rootId}`);\n }\n\n // 默认不注册全局监听;仅在 chunkRecovery.globalHandlers 显式开启时安装。\n // 放在所有可失败的异步准备步骤之后,避免启动失败遗留 window listener。\n disposeChunkRecoveryHandlers?.();\n const nextDisposeChunkRecoveryHandlers = installGlobalChunkRecoveryHandlers({\n config: resolvedConfig.chunkRecovery,\n isMicroApp,\n onError: error => resolvedConfig.lifecycle?.onError?.(error),\n onRecoveryEvent: resolvedConfig.lifecycle?.onRecoveryEvent,\n });\n\n try {\n // 创建 React Root 并渲染应用\n root = createRoot(rootElement);\n root.render(<RootProvider config={resolvedConfig} isMicroApp={isMicroApp} />);\n disposeChunkRecoveryHandlers = nextDisposeChunkRecoveryHandlers;\n } catch (error) {\n nextDisposeChunkRecoveryHandlers();\n root = null;\n throw error;\n }\n\n // 执行挂载后钩子\n if (lifecycle?.onMounted) {\n // 使用 setTimeout 确保 React 渲染完成\n setTimeout(() => {\n lifecycle.onMounted?.();\n }, 0);\n }\n\n // 注册卸载钩子\n if (lifecycle?.onUnmount) {\n window.addEventListener(\"beforeunload\", () => {\n lifecycle.onUnmount?.();\n });\n }\n}\n\n/**\n * 卸载应用\n */\nexport function unmount(): void {\n disposeChunkRecoveryHandlers?.();\n disposeChunkRecoveryHandlers = null;\n\n if (root) {\n root.unmount();\n root = null;\n }\n}\n\n/**\n * 创建微前端应用入口\n *\n * 用于 qiankun/garfish 等微前端框架\n */\nexport function createMicroApp(getConfig: (props?: MicroAppConfig) => AppConfig) {\n let microRoot: Root | null = null;\n let disposeMicroChunkRecoveryHandlers: (() => void) | null = null;\n\n return {\n /**\n * 微前端 bootstrap 生命周期\n */\n async bootstrap() {\n console.log(\"[MicroApp] bootstrap\");\n },\n\n /**\n * 微前端 mount 生命周期\n */\n async mount(props?: MicroAppConfig) {\n console.log(\"[MicroApp] mount\", props);\n\n const config = getConfig(props);\n // 解析约定式路由\n const resolvedConfig = await resolveAppConfig(config);\n\n const container = props?.masterProps?.container as Element | undefined;\n const rootId = resolvedConfig.rootId || \"root\";\n\n // 获取根元素(优先使用微前端容器)\n const rootElement = container\n ? container.querySelector(`#${rootId}`)\n : document.getElementById(rootId);\n\n if (!rootElement) {\n throw new Error(`[MicroApp] 找不到根元素 #${rootId}`);\n }\n\n // 执行挂载前钩子\n if (resolvedConfig.lifecycle?.onBeforeMount) {\n await resolvedConfig.lifecycle.onBeforeMount();\n }\n\n disposeMicroChunkRecoveryHandlers?.();\n const nextDisposeMicroChunkRecoveryHandlers = installGlobalChunkRecoveryHandlers({\n config: resolvedConfig.chunkRecovery,\n isMicroApp: true,\n onError: error => resolvedConfig.lifecycle?.onError?.(error),\n onRecoveryEvent: resolvedConfig.lifecycle?.onRecoveryEvent,\n });\n\n try {\n // 创建 React Root\n microRoot = createRoot(rootElement);\n microRoot.render(<RootProvider config={resolvedConfig} isMicroApp />);\n disposeMicroChunkRecoveryHandlers = nextDisposeMicroChunkRecoveryHandlers;\n } catch (error) {\n nextDisposeMicroChunkRecoveryHandlers();\n microRoot = null;\n throw error;\n }\n\n // 执行挂载后钩子\n if (resolvedConfig.lifecycle?.onMounted) {\n setTimeout(() => {\n resolvedConfig.lifecycle?.onMounted?.();\n }, 0);\n }\n },\n\n /**\n * 微前端 unmount 生命周期\n */\n async unmount(props?: MicroAppConfig) {\n console.log(\"[MicroApp] unmount\", props);\n\n const config = getConfig(props);\n\n // 执行卸载钩子\n if (config.lifecycle?.onUnmount) {\n config.lifecycle.onUnmount();\n }\n\n if (microRoot) {\n microRoot.unmount();\n microRoot = null;\n }\n\n disposeMicroChunkRecoveryHandlers?.();\n disposeMicroChunkRecoveryHandlers = null;\n },\n\n /**\n * 微前端 update 生命周期(可选)\n */\n async update(props?: MicroAppConfig) {\n console.log(\"[MicroApp] update\", props);\n },\n };\n}\n\n/**\n * Garfish 子应用 provider\n *\n * Garfish 要求子应用导出 provider 函数,接收 { dom, basename, props },\n * 返回 { render, destroy } 对象。\n */\nexport function createGarfishProvider(getConfig: (overrides?: Partial<AppConfig>) => AppConfig) {\n let garfishRoot: Root | null = null;\n let disposeGarfishChunkRecoveryHandlers: (() => void) | null = null;\n\n return function provider(providerContext: {\n dom: Element;\n basename: string;\n props?: Record<string, unknown>;\n }) {\n const { dom, basename } = providerContext;\n\n return {\n render() {\n const config = getConfig({ basename });\n const resolvedConfig = { ...config, basename };\n const rootId = resolvedConfig.rootId || \"root\";\n\n let rootElement = dom.querySelector(`#${rootId}`);\n if (!rootElement) {\n rootElement = document.createElement(\"div\");\n rootElement.id = rootId;\n dom.appendChild(rootElement);\n }\n\n disposeGarfishChunkRecoveryHandlers?.();\n const nextDisposeGarfishChunkRecoveryHandlers = installGlobalChunkRecoveryHandlers({\n config: resolvedConfig.chunkRecovery,\n isMicroApp: true,\n onError: error => resolvedConfig.lifecycle?.onError?.(error),\n onRecoveryEvent: resolvedConfig.lifecycle?.onRecoveryEvent,\n });\n\n try {\n garfishRoot = createRoot(rootElement);\n garfishRoot.render(<RootProvider config={resolvedConfig} isMicroApp />);\n disposeGarfishChunkRecoveryHandlers = nextDisposeGarfishChunkRecoveryHandlers;\n } catch (error) {\n nextDisposeGarfishChunkRecoveryHandlers();\n garfishRoot = null;\n throw error;\n }\n\n if (resolvedConfig.lifecycle?.onMounted) {\n setTimeout(() => resolvedConfig.lifecycle?.onMounted?.(), 0);\n }\n },\n\n destroy() {\n if (garfishRoot) {\n garfishRoot.unmount();\n garfishRoot = null;\n }\n\n disposeGarfishChunkRecoveryHandlers?.();\n disposeGarfishChunkRecoveryHandlers = null;\n },\n };\n };\n}\n\n/**\n * 判断是否在微前端环境中运行\n */\nexport function isMicroAppEnv(): boolean {\n // qiankun\n if ((window as unknown as Record<string, unknown>).__POWERED_BY_QIANKUN__) {\n return true;\n }\n\n // garfish\n if ((window as unknown as Record<string, unknown>).__GARFISH__) {\n return true;\n }\n\n return false;\n}\n\n/**\n * 获取微前端公共路径\n */\nexport function getMicroAppPublicPath(): string {\n // qiankun 注入的公共路径\n if ((window as unknown as Record<string, string>).__INJECTED_PUBLIC_PATH_BY_QIANKUN__) {\n return (window as unknown as Record<string, string>).__INJECTED_PUBLIC_PATH_BY_QIANKUN__;\n }\n\n return \"/\";\n}\n","import { ConfigProvider } from \"antd\";\nimport zhCN from \"antd/locale/zh_CN.js\";\nimport { type ComponentType, type ReactNode, StrictMode, Suspense } from \"react\";\nimport { RouterProvider } from \"react-router\";\nimport { AppContextProvider } from \"./context.js\";\nimport { isMicroAppRuntime } from \"./chunk-recovery.js\";\nimport { ChunkRecoveryRuntimeProvider, ErrorBoundary } from \"./error-boundary.js\";\nimport type { AppConfig, AppContextValue, ProviderConfig } from \"./types.js\";\n\n/**\n * 默认加载中组件\n */\nfunction DefaultLoading() {\n return (\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n height: \"100vh\",\n fontSize: 16,\n color: \"#999\",\n }}\n >\n 加载中...\n </div>\n );\n}\n\n/**\n * 组合多个 Provider\n */\nfunction composeProviders(providers: ProviderConfig[]): ComponentType<{ children: ReactNode }> {\n const sortedProviders = [...providers].sort((a, b) => (a.order ?? 100) - (b.order ?? 100));\n\n return function ComposedProviders({ children }: { children: ReactNode }) {\n return sortedProviders.reduceRight((acc, { component: Provider, props }) => {\n return <Provider {...props}>{acc}</Provider>;\n }, children);\n };\n}\n\nexport interface RootProviderProps {\n config: AppConfig;\n children?: ReactNode;\n /** 是否运行在微前端子应用中;未传时由运行环境自动判断 */\n isMicroApp?: boolean;\n}\n\n/**\n * 根 Provider 组件\n * 自动组合所有必要的 Provider\n */\nexport function RootProvider({ config, children, isMicroApp }: RootProviderProps) {\n const {\n appName = \"app\",\n router,\n basename = \"/\",\n strictMode = true,\n antd = { enabled: true },\n providers = [],\n lifecycle,\n chunkRecovery,\n } = config;\n\n // 构建应用上下文\n const appContextValue: Partial<AppContextValue> = {\n appName,\n basename,\n isDev: process.env.NODE_ENV === \"development\",\n env: typeof process !== \"undefined\" ? (process.env as Record<string, string>) : {},\n };\n\n // 构建 Provider 列表\n const allProviders: ProviderConfig[] = [\n // 应用上下文 Provider(最外层)\n {\n component: AppContextProvider as ComponentType<{ children: ReactNode }>,\n props: { value: appContextValue },\n order: 0,\n },\n // Ant Design ConfigProvider\n ...(antd.enabled !== false\n ? [\n {\n component: ConfigProvider as ComponentType<{ children: ReactNode }>,\n props: {\n locale: antd.locale || zhCN,\n theme: antd.theme,\n ...antd.configProvider,\n },\n order: 10,\n },\n ]\n : []),\n // 用户自定义 Providers\n ...providers.map((p) => ({ ...p, order: p.order ?? 50 })),\n ];\n\n const ComposedProviders = composeProviders(allProviders);\n const rootChunkRecovery = chunkRecovery ?? {\n enabled: process.env.NODE_ENV === \"production\",\n };\n const resolvedIsMicroApp = isMicroApp ?? isMicroAppRuntime();\n\n // 内容:路由或自定义 children\n const content = router ? (\n <Suspense fallback={<DefaultLoading />}>\n <RouterProvider router={router} />\n </Suspense>\n ) : (\n children\n );\n\n // 组装最终结构\n const app = (\n <ErrorBoundary\n chunkRecovery={rootChunkRecovery}\n isMicroApp={resolvedIsMicroApp}\n onError={lifecycle?.onError}\n onRecoveryEvent={lifecycle?.onRecoveryEvent}\n >\n <ChunkRecoveryRuntimeProvider\n chunkRecovery={rootChunkRecovery}\n isMicroApp={resolvedIsMicroApp}\n onError={lifecycle?.onError}\n onRecoveryEvent={lifecycle?.onRecoveryEvent}\n >\n <ComposedProviders>{content}</ComposedProviders>\n </ChunkRecoveryRuntimeProvider>\n </ErrorBoundary>\n );\n\n // 严格模式包装\n if (strictMode) {\n return <StrictMode>{app}</StrictMode>;\n }\n\n return app;\n}\n\n/**\n * 创建自定义 Provider 配置的辅助函数\n */\nexport function createProvider<P extends Record<string, unknown>>(\n component: ComponentType<P & { children: ReactNode }>,\n props?: Omit<P, \"children\">,\n order?: number,\n): ProviderConfig {\n return {\n component: component as ComponentType<{ children: ReactNode }>,\n props,\n order,\n };\n}\n","import { createContext, type ReactNode, useContext } from \"react\";\nimport type { AppContextValue } from \"./types.js\";\n\n/**\n * 默认上下文值\n */\nconst defaultContextValue: AppContextValue = {\n appName: \"app\",\n basename: \"/\",\n isDev: process.env.NODE_ENV === \"development\",\n env: {},\n};\n\n/**\n * 应用上下文\n */\nexport const AppContext = createContext<AppContextValue>(defaultContextValue);\n\n/**\n * 应用上下文 Provider\n */\nexport interface AppContextProviderProps {\n value: Partial<AppContextValue>;\n children: ReactNode;\n}\n\nexport function AppContextProvider({ value, children }: AppContextProviderProps) {\n const contextValue: AppContextValue = {\n ...defaultContextValue,\n ...value,\n env: {\n ...defaultContextValue.env,\n ...value.env,\n },\n };\n\n return <AppContext.Provider value={contextValue}>{children}</AppContext.Provider>;\n}\n\n/**\n * 获取应用上下文的 Hook\n */\nexport function useApp(): AppContextValue {\n const context = useContext(AppContext);\n\n if (!context) {\n throw new Error(\"useApp must be used within AppContextProvider\");\n }\n\n return context;\n}\n\n/**\n * 获取应用名称\n */\nexport function useAppName(): string {\n return useApp().appName;\n}\n\n/**\n * 获取路由 basename\n */\nexport function useBasename(): string {\n return useApp().basename;\n}\n\n/**\n * 获取环境变量\n */\nexport function useEnv(): Record<string, string | undefined> {\n return useApp().env;\n}\n\n/**\n * 判断是否开发环境\n */\nexport function useIsDev(): boolean {\n return useApp().isDev;\n}\n","import {\n Component,\n createContext,\n type ErrorInfo,\n type ReactNode,\n useContext,\n useEffect,\n useMemo,\n useRef,\n} from \"react\";\nimport { isRouteErrorResponse, useRouteError } from \"react-router\";\nimport {\n handleChunkLoadError,\n isChunkLoadError,\n isMicroAppRuntime,\n resolveChunkRecoveryPolicy,\n} from \"./chunk-recovery.js\";\nimport type { ChunkRecoveryConfig, ChunkRecoveryEvent } from \"./types.js\";\n\nexport interface ErrorBoundaryProps {\n /** 子组件 */\n children: ReactNode;\n /** 错误回退 UI */\n fallback?: ReactNode | ((error: Error, reset: () => void) => ReactNode);\n /** 错误回调 */\n onError?: (error: Error, errorInfo: ErrorInfo) => void;\n /** 异步 chunk 加载失败恢复配置;公开组件默认不启用,由 RootProvider 显式传入 */\n chunkRecovery?: boolean | ChunkRecoveryConfig;\n /** chunk 加载恢复事件 */\n onRecoveryEvent?: (event: ChunkRecoveryEvent) => void;\n /** 是否运行在微前端子应用中 */\n isMicroApp?: boolean;\n}\n\ninterface ChunkRecoveryRuntimeContextValue {\n chunkRecovery: boolean | ChunkRecoveryConfig;\n isMicroApp: boolean;\n onError?: (error: Error) => void;\n onRecoveryEvent?: (event: ChunkRecoveryEvent) => void;\n}\n\ninterface ChunkRecoveryRuntimeProviderProps extends ChunkRecoveryRuntimeContextValue {\n children: ReactNode;\n}\n\nconst ChunkRecoveryRuntimeContext = createContext<ChunkRecoveryRuntimeContextValue | null>(null);\n\n/** 向 React Router 内部的 route errorElement 传递根恢复策略。 */\nexport function ChunkRecoveryRuntimeProvider({\n children,\n ...value\n}: ChunkRecoveryRuntimeProviderProps) {\n return (\n <ChunkRecoveryRuntimeContext.Provider value={value}>\n {children}\n </ChunkRecoveryRuntimeContext.Provider>\n );\n}\n\ninterface ErrorBoundaryState {\n hasError: boolean;\n error: Error | null;\n}\n\n/**\n * 错误边界组件\n */\nexport class ErrorBoundary extends Component<ErrorBoundaryProps, ErrorBoundaryState> {\n constructor(props: ErrorBoundaryProps) {\n super(props);\n this.state = { hasError: false, error: null };\n }\n\n static getDerivedStateFromError(error: Error): ErrorBoundaryState {\n return { hasError: true, error };\n }\n\n componentDidCatch(error: Error, errorInfo: ErrorInfo): void {\n const reportError = () => {\n console.error(\"[ErrorBoundary] Caught error:\", error, errorInfo);\n this.props.onError?.(error, errorInfo);\n };\n\n if (this.props.chunkRecovery === undefined) {\n reportError();\n return;\n }\n\n const recoveryEvent = handleChunkLoadError(error, {\n source: \"error-boundary\",\n config: this.props.chunkRecovery,\n isMicroApp: this.props.isMicroApp,\n onError: reportError,\n onRecoveryEvent: this.props.onRecoveryEvent,\n });\n\n if (!recoveryEvent) {\n reportError();\n }\n }\n\n reset = (): void => {\n this.setState({ hasError: false, error: null });\n };\n\n render(): ReactNode {\n const { hasError, error } = this.state;\n const { children, chunkRecovery, fallback, isMicroApp } = this.props;\n\n if (hasError && error) {\n if (typeof fallback === \"function\") {\n return fallback(error, this.reset);\n }\n\n if (fallback) {\n return fallback;\n }\n\n const resolvedIsMicroApp = isMicroApp ?? isMicroAppRuntime();\n const chunkRecoveryEnabled =\n chunkRecovery !== undefined &&\n resolveChunkRecoveryPolicy(chunkRecovery, {\n isProduction: process.env.NODE_ENV === \"production\",\n isMicroApp: resolvedIsMicroApp,\n }).enabled;\n const canReloadPage =\n !resolvedIsMicroApp ||\n (typeof chunkRecovery === \"object\" && chunkRecovery.allowInMicroApp === true);\n\n return (\n <DefaultErrorFallback\n canReloadPage={canReloadPage}\n error={error}\n isChunkError={chunkRecoveryEnabled && isChunkLoadError(error)}\n onReset={this.reset}\n />\n );\n }\n\n return children;\n }\n}\n\nconst UNHANDLED_ROUTE_ERROR = Symbol(\"unhandled-route-error\");\n\nfunction normalizeRouteError(reason: unknown): Error {\n if (reason instanceof Error) return reason;\n if (typeof reason === \"string\") return new Error(reason);\n\n if (isRouteErrorResponse(reason)) {\n const message = [reason.status, reason.statusText].filter(Boolean).join(\" \");\n const error = new Error(message || \"Route request failed\");\n error.name = \"RouteErrorResponse\";\n return error;\n }\n\n return new Error(\"Route rendering failed\");\n}\n\nexport interface RouteErrorBoundaryProps {\n /** 业务自定义的同步错误 UI;函数形式可接收标准化后的错误 */\n fallback?: ReactNode | ((error: Error) => ReactNode);\n}\n\n/**\n * React Router 专用的同步错误元素。\n * Router 会在内部吞掉 lazy route 异常,因此约定式路由必须用该组件把 chunk 错误交回恢复器。\n */\nexport function RouteErrorBoundary({ fallback }: RouteErrorBoundaryProps) {\n const reason = useRouteError();\n const error = useMemo(() => normalizeRouteError(reason), [reason]);\n const recoveryRuntime = useContext(ChunkRecoveryRuntimeContext);\n const handledReasonRef = useRef<unknown>(UNHANDLED_ROUTE_ERROR);\n\n useEffect(() => {\n if (Object.is(handledReasonRef.current, reason)) return;\n handledReasonRef.current = reason;\n\n const reportError = () => {\n console.error(\"[RouteErrorBoundary] Caught error:\", error);\n recoveryRuntime?.onError?.(error);\n };\n\n if (!recoveryRuntime) {\n reportError();\n return;\n }\n\n const recoveryEvent = handleChunkLoadError(reason, {\n source: \"route-error-boundary\",\n config: recoveryRuntime.chunkRecovery,\n isMicroApp: recoveryRuntime.isMicroApp,\n onError: reportError,\n onRecoveryEvent: recoveryRuntime.onRecoveryEvent,\n });\n\n if (!recoveryEvent) reportError();\n }, [error, reason, recoveryRuntime]);\n\n if (typeof fallback === \"function\") return fallback(error);\n if (fallback) return fallback;\n\n const chunkRecovery = recoveryRuntime?.chunkRecovery;\n const resolvedIsMicroApp = recoveryRuntime?.isMicroApp ?? isMicroAppRuntime();\n const chunkRecoveryEnabled =\n chunkRecovery !== undefined &&\n resolveChunkRecoveryPolicy(chunkRecovery, {\n isProduction: process.env.NODE_ENV === \"production\",\n isMicroApp: resolvedIsMicroApp,\n }).enabled;\n const canReloadPage =\n !resolvedIsMicroApp ||\n (typeof chunkRecovery === \"object\" && chunkRecovery.allowInMicroApp === true);\n\n return (\n <DefaultErrorFallback\n canReloadPage={canReloadPage}\n error={error}\n isChunkError={chunkRecoveryEnabled && isChunkLoadError(reason)}\n />\n );\n}\n\n/**\n * 默认错误回退 UI\n */\ninterface DefaultErrorFallbackProps {\n canReloadPage: boolean;\n error: Error;\n isChunkError: boolean;\n onReset?: () => void;\n}\n\nfunction DefaultErrorFallback({\n canReloadPage,\n error,\n isChunkError,\n onReset,\n}: DefaultErrorFallbackProps) {\n const isDev = process.env.NODE_ENV === \"development\";\n\n return (\n <div\n style={{\n padding: 24,\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n justifyContent: \"center\",\n minHeight: \"100vh\",\n backgroundColor: \"#f5f5f5\",\n }}\n >\n <div\n style={{\n maxWidth: 600,\n padding: 32,\n backgroundColor: \"#fff\",\n borderRadius: 8,\n boxShadow: \"0 2px 8px rgba(0,0,0,0.1)\",\n }}\n >\n <h1 style={{ color: \"#ff4d4f\", marginBottom: 16 }}>页面出错了</h1>\n <p style={{ color: \"#666\", marginBottom: 16 }}>\n {canReloadPage\n ? \"抱歉,页面遇到了一些问题。请尝试刷新页面或联系管理员。\"\n : \"抱歉,页面遇到了一些问题。请关闭当前页面后重新打开,或联系管理员。\"}\n </p>\n\n {isDev && (\n <details\n style={{\n marginBottom: 16,\n padding: 12,\n backgroundColor: \"#fff2f0\",\n borderRadius: 4,\n border: \"1px solid #ffccc7\",\n }}\n >\n <summary style={{ cursor: \"pointer\", fontWeight: \"bold\" }}>\n 错误详情(仅开发环境可见)\n </summary>\n <pre\n style={{\n marginTop: 8,\n padding: 8,\n backgroundColor: \"#fff\",\n borderRadius: 4,\n overflow: \"auto\",\n fontSize: 12,\n }}\n >\n {error.message}\n {\"\\n\\n\"}\n {error.stack}\n </pre>\n </details>\n )}\n\n {(canReloadPage || (!isChunkError && onReset)) && (\n <div style={{ display: \"flex\", gap: 8 }}>\n {!isChunkError && onReset && (\n <button\n onClick={onReset}\n style={{\n padding: \"8px 16px\",\n backgroundColor: \"#1890ff\",\n color: \"#fff\",\n border: \"none\",\n borderRadius: 4,\n cursor: \"pointer\",\n }}\n >\n 重试\n </button>\n )}\n {canReloadPage && (\n <button\n onClick={() => window.location.reload()}\n style={{\n padding: \"8px 16px\",\n backgroundColor: \"#fff\",\n color: \"#666\",\n border: \"1px solid #d9d9d9\",\n borderRadius: 4,\n cursor: \"pointer\",\n }}\n >\n 刷新页面\n </button>\n )}\n </div>\n )}\n </div>\n </div>\n );\n}\n"],"mappings":"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","names":["createContext","useContext","jsx","createContext","useContext","jsx","jsx"]}
@@ -1,5 +1,5 @@
1
1
  import { Configuration } from '@rspack/core';
2
- import { a as AppConfig, P as ProviderConfig } from './types-BYqzyGAY.js';
2
+ import { a as AppConfig, P as ProviderConfig } from './types-ZJhd87ue.js';
3
3
 
4
4
  /**
5
5
  * 路由项定义
@@ -1090,6 +1090,11 @@ interface YwkfConfig {
1090
1090
  appCName?: string;
1091
1091
  /** 是否启用 React StrictMode @default true */
1092
1092
  strictMode?: boolean;
1093
+ /** 是否启用 SWC 原生 React Compiler(需 rspack ≥2.1、React 19;React 18 用 { target: "18" } 并安装 react-compiler-runtime) @default false */
1094
+ reactCompiler?: boolean | {
1095
+ compilationMode?: "infer" | "annotation" | "all";
1096
+ target?: "17" | "18" | "19";
1097
+ };
1093
1098
  /** 开发服务器配置 */
1094
1099
  dev?: DevServerConfig;
1095
1100
  /** 输出配置 */
@@ -29,6 +29,54 @@ interface AppConfig {
29
29
  providers?: ProviderConfig[];
30
30
  /** 生命周期钩子 */
31
31
  lifecycle?: LifecycleHooks;
32
+ /** 异步 chunk 加载失败恢复配置 */
33
+ chunkRecovery?: boolean | ChunkRecoveryConfig;
34
+ }
35
+ /**
36
+ * 异步 chunk 加载失败恢复配置
37
+ */
38
+ interface ChunkRecoveryConfig {
39
+ /**
40
+ * 是否启用自动恢复
41
+ * 默认仅在 production 环境启用
42
+ */
43
+ enabled?: boolean;
44
+ /**
45
+ * 当前构建的稳定标识(可选覆盖;ywkf 构建默认自动注入)
46
+ * 同一 build 在一个标签页内最多自动刷新一次
47
+ */
48
+ buildId?: string;
49
+ /** 自动刷新冷却时间(毫秒),默认 30000 */
50
+ cooldownMs?: number;
51
+ /**
52
+ * 是否允许在微前端子应用中刷新整个页面
53
+ * 默认 false,避免子应用刷新宿主应用
54
+ */
55
+ allowInMicroApp?: boolean;
56
+ /**
57
+ * 是否注册 unhandledrejection / vite:preloadError 全局监听
58
+ * 默认 false;已有应用级监听时无需开启
59
+ */
60
+ globalHandlers?: boolean;
61
+ }
62
+ /** chunk 加载失败的来源 */
63
+ type ChunkRecoverySource = "error-boundary" | "route-error-boundary" | "unhandled-rejection" | "vite-preload-error";
64
+ /** chunk 恢复处理结果 */
65
+ type ChunkRecoveryOutcome = "reload-scheduled" | "reload-skipped-already-attempted" | "reload-skipped-disabled" | "reload-skipped-micro-app" | "reload-skipped-storage-unavailable" | "reload-skipped-cooldown";
66
+ /** chunk 恢复事件,可用于接入业务侧监控 */
67
+ interface ChunkRecoveryEvent {
68
+ /** 原始错误(非 Error 类型会被标准化) */
69
+ error: Error;
70
+ /** 错误来源 */
71
+ source: ChunkRecoverySource;
72
+ /** 本次处理结果 */
73
+ outcome: ChunkRecoveryOutcome;
74
+ /** 事件发生时间 */
75
+ timestamp: number;
76
+ /** 当前使用的刷新冷却时间 */
77
+ cooldownMs: number;
78
+ /** 用于防止同一构建重复刷新的匿名恢复标识 */
79
+ recoveryId: string;
32
80
  }
33
81
  /**
34
82
  * Ant Design 配置
@@ -68,6 +116,8 @@ interface LifecycleHooks {
68
116
  onUnmount?: () => void;
69
117
  /** 全局错误处理 */
70
118
  onError?: (error: Error, errorInfo?: React.ErrorInfo) => void;
119
+ /** chunk 加载恢复事件 */
120
+ onRecoveryEvent?: (event: ChunkRecoveryEvent) => void;
71
121
  }
72
122
  /**
73
123
  * 应用上下文数据
@@ -169,4 +219,4 @@ interface RequestConfig {
169
219
  errorHandler?: (error: Record<string, unknown>) => unknown;
170
220
  }
171
221
 
172
- export type { AntdConfig as A, LifecycleHooks as L, MicroAppConfig as M, ProviderConfig as P, RequestConfig as R, AppConfig as a, AppContextValue as b, Result as c };
222
+ export type { AntdConfig as A, ChunkRecoveryConfig as C, LifecycleHooks as L, MicroAppConfig as M, ProviderConfig as P, RequestConfig as R, AppConfig as a, AppContextValue as b, ChunkRecoveryEvent as c, ChunkRecoveryOutcome as d, ChunkRecoverySource as e, Result as f };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@4399ywkf/core",
3
- "version": "5.1.4",
3
+ "version": "5.1.6",
4
4
  "description": "4399运维开发前端框架核心",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -42,6 +42,7 @@
42
42
  "scripts": {
43
43
  "build": "tsup",
44
44
  "dev": "tsup --watch",
45
+ "test": "vitest run",
45
46
  "typecheck": "tsc --noEmit",
46
47
  "prepublishOnly": "npm run build",
47
48
  "release": "npm version patch && npm publish --access public",
@@ -49,10 +50,10 @@
49
50
  "release:major": "npm version major && npm publish --access public"
50
51
  },
51
52
  "dependencies": {
52
- "@rsdoctor/rspack-plugin": "^1.5.0",
53
- "@rspack/core": "^2.0.0",
54
- "@rspack/dev-server": "2.0.1",
55
- "@rspack/plugin-react-refresh": "^2.0.0",
53
+ "@rsdoctor/rspack-plugin": "^1.5.17",
54
+ "@rspack/core": "^2.1.0",
55
+ "@rspack/dev-server": "2.1.0",
56
+ "@rspack/plugin-react-refresh": "^2.0.2",
56
57
  "@svgr/webpack": "^8.1.0",
57
58
  "@tailwindcss/postcss": "^4.2.1",
58
59
  "assert": "^2.1.0",
@@ -91,7 +92,8 @@
91
92
  "react-dom": "^19.2.4",
92
93
  "react-router": "^7.13.1",
93
94
  "tsup": "^8.4.0",
94
- "typescript": "^5.8.2"
95
+ "typescript": "^5.8.2",
96
+ "vitest": "^4.0.18"
95
97
  },
96
98
  "peerDependencies": {
97
99
  "antd": "^5.0.0 || ^6.0.0",