@fulgurjs/federation 5.0.3 → 5.1.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.
Files changed (43) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/DESIGN.md +11 -0
  3. package/README.en.md +441 -0
  4. package/README.md +120 -5
  5. package/dist/chunk-4PLNAYZX.js +84 -0
  6. package/dist/cli.js +4 -1
  7. package/dist/host-pages-core-BFxp-IOj.d.cts +37 -0
  8. package/dist/host-pages-core-DLfMeDrO.d.ts +37 -0
  9. package/dist/index.cjs +137 -26
  10. package/dist/index.js +137 -26
  11. package/dist/react-adapter.cjs +518 -0
  12. package/dist/react-adapter.d.cts +117 -0
  13. package/dist/react-adapter.d.ts +117 -0
  14. package/dist/react-adapter.js +292 -0
  15. package/dist/react.d.ts +442 -0
  16. package/dist/react.js +10 -0
  17. package/dist/runtime-entry.d.ts +29 -17
  18. package/dist/runtime.js +13 -13
  19. package/dist/vue-adapter.cjs +66 -50
  20. package/dist/vue-adapter.d.cts +4 -25
  21. package/dist/vue-adapter.d.ts +4 -25
  22. package/dist/vue-adapter.js +14 -66
  23. package/examples/README.md +5 -0
  24. package/examples/react-host/README.md +28 -0
  25. package/examples/react-host/fulgurjs.config.ts +19 -0
  26. package/examples/react-host/index.html +11 -0
  27. package/examples/react-host/package.json +23 -0
  28. package/examples/react-host/src/App.tsx +66 -0
  29. package/examples/react-host/src/federation/pages.data.ts +19 -0
  30. package/examples/react-host/src/main.tsx +8 -0
  31. package/examples/react-host/tsconfig.json +14 -0
  32. package/examples/react-host/vite.config.ts +8 -0
  33. package/examples/react-remote/fulgurjs.config.ts +17 -0
  34. package/examples/react-remote/index.html +11 -0
  35. package/examples/react-remote/package.json +22 -0
  36. package/examples/react-remote/src/Button.tsx +15 -0
  37. package/examples/react-remote/src/main.tsx +6 -0
  38. package/examples/react-remote/src/pages/Detail.tsx +10 -0
  39. package/examples/react-remote/src/pages/Home.tsx +14 -0
  40. package/examples/react-remote/src/utils.ts +3 -0
  41. package/examples/react-remote/tsconfig.json +14 -0
  42. package/examples/react-remote/vite.config.ts +8 -0
  43. package/package.json +30 -3
@@ -0,0 +1,442 @@
1
+ import * as react from 'react';
2
+ import { ComponentType, ReactNode, Component, ErrorInfo } from 'react';
3
+
4
+ /** 统一错误码体系(对齐 webpack ScriptExternalLoadError 等运行时错误的可诊断性) */
5
+ declare class FgError extends Error {
6
+ code: string;
7
+ details?: Record<string, unknown>;
8
+ constructor(code: string, message: string, details?: Record<string, unknown>);
9
+ }
10
+
11
+ interface ShareEntry {
12
+ version: string;
13
+ get: () => Promise<any>;
14
+ from: string;
15
+ eager: boolean;
16
+ loaded?: boolean;
17
+ }
18
+ type ShareScope = Record<string, Record<string, ShareEntry>>;
19
+ type ShareScopeMap = Record<string, ShareScope>;
20
+ interface RemoteConfig {
21
+ name: string;
22
+ entry: string;
23
+ shareScope?: string;
24
+ /**
25
+ * 加载超时 ms,默认 15000。注意:超时只代表"调用方不再等待",浏览器不会取消已发出的
26
+ * 动态 import——下一次调用复用同一条 in-flight 记录,不会重复初始化同一容器。
27
+ */
28
+ timeout?: number;
29
+ /** 失败重试次数,默认 2(上限 10;配置期与运行时注册均校验,非法当场抛错) */
30
+ retries?: number;
31
+ /** 备用 remoteEntry 地址(首个失败后依次尝试) */
32
+ fallback?: string[];
33
+ breaker?: {
34
+ threshold?: number;
35
+ resetMs?: number;
36
+ };
37
+ /** promise-based remote:运行时解析出容器或容器地址(其解析同样受 timeout 约束) */
38
+ promise?: () => Promise<any>;
39
+ /** 内部:远程自报的发布路径(preload 用) */
40
+ manifestUrl?: string;
41
+ }
42
+ /** @deprecated 兼容旧版公开类型;新代码使用 RemoteConfig。 */
43
+ interface RemoteInput extends RemoteConfig {
44
+ container?: unknown;
45
+ containerPromise?: Promise<unknown>;
46
+ }
47
+ interface LoadRemoteOptions {
48
+ shareScope?: string;
49
+ retries?: number;
50
+ fallbackModule?: () => any;
51
+ }
52
+ interface PreloadRemoteOptions {
53
+ mode?: 'preload' | 'prefetch';
54
+ }
55
+ interface LoadShareOptions {
56
+ requiredVersion?: string | false;
57
+ singleton?: boolean;
58
+ strictVersion?: boolean;
59
+ shareKey?: string;
60
+ shareScope?: string;
61
+ /** 本地副本兜底(webpack shared.import) */
62
+ fallback?: () => Promise<any>;
63
+ }
64
+ interface RuntimePlugin {
65
+ name?: string;
66
+ init?: (hooks: RuntimeHooks) => void;
67
+ }
68
+ interface RuntimeHooks {
69
+ /** 覆写共享版本裁决结果:返回 ShareEntry 即生效 */
70
+ resolveShare?: (shareInfo: {
71
+ shareKey: string;
72
+ shareScope: string;
73
+ requiredVersion?: string | false;
74
+ picked?: ShareEntry;
75
+ available: ShareEntry[];
76
+ }) => Promise<ShareEntry | void> | ShareEntry | void;
77
+ beforeLoadRemote?: (info: {
78
+ remote: string;
79
+ module: string;
80
+ }) => void;
81
+ afterLoadRemote?: (info: {
82
+ remote: string;
83
+ module: string;
84
+ module_ns?: any;
85
+ }) => void;
86
+ onRemoteError?: (info: {
87
+ remote: string;
88
+ error: FgError;
89
+ }) => void;
90
+ }
91
+ interface RemoteDebugInfo {
92
+ entry: string;
93
+ status: 'idle' | 'loading' | 'loaded' | 'failed';
94
+ lastLoadMs?: number;
95
+ error?: string;
96
+ /** setup 生命周期状态(§3.3.1):none=未配置 / pending=执行中 / ready=应用级已完成 / failed=失败可重试 */
97
+ setup?: 'none' | 'pending' | 'ready' | 'failed';
98
+ }
99
+ /**
100
+ * 远程初始化上下文(federation({ setup }) 模块的默认导出与具名 onSession 收到的参数)。
101
+ * appContext 是调用时从页面级 AppContext 取得的当前快照(不缓存旧引用);
102
+ * signal 在登录代次变化或退出清理时失效,业务异步写回前必须检查 aborted。
103
+ */
104
+ interface RemoteSetupContext {
105
+ appContext: Readonly<Record<string, any>>;
106
+ sessionKey?: string;
107
+ signal: AbortSignal;
108
+ }
109
+ /** setup 模块的固定导出契约:默认导出必为函数;onSession 可选且必须是函数 */
110
+ interface RemoteSetupModule {
111
+ default: (ctx: RemoteSetupContext) => void | Promise<void>;
112
+ onSession?: (ctx: RemoteSetupContext) => void | Promise<void>;
113
+ }
114
+ declare function createRuntime(): {
115
+ shareScopeMap: ShareScopeMap;
116
+ initSharing: (scopeName?: string) => ShareScopeMap;
117
+ registerShare: (scopeName: string, name: string, version: string, get: () => Promise<any>, opts?: {
118
+ from?: string;
119
+ eager?: boolean;
120
+ loaded?: boolean;
121
+ }) => void;
122
+ registerRemotes: (list: RemoteConfig[]) => void;
123
+ registerRemote: (remote: RemoteConfig) => void;
124
+ registerPlugins: (list: RuntimePlugin[]) => void;
125
+ loadShare: (name: string, opts?: LoadShareOptions) => Promise<any>;
126
+ loadRemote: <T = Record<string, any>>(spec: string, opts?: LoadRemoteOptions) => Promise<T>;
127
+ getContainer: (name: string) => Promise<any>;
128
+ preloadRemote: (spec: string, opts?: PreloadRemoteOptions) => Promise<void>;
129
+ parseSpec: (spec: string) => {
130
+ remote: string;
131
+ module: string;
132
+ };
133
+ clearSessionState: () => void;
134
+ };
135
+ type FgRuntime = ReturnType<typeof createRuntime>;
136
+ /** 插件版本(与 package.json 同步维护于 src/version.ts,测试拦截漂移;用于跨源副本一致性诊断) */
137
+ declare const version: string;
138
+ /**
139
+ * 取当前页面生效的运行时单例(与 globalThis.__FULGURJS_RUNTIME__ 同一实例)。
140
+ *
141
+ * 远程页面禁止静态 import 'virtual:fulgurjs-runtime'——该虚拟模块由远程 dev server
142
+ * 求值,会在远程模块图内实例化独立的运行时副本,破坏渲染上下文
143
+ * (resolveComponent / withDirectives / ref owner 告警、内容区空白)。
144
+ * 跨源取运行时一律用本入口,或直接读全局单例。
145
+ */
146
+ declare function getRuntime(): FgRuntime;
147
+ declare const initSharing: (scopeName?: string) => ShareScopeMap;
148
+ declare const registerShare: (scopeName: string, name: string, version: string, get: () => Promise<any>, opts?: {
149
+ from?: string;
150
+ eager?: boolean;
151
+ loaded?: boolean;
152
+ }) => void;
153
+ declare const registerRemotes: (list: RemoteConfig[]) => void;
154
+ declare const registerRemote: (remote: RemoteConfig) => void;
155
+ declare const registerPlugins: (list: RuntimePlugin[]) => void;
156
+ declare const loadShare: (name: string, opts?: LoadShareOptions) => Promise<any>;
157
+ declare const loadRemote: <T = Record<string, any>>(spec: string, opts?: LoadRemoteOptions) => Promise<T>;
158
+ declare const getContainer: (name: string) => Promise<any>;
159
+ declare const preloadRemote: (spec: string, opts?: PreloadRemoteOptions) => Promise<void>;
160
+ declare const parseSpec: (spec: string) => {
161
+ remote: string;
162
+ module: string;
163
+ };
164
+ declare const shareScopeMap: ShareScopeMap;
165
+ /** default 导出 interop:ESM 取 .default;CJS 命名空间回退整体 */
166
+ declare function unwrapDefault(ns: any): any;
167
+
168
+ /**
169
+ * D.2 宿主路由表校验器(definePages)
170
+ *
171
+ * 背景:带参路由缺省推导 spec 时会剥离 :参数 段,可能与其它条目(如列表页)的
172
+ * expose 键收敛相同 → 静默加载错误组件(真实事故:复制流程误走更新语义)。
173
+ *
174
+ * 定位:纯同步纯函数,dev(宿主浏览器模块求值)与 build(node)行为一致;
175
+ * 只校验不改写入参;ERROR 级聚合一次 throw(strict:false 降级 console.error),
176
+ * WARN 级聚合 console.warn。
177
+ *
178
+ * 规则:
179
+ * - R1 [ERROR] 带参路由(无显式 spec)的推导 spec 与任一其它条目的有效 spec 相同
180
+ * - R2 [WARN] 多条目的有效 spec 完全相同(可能是刻意的菜单别名,要求有意识)
181
+ * - R3 [ERROR] schema 提供时:有效 spec 的 exposes 键不在对应 remote 清单中
182
+ * (把运行时 MFU-006 提前到启动期;schema 缺失/remote 不可达则跳过)
183
+ * - R4 [ERROR] 静态路由被数组中更靠前的带参路由遮蔽(先到先得 → 静态路由成死路由);
184
+ * 含路由完全重复
185
+ * - R5 [WARN] name 字段重复(vue-router 命名跳转歧义)
186
+ */
187
+ interface PageRouteLike {
188
+ /** 宿主路由路径(:param 段) */
189
+ route: string;
190
+ /** 显式 spec(缺省走推导) */
191
+ spec?: string;
192
+ /** 其余字段(name/title/...)由宿主自由扩展,校验器按需读取 */
193
+ name?: string;
194
+ [key: string]: unknown;
195
+ }
196
+ interface RemoteSchemaEntry {
197
+ /** 该 remote 的 exposes 键清单(与 spec 同口径,剥 ./ 前缀比较) */
198
+ exposes: string[];
199
+ /** manifest 是否成功拉取(false 时跳过该 remote 的 R3,诚实降级) */
200
+ exists?: boolean;
201
+ }
202
+ interface PagesOptions {
203
+ /**
204
+ * 带参路由的缺省 spec 推导规则(宿主私有约定,如
205
+ * (route) => `pages/${route 去前缀去 :参}`)。
206
+ * 缺省 = 去掉首段(远程前缀)+ 剥 :参 段(无 pages/ 前缀)——
207
+ * 推导只需在全部条目间自洽即可保持冲突判定成立。
208
+ */
209
+ deriveSpec?: (route: string) => string;
210
+ /** 路由前缀 → remote 名(R3 用:{'/remote-a/': 'remote-a'});缺省跳过 R3 */
211
+ remotes?: Record<string, string>;
212
+ /** remote exposes 清单(dev 由 virtual:fulgurjs-remote-schema 提供);缺省跳过 R3 */
213
+ schema?: Record<string, RemoteSchemaEntry>;
214
+ /** false = ERROR 降级 console.error(默认 true = throw) */
215
+ strict?: boolean;
216
+ }
217
+ interface PageViolation {
218
+ rule: 'R1' | 'R2' | 'R3' | 'R4' | 'R5';
219
+ level: 'error' | 'warn';
220
+ message: string;
221
+ }
222
+ /**
223
+ * 校验路由表(独立导出便于单测):返回违例清单(不抛错)。
224
+ */
225
+ declare function validatePages(pages: PageRouteLike[], options?: PagesOptions): PageViolation[];
226
+ /**
227
+ * 宿主路由表定义入口:校验(聚合报错)后原样返回入参,不改写任何字段。
228
+ * 违反 ERROR 级规则时默认 throw(dev overlay / build 失败直接可见);
229
+ * strict: false 时降级 console.error。WARN 级始终 console.warn。
230
+ */
231
+ declare function definePages<P extends PageRouteLike[]>(pages: P, options?: PagesOptions): P;
232
+
233
+ /**
234
+ * 宿主页面表纯解析核心(框架无关)。
235
+ *
236
+ * 5.1.0 从 vue-adapter 提取:definePages 校验接入、最长前缀远程归属、缺省 spec 推导、
237
+ * base 剥离、段式参数匹配——Vue 与 React 适配器共用同一份解析,组件缓存/错误边界/
238
+ * 保活策略由各框架适配器自行负责(不把 Vue 的卸载策略强加给 React,反之亦然)。
239
+ */
240
+
241
+ /** 页面表数据项(两个框架适配器共用;展示项 fallback/error 等在各适配器定义) */
242
+ interface HostPagesCoreOptions {
243
+ /** 页面表(宿主路由与布局共用的唯一数据源;definePages R1–R5 校验照常执行) */
244
+ pages: PageRouteLike[];
245
+ /** 路由前缀 → remote 名(最长前缀匹配;页面路由无匹配前缀时创建期即报错) */
246
+ remotePrefixes: Record<string, string>;
247
+ /** 缺省 spec 推导(缺省 = 去首段前缀 + 剥 :参数 段,同 definePages 默认) */
248
+ deriveSpec?: (route: string) => string;
249
+ /** 远程 exposes 清单(dev 由 remoteSchema 提供;build 为空表时按语义诚实降级) */
250
+ schema?: Record<string, RemoteSchemaEntry>;
251
+ /** ERROR 级校验失败是否 throw(默认 true) */
252
+ strict?: boolean;
253
+ /** 站点 base 前缀(如 '/main'):resolve 时先剥离再匹配路由空间 */
254
+ base?: string;
255
+ }
256
+ interface ResolvedHostPage {
257
+ /** 原页面记录(含宿主自由扩展字段 name/title/keepAlive/...) */
258
+ page: PageRouteLike;
259
+ /** 命中的 remote 名 */
260
+ remote: string;
261
+ /** 完整加载 spec(`<remote>/<exposes 键>`,loadRemote 直用) */
262
+ spec: string;
263
+ /** 路径参数(解码失败只让该次匹配失败,不让页面初始化崩溃) */
264
+ params: Record<string, string>;
265
+ }
266
+
267
+ /**
268
+ * React 适配层:remoteComponent() / useLoadRemote() / RemoteErrorBoundary /
269
+ * createReactHostPages()。只接收加载函数,不静态引用运行时内核(同 vue-adapter 形态,
270
+ * dist/react.js 由构建脚本绑定 loadRemote 后再导出)。
271
+ *
272
+ * 语义要点(README React 章节的实现依据):
273
+ * - remoteComponent:工厂与页面表声明零加载副作用;首次渲染才 loadRemote;
274
+ * 加载状态机自带 pending/error/ready 三态,不用 React.lazy——lazy 的失败 Promise
275
+ * 会缓存在实例上,仅重置错误边界无法恢复,必须重建加载尝试。retry 以受控 attempt
276
+ * 计数触发(不在普通 render 中重建加载器,组件本地状态不因重渲染反复重置)。
277
+ * - timeout 是本次组件加载等待上限(适配层实现),不取消 loadRemote 的共享请求,
278
+ * 不修改远程入口配置超时;迟到的成功/失败一律丢弃,不产生未处理 rejection。
279
+ * retry 对已成功缓存的模块不重新下载(运行时缓存),只重走生命周期(onSession 按代次去重)。
280
+ * - 渲染期异常由内置 RemoteRenderBoundary 捕获,与网络/导出错误分开记录与展示;
281
+ * ErrorBoundary 不捕获事件处理器与任意异步回调(React 边界语义,README 已声明)。
282
+ * - 代码全部 createElement(无 JSX):适配器自身不依赖 jsx-runtime,减少共享子路径面。
283
+ */
284
+
285
+ type LoadRemoteFn = (spec: string, opts?: LoadRemoteOptions) => Promise<any>;
286
+ /** 渲染函数形态的错误占位:(error, retry) => ReactNode;与 remoteComponent.error 一致 */
287
+ type RemoteErrorFallback = (error: unknown, retry: () => void) => ReactNode;
288
+ interface ReactRemoteComponentOptions {
289
+ /** 本次加载 pending 时的占位(区别于失败占位);默认 null */
290
+ fallback?: ReactNode;
291
+ /** 加载失败或子树渲染错误的展示;默认内置中文占位(错误码+根因+修法+重试) */
292
+ error?: ReactNode | RemoteErrorFallback;
293
+ /** 透传现行 loadRemote 的重试选项(0-10 整数),不另叠自动重试 */
294
+ retries?: number;
295
+ /** 本次组件加载等待上限 ms;不提供则沿用 loadRemote 自身超时。不取消已发出的共享请求 */
296
+ timeout?: number;
297
+ }
298
+ interface RemoteErrorBoundaryProps {
299
+ children?: ReactNode;
300
+ /** 错误占位:节点或 ({ error, reset }) 渲染函数;默认内置中文占位 */
301
+ fallback?: ReactNode | ((args: {
302
+ error: unknown;
303
+ reset: () => void;
304
+ }) => ReactNode);
305
+ /** 渲染异常回调(error + React componentStack 信息) */
306
+ onError?: (error: unknown, info: ErrorInfo) => void;
307
+ /** 任一项变化时重置边界状态(受控重试的常用形态:传 [retryEpoch]) */
308
+ resetKeys?: readonly unknown[];
309
+ }
310
+ interface BoundaryState {
311
+ error: unknown | null;
312
+ }
313
+ /**
314
+ * 页面级错误边界:只捕获传到它的子树渲染错误。remoteComponent 内置边界已处理自身错误,
315
+ * 外层边界看不到内层已消费的异常。reset 只重置边界状态;子组件若持有失败缓存
316
+ * (如 React.lazy),还需要由调用方重建加载尝试(remoteComponent 的 retry 已含两者)。
317
+ */
318
+ declare class RemoteErrorBoundary extends Component<RemoteErrorBoundaryProps, BoundaryState> {
319
+ state: BoundaryState;
320
+ static getDerivedStateFromError(error: unknown): BoundaryState;
321
+ componentDidCatch(error: unknown, info: ErrorInfo): void;
322
+ componentDidUpdate(prev: RemoteErrorBoundaryProps): void;
323
+ readonly reset: () => void;
324
+ render(): ReactNode;
325
+ }
326
+ interface UseLoadRemoteOptions {
327
+ /** 透传 loadRemote 的 shareScope */
328
+ shareScope?: string;
329
+ /** 透传 loadRemote 的重试次数(0-10 整数) */
330
+ retries?: number;
331
+ /**
332
+ * 用户显式配置的失败兜底模块(透传 loadRemote.fallbackModule):配置后加载失败返回
333
+ * 兜底值而不写 error。这是显式声明的行为,不是静默成功——README 已说明。
334
+ */
335
+ fallbackModule?: () => any;
336
+ }
337
+ interface UseLoadRemoteResult<Module = any> {
338
+ /** 加载成功后的模块命名空间;未成功时 undefined */
339
+ data: Module | undefined;
340
+ /** 失败原因;无错误时恒为 undefined(统一空值) */
341
+ error: unknown;
342
+ /** 是否有请求在途 */
343
+ loading: boolean;
344
+ /** 重新走一次加载生命周期;已成功的模块经运行时缓存不会重新下载。Promise<void> 正常结束(不抛) */
345
+ reload: () => Promise<void>;
346
+ }
347
+ interface ReactHostPagesOptions extends HostPagesCoreOptions {
348
+ /** 每次页面模块实际加载尝试前执行(同步或异步);宿主在此提供最新 context */
349
+ beforeLoad?: () => void | Promise<void>;
350
+ /** 页面加载 pending 占位(同 remoteComponent.fallback) */
351
+ fallback?: ReactNode;
352
+ /** 页面加载/渲染错误占位(同 remoteComponent.error) */
353
+ error?: ReactNode | RemoteErrorFallback;
354
+ /** 透传 loadRemote 重试(0-10 整数) */
355
+ retries?: number;
356
+ /** 单次页面组件加载等待上限 ms(同 remoteComponent.timeout) */
357
+ timeout?: number;
358
+ }
359
+ interface ReactHostPages {
360
+ /** 原页面记录 */
361
+ pages: PageRouteLike[];
362
+ /** 路径 → 页面解析(base 前缀、最长前缀、参数解码、R1–R5 语义与 Vue 完全一致) */
363
+ resolve(path: string): ResolvedHostPage | null;
364
+ /** 按 spec 取页面组件(同 spec 同登录代次复用;新非空 sessionKey 到来时重建以触发 onSession) */
365
+ component<P = Record<string, unknown>>(spec: string): ComponentType<P>;
366
+ }
367
+ declare function createReactHostPages$1(options: ReactHostPagesOptions, loadRemote: LoadRemoteFn): ReactHostPages;
368
+
369
+ /**
370
+ * 跨应用上下文标准字段表(§4.3,0.8.2 精简后)。
371
+ *
372
+ * 读写约定:宿主桥先写标准字段;远程 boot 只增不改宿主键;
373
+ * 嵌套对象(如 events)是引用共享,子应用挂属性即时可见(同 realm 直引用)。
374
+ *
375
+ * 精简记录(0.8.2):`token` 快照与 `formUrl`/`baseUrl` 从默认 provide 集合移除——
376
+ * token 快照与 getToken 函数引用重复(快照会过期),formUrl/baseUrl 自 0.7.0
377
+ * remoteComponent 直渲染后无消费点;项目如需可经扩展位自行提供。
378
+ */
379
+ interface AppContext {
380
+ /** 宿主登录用户原始形态(只读约定) */
381
+ user: Record<string, any>;
382
+ /** 取最新 token(拉取式防过期;0.8.2 起 bridge 不再传一次性 token 快照,用本函数取值) */
383
+ getToken?: () => string | undefined;
384
+ /** 宿主 pinia 实例:子应用 useUserStore(ctx.store) 拿共享响应式状态 */
385
+ store?: unknown;
386
+ /** 宿主 Vue App 实例(同 realm 直引用):全局组件/指令注册目标 */
387
+ hostApp?: unknown;
388
+ /** EP locale 等 UI 配置(原 W4 字段) */
389
+ locale?: unknown;
390
+ /** 事件/方法池:events.main.* 宿主提供、events.bpm.* / events.lowcode.* 子应用反向注册 */
391
+ events?: Record<string, any>;
392
+ /**
393
+ * 非敏感登录代次 ID:宿主每次成功登录/重新登录生成新值,token 刷新但会话未变时沿用。
394
+ * 远程 onSession 按它去重(同一代次只执行一次)。不是用户 ID、不是 token、不作为授权凭证。
395
+ * 远程声明了 onSession 时必填(缺省即 MFU-013)。
396
+ */
397
+ sessionKey?: string;
398
+ /** 项目扩展位(formUrl/baseUrl 等自定义键,按需自行提供) */
399
+ [key: string]: unknown;
400
+ }
401
+ /**
402
+ * 宿主写入跨应用上下文(merge 语义,幂等可多次调用,后写覆盖同键)。
403
+ *
404
+ * 宿主桥(host/src/fulgurjs/host/bridge.ts)在登录完成后调用:
405
+ * provideAppContext({ user, getToken, store, hostApp, locale, sessionKey, events: { main: mainEvents }, ... })
406
+ * 登录态变化(换账号/token 刷新)时再次调用即以最新值覆盖同键——不要用布尔闩锁把桥封成只跑一次。
407
+ */
408
+ declare function provideAppContext(config: Partial<AppContext> & Record<string, unknown>): void;
409
+ /**
410
+ * 宿主退出登录时清理:删除整个 context 对象(旧 user/getToken 引用一并失效),并通知
411
+ * 运行时单例作废全部远程的会话信号与 onSession 去重状态(下次登录必须重新执行 onSession)。
412
+ *
413
+ * 边界(契约):只清 AppContext 与会话初始化状态;不重置远程模块缓存、共享模块图与
414
+ * 应用级 setup 注册(同一页面内组件与共享实例继续复用)。页面无运行时单例时静默幂等
415
+ * (退出动作不依赖联邦形态,不得因缺运行时而打断登出流程)。
416
+ */
417
+ declare function clearAppContext(): void;
418
+ /**
419
+ * 读上下文快照(传输层快照:顶层 merge 结果 + 嵌套对象引用共享)。
420
+ * 页面无运行时单例(独立直开远程页)→ CC-002 显式抛错,不静默回空。
421
+ */
422
+ declare function getAppContext(): AppContext;
423
+ /**
424
+ * 显式校验读取(远程 setup/boot 消费入口):任一键缺失 → CC-001 三段式。
425
+ *
426
+ * 用法:const { store, user, hostApp } = requireAppContext('store', 'user', 'hostApp')
427
+ * 时序契约:宿主桥先 provide,远程 setup/onSession 后 require——违反即在初始化处显式失败。
428
+ */
429
+ declare function requireAppContext(...keys: string[]): AppContext;
430
+
431
+ declare const remoteComponent: <P = Record<string, unknown>>(spec: string, opts?: ReactRemoteComponentOptions) => react.ComponentType<P & {
432
+ ref?: react.Ref<unknown>;
433
+ }>;
434
+ declare const useLoadRemote: <Module = any>(spec: string, opts?: UseLoadRemoteOptions) => UseLoadRemoteResult<Module>;
435
+ /** 宿主页面适配器(绑定本包运行时的 loadRemote;选项与返回值类型见 react-adapter) */
436
+ declare function createReactHostPages(options: Parameters<typeof createReactHostPages$1>[0]): ReactHostPages;
437
+
438
+ type RemoteSchema = Record<string, RemoteSchemaEntry>;
439
+ /** 无插件转换的场景(构建、Node 导入)如实返回空清单。 */
440
+ declare const remoteSchema: RemoteSchema;
441
+
442
+ export { type AppContext, type FgRuntime, type LoadRemoteOptions, type LoadShareOptions, type PageRouteLike, type PageViolation, type PagesOptions, type PreloadRemoteOptions, type ReactHostPages, type ReactHostPagesOptions, type ReactRemoteComponentOptions, type RemoteConfig, type RemoteDebugInfo, RemoteErrorBoundary, type RemoteErrorBoundaryProps, type RemoteErrorFallback, type RemoteInput, type RemoteSchema, type RemoteSchemaEntry, type RemoteSetupContext, type RemoteSetupModule, type ResolvedHostPage, type RuntimeHooks, type RuntimePlugin, type ShareEntry, type ShareScope, type ShareScopeMap, type UseLoadRemoteOptions, type UseLoadRemoteResult, clearAppContext, createReactHostPages, definePages, getAppContext, getContainer, getRuntime, initSharing, loadRemote, loadShare, parseSpec, preloadRemote, provideAppContext, registerPlugins, registerRemote, registerRemotes, registerShare, remoteComponent, remoteSchema, requireAppContext, shareScopeMap, unwrapDefault, useLoadRemote, validatePages, version };
package/dist/react.js ADDED
@@ -0,0 +1,10 @@
1
+ export { initSharing, registerShare, registerRemotes, registerRemote, registerPlugins, loadShare, loadRemote, getContainer, preloadRemote, parseSpec, getRuntime, shareScopeMap, unwrapDefault, version } from "./runtime.js";
2
+ export { provideAppContext, getAppContext, requireAppContext, clearAppContext } from "./context.js";
3
+ export { definePages, validatePages } from "./pages.js";
4
+ import { loadRemote } from "./runtime.js";
5
+ import { createRemoteComponent, createUseLoadRemote, RemoteErrorBoundary, createReactHostPages as createReactHostPagesWithLoader } from "./react-adapter.js";
6
+ export const remoteComponent = createRemoteComponent(loadRemote);
7
+ export const useLoadRemote = createUseLoadRemote(loadRemote);
8
+ export { RemoteErrorBoundary };
9
+ export const createReactHostPages = (options) => createReactHostPagesWithLoader(options, loadRemote);
10
+ export const remoteSchema = {};
@@ -292,16 +292,16 @@ declare function validatePages(pages: PageRouteLike[], options?: PagesOptions):
292
292
  */
293
293
  declare function definePages<P extends PageRouteLike[]>(pages: P, options?: PagesOptions): P;
294
294
 
295
- /** Vue 适配层只接收加载函数,不静态引用运行时内核。 */
295
+ /**
296
+ * 宿主页面表纯解析核心(框架无关)。
297
+ *
298
+ * 5.1.0 从 vue-adapter 提取:definePages 校验接入、最长前缀远程归属、缺省 spec 推导、
299
+ * base 剥离、段式参数匹配——Vue 与 React 适配器共用同一份解析,组件缓存/错误边界/
300
+ * 保活策略由各框架适配器自行负责(不把 Vue 的卸载策略强加给 React,反之亦然)。
301
+ */
296
302
 
297
- interface RemoteComponentOptions {
298
- loadingComponent?: Component;
299
- errorComponent?: Component;
300
- retries?: number;
301
- delay?: number;
302
- timeout?: number;
303
- }
304
- interface HostPagesOptions {
303
+ /** 页面表数据项(两个框架适配器共用;展示项 fallback/error 等在各适配器定义) */
304
+ interface HostPagesCoreOptions {
305
305
  /** 页面表(宿主路由与布局共用的唯一数据源;definePages R1–R5 校验照常执行) */
306
306
  pages: PageRouteLike[];
307
307
  /** 路由前缀 → remote 名(最长前缀匹配;页面路由无匹配前缀时创建期即报错) */
@@ -314,14 +314,6 @@ interface HostPagesOptions {
314
314
  strict?: boolean;
315
315
  /** 站点 base 前缀(如 '/main'):resolve 时先剥离再匹配路由空间 */
316
316
  base?: string;
317
- /** 每次页面模块实际加载前执行(同步或异步);宿主在此提供最新 context */
318
- beforeLoad?: () => void | Promise<void>;
319
- /** 加载期占位组件(骨架屏) */
320
- loadingComponent?: Component;
321
- /** 错误占位组件(缺省 = 内置三段式错误占位:错误码+根因+修法) */
322
- errorComponent?: Component;
323
- /** 骨架屏延迟 ms(默认 200,防闪) */
324
- delay?: number;
325
317
  }
326
318
  interface ResolvedHostPage {
327
319
  /** 原页面记录(含宿主自由扩展字段 name/title/keepAlive/...) */
@@ -333,6 +325,26 @@ interface ResolvedHostPage {
333
325
  /** 路径参数(解码失败只让该次匹配失败,不让页面初始化崩溃) */
334
326
  params: Record<string, string>;
335
327
  }
328
+
329
+ /** Vue 适配层只接收加载函数,不静态引用运行时内核。 */
330
+
331
+ interface RemoteComponentOptions {
332
+ loadingComponent?: Component;
333
+ errorComponent?: Component;
334
+ retries?: number;
335
+ delay?: number;
336
+ timeout?: number;
337
+ }
338
+ interface HostPagesOptions extends HostPagesCoreOptions {
339
+ /** 每次页面模块实际加载前执行(同步或异步);宿主在此提供最新 context */
340
+ beforeLoad?: () => void | Promise<void>;
341
+ /** 加载期占位组件(骨架屏) */
342
+ loadingComponent?: Component;
343
+ /** 错误占位组件(缺省 = 内置三段式错误占位:错误码+根因+修法) */
344
+ errorComponent?: Component;
345
+ /** 骨架屏延迟 ms(默认 200,防闪) */
346
+ delay?: number;
347
+ }
336
348
  interface HostPages {
337
349
  /** 原页面记录 */
338
350
  pages: PageRouteLike[];