@fulgurjs/federation 6.11.7 → 6.12.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 (51) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/README.en.md +2 -0
  3. package/README.md +3 -3
  4. package/dist/{application-core-DWI3eKme.d.ts → application-core-C72tVRT7.d.ts} +1 -1
  5. package/dist/{application-core-BuhXQmLF.d.cts → application-core-Coa0CIre.d.cts} +1 -1
  6. package/dist/bridge-app-react.d.cts +2 -2
  7. package/dist/bridge-app-react.d.ts +2 -2
  8. package/dist/bridge-app-react.js +1 -1
  9. package/dist/bridge-app-vue.d.cts +2 -2
  10. package/dist/bridge-app-vue.d.ts +2 -2
  11. package/dist/bridge-app-vue.js +1 -1
  12. package/dist/{bridge-core-77BT1__I.d.cts → bridge-core-CGFET9Qi.d.cts} +2 -1
  13. package/dist/{bridge-core-CoQRVgnZ.d.ts → bridge-core-Dm6ABUxQ.d.ts} +2 -1
  14. package/dist/bridge-core.cjs +4 -1
  15. package/dist/bridge-core.d.cts +1 -1
  16. package/dist/bridge-core.d.ts +1 -1
  17. package/dist/bridge-core.js +1 -1
  18. package/dist/bridge-host-react.cjs +4 -1
  19. package/dist/bridge-host-react.d.cts +2 -2
  20. package/dist/bridge-host-react.d.ts +2 -2
  21. package/dist/bridge-host-react.js +1 -1
  22. package/dist/bridge-host-vue.cjs +42 -5
  23. package/dist/bridge-host-vue.d.cts +12 -4
  24. package/dist/bridge-host-vue.d.ts +12 -4
  25. package/dist/bridge-host-vue.js +40 -5
  26. package/dist/bridge-session-auto.cjs +121 -0
  27. package/dist/bridge-session-auto.d.cts +21 -0
  28. package/dist/bridge-session-auto.d.ts +21 -0
  29. package/dist/bridge-session-auto.js +88 -0
  30. package/dist/{chunk-HDRZBSND.js → chunk-2MWIIRQZ.js} +4 -1
  31. package/dist/cli.js +53 -10
  32. package/dist/index.cjs +4 -3
  33. package/dist/index.js +4 -3
  34. package/dist/react-adapter.d.cts +2 -2
  35. package/dist/react-adapter.d.ts +2 -2
  36. package/dist/react.d.ts +2 -2
  37. package/dist/{remote-types-COmBhjRc.d.ts → remote-types-CMtfvLcH.d.ts} +1 -1
  38. package/dist/{remote-types-CStGOJwu.d.cts → remote-types-Cf4SSzus.d.cts} +1 -1
  39. package/dist/runtime-entry.d.ts +2 -2
  40. package/dist/runtime.js +13 -13
  41. package/dist/vue-adapter.d.cts +2 -2
  42. package/dist/vue-adapter.d.ts +2 -2
  43. package/dist/vue.d.ts +10 -3
  44. package/dist/vue.js +2 -1
  45. package/docs/en/reference/api.md +15 -4
  46. package/docs/en/reference/errors.md +1 -1
  47. package/docs/en/reference/types.md +4 -2
  48. package/docs/zh/reference/api.md +16 -6
  49. package/docs/zh/reference/errors.md +1 -1
  50. package/docs/zh/reference/types.md +4 -2
  51. package/package.json +6 -2
@@ -344,6 +344,8 @@ export const pageProviders: RemoteSetupModule['pageProviders'] = [
344
344
 
345
345
  `RemoteSetupContext`: `{ appContext: Readonly<AppContext>, sessionKey?: string, signal: AbortSignal }`. `appContext` is the snapshot taken from the page-level AppContext **at call time** (never a saved stale reference); `signal` is invalidated when the login generation changes or on logout cleanup.
346
346
 
347
+ A module with only pageProviders/globalComponents/onSession can omit the default function. Empty modules and non-function defaults remain invalid.
348
+
347
349
  Fixed contract:
348
350
 
349
351
  | Dimension | Semantics |
@@ -355,7 +357,7 @@ Fixed contract:
355
357
  | Execution count (pageProviders) | Declaration is extracted once with setup; **wrapping applies on every component render** (the declared array is cached by reference, successful loader results are reused; rejected loaders evict the cache so same-page retries execute them again). Vue `remoteComponent`/`createHostPages` and React `remoteComponent`/`createReactHostPages` apply it automatically (outer→inner wrap; attrs/slots pass through to the innermost business component; providers receive no props); manual `loadRemote` and `useLoadRemote` (returning the module for self-rendering) do not — wrap yourself there |
356
358
  | Execution count (onSession) | Deduplicated by the non-sensitive `sessionKey`: once per login generation; a new generation first invalidates the old `signal`, then chains the old call and the new call **serially** per remote (preventing two accounts' async writes from interleaving); `clearAppContext()` invalidates the dedup state, forcing a rerun on the next login. App-level setup does not re-run on logout/generation switch |
357
359
  | sessionKey | The host login flow generates a new generation on every successful login/re-login (non-sensitive ID, never a token); kept when a token refreshes but the session does not. **onSession present but sessionKey missing → MFU-013**; identity is never guessed from a user object reference; remotes without onSession need no sessionKey |
358
- | Export validation | Must default-export a function; the named `onSession` is optional and must be a function; `globalComponents` is optional and must be an object (key = registered name, value = component); `pageProviders` is optional and must be an array (entries = component objects or zero-arg loaders; functions with parameters or `displayName`/`props`/`emits` metadata remain static components; wrap unmarked zero-argument components with `defineComponent`; entry contents are validated at consumer-side resolution). Violations → MFU-011 (reports actual type / expected signature / fix) |
360
+ | Export validation | At least one of default/onSession/globalComponents/pageProviders must be declared; any provided default must be a function; the named `onSession` is optional and must be a function; `globalComponents` is optional and must be an object (key = registered name, value = component); `pageProviders` is optional and must be an array (entries = component objects or zero-arg loaders; functions with parameters or `displayName`/`props`/`emits` metadata remain static components; wrap unmarked zero-argument components with `defineComponent`; entry contents are validated at consumer-side resolution). Violations → MFU-011 (reports actual type / expected signature / fix) |
359
361
  | Failure and retry | setup/onSession throwing → that `loadRemote` rejects (MFU-012); **only the failed stage's cache is cleared** (after a setup failure the retry starts at setup; an onSession failure only reruns the session segment); already-successful stages are not repeated. `fallbackModule` never masks an initialization failure |
360
362
  | Self-recursion | `loadRemote(same remote/…)` inside setup/onSession's synchronous segment → MFU-014 (the call waits on itself, deadlocking). Same-remote recursion inside the async segment cannot be attributed precisely and shows up as a hang — never load same-remote modules inside initialization |
361
363
  | dev/prod parity | The dev container (middleware-served) and the prod container (build artifact) carry the same setup metadata (the container's `__fulgurjsSetup` field + the manifest's `setup` field); the internal expose key `./__fulgurjs_setup__` never appears in type artifacts or public exposes lists |
@@ -444,7 +446,7 @@ export default defineBridgeApp(async (props, ctx) => {
444
446
  // Vue host (/vue)
445
447
  import { createVueBridgeApp } from '@fulgurjs/federation/vue'
446
448
  const RemoteReactApp = createVueBridgeApp<P>('react-remote/bridge', {
447
- loadingComponent?, errorComponent?, retries?, timeout?, getContext?,
449
+ loadingComponent?, errorComponent?, retries?, timeout?, getContext?, session?, sessionStorageKey?,
448
450
  })
449
451
  // Template: <RemoteReactApp :session-key="loginKey" :app-props="{ userId, onReady }" />
450
452
 
@@ -471,12 +473,21 @@ const RemoteVueApp = createReactBridgeApp<P>('vue-remote/bridge', {
471
473
  - **DOM ownership**: the wrapper component only creates and keeps a stable empty mount container; host re-renders never patch inside the child app's root. React host StrictMode double effects are safe. Vue `<KeepAlive>` deactivate is not unmount — a child app in a cached page keeps its root and state.
472
474
  - **Old requests never pretend to be cancelled**: work already inside `loadRemote` is not cancelled because the bridge layer invalidates it — late old results are discarded by generation; the remote's `onSession` must honor the `signal.aborted` contract.
473
475
 
476
+ ### Automatic Vue session options
477
+
478
+ | Option | Type / default | Behavior |
479
+ |---|---|---|
480
+ | `session` | `() => string \| number \| null \| undefined` / disabled | Synchronous reactive identity getter in createVueBridgeApp: stable ID=ready, null=logout, undefined=restoring. The plugin owns generation/context; do not also pass sessionKey. |
481
+ | `sessionStorageKey` | `string` / `fulgurjs-bridge-session` | Records use this namespace plus `:auto`. All remotes of one host share it. Only meaningful with session enabled. |
482
+
483
+ The same identity restores its generation on reentry/reload; a changed identity generates a new one. Never use credentials or sensitive data. localStorage updates must be reflected in reactive state. Omit session to disable, provide a getter to enable, add sessionStorageKey to customize. getContext need not return sessionKey; explicit conflicts remain errors. Getter errors/illegal results appear as MFU-016 (getContext); invalid option types throw TypeError immediately. See [automatic sessions](../guide/app-bridge.md).
484
+
474
485
  ### Host-side helper: `createBridgeSession` (Vue)
475
486
 
476
- `createBridgeSession(options?)` (`/vue`) — moves the **contract semantics** of sessionKey (non-sensitive login generation, never the token itself, null = logged out, unchanged across reloads within one session) into the plugin; the host only decides when to call it:
487
+ `createBridgeSession(options?)` (`/vue`) — moves the **contract semantics** of sessionKey (non-sensitive login generation, never the token itself, null = logged out, unchanged across reloads within one session) into the plugin; this is the explicit-control helper. Normal Vue bridges should use the factory session identity getter instead of manual calls:
477
488
 
478
489
  ```ts
479
- // src/fulgurjs/host/session.ts (create once at module level)
490
+ // src/fulgurjs/host/context.ts (create once at module level)
480
491
  import { createBridgeSession } from '@fulgurjs/federation/vue'
481
492
  export const bridgeSession = createBridgeSession()
482
493
  // on successful login → bridgeSession.renew(); on logout → bridgeSession.clear()
@@ -66,7 +66,7 @@
66
66
  | `MFU-008` | Runtime reports an unknown remote | The remote name in the spec/call is not in `remotes`/the runtime registry | Check the remote name spelling; for dynamic remotes call `registerRemote`/`registerRemotes` first |
67
67
  | `MFU-009` | Runtime reports the loaded module has no exports | The expose target file has no exports (an empty module / side effects only) | Add exports to the expose target file; confirm the expected file is what got loaded |
68
68
  | `MFU-010` | Runtime warns the selected shared singleton version fails some consumer's requirement (lists candidate versions, the provider, impact, and fixes; the same combination warns once) | The version singleton converged on is outside some consumer's requiredVersion; or a bridge host/child app missing singleton causes double-instance symptoms (Invalid hook call) | Align dependency versions; confirm the warning is acceptable or adjust requiredVersion; three singleton keys for cross-framework hosts |
69
- | `MFU-011` | Runtime reports an illegal setup lifecycle entry export shape (reports actual type / expected signature / fix) | The setup module's default export or named `onSession` is not a function (other exports are not entries) | Default-export a `setup(context)` function from the setup file; optionally a named `onSession(context)` function |
69
+ | `MFU-011` | Runtime reports an illegal setup lifecycle entry export shape (reports actual type / expected signature / fix) | Empty setup module, non-function default/onSession, or invalid component/Provider declarations | Export an initialization function or valid onSession/globalComponents/pageProviders; no empty function is required and an empty module is invalid |
70
70
  | `MFU-012` | That `loadRemote` rejects, reporting setup/onSession threw (cause carries the original exception) | The initialization code itself threw | Fix the error inside setup/onSession and retry directly — only the failed stage's cache is cleared (after a setup failure the retry starts at setup; an onSession failure only reruns the session segment); already-successful stages are not repeated |
71
71
  | `MFU-013` | Runtime reports the remote declares onSession but the host AppContext lacks sessionKey | The host did not provide a non-sensitive login generation ID (never use a token as one) | In the host login flow call `provideAppContext({ sessionKey })` — generate a new value on every successful login/re-login; token refreshes keep it |
72
72
  | `MFU-014` | Runtime reports a recursive loadRemote of the same remote inside setup/onSession's synchronous segment | Loading a module of the same remote inside the initialization's synchronous segment — the call waits on itself, deadlocking | Do not load same-remote modules inside initialization; put cross-remote loads in the async segment |
@@ -213,10 +213,9 @@ Import from: `@fulgurjs/federation/react`, `@fulgurjs/federation/runtime`, `@ful
213
213
 
214
214
  | Field | Optional | Type | Contract |
215
215
  |---|---|---|---|
216
- | `default` | no | `(ctx: RemoteSetupContext) => void \| Promise<void>` | See the owning API for lifecycle and runtime defaults. |
216
+ | `default` | yes | `(ctx: RemoteSetupContext) => void \| Promise<void>` | See the owning API for lifecycle and runtime defaults. |
217
217
  | `onSession` | yes | `(ctx: RemoteSetupContext) => void \| Promise<void>` | See the owning API for lifecycle and runtime defaults. |
218
218
  | `globalComponents` | yes | `Record<string, unknown>` | Static components retain their identity. Zero-argument functions with displayName/props/emits metadata are components; unmarked zero-argument functions are lazy loaders. See the setup API for installation and retry semantics. |
219
-
220
219
  | `pageProviders` | yes | `unknown[]` | Ancestor Providers required by remote components; each item is a component or zero-argument loader. Adapters wrap the actual consumer tree without copying the provider application. |
221
220
 
222
221
  ## AppContext
@@ -433,6 +432,9 @@ Import from: `@fulgurjs/federation/vue`.
433
432
  | `retries` | yes | `number` | See the owning API for lifecycle and runtime defaults. |
434
433
  | `timeout` | yes | `number` | See the owning API for lifecycle and runtime defaults. |
435
434
  | `getContext` | yes | `() => Partial<AppContext> & Record<string, unknown>` | See the owning API for lifecycle and runtime defaults. |
435
+ | `session` | yes | `() => string \| number \| null \| undefined` | Reactive non-sensitive identity; managed generations. null=logout, undefined=restoring; do not combine with sessionKey. |
436
+ | `sessionStorageKey` | yes | `string` | Automatic session namespace; defaults to fulgurjs-bridge-session and is shared by one host. |
437
+
436
438
 
437
439
  ## VueBridgeRouterConnection
438
440
 
@@ -339,6 +339,8 @@ export const pageProviders: RemoteSetupModule['pageProviders'] = [
339
339
 
340
340
  `RemoteSetupContext`:`{ appContext: Readonly<AppContext>, sessionKey?: string, signal: AbortSignal }`。`appContext` 是**调用时**从页面级 AppContext 取得的快照(不保存永不更新的旧引用);`signal` 在登录代次变化或退出清理时失效。
341
341
 
342
+ 没有应用级副作用时可只导出 pageProviders/globalComponents/onSession,省略默认函数;模块至少有一项有效声明,不为通过校验写空函数。
343
+
342
344
  固定契约:
343
345
 
344
346
  | 维度 | 语义 |
@@ -348,10 +350,9 @@ export const pageProviders: RemoteSetupModule['pageProviders'] = [
348
350
  | 执行次数(setup) | 每容器一次;并发调用共享同一 Promise;成功后不重复。`preloadRemote` 只预取资源不执行 |
349
351
  | 执行次数(globalComponents) | 声明提取随 setup 一次;**安装随每次 `loadRemote` 执行**(幂等,`app.component` 同名覆盖,后注册生效)——桥接子应用每次挂载新建 app 实例也能拿到注册。Vue `remoteComponent` 和 `createHostPages` 自动捕获消费方 app;手动 `loadRemote` 与 React 侧不自动传入(React 无 Vue 全局注册表)——跳过安装,不报错。注册随消费方 app 生命周期驻留,无独立卸载 API |
350
352
  | 执行次数(pageProviders) | 声明提取随 setup 一次;**包裹随每次组件渲染生效**(声明数组按引用缓存,成功的 loader 结果复用,失败清缓存允许同页重试;setup 重跑换新数组时也重新解析)。Vue `remoteComponent`/`createHostPages` 与 React `remoteComponent`/`createReactHostPages` 自动应用(按 外→内 包裹,attrs/slots 透传给最内层业务组件,Provider 不收 props);手动 `loadRemote` 与 `useLoadRemote`(返回模块自行渲染)不自动应用——这类消费自行包裹 |
351
- | 导出校验 | 必须默认导出函数;具名 `onSession` 可选且必须是函数;`globalComponents` 可选且必须是对象(键=注册名,值=组件);`pageProviders` 可选且必须是数组(项=组件对象或零参 loader,带参函数或带 `displayName`/`props`/`emits` 元数据的函数视为静态函数组件;无元数据的零参组件请用 `defineComponent` 包装;项内容在消费方解析时校验)。违反 → MFU-011(报实际类型/预期签名/修法) |
353
+ | 导出校验 | 默认函数可省略,但必须声明 default/onSession/globalComponents/pageProviders 中至少一项;已有默认导出必须为函数,具名 `onSession` 可选且必须是函数;`globalComponents` 可选且必须是对象(键=注册名,值=组件);`pageProviders` 可选且必须是数组(项=组件对象或零参 loader,带参函数或带 `displayName`/`props`/`emits` 元数据的函数视为静态函数组件;无元数据的零参组件请用 `defineComponent` 包装;项内容在消费方解析时校验)。违反 → MFU-011(报实际类型/预期签名/修法) |
352
354
  | 执行次数(onSession) | 按非敏感 `sessionKey` 去重:同一登录代次一次;新代次先作废旧 `signal`,再按远程**串行**衔接旧调用与新调用(防两账号异步写入交错);`clearAppContext()` 失效去重状态,下次登录必须重跑。应用级 setup 不因退出/换代重复执行 |
353
355
  | sessionKey | 宿主登录流程每次成功登录/重登生成新代次(非敏感 ID,禁止用 token);token 刷新但会话未变时沿用。**有 onSession 却缺 sessionKey → MFU-013**,不凭用户对象引用猜测身份;无 onSession 的远程无需 sessionKey |
354
- | 导出校验 | 必须默认导出函数;具名 `onSession` 可选且必须是函数;`globalComponents` 可选且必须是对象(键=注册名,值=组件)。违反 → MFU-011(报实际类型/预期签名/修法) |
355
356
  | 失败与重试 | setup/onSession 抛错 → 该次 `loadRemote` 拒绝(MFU-012);**只清失败阶段的缓存**(setup 失败重试从 setup 开始;onSession 失败只重跑会话段),已成功的阶段不重复。`fallbackModule` 不掩盖初始化失败 |
356
357
  | 自递归 | setup/onSession 同步段内 `loadRemote(同 remote/…)` → MFU-014(该调用会等待自身形成死锁)。异步段内的同远程递归无法精确归因,表现为挂起——不要在初始化内加载同远程模块 |
357
358
  | dev/prod 一致 | dev 容器(中间件直出)与 prod 容器(构建产物)携带同一 setup 元数据(容器上的 `__fulgurjsSetup` 字段 + manifest 的 `setup` 字段);内部 expose 键 `./__fulgurjs_setup__` 不出现在类型产物与公开文档 exposes 清单中 |
@@ -440,7 +441,7 @@ export default defineBridgeApp(async (props, ctx) => {
440
441
  // Vue 宿主(/vue)
441
442
  import { createVueBridgeApp } from '@fulgurjs/federation/vue'
442
443
  const RemoteReactApp = createVueBridgeApp<P>('react-remote/bridge', {
443
- loadingComponent?, errorComponent?, retries?, timeout?, getContext?,
444
+ loadingComponent?, errorComponent?, retries?, timeout?, getContext?, session?, sessionStorageKey?,
444
445
  })
445
446
  // 模板:<RemoteReactApp :session-key="loginKey" :app-props="{ userId, onReady }" />
446
447
 
@@ -454,7 +455,7 @@ const RemoteVueApp = createReactBridgeApp<P>('vue-remote/bridge', {
454
455
 
455
456
  | 项 | `createVueBridgeApp`(Vue 宿主) | `createReactBridgeApp`(React 宿主) |
456
457
  |---|---|---|
457
- | 工厂选项 | `loadingComponent?` `errorComponent?`(收到 `error` prop,完全接管) `retries?`(0–10 整数) `timeout?`(正有限 ms) `getContext?` | `fallback?`(pending 占位) `error?`(节点或 `(error, retry) => ReactNode`) `retries?` `timeout?` `getContext?` |
458
+ | 工厂选项 | `loadingComponent?` `errorComponent?`(收到 `error` prop,完全接管) `retries?`(0–10 整数) `timeout?`(正有限 ms) `getContext?` `session?` `sessionStorageKey?` | `fallback?`(pending 占位) `error?`(节点或 `(error, retry) => ReactNode`) `retries?` `timeout?` `getContext?` |
458
459
  | 返回组件 props | `appProps: P`(业务数据)+ `sessionKey?: string \| null`(控制参数,不混入业务 props) | 同左,`ComponentType<{ appProps: P; sessionKey?: string \| null }>` |
459
460
  | 泛型 | `createVueBridgeApp<P>(spec, options?)`,P 只约束 `appProps` | 同左 |
460
461
  | spec | 完整 `<remote>/<expose>`,与 `remoteComponent` 同一解析规则;无 remotePrefixes/schema/deriveSpec | 同左 |
@@ -467,12 +468,21 @@ const RemoteVueApp = createReactBridgeApp<P>('vue-remote/bridge', {
467
468
  - **DOM 所有权**:包装组件只创建并保持稳定的空挂载容器;宿主重渲染不 patch 子应用 root 内部。React 宿主 StrictMode 双 effect 安全。Vue `<KeepAlive>` 的 deactivate 不是卸载——缓存页中的子应用保有 root 与状态。
468
469
  - **旧请求不冒充取消**:已进入 `loadRemote` 的工作不因桥接层作废而被取消——迟到的旧结果按代次丢弃;远程 `onSession` 必须遵守 `signal.aborted` 契约。
469
470
 
471
+ ### Vue 自动会话选项
472
+
473
+ | 选项 | 类型 / 默认 | 配置与效果 |
474
+ |---|---|---|
475
+ | `session` | `() => string \| number \| null \| undefined` / 不启用 | createVueBridgeApp 的同步响应式身份 getter;非空标识=登录就绪,null=退出,undefined=恢复中。插件管理代次与AppContext,不能同时传sessionKey prop。 |
476
+ | `sessionStorageKey` | `string` / `fulgurjs-bridge-session` | 自动记录写入此命名空间的 `:auto` 键。同一宿主的远程使用相同命名空间;只在 session 启用时有意义。 |
477
+
478
+ 同身份重进/刷新恢复同代次,身份变化新建代次,token不参与身份判断。身份记录不能包含凭据或敏感资料;localStorage变化必须反映到响应式状态。关闭:省略session;开启:在工厂提供身份getter;自定义:同时提供sessionStorageKey。getContext不需要返回sessionKey;显式矛盾仍拒绝。getter非法返回值/抛错显示MFU-016(getContext),配置类型错误立即抛出TypeError。详见[自动会话](../guide/app-bridge.md)。
479
+
470
480
  ### 宿主侧辅助:`createBridgeSession`(Vue)
471
481
 
472
- `createBridgeSession(options?)`(`/vue`)——把 sessionKey 的**契约语义**(非敏感登录代次、禁用 token 充当、null=登出、同会话刷新不变)收进插件,宿主只决定调用时机:
482
+ `createBridgeSession(options?)`(`/vue`)——把 sessionKey 的**契约语义**(非敏感登录代次、禁用 token 充当、null=登出、同会话刷新不变)收进插件,这是显式控制工具;常规Vue桥接推荐配置工厂 `session` 身份 getter,由插件自动管理,不必调用下方方法:
473
483
 
474
484
  ```ts
475
- // src/fulgurjs/host/session.ts(模块级创建一次)
485
+ // src/fulgurjs/host/context.ts(模块级创建一次)
476
486
  import { createBridgeSession } from '@fulgurjs/federation/vue'
477
487
  export const bridgeSession = createBridgeSession()
478
488
  // 登录成功 → bridgeSession.renew();退出登录 → bridgeSession.clear()
@@ -65,7 +65,7 @@
65
65
  | `MFU-008` | 运行时报未知远程 | spec/调用里的远程名不在 `remotes`/运行时注册表里 | 核对远程名拼写;动态远程先 `registerRemote`/`registerRemotes` |
66
66
  | `MFU-009` | 运行时报加载到的模块没有任何导出 | expose 目标文件没有导出(空模块/只有副作用) | 给 expose 目标文件补导出;确认加载的是预期文件 |
67
67
  | `MFU-010` | 运行时警告选中的共享单例版本不满足某消费方要求(列出候选版本、提供方、影响与修法;同一组合只告警一次) | singleton 收敛到的版本不在某消费方 requiredVersion 内;或桥接宿主/子应用缺 singleton 导致双实例症状(Invalid hook call) | 统一依赖版本;确认告警可接受或调整 requiredVersion;跨框架宿主三键 singleton |
68
- | `MFU-011` | 运行时报 setup 生命周期入口导出形态非法(报实际类型/预期签名/修法) | setup 模块的默认导出或具名 `onSession` 不是函数(其他导出不作为入口) | setup 文件默认导出 `setup(context)` 函数;可选具名导出 `onSession(context)` 函数 |
68
+ | `MFU-011` | 运行时报 setup 生命周期入口导出形态非法(报实际类型/预期签名/修法) | setup模块为空、已有默认导出/onSession不是函数,或组件/Provider声明形态非法 | 默认导出初始化函数,或声明有效onSession/globalComponents/pageProviders;无需空函数,不接受空模块 |
69
69
  | `MFU-012` | 该次 `loadRemote` 拒绝,报 setup/onSession 执行抛错(cause 含原始异常) | 初始化代码自身抛错 | 修复 setup/onSession 内部错误后直接重试——只清失败阶段缓存(setup 失败重试从 setup 开始;onSession 失败只重跑会话段),已成功阶段不重复 |
70
70
  | `MFU-013` | 运行时报远程声明 onSession 但宿主 AppContext 缺 sessionKey | 宿主未提供非敏感登录代次 ID(禁止用 token 充当) | 宿主登录流程 `provideAppContext({ sessionKey })`——每次成功登录/重登生成新值,token 刷新沿用 |
71
71
  | `MFU-014` | 运行时报 setup/onSession 同步段内递归 loadRemote 同一远程 | 初始化同步段内加载同远程模块——该调用会等待自身形成死锁 | 初始化内不要加载同远程模块;跨远程加载放异步段 |
@@ -213,10 +213,9 @@ setup/onSession 收到的上下文.
213
213
 
214
214
  | 字段 | 可省略 | 类型 | 说明 |
215
215
  |---|---|---|---|
216
- | `default` | no | `(ctx: RemoteSetupContext) => void \| Promise<void>` | 见对应 API 合同。 |
216
+ | `default` | yes | `(ctx: RemoteSetupContext) => void \| Promise<void>` | 见对应 API 合同。 |
217
217
  | `onSession` | yes | `(ctx: RemoteSetupContext) => void \| Promise<void>` | 见对应 API 合同。 |
218
218
  | `globalComponents` | yes | `Record<string, unknown>` | 远程暴露面依赖的「宿主全局注册组件」声明(键=组件注册名,值=组件对象或零参 loader): 组件联邦(remoteComponent)把远程组件渲染进消费方 app 上下文,模板里的 字符串标签(如 <a-divider>)按消费方 app 的全局注册表解析——消费方没注册就 渲染成死元素。提供方在此声明后,运行时在每次 loadRemote 时把它们幂等注册到 当次传入的 consumerApp 上;无 consumerApp(无组件上下文的手动加载)时静默跳过。 值推荐「零参 loader(() => import('./X.vue'))」:setup 模块保持零重依赖, 组件只在本框架消费方真实渲染时才加载——Vue 适配器注册时自动包 defineAsyncComponent; 静态组件值仍支持;带 displayName/props/emits 的零参函数保留组件身份,未标记零参函数作 loader。运行时对值原样透传。 |
219
-
220
219
  | `pageProviders` | yes | `unknown[]` | 远程组件所需的祖先 Provider;元素为组件或零参 loader。由组件适配器包裹实际消费树,不复制提供方整个 app。 |
221
220
 
222
221
  ## AppContext
@@ -419,6 +418,9 @@ Vue 宿主桥接的加载与上下文选项.
419
418
  | `retries` | yes | `number` | 透传现行 loadRemote 的重试选项(0-10 整数),不另叠自动重试 |
420
419
  | `timeout` | yes | `number` | 本次桥接加载等待上限 ms;不取消已发出的共享请求,迟到结果一律丢弃 |
421
420
  | `getContext` | yes | `() => Partial<AppContext> & Record<string, unknown>` | 无副作用的同步 getter:首次、重试及换会话的实际加载前返回本次所需上下文快照 |
421
+ | `session` | yes | `() => string \| number \| null \| undefined` | 响应式非敏感身份;插件自动管理代次。null退出、undefined恢复中;不与sessionKey prop并用。 |
422
+ | `sessionStorageKey` | yes | `string` | 自动会话命名空间,默认fulgurjs-bridge-session;同一宿主的远程一致。 |
423
+
422
424
 
423
425
  ## VueBridgeRouterConnection
424
426
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fulgurjs/federation",
3
- "version": "6.11.7",
3
+ "version": "6.12.0",
4
4
  "type": "module",
5
5
  "description": "Vite Module Federation for Vue and React: remote modules, shared dependencies and app bridges.",
6
6
  "license": "MIT",
@@ -85,6 +85,10 @@
85
85
  "./internal/vue-store.js": {
86
86
  "types": "./dist/vue-store.d.ts",
87
87
  "import": "./dist/vue-store.js"
88
+ },
89
+ "./internal/bridge-session-auto.js": {
90
+ "types": "./dist/bridge-session-auto.d.ts",
91
+ "import": "./dist/bridge-session-auto.js"
88
92
  }
89
93
  },
90
94
  "typesVersions": {
@@ -122,7 +126,7 @@
122
126
  "types"
123
127
  ],
124
128
  "scripts": {
125
- "build": "cp ../../README.md README.md && cp ../../README.en.md README.en.md && mkdir -p docs && mkdir -p docs/zh/reference docs/en/reference docs/maintainers && cp ../../docs/zh/reference/api.md ../../docs/zh/reference/errors.md ../../docs/zh/reference/types.md docs/zh/reference/ && cp ../../docs/en/reference/api.md ../../docs/en/reference/errors.md ../../docs/en/reference/types.md docs/en/reference/ && cp ../../docs/maintainers/webpack-mf-对照与缺口.md ../../docs/maintainers/沙箱边界审计.md ../../docs/maintainers/compatibility-testing.md docs/maintainers/ && cp ../../CHANGELOG.md CHANGELOG.md && node scripts/sync-package-examples.mjs && esbuild src/runtime/index.ts --bundle --format=esm --target=es2022 --minify --outfile=dist/runtime.js && node scripts/gen-runtime.mjs && tsup src/index.ts src/pages.ts src/vue-adapter.ts src/react-adapter.ts src/context.ts src/bridge-core.ts src/bridge-errors.ts src/bridge-session.ts src/bridge-app-vue.ts src/bridge-app-react.ts src/vue-store.ts src/bridge-host-vue.ts src/bridge-host-react.ts --format esm,cjs --dts --external vite --external @fulgurjs/federation/internal/registry.js --target node18 --clean && tsup src/runtime-entry.ts --format esm --dts --external vite --external @fulgurjs/federation/internal/registry.js --target node18 && tsup src/vue.ts --format esm --dts --external vite,vue,vue-router,@fulgurjs/federation/internal/registry.js --target node18 && tsup src/react.ts --format esm --dts --external vite,react,react-dom,react-router-dom,@fulgurjs/federation/internal/registry.js --target node18 && tsup src/bridge-router-vue.ts --format esm --dts --external vite,vue,vue-router --target node18 && tsup src/bridge-router-react.tsx --format esm --dts --external vite,react,react-dom,react-router-dom --target node18 && esbuild src/cli.ts --bundle --format=esm --target=node18 --platform=node --outfile=dist/cli.js && esbuild src/runtime/index.ts --bundle --format=esm --target=es2022 --minify --outfile=dist/runtime.js && node scripts/gen-runtime-entry.mjs && node scripts/check-gzip.mjs && node scripts/check-tree-shaking.mjs && node scripts/check-manual-codes.mjs",
129
+ "build": "cp ../../README.md README.md && cp ../../README.en.md README.en.md && mkdir -p docs && mkdir -p docs/zh/reference docs/en/reference docs/maintainers && cp ../../docs/zh/reference/api.md ../../docs/zh/reference/errors.md ../../docs/zh/reference/types.md docs/zh/reference/ && cp ../../docs/en/reference/api.md ../../docs/en/reference/errors.md ../../docs/en/reference/types.md docs/en/reference/ && cp ../../docs/maintainers/webpack-mf-对照与缺口.md ../../docs/maintainers/沙箱边界审计.md ../../docs/maintainers/compatibility-testing.md docs/maintainers/ && cp ../../CHANGELOG.md CHANGELOG.md && node scripts/sync-package-examples.mjs && esbuild src/runtime/index.ts --bundle --format=esm --target=es2022 --minify --outfile=dist/runtime.js && node scripts/gen-runtime.mjs && tsup src/index.ts src/pages.ts src/vue-adapter.ts src/react-adapter.ts src/context.ts src/bridge-core.ts src/bridge-errors.ts src/bridge-session.ts src/bridge-app-vue.ts src/bridge-app-react.ts src/vue-store.ts src/bridge-host-vue.ts src/bridge-host-react.ts src/bridge-session-auto.ts --format esm,cjs --dts --external vite --external @fulgurjs/federation/internal/registry.js --target node18 --clean && tsup src/runtime-entry.ts --format esm --dts --external vite --external @fulgurjs/federation/internal/registry.js --target node18 && tsup src/vue.ts --format esm --dts --external vite,vue,vue-router,@fulgurjs/federation/internal/registry.js --target node18 && tsup src/react.ts --format esm --dts --external vite,react,react-dom,react-router-dom,@fulgurjs/federation/internal/registry.js --target node18 && tsup src/bridge-router-vue.ts --format esm --dts --external vite,vue,vue-router --target node18 && tsup src/bridge-router-react.tsx --format esm --dts --external vite,react,react-dom,react-router-dom --target node18 && esbuild src/cli.ts --bundle --format=esm --target=node18 --platform=node --outfile=dist/cli.js && esbuild src/runtime/index.ts --bundle --format=esm --target=es2022 --minify --outfile=dist/runtime.js && node scripts/gen-runtime-entry.mjs && node scripts/check-gzip.mjs && node scripts/check-tree-shaking.mjs && node scripts/check-manual-codes.mjs",
126
130
  "dev": "tsup --watch",
127
131
  "test": "vitest run --dir tests",
128
132
  "typecheck": "tsc --noEmit",