@4399ywkf/core 5.3.1 → 5.4.0

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,5 +1,5 @@
1
- import { C as ChunkRecoveryConfig, c as ChunkRecoveryEvent, e as ChunkRecoverySource, a as AppConfig, M as MicroAppConfig, b as AppContextValue, P as ProviderConfig } from '../types-ZJhd87ue.js';
2
- export { A as AntdConfig, d as ChunkRecoveryOutcome, L as LifecycleHooks, R as RequestConfig, f as Result } from '../types-ZJhd87ue.js';
1
+ import { C as ChunkRecoveryConfig, c as ChunkRecoveryEvent, e as ChunkRecoverySource, a as AppConfig, M as MicroAppConfig, b as AppContextValue, P as ProviderConfig } from '../types-DZ7Nz9bQ.js';
2
+ export { A as AntdConfig, d as ChunkRecoveryOutcome, L as LifecycleHooks, R as RequestConfig, f as Result } from '../types-DZ7Nz9bQ.js';
3
3
  import * as react_jsx_runtime from 'react/jsx-runtime';
4
4
  import * as react from 'react';
5
5
  import { ReactNode, Component, ErrorInfo, ComponentType } from 'react';
@@ -10,15 +10,15 @@ declare const CHUNK_RECOVERY_STORAGE_KEY = "@4399ywkf/core:chunk-recovery-attemp
10
10
  declare const CHUNK_RECOVERY_CACHE_BUST_PARAM = "__ywkf_chunk_retry";
11
11
  declare const CHUNK_RECOVERY_ACTIVE_SYMBOL: unique symbol;
12
12
  interface ChunkRecoveryStorage {
13
- getItem(key: string): string | null;
14
- setItem(key: string, value: string): void;
13
+ getItem: (key: string) => string | null;
14
+ setItem: (key: string, value: string) => void;
15
15
  }
16
16
  type ChunkRecoveryClaim = {
17
17
  claimed: true;
18
18
  attemptedAt: number;
19
19
  } | {
20
20
  claimed: false;
21
- reason: "already-attempted" | "cooldown" | "storage-unavailable";
21
+ reason: 'already-attempted' | 'cooldown' | 'storage-unavailable';
22
22
  attemptedAt?: number;
23
23
  };
24
24
  interface ClaimChunkRecoveryAttemptOptions {
@@ -28,21 +28,21 @@ interface ClaimChunkRecoveryAttemptOptions {
28
28
  storageKey?: string;
29
29
  }
30
30
  interface ChunkRecoveryPolicyContext {
31
- isProduction: boolean;
32
31
  isMicroApp: boolean;
32
+ isProduction: boolean;
33
33
  }
34
34
  interface ChunkRecoveryPolicy {
35
- enabled: boolean;
36
- disabledReason?: "configuration" | "environment" | "micro-app";
37
35
  cooldownMs: number;
36
+ disabledReason?: 'configuration' | 'environment' | 'micro-app';
37
+ enabled: boolean;
38
38
  globalHandlers: boolean;
39
39
  }
40
40
  interface HandleChunkRecoveryOptions {
41
- source: ChunkRecoverySource;
42
41
  config?: boolean | ChunkRecoveryConfig;
43
42
  isMicroApp?: boolean;
44
43
  onError?: (error: Error) => void;
45
44
  onRecoveryEvent?: (event: ChunkRecoveryEvent) => void;
45
+ source: ChunkRecoverySource;
46
46
  }
47
47
  interface GlobalChunkRecoveryHandlersOptions {
48
48
  config?: boolean | ChunkRecoveryConfig;
@@ -132,8 +132,8 @@ declare const AppContext: react.Context<AppContextValue>;
132
132
  * 应用上下文 Provider
133
133
  */
134
134
  interface AppContextProviderProps {
135
- value: Partial<AppContextValue>;
136
135
  children: ReactNode;
136
+ value: Partial<AppContextValue>;
137
137
  }
138
138
  declare function AppContextProvider({ value, children }: AppContextProviderProps): react_jsx_runtime.JSX.Element;
139
139
  /**
@@ -160,20 +160,20 @@ declare function useIsDev(): boolean;
160
160
  interface ErrorBoundaryProps {
161
161
  /** 子组件 */
162
162
  children: ReactNode;
163
+ /** 异步 chunk 加载失败恢复配置;公开组件默认不启用,由 RootProvider 显式传入 */
164
+ chunkRecovery?: boolean | ChunkRecoveryConfig;
163
165
  /** 错误回退 UI */
164
166
  fallback?: ReactNode | ((error: Error, reset: () => void) => ReactNode);
167
+ /** 是否运行在微前端子应用中 */
168
+ isMicroApp?: boolean;
165
169
  /** 错误回调 */
166
170
  onError?: (error: Error, errorInfo: ErrorInfo) => void;
167
- /** 异步 chunk 加载失败恢复配置;公开组件默认不启用,由 RootProvider 显式传入 */
168
- chunkRecovery?: boolean | ChunkRecoveryConfig;
169
171
  /** chunk 加载恢复事件 */
170
172
  onRecoveryEvent?: (event: ChunkRecoveryEvent) => void;
171
- /** 是否运行在微前端子应用中 */
172
- isMicroApp?: boolean;
173
173
  }
174
174
  interface ErrorBoundaryState {
175
- hasError: boolean;
176
175
  error: Error | null;
176
+ hasError: boolean;
177
177
  }
178
178
  /**
179
179
  * 错误边界组件
@@ -196,8 +196,8 @@ interface RouteErrorBoundaryProps {
196
196
  declare function RouteErrorBoundary({ fallback }: RouteErrorBoundaryProps): string | number | bigint | boolean | Iterable<ReactNode> | Promise<string | number | bigint | boolean | react.ReactPortal | react.ReactElement<unknown, string | react.JSXElementConstructor<any>> | Iterable<ReactNode> | null | undefined> | react_jsx_runtime.JSX.Element | null | undefined;
197
197
 
198
198
  interface RootProviderProps {
199
- config: AppConfig;
200
199
  children?: ReactNode;
200
+ config: AppConfig;
201
201
  /** 是否运行在微前端子应用中;未传时由运行环境自动判断 */
202
202
  isMicroApp?: boolean;
203
203
  }
@@ -211,6 +211,6 @@ declare function RootProvider({ config, children, isMicroApp }: RootProviderProp
211
211
  */
212
212
  declare function createProvider<P extends Record<string, unknown>>(component: ComponentType<P & {
213
213
  children: ReactNode;
214
- }>, props?: Omit<P, "children">, order?: number): ProviderConfig;
214
+ }>, props?: Omit<P, 'children'>, order?: number): ProviderConfig;
215
215
 
216
216
  export { AppConfig, AppContext, AppContextProvider, AppContextValue, CHUNK_RECOVERY_ACTIVE_SYMBOL, CHUNK_RECOVERY_CACHE_BUST_PARAM, CHUNK_RECOVERY_STORAGE_KEY, type ChunkRecoveryClaim, ChunkRecoveryConfig, ChunkRecoveryEvent, type ChunkRecoveryPolicy, type ChunkRecoveryPolicyContext, ChunkRecoverySource, type ChunkRecoveryStorage, type ClaimChunkRecoveryAttemptOptions, DEFAULT_CHUNK_RECOVERY_COOLDOWN_MS, ErrorBoundary, type ErrorBoundaryProps, type GlobalChunkRecoveryHandlersOptions, type HandleChunkRecoveryOptions, MicroAppConfig, ProviderConfig, RootProvider, type RootProviderProps, RouteErrorBoundary, type RouteErrorBoundaryProps, bootstrap, claimChunkRecoveryAttempt, clearChunkRecoveryCacheBustParam, createGarfishProvider, createMicroApp, createProvider, getMicroAppPublicPath, handleChunkLoadError, installGlobalChunkRecoveryHandlers, isChunkLoadError, isMicroAppEnv, isMicroAppRuntime, resolveChunkRecoveryPolicy, unmount, useApp, useAppName, useBasename, useEnv, useIsDev };
@@ -2,12 +2,8 @@
2
2
  var DEFAULT_CHUNK_RECOVERY_COOLDOWN_MS = 3e4;
3
3
  var CHUNK_RECOVERY_STORAGE_KEY = "@4399ywkf/core:chunk-recovery-attempt";
4
4
  var CHUNK_RECOVERY_CACHE_BUST_PARAM = "__ywkf_chunk_retry";
5
- var CHUNK_RECOVERY_ACTIVE_SYMBOL = /* @__PURE__ */ Symbol.for(
6
- "@4399ywkf/core/chunk-recovery-active"
7
- );
8
- var CHUNK_RECOVERY_REGISTRY_SYMBOL = /* @__PURE__ */ Symbol.for(
9
- "@4399ywkf/core/chunk-recovery-registry"
10
- );
5
+ var CHUNK_RECOVERY_ACTIVE_SYMBOL = /* @__PURE__ */ Symbol.for("@4399ywkf/core/chunk-recovery-active");
6
+ var CHUNK_RECOVERY_REGISTRY_SYMBOL = /* @__PURE__ */ Symbol.for("@4399ywkf/core/chunk-recovery-registry");
11
7
  var CHUNK_LOAD_ERROR_PATTERNS = [
12
8
  /\bChunkLoadError\b/i,
13
9
  /\bLoading (?:CSS )?chunk\s+\S+\s+failed\b/i,
@@ -614,7 +610,6 @@ function DefaultErrorFallback({
614
610
  !isChunkError && onReset && /* @__PURE__ */ jsx2(
615
611
  "button",
616
612
  {
617
- onClick: onReset,
618
613
  style: {
619
614
  padding: "8px 16px",
620
615
  backgroundColor: "#1890ff",
@@ -623,13 +618,13 @@ function DefaultErrorFallback({
623
618
  borderRadius: 4,
624
619
  cursor: "pointer"
625
620
  },
621
+ onClick: onReset,
626
622
  children: "\u91CD\u8BD5"
627
623
  }
628
624
  ),
629
625
  canReloadPage && /* @__PURE__ */ jsx2(
630
626
  "button",
631
627
  {
632
- onClick: () => window.location.reload(),
633
628
  style: {
634
629
  padding: "8px 16px",
635
630
  backgroundColor: "#fff",
@@ -638,6 +633,7 @@ function DefaultErrorFallback({
638
633
  borderRadius: 4,
639
634
  cursor: "pointer"
640
635
  },
636
+ onClick: () => window.location.reload(),
641
637
  children: "\u5237\u65B0\u9875\u9762"
642
638
  }
643
639
  )
@@ -765,7 +761,7 @@ async function resolveAppConfig(config) {
765
761
  const createRouter = routesModule.createRouter || routesModule.default?.createRouter;
766
762
  if (typeof createRouter === "function") {
767
763
  const router = createRouter(config.basename);
768
- console.log("[ywkf] \u5DF2\u81EA\u52A8\u6CE8\u5165\u7EA6\u5B9A\u5F0F\u8DEF\u7531");
764
+ console.info("[ywkf] \u5DF2\u81EA\u52A8\u6CE8\u5165\u7EA6\u5B9A\u5F0F\u8DEF\u7531");
769
765
  return { ...config, router };
770
766
  } else {
771
767
  console.warn("[ywkf] @ywkf/routes \u672A\u5BFC\u51FA createRouter \u51FD\u6570");
@@ -833,13 +829,13 @@ function createMicroApp(getConfig) {
833
829
  * 微前端 bootstrap 生命周期
834
830
  */
835
831
  async bootstrap() {
836
- console.log("[MicroApp] bootstrap");
832
+ console.info("[MicroApp] bootstrap");
837
833
  },
838
834
  /**
839
835
  * 微前端 mount 生命周期
840
836
  */
841
837
  async mount(props) {
842
- console.log("[MicroApp] mount", props);
838
+ console.info("[MicroApp] mount", props);
843
839
  const config = getConfig(props);
844
840
  const resolvedConfig = await resolveAppConfig(config);
845
841
  const container = props?.masterProps?.container;
@@ -860,7 +856,7 @@ function createMicroApp(getConfig) {
860
856
  });
861
857
  try {
862
858
  microRoot = createRoot(rootElement);
863
- microRoot.render(/* @__PURE__ */ jsx4(RootProvider, { config: resolvedConfig, isMicroApp: true }));
859
+ microRoot.render(/* @__PURE__ */ jsx4(RootProvider, { isMicroApp: true, config: resolvedConfig }));
864
860
  disposeMicroChunkRecoveryHandlers = nextDisposeMicroChunkRecoveryHandlers;
865
861
  } catch (error) {
866
862
  nextDisposeMicroChunkRecoveryHandlers();
@@ -877,7 +873,7 @@ function createMicroApp(getConfig) {
877
873
  * 微前端 unmount 生命周期
878
874
  */
879
875
  async unmount(props) {
880
- console.log("[MicroApp] unmount", props);
876
+ console.info("[MicroApp] unmount", props);
881
877
  const config = getConfig(props);
882
878
  if (config.lifecycle?.onUnmount) {
883
879
  config.lifecycle.onUnmount();
@@ -893,7 +889,7 @@ function createMicroApp(getConfig) {
893
889
  * 微前端 update 生命周期(可选)
894
890
  */
895
891
  async update(props) {
896
- console.log("[MicroApp] update", props);
892
+ console.info("[MicroApp] update", props);
897
893
  }
898
894
  };
899
895
  }
@@ -922,7 +918,7 @@ function createGarfishProvider(getConfig) {
922
918
  });
923
919
  try {
924
920
  garfishRoot = createRoot(rootElement);
925
- garfishRoot.render(/* @__PURE__ */ jsx4(RootProvider, { config: resolvedConfig, isMicroApp: true }));
921
+ garfishRoot.render(/* @__PURE__ */ jsx4(RootProvider, { isMicroApp: true, config: resolvedConfig }));
926
922
  disposeGarfishChunkRecoveryHandlers = nextDisposeGarfishChunkRecoveryHandlers;
927
923
  } catch (error) {
928
924
  nextDisposeGarfishChunkRecoveryHandlers();
@@ -1 +1 @@
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
+ {"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('@4399ywkf/core/chunk-recovery-active');\nconst CHUNK_RECOVERY_REGISTRY_SYMBOL = Symbol.for('@4399ywkf/core/chunk-recovery-registry');\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 isMicroApp: boolean;\n isProduction: boolean;\n}\n\nexport interface ChunkRecoveryPolicy {\n cooldownMs: number;\n disabledReason?: 'configuration' | 'environment' | 'micro-app';\n enabled: boolean;\n globalHandlers: boolean;\n}\n\nexport interface HandleChunkRecoveryOptions {\n config?: boolean | ChunkRecoveryConfig;\n isMicroApp?: boolean;\n onError?: (error: Error) => void;\n onRecoveryEvent?: (event: ChunkRecoveryEvent) => void;\n source: ChunkRecoverySource;\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 = (globalThis as typeof globalThis & { __YWKF_BUILD_ID__?: unknown })\n .__YWKF_BUILD_ID__;\n return typeof buildId === 'string' ? buildId.trim() : '';\n}\n\nfunction resolveRecoveryId(\n error: unknown,\n config: boolean | ChunkRecoveryConfig | undefined,\n): 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 | 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';\n\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.info('[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.info('[MicroApp] bootstrap');\n },\n\n /**\n * 微前端 mount 生命周期\n */\n async mount(props?: MicroAppConfig) {\n console.info('[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 isMicroApp config={resolvedConfig} />);\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.info('[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.info('[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 isMicroApp config={resolvedConfig} />);\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';\n\nimport { isMicroAppRuntime } from './chunk-recovery.js';\nimport { AppContextProvider } from './context.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 children?: ReactNode;\n config: AppConfig;\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';\n\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 children: ReactNode;\n value: Partial<AppContextValue>;\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';\n\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 /** 异步 chunk 加载失败恢复配置;公开组件默认不启用,由 RootProvider 显式传入 */\n chunkRecovery?: boolean | ChunkRecoveryConfig;\n /** 错误回退 UI */\n fallback?: ReactNode | ((error: Error, reset: () => void) => ReactNode);\n /** 是否运行在微前端子应用中 */\n isMicroApp?: boolean;\n /** 错误回调 */\n onError?: (error: Error, errorInfo: ErrorInfo) => void;\n /** chunk 加载恢复事件 */\n onRecoveryEvent?: (event: ChunkRecoveryEvent) => void;\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 error: Error | null;\n hasError: boolean;\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 style={{\n padding: '8px 16px',\n backgroundColor: '#1890ff',\n color: '#fff',\n border: 'none',\n borderRadius: 4,\n cursor: 'pointer',\n }}\n onClick={onReset}\n >\n 重试\n </button>\n )}\n {canReloadPage && (\n <button\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 onClick={() => window.location.reload()}\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"]}