@fulgurjs/federation 5.3.0 → 5.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,18 @@
1
1
  # Changelog
2
2
 
3
+ ## 5.3.2
4
+
5
+ - **修正:回滚 5.3.1 中「宿主入口 init 注入改为 `import "virtual:fulgurjs-init"`」的实验性变更**——该变更本意是修复 vite 8 生产运行死锁(未成功,vite 8 运行期仍单列 rolldown 上游 BLOCKED),但在大型宿主(jeecg 系,vite 6)生产实测存在破坏地图渲染的风险面。5.3.2 恢复 5.3.0 的「init 代码内联入口模块」形态(原始注释「rollup 会摇树剥离独立模块的顶层调用」仍然成立),其余 5.3.1 修复(同步 CJS-NS 垫片 / BN09 容器封锁 / BN08 getContext 诊断 / publisher 守卫)全部保留。单元 540/540、e2e dev 43 + prod 28 复验通过。
6
+
7
+ ## 5.3.1
8
+
9
+ - **修复:Vite 8(rolldown)下 React 联邦生产构建 REQUIRE_TLA 失败**——React 生态的本体为 CJS(`react-dom/cjs/*` 内部 `require("react")`),插件的 CJS require 重定向此前把目标指向与共享协商门面同体的垫片(`await loadShare(...)` 顶层 await 形态);rolldown 按 Node 语义在构建期拒绝「CJS require 含顶层 await 的模块」(vite 5-7 的 rollup 无此限制,属存量兼容缺口,5.2.5 无桥接工程在 vite8 下同样复现)。现在 CJS 垫片改为**同步形态**:运行时新增 `getLoadedShare` 同步查询(loadShare 成功后缓存实例值,已协商加载的实例优先命中,跨端单例语义与 TLA 版 loadShare 对齐),未就绪时直连本应用本体(与 provide/fallback 同一模块,构建期单份 → 实例恒同)。vite 5.1.8/6.4.3/7.3.6/8.3.1 × {vue,react}×{host,remote} 十六个真实工程构建全部通过;`runtime.js` gzip 8812B(门禁 ≤9216B)。**已知边界(如实声明)**:vite 8.3.1 的桥接/React 生产**页面运行**在本轮仍无法通过挂载验收(rolldown 对「TLA 协商门面 × 动态目标透传重定向 × async chunk 强制拆分」的组合行为导致入口求值死锁,插件层六种分组/时序变体均无法完全规避;dev 全功能正常),归因为 rolldown-vite 上游行为,详见验收报告。
10
+ - **修复:Vue 宿主桥接 unmount 失败后容器未持久封锁(BN09)**——`createVueBridgeApp` 的 `invalidate()` 在契约卸载抛错时仅返回 false,未封锁容器;点击「重试加载」或改变 `sessionKey` 会绕过封锁在清理状态不明的同一容器上重挂(mount 次数增加、状态转 ready)。现在与 React 宿主对齐引入持久封锁标志:封锁后重试与换会话都不再在此容器启动新实例,默认错误占位移除「重试加载」按钮(只保留「刷新页面重试」),`bridgeLifecycleError` 的 unmount 修法文案明确「插件已持久封锁该容器,只能整页刷新恢复」。新增回归:A→B unmount 抛错后 mount 次数恒定、封锁后占位无重试按钮、换会话不绕过封锁、正常卸载后重挂仍可用。
11
+ - **修复:getContext 返回 null/undefined 时错误码丢失(BN08)**——`resolveBridgeContext` 已判定快照非法,但构造诊断消息时再次访问 `snapshot.then`,对 null/undefined 抛出普通 `TypeError`(`Cannot read properties of null (reading 'then')`),约定的 `MFU-016 phase: getContext` 丢失。现在诊断分支安全描述实际返回值(null/undefined/原始值/Promise/thenable 四类各有明确中文说明与修法),并新增四类返回值的回归断言(含"不抛 TypeError")。
12
+ - **修复:宿主未装 @vitejs/plugin-react 时被注入失效的 react-refresh 探针(5.2.0 起回归)**——dev 下 `transformIndexHtml` 的 publisher 注入条件只检查「remotes 中存在 http dev 远程」,纯 Vue 宿主(remotes 全是 Vue 远程)也会被注入 `import "http://<Vue 远程>/@react-refresh"`,而 Vue 远程无 plugin-react 中间件,每页一条 404 console error(host-vue fixtures 实测,破坏 B-16 等用例的零 console 断言)。现在注入前增加「宿主 shared 含 react/react-dom(确有消费 React 模块的意图)」判定;桥接宿主(shared 三键 singleton)不受影响。
13
+ - **改善:loadShare 成功后缓存实例值(`ShareEntry.value`)**,供 CJS 垫片同步查询与未来同步消费通道使用;`getLoadedShare` 为内部 API,不进入公开入口导出面。
14
+ - 新增回归测试 5 个(单测 535 → 540);e2e dev 43 例 / prod 28 例全绿;MES 真实项目回归与 Vite 矩阵详见验收报告(`docs/跨框架桥接实施验收报告-20261001.md` 补录节)。
15
+
3
16
  ## 5.3.0
4
17
 
5
18
  - **新增:跨框架桥接 `/bridge` —— 子应用级 Vue↔React 双向互嵌**(README §8.2;实现合同见 `docs/跨框架桥接实施任务书-20260929.md`)
package/README.en.md CHANGED
@@ -301,7 +301,7 @@ export default defineBridgeApp((props) => <MemoryRouter><App {...props} /></Memo
301
301
 
302
302
  Contract semantics (`BridgeApp`):
303
303
  - `mount(el, props?): void | Promise<void>` — returning `void` means the first root commit completed synchronously (Vue); a Promise keeps the host pending until the first root commit completes (React uses a built-in commit probe; `root.render()` returning does **not** count as success). Failure before the first commit must throw/reject (host turns it into `MFU-016`, `details.phase: 'mount'`) after cleaning up any created root.
304
- - `unmount(el): void` — synchronously invalidates the current generation for that container and cleans up; unknown containers are a no-op. Unmounting while pending immediately invalidates the in-flight generation: late results must not revive DOM, overwrite host state, or produce unhandled rejections. An `unmount` throw is reported as `MFU-016` (`phase: 'unmount'`); the container's cleanup state is uncertain and must not be reused for a new root directly.
304
+ - `unmount(el): void` — synchronously invalidates the current generation for that container and cleans up; unknown containers are a no-op. Unmounting while pending immediately invalidates the in-flight generation: late results must not revive DOM, overwrite host state, or produce unhandled rejections. An `unmount` throw is reported as `MFU-016` (`phase: 'unmount'`); the container's cleanup state is uncertain, and the plugin **permanently blocks that container**: neither the in-page retry nor a session change will mount a new instance there (the default placeholder removes its retry button), so a full page reload is the only recovery; audit leftover resources (subscriptions/timers/global side effects) honestly.
305
305
  - Contract instances are keyed **per container element**; double-mount on the same container is rejected (`MFU-016`).
306
306
  - Errors inside the sub-app after the first commit belong to **the sub-app's own error boundary** — host boundaries cannot catch cross-root render errors.
307
307
 
package/README.md CHANGED
@@ -819,7 +819,7 @@ export default defineBridgeApp((props) => (
819
819
  契约语义(`BridgeApp` 接口,双方入口共享同一类型定义):
820
820
 
821
821
  - `mount(el, props?): void | Promise<void>`——返回 `void` 表示首次根提交已同步完成(Vue 同步 mount);返回 Promise 时宿主保持 pending 直到首次根提交后完成(React 由契约内建提交探针兑现,`root.render()` 返回**不**算成功)。首次提交前的失败必须抛错/拒绝(宿主转 `MFU-016`,`details.phase: 'mount'`)并清理已创建的 app/root。
822
- - `unmount(el): void`——同步使该容器代次失效并清理;未知容器为 no-op。pending 时卸载立即作废本轮代次,迟到的成功/失败不得复活 DOM、改写宿主状态或产生未处理拒绝。unmount 抛错由宿主捕获报 `MFU-016`(`phase: 'unmount'`),该容器清理状态不确定,不得直接在同一 el 上再挂新实例。
822
+ - `unmount(el): void`——同步使该容器代次失效并清理;未知容器为 no-op。pending 时卸载立即作废本轮代次,迟到的成功/失败不得复活 DOM、改写宿主状态或产生未处理拒绝。unmount 抛错由宿主捕获报 `MFU-016`(`phase: 'unmount'`),该容器清理状态不确定,插件会**持久封锁该容器**:同页「重试加载」与换会话都不会在此容器重新挂载(默认占位随之移除「重试加载」按钮),只能整页刷新恢复;残留资源(事件订阅/定时器/全局副作用)请如实排查。
823
823
  - 契约实例**按容器 el 分键**:同一契约多处挂载互不干扰;同一容器未卸载再次 mount 拒绝(`MFU-016`,容器已被占用)且不覆盖原实例。
824
824
  - 首次根提交后的子应用内部错误由**子应用自己的错误边界**负责——宿主 ErrorBoundary/errorCaptured 捕不到跨 root 的渲染错误,插件不冒充兜底(§4.4 语义,README 不承诺「宿主兜底子应用一切错误」)。
825
825
 
@@ -61,7 +61,7 @@ function bridgeLifecycleError(phase, spec, cause, extra) {
61
61
  const fixes = {
62
62
  getContext: "\u4FEE\u6CD5: \u2460 getContext \u5FC5\u987B\u662F\u540C\u6B65\u3001\u65E0\u526F\u4F5C\u7528\u7684 getter\uFF08\u4E0D\u5F97\u8FD4\u56DE Promise/thenable\uFF09\uFF1B\n \u2461 \u8FD4\u56DE\u503C\u987B\u662F\u5305\u542B\u672C\u6B21\u4F1A\u8BDD\u5FEB\u7167\u7684\u5BF9\u8C61\uFF08\u53D7\u63A7 sessionKey \u65F6\u987B\u542B\u76F8\u540C sessionKey\uFF09\uFF1B\n \u2462 \u5F02\u6B65\u83B7\u53D6\u7528\u6237\u8D44\u6599\u8BF7\u5728\u5BBF\u4E3B\u5B8C\u6210\u540E\u518D\u8BA9\u6865\u63A5\u7EC4\u4EF6\u8FDB\u5165\u53EF\u6302\u8F7D\u72B6\u6001\u3002",
63
63
  mount: "\u4FEE\u6CD5: \u2460 \u67E5\u770B\u6839\u56E0\u4E2D\u5B50\u5E94\u7528 mount \u7684\u539F\u59CB\u9519\u8BEF\uFF08\u5DE5\u5382\u629B\u9519\u6216\u9996\u6B21\u6E32\u67D3\u5931\u8D25\uFF09\uFF1B\n \u2461 \u540C\u4E00\u5BB9\u5668\u672A\u5378\u8F7D\u524D\u91CD\u590D mount \u662F\u5951\u7EA6\u8FDD\u4F8B\u2014\u2014\u5148 unmount \u518D mount\uFF1B\n \u2462 \u4FEE\u590D\u540E\u70B9\u51FB\u300C\u91CD\u8BD5\u52A0\u8F7D\u300D\u5728\u540C\u9875\u91CD\u5EFA\u6302\u8F7D\u3002",
64
- unmount: "\u4FEE\u6CD5: \u2460 \u6839\u56E0\u6765\u81EA\u5B50\u5E94\u7528 unmount \u5B9E\u73B0\uFF08app.unmount/root.unmount \u629B\u9519\uFF09\uFF1B\n \u2461 \u8BE5\u5BB9\u5668\u6E05\u7406\u72B6\u6001\u4E0D\u786E\u5B9A\u2014\u2014\u4E0D\u8981\u76F4\u63A5\u5728\u540C\u4E00 el \u4E0A\u542F\u52A8\u65B0\u5B9E\u4F8B\uFF1B\n \u2462 \u5237\u65B0\u9875\u9762\u53EF\u5F7B\u5E95\u6E05\u7406\uFF0C\u6B8B\u7559\u8D44\u6E90\u8BF7\u5982\u5B9E\u6392\u67E5\uFF08\u4E8B\u4EF6\u8BA2\u9605/\u5B9A\u65F6\u5668/\u5168\u5C40\u526F\u4F5C\u7528\uFF09\u3002"
64
+ unmount: "\u4FEE\u6CD5: \u2460 \u6839\u56E0\u6765\u81EA\u5B50\u5E94\u7528 unmount \u5B9E\u73B0\uFF08app.unmount/root.unmount \u629B\u9519\uFF09\uFF1B\n \u2461 \u8BE5\u5BB9\u5668\u6E05\u7406\u72B6\u6001\u4E0D\u786E\u5B9A\uFF0C\u63D2\u4EF6\u5DF2\u6301\u4E45\u5C01\u9501\u8BE5\u5BB9\u5668\u2014\u2014\u540C\u9875\u300C\u91CD\u8BD5\u52A0\u8F7D\u300D\u4E0E\n \u6362\u4F1A\u8BDD\u90FD\u4E0D\u4F1A\u5728\u6B64\u5BB9\u5668\u91CD\u65B0\u6302\u8F7D\uFF1B\n \u2462 \u53EA\u80FD\u6574\u9875\u5237\u65B0\u6062\u590D\uFF08\u300C\u5237\u65B0\u9875\u9762\u91CD\u8BD5\u300D\uFF09\uFF1B\u6B8B\u7559\u8D44\u6E90\uFF08\u4E8B\u4EF6\u8BA2\u9605/\u5B9A\u65F6\u5668/\u5168\u5C40\u526F\u4F5C\u7528\uFF09\u8BF7\u5982\u5B9E\u6392\u67E5\u3002"
65
65
  };
66
66
  return new FgError(
67
67
  BridgeErrorCodes.BRIDGE_LIFECYCLE_FAILED,
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  bridgeLifecycleError
3
- } from "./chunk-E55P4TIY.js";
3
+ } from "./chunk-DH2QMM4Y.js";
4
4
  import "./chunk-OF2JCXTZ.js";
5
5
 
6
6
  // src/bridge-app-react.ts
@@ -50,7 +50,7 @@ function bridgeLifecycleError(phase, spec, cause, extra) {
50
50
  const fixes = {
51
51
  getContext: "\u4FEE\u6CD5: \u2460 getContext \u5FC5\u987B\u662F\u540C\u6B65\u3001\u65E0\u526F\u4F5C\u7528\u7684 getter\uFF08\u4E0D\u5F97\u8FD4\u56DE Promise/thenable\uFF09\uFF1B\n \u2461 \u8FD4\u56DE\u503C\u987B\u662F\u5305\u542B\u672C\u6B21\u4F1A\u8BDD\u5FEB\u7167\u7684\u5BF9\u8C61\uFF08\u53D7\u63A7 sessionKey \u65F6\u987B\u542B\u76F8\u540C sessionKey\uFF09\uFF1B\n \u2462 \u5F02\u6B65\u83B7\u53D6\u7528\u6237\u8D44\u6599\u8BF7\u5728\u5BBF\u4E3B\u5B8C\u6210\u540E\u518D\u8BA9\u6865\u63A5\u7EC4\u4EF6\u8FDB\u5165\u53EF\u6302\u8F7D\u72B6\u6001\u3002",
52
52
  mount: "\u4FEE\u6CD5: \u2460 \u67E5\u770B\u6839\u56E0\u4E2D\u5B50\u5E94\u7528 mount \u7684\u539F\u59CB\u9519\u8BEF\uFF08\u5DE5\u5382\u629B\u9519\u6216\u9996\u6B21\u6E32\u67D3\u5931\u8D25\uFF09\uFF1B\n \u2461 \u540C\u4E00\u5BB9\u5668\u672A\u5378\u8F7D\u524D\u91CD\u590D mount \u662F\u5951\u7EA6\u8FDD\u4F8B\u2014\u2014\u5148 unmount \u518D mount\uFF1B\n \u2462 \u4FEE\u590D\u540E\u70B9\u51FB\u300C\u91CD\u8BD5\u52A0\u8F7D\u300D\u5728\u540C\u9875\u91CD\u5EFA\u6302\u8F7D\u3002",
53
- unmount: "\u4FEE\u6CD5: \u2460 \u6839\u56E0\u6765\u81EA\u5B50\u5E94\u7528 unmount \u5B9E\u73B0\uFF08app.unmount/root.unmount \u629B\u9519\uFF09\uFF1B\n \u2461 \u8BE5\u5BB9\u5668\u6E05\u7406\u72B6\u6001\u4E0D\u786E\u5B9A\u2014\u2014\u4E0D\u8981\u76F4\u63A5\u5728\u540C\u4E00 el \u4E0A\u542F\u52A8\u65B0\u5B9E\u4F8B\uFF1B\n \u2462 \u5237\u65B0\u9875\u9762\u53EF\u5F7B\u5E95\u6E05\u7406\uFF0C\u6B8B\u7559\u8D44\u6E90\u8BF7\u5982\u5B9E\u6392\u67E5\uFF08\u4E8B\u4EF6\u8BA2\u9605/\u5B9A\u65F6\u5668/\u5168\u5C40\u526F\u4F5C\u7528\uFF09\u3002"
53
+ unmount: "\u4FEE\u6CD5: \u2460 \u6839\u56E0\u6765\u81EA\u5B50\u5E94\u7528 unmount \u5B9E\u73B0\uFF08app.unmount/root.unmount \u629B\u9519\uFF09\uFF1B\n \u2461 \u8BE5\u5BB9\u5668\u6E05\u7406\u72B6\u6001\u4E0D\u786E\u5B9A\uFF0C\u63D2\u4EF6\u5DF2\u6301\u4E45\u5C01\u9501\u8BE5\u5BB9\u5668\u2014\u2014\u540C\u9875\u300C\u91CD\u8BD5\u52A0\u8F7D\u300D\u4E0E\n \u6362\u4F1A\u8BDD\u90FD\u4E0D\u4F1A\u5728\u6B64\u5BB9\u5668\u91CD\u65B0\u6302\u8F7D\uFF1B\n \u2462 \u53EA\u80FD\u6574\u9875\u5237\u65B0\u6062\u590D\uFF08\u300C\u5237\u65B0\u9875\u9762\u91CD\u8BD5\u300D\uFF09\uFF1B\u6B8B\u7559\u8D44\u6E90\uFF08\u4E8B\u4EF6\u8BA2\u9605/\u5B9A\u65F6\u5668/\u5168\u5C40\u526F\u4F5C\u7528\uFF09\u8BF7\u5982\u5B9E\u6392\u67E5\u3002"
54
54
  };
55
55
  return new FgError(
56
56
  BridgeErrorCodes.BRIDGE_LIFECYCLE_FAILED,
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  bridgeLifecycleError
3
- } from "./chunk-E55P4TIY.js";
3
+ } from "./chunk-DH2QMM4Y.js";
4
4
  import "./chunk-OF2JCXTZ.js";
5
5
 
6
6
  // src/bridge-app-vue.ts
@@ -83,7 +83,7 @@ function bridgeLifecycleError(phase, spec, cause, extra) {
83
83
  const fixes = {
84
84
  getContext: "\u4FEE\u6CD5: \u2460 getContext \u5FC5\u987B\u662F\u540C\u6B65\u3001\u65E0\u526F\u4F5C\u7528\u7684 getter\uFF08\u4E0D\u5F97\u8FD4\u56DE Promise/thenable\uFF09\uFF1B\n \u2461 \u8FD4\u56DE\u503C\u987B\u662F\u5305\u542B\u672C\u6B21\u4F1A\u8BDD\u5FEB\u7167\u7684\u5BF9\u8C61\uFF08\u53D7\u63A7 sessionKey \u65F6\u987B\u542B\u76F8\u540C sessionKey\uFF09\uFF1B\n \u2462 \u5F02\u6B65\u83B7\u53D6\u7528\u6237\u8D44\u6599\u8BF7\u5728\u5BBF\u4E3B\u5B8C\u6210\u540E\u518D\u8BA9\u6865\u63A5\u7EC4\u4EF6\u8FDB\u5165\u53EF\u6302\u8F7D\u72B6\u6001\u3002",
85
85
  mount: "\u4FEE\u6CD5: \u2460 \u67E5\u770B\u6839\u56E0\u4E2D\u5B50\u5E94\u7528 mount \u7684\u539F\u59CB\u9519\u8BEF\uFF08\u5DE5\u5382\u629B\u9519\u6216\u9996\u6B21\u6E32\u67D3\u5931\u8D25\uFF09\uFF1B\n \u2461 \u540C\u4E00\u5BB9\u5668\u672A\u5378\u8F7D\u524D\u91CD\u590D mount \u662F\u5951\u7EA6\u8FDD\u4F8B\u2014\u2014\u5148 unmount \u518D mount\uFF1B\n \u2462 \u4FEE\u590D\u540E\u70B9\u51FB\u300C\u91CD\u8BD5\u52A0\u8F7D\u300D\u5728\u540C\u9875\u91CD\u5EFA\u6302\u8F7D\u3002",
86
- unmount: "\u4FEE\u6CD5: \u2460 \u6839\u56E0\u6765\u81EA\u5B50\u5E94\u7528 unmount \u5B9E\u73B0\uFF08app.unmount/root.unmount \u629B\u9519\uFF09\uFF1B\n \u2461 \u8BE5\u5BB9\u5668\u6E05\u7406\u72B6\u6001\u4E0D\u786E\u5B9A\u2014\u2014\u4E0D\u8981\u76F4\u63A5\u5728\u540C\u4E00 el \u4E0A\u542F\u52A8\u65B0\u5B9E\u4F8B\uFF1B\n \u2462 \u5237\u65B0\u9875\u9762\u53EF\u5F7B\u5E95\u6E05\u7406\uFF0C\u6B8B\u7559\u8D44\u6E90\u8BF7\u5982\u5B9E\u6392\u67E5\uFF08\u4E8B\u4EF6\u8BA2\u9605/\u5B9A\u65F6\u5668/\u5168\u5C40\u526F\u4F5C\u7528\uFF09\u3002"
86
+ unmount: "\u4FEE\u6CD5: \u2460 \u6839\u56E0\u6765\u81EA\u5B50\u5E94\u7528 unmount \u5B9E\u73B0\uFF08app.unmount/root.unmount \u629B\u9519\uFF09\uFF1B\n \u2461 \u8BE5\u5BB9\u5668\u6E05\u7406\u72B6\u6001\u4E0D\u786E\u5B9A\uFF0C\u63D2\u4EF6\u5DF2\u6301\u4E45\u5C01\u9501\u8BE5\u5BB9\u5668\u2014\u2014\u540C\u9875\u300C\u91CD\u8BD5\u52A0\u8F7D\u300D\u4E0E\n \u6362\u4F1A\u8BDD\u90FD\u4E0D\u4F1A\u5728\u6B64\u5BB9\u5668\u91CD\u65B0\u6302\u8F7D\uFF1B\n \u2462 \u53EA\u80FD\u6574\u9875\u5237\u65B0\u6062\u590D\uFF08\u300C\u5237\u65B0\u9875\u9762\u91CD\u8BD5\u300D\uFF09\uFF1B\u6B8B\u7559\u8D44\u6E90\uFF08\u4E8B\u4EF6\u8BA2\u9605/\u5B9A\u65F6\u5668/\u5168\u5C40\u526F\u4F5C\u7528\uFF09\u8BF7\u5982\u5B9E\u6392\u67E5\u3002"
87
87
  };
88
88
  return new FgError(
89
89
  BridgeErrorCodes.BRIDGE_LIFECYCLE_FAILED,
@@ -149,11 +149,7 @@ function resolveBridgeContext(spec, controlled, getContext) {
149
149
  throw bridgeLifecycleError("getContext", spec, e);
150
150
  }
151
151
  if (snapshot === null || typeof snapshot !== "object" || typeof snapshot.then === "function") {
152
- throw bridgeLifecycleError(
153
- "getContext",
154
- spec,
155
- `getContext \u8FD4\u56DE\u4E86${typeof snapshot.then === "function" ? " Promise/thenable" : "\u975E\u5BF9\u8C61\u503C\uFF08" + typeof snapshot + "\uFF09"}\uFF1B\u5B83\u5FC5\u987B\u662F\u540C\u6B65\u8FD4\u56DE\u5FEB\u7167\u5BF9\u8C61\u7684\u7EAF getter\u3002`
156
- );
152
+ throw bridgeLifecycleError("getContext", spec, describeContextValue(snapshot));
157
153
  }
158
154
  if (controlled !== void 0 && snapshot.sessionKey !== controlled) {
159
155
  throw bridgeSessionMismatchError(spec, controlled, snapshot.sessionKey, { reason: "getter-snapshot" });
@@ -176,6 +172,18 @@ function currentSessionKey() {
176
172
  const sk = (globalThis.__FULGURJS_APP_CONFIG__ ?? {}).sessionKey;
177
173
  return typeof sk === "string" && sk !== "" ? sk : void 0;
178
174
  }
175
+ function describeContextValue(snapshot) {
176
+ if (snapshot === null) {
177
+ return "getContext \u8FD4\u56DE\u4E86 null\u3002\u5B83\u5FC5\u987B\u662F\u540C\u6B65\u8FD4\u56DE\u5FEB\u7167\u5BF9\u8C61\u7684\u7EAF getter\uFF1A\u8FD4\u56DE\u503C\u5E94\u4E3A\u5305\u542B\u672C\u6B21\u4F1A\u8BDD\u5FEB\u7167\u7684\u5BF9\u8C61\uFF08\u53D7\u63A7 sessionKey \u65F6\u987B\u542B\u76F8\u540C sessionKey\uFF09\uFF0C\u4E0D\u80FD\u8FD4\u56DE null\u3002";
178
+ }
179
+ if (snapshot === void 0) {
180
+ return "getContext \u8FD4\u56DE\u4E86 undefined\u3002\u5B83\u5FC5\u987B\u662F\u540C\u6B65\u8FD4\u56DE\u5FEB\u7167\u5BF9\u8C61\u7684\u7EAF getter\uFF1A\u8FD4\u56DE\u503C\u5E94\u4E3A\u5305\u542B\u672C\u6B21\u4F1A\u8BDD\u5FEB\u7167\u7684\u5BF9\u8C61\uFF0C\u8BF7\u68C0\u67E5 getter \u662F\u5426\u6F0F\u5199 return \u6216\u8FD4\u56DE\u4E86\u672A\u521D\u59CB\u5316\u7684\u53D8\u91CF\u3002";
181
+ }
182
+ if (typeof snapshot.then === "function") {
183
+ return "getContext \u8FD4\u56DE\u4E86 Promise/thenable\u3002\u5B83\u5FC5\u987B\u662F\u540C\u6B65 getter\uFF0C\u4E0D\u5F97\u8FD4\u56DE Promise\uFF1A\u5F02\u6B65\u83B7\u53D6\u7528\u6237\u8D44\u6599\u8BF7\u5728\u5BBF\u4E3B\u5B8C\u6210\u540E\u518D\u8BA9\u6865\u63A5\u7EC4\u4EF6\u8FDB\u5165\u53EF\u6302\u8F7D\u72B6\u6001\u3002";
184
+ }
185
+ return `getContext \u8FD4\u56DE\u4E86\u975E\u5BF9\u8C61\u503C\uFF08${typeof snapshot}\uFF1A"${String(snapshot)}"\uFF09\u3002\u5B83\u5FC5\u987B\u662F\u540C\u6B65\u8FD4\u56DE\u5FEB\u7167\u5BF9\u8C61\u7684\u7EAF getter\uFF0C\u8FD4\u56DE\u503C\u5E94\u4E3A\u5BF9\u8C61\u800C\u4E0D\u662F\u539F\u59CB\u503C\u3002`;
186
+ }
179
187
  function assertControlledSessionKey(spec, value) {
180
188
  if (value === void 0 || value === null) return;
181
189
  if (typeof value === "string" && value !== "") return;
@@ -6,8 +6,8 @@ import {
6
6
  releaseBridgeSession,
7
7
  resolveBridgeContext,
8
8
  withBridgeTimeout
9
- } from "./chunk-LWJBHUJQ.js";
10
- import "./chunk-E55P4TIY.js";
9
+ } from "./chunk-LE2G23E7.js";
10
+ import "./chunk-DH2QMM4Y.js";
11
11
  import "./chunk-TSYLDY6H.js";
12
12
  import "./chunk-OF2JCXTZ.js";
13
13
  export {
@@ -70,7 +70,7 @@ function bridgeLifecycleError(phase, spec, cause, extra) {
70
70
  const fixes = {
71
71
  getContext: "\u4FEE\u6CD5: \u2460 getContext \u5FC5\u987B\u662F\u540C\u6B65\u3001\u65E0\u526F\u4F5C\u7528\u7684 getter\uFF08\u4E0D\u5F97\u8FD4\u56DE Promise/thenable\uFF09\uFF1B\n \u2461 \u8FD4\u56DE\u503C\u987B\u662F\u5305\u542B\u672C\u6B21\u4F1A\u8BDD\u5FEB\u7167\u7684\u5BF9\u8C61\uFF08\u53D7\u63A7 sessionKey \u65F6\u987B\u542B\u76F8\u540C sessionKey\uFF09\uFF1B\n \u2462 \u5F02\u6B65\u83B7\u53D6\u7528\u6237\u8D44\u6599\u8BF7\u5728\u5BBF\u4E3B\u5B8C\u6210\u540E\u518D\u8BA9\u6865\u63A5\u7EC4\u4EF6\u8FDB\u5165\u53EF\u6302\u8F7D\u72B6\u6001\u3002",
72
72
  mount: "\u4FEE\u6CD5: \u2460 \u67E5\u770B\u6839\u56E0\u4E2D\u5B50\u5E94\u7528 mount \u7684\u539F\u59CB\u9519\u8BEF\uFF08\u5DE5\u5382\u629B\u9519\u6216\u9996\u6B21\u6E32\u67D3\u5931\u8D25\uFF09\uFF1B\n \u2461 \u540C\u4E00\u5BB9\u5668\u672A\u5378\u8F7D\u524D\u91CD\u590D mount \u662F\u5951\u7EA6\u8FDD\u4F8B\u2014\u2014\u5148 unmount \u518D mount\uFF1B\n \u2462 \u4FEE\u590D\u540E\u70B9\u51FB\u300C\u91CD\u8BD5\u52A0\u8F7D\u300D\u5728\u540C\u9875\u91CD\u5EFA\u6302\u8F7D\u3002",
73
- unmount: "\u4FEE\u6CD5: \u2460 \u6839\u56E0\u6765\u81EA\u5B50\u5E94\u7528 unmount \u5B9E\u73B0\uFF08app.unmount/root.unmount \u629B\u9519\uFF09\uFF1B\n \u2461 \u8BE5\u5BB9\u5668\u6E05\u7406\u72B6\u6001\u4E0D\u786E\u5B9A\u2014\u2014\u4E0D\u8981\u76F4\u63A5\u5728\u540C\u4E00 el \u4E0A\u542F\u52A8\u65B0\u5B9E\u4F8B\uFF1B\n \u2462 \u5237\u65B0\u9875\u9762\u53EF\u5F7B\u5E95\u6E05\u7406\uFF0C\u6B8B\u7559\u8D44\u6E90\u8BF7\u5982\u5B9E\u6392\u67E5\uFF08\u4E8B\u4EF6\u8BA2\u9605/\u5B9A\u65F6\u5668/\u5168\u5C40\u526F\u4F5C\u7528\uFF09\u3002"
73
+ unmount: "\u4FEE\u6CD5: \u2460 \u6839\u56E0\u6765\u81EA\u5B50\u5E94\u7528 unmount \u5B9E\u73B0\uFF08app.unmount/root.unmount \u629B\u9519\uFF09\uFF1B\n \u2461 \u8BE5\u5BB9\u5668\u6E05\u7406\u72B6\u6001\u4E0D\u786E\u5B9A\uFF0C\u63D2\u4EF6\u5DF2\u6301\u4E45\u5C01\u9501\u8BE5\u5BB9\u5668\u2014\u2014\u540C\u9875\u300C\u91CD\u8BD5\u52A0\u8F7D\u300D\u4E0E\n \u6362\u4F1A\u8BDD\u90FD\u4E0D\u4F1A\u5728\u6B64\u5BB9\u5668\u91CD\u65B0\u6302\u8F7D\uFF1B\n \u2462 \u53EA\u80FD\u6574\u9875\u5237\u65B0\u6062\u590D\uFF08\u300C\u5237\u65B0\u9875\u9762\u91CD\u8BD5\u300D\uFF09\uFF1B\u6B8B\u7559\u8D44\u6E90\uFF08\u4E8B\u4EF6\u8BA2\u9605/\u5B9A\u65F6\u5668/\u5168\u5C40\u526F\u4F5C\u7528\uFF09\u8BF7\u5982\u5B9E\u6392\u67E5\u3002"
74
74
  };
75
75
  return new FgError(
76
76
  BridgeErrorCodes.BRIDGE_LIFECYCLE_FAILED,
@@ -4,7 +4,7 @@ import {
4
4
  bridgeSessionMismatchError,
5
5
  invalidBridgeContractError,
6
6
  invalidSessionKeyError
7
- } from "./chunk-E55P4TIY.js";
7
+ } from "./chunk-DH2QMM4Y.js";
8
8
  import "./chunk-OF2JCXTZ.js";
9
9
  export {
10
10
  BridgeErrorCodes,
@@ -100,7 +100,7 @@ function bridgeLifecycleError(phase, spec, cause, extra) {
100
100
  const fixes = {
101
101
  getContext: "\u4FEE\u6CD5: \u2460 getContext \u5FC5\u987B\u662F\u540C\u6B65\u3001\u65E0\u526F\u4F5C\u7528\u7684 getter\uFF08\u4E0D\u5F97\u8FD4\u56DE Promise/thenable\uFF09\uFF1B\n \u2461 \u8FD4\u56DE\u503C\u987B\u662F\u5305\u542B\u672C\u6B21\u4F1A\u8BDD\u5FEB\u7167\u7684\u5BF9\u8C61\uFF08\u53D7\u63A7 sessionKey \u65F6\u987B\u542B\u76F8\u540C sessionKey\uFF09\uFF1B\n \u2462 \u5F02\u6B65\u83B7\u53D6\u7528\u6237\u8D44\u6599\u8BF7\u5728\u5BBF\u4E3B\u5B8C\u6210\u540E\u518D\u8BA9\u6865\u63A5\u7EC4\u4EF6\u8FDB\u5165\u53EF\u6302\u8F7D\u72B6\u6001\u3002",
102
102
  mount: "\u4FEE\u6CD5: \u2460 \u67E5\u770B\u6839\u56E0\u4E2D\u5B50\u5E94\u7528 mount \u7684\u539F\u59CB\u9519\u8BEF\uFF08\u5DE5\u5382\u629B\u9519\u6216\u9996\u6B21\u6E32\u67D3\u5931\u8D25\uFF09\uFF1B\n \u2461 \u540C\u4E00\u5BB9\u5668\u672A\u5378\u8F7D\u524D\u91CD\u590D mount \u662F\u5951\u7EA6\u8FDD\u4F8B\u2014\u2014\u5148 unmount \u518D mount\uFF1B\n \u2462 \u4FEE\u590D\u540E\u70B9\u51FB\u300C\u91CD\u8BD5\u52A0\u8F7D\u300D\u5728\u540C\u9875\u91CD\u5EFA\u6302\u8F7D\u3002",
103
- unmount: "\u4FEE\u6CD5: \u2460 \u6839\u56E0\u6765\u81EA\u5B50\u5E94\u7528 unmount \u5B9E\u73B0\uFF08app.unmount/root.unmount \u629B\u9519\uFF09\uFF1B\n \u2461 \u8BE5\u5BB9\u5668\u6E05\u7406\u72B6\u6001\u4E0D\u786E\u5B9A\u2014\u2014\u4E0D\u8981\u76F4\u63A5\u5728\u540C\u4E00 el \u4E0A\u542F\u52A8\u65B0\u5B9E\u4F8B\uFF1B\n \u2462 \u5237\u65B0\u9875\u9762\u53EF\u5F7B\u5E95\u6E05\u7406\uFF0C\u6B8B\u7559\u8D44\u6E90\u8BF7\u5982\u5B9E\u6392\u67E5\uFF08\u4E8B\u4EF6\u8BA2\u9605/\u5B9A\u65F6\u5668/\u5168\u5C40\u526F\u4F5C\u7528\uFF09\u3002"
103
+ unmount: "\u4FEE\u6CD5: \u2460 \u6839\u56E0\u6765\u81EA\u5B50\u5E94\u7528 unmount \u5B9E\u73B0\uFF08app.unmount/root.unmount \u629B\u9519\uFF09\uFF1B\n \u2461 \u8BE5\u5BB9\u5668\u6E05\u7406\u72B6\u6001\u4E0D\u786E\u5B9A\uFF0C\u63D2\u4EF6\u5DF2\u6301\u4E45\u5C01\u9501\u8BE5\u5BB9\u5668\u2014\u2014\u540C\u9875\u300C\u91CD\u8BD5\u52A0\u8F7D\u300D\u4E0E\n \u6362\u4F1A\u8BDD\u90FD\u4E0D\u4F1A\u5728\u6B64\u5BB9\u5668\u91CD\u65B0\u6302\u8F7D\uFF1B\n \u2462 \u53EA\u80FD\u6574\u9875\u5237\u65B0\u6062\u590D\uFF08\u300C\u5237\u65B0\u9875\u9762\u91CD\u8BD5\u300D\uFF09\uFF1B\u6B8B\u7559\u8D44\u6E90\uFF08\u4E8B\u4EF6\u8BA2\u9605/\u5B9A\u65F6\u5668/\u5168\u5C40\u526F\u4F5C\u7528\uFF09\u8BF7\u5982\u5B9E\u6392\u67E5\u3002"
104
104
  };
105
105
  return new FgError(
106
106
  BridgeErrorCodes.BRIDGE_LIFECYCLE_FAILED,
@@ -166,11 +166,7 @@ function resolveBridgeContext(spec, controlled, getContext) {
166
166
  throw bridgeLifecycleError("getContext", spec, e);
167
167
  }
168
168
  if (snapshot === null || typeof snapshot !== "object" || typeof snapshot.then === "function") {
169
- throw bridgeLifecycleError(
170
- "getContext",
171
- spec,
172
- `getContext \u8FD4\u56DE\u4E86${typeof snapshot.then === "function" ? " Promise/thenable" : "\u975E\u5BF9\u8C61\u503C\uFF08" + typeof snapshot + "\uFF09"}\uFF1B\u5B83\u5FC5\u987B\u662F\u540C\u6B65\u8FD4\u56DE\u5FEB\u7167\u5BF9\u8C61\u7684\u7EAF getter\u3002`
173
- );
169
+ throw bridgeLifecycleError("getContext", spec, describeContextValue(snapshot));
174
170
  }
175
171
  if (controlled !== void 0 && snapshot.sessionKey !== controlled) {
176
172
  throw bridgeSessionMismatchError(spec, controlled, snapshot.sessionKey, { reason: "getter-snapshot" });
@@ -193,6 +189,18 @@ function currentSessionKey() {
193
189
  const sk = (globalThis.__FULGURJS_APP_CONFIG__ ?? {}).sessionKey;
194
190
  return typeof sk === "string" && sk !== "" ? sk : void 0;
195
191
  }
192
+ function describeContextValue(snapshot) {
193
+ if (snapshot === null) {
194
+ return "getContext \u8FD4\u56DE\u4E86 null\u3002\u5B83\u5FC5\u987B\u662F\u540C\u6B65\u8FD4\u56DE\u5FEB\u7167\u5BF9\u8C61\u7684\u7EAF getter\uFF1A\u8FD4\u56DE\u503C\u5E94\u4E3A\u5305\u542B\u672C\u6B21\u4F1A\u8BDD\u5FEB\u7167\u7684\u5BF9\u8C61\uFF08\u53D7\u63A7 sessionKey \u65F6\u987B\u542B\u76F8\u540C sessionKey\uFF09\uFF0C\u4E0D\u80FD\u8FD4\u56DE null\u3002";
195
+ }
196
+ if (snapshot === void 0) {
197
+ return "getContext \u8FD4\u56DE\u4E86 undefined\u3002\u5B83\u5FC5\u987B\u662F\u540C\u6B65\u8FD4\u56DE\u5FEB\u7167\u5BF9\u8C61\u7684\u7EAF getter\uFF1A\u8FD4\u56DE\u503C\u5E94\u4E3A\u5305\u542B\u672C\u6B21\u4F1A\u8BDD\u5FEB\u7167\u7684\u5BF9\u8C61\uFF0C\u8BF7\u68C0\u67E5 getter \u662F\u5426\u6F0F\u5199 return \u6216\u8FD4\u56DE\u4E86\u672A\u521D\u59CB\u5316\u7684\u53D8\u91CF\u3002";
198
+ }
199
+ if (typeof snapshot.then === "function") {
200
+ return "getContext \u8FD4\u56DE\u4E86 Promise/thenable\u3002\u5B83\u5FC5\u987B\u662F\u540C\u6B65 getter\uFF0C\u4E0D\u5F97\u8FD4\u56DE Promise\uFF1A\u5F02\u6B65\u83B7\u53D6\u7528\u6237\u8D44\u6599\u8BF7\u5728\u5BBF\u4E3B\u5B8C\u6210\u540E\u518D\u8BA9\u6865\u63A5\u7EC4\u4EF6\u8FDB\u5165\u53EF\u6302\u8F7D\u72B6\u6001\u3002";
201
+ }
202
+ return `getContext \u8FD4\u56DE\u4E86\u975E\u5BF9\u8C61\u503C\uFF08${typeof snapshot}\uFF1A"${String(snapshot)}"\uFF09\u3002\u5B83\u5FC5\u987B\u662F\u540C\u6B65\u8FD4\u56DE\u5FEB\u7167\u5BF9\u8C61\u7684\u7EAF getter\uFF0C\u8FD4\u56DE\u503C\u5E94\u4E3A\u5BF9\u8C61\u800C\u4E0D\u662F\u539F\u59CB\u503C\u3002`;
203
+ }
196
204
  function assertControlledSessionKey(spec, value) {
197
205
  if (value === void 0 || value === null) return;
198
206
  if (typeof value === "string" && value !== "") return;
@@ -261,7 +269,7 @@ var SECONDARY_BUTTON_STYLE = {
261
269
  fontSize: "13px",
262
270
  cursor: "pointer"
263
271
  };
264
- function DefaultBridgeErrorView({ error, retry }) {
272
+ function DefaultBridgeErrorView({ error, retry, blocked }) {
265
273
  const err = error;
266
274
  const code = err?.code ?? "UNKNOWN";
267
275
  const message = err?.message ?? String(error ?? "unknown error");
@@ -271,9 +279,9 @@ function DefaultBridgeErrorView({ error, retry }) {
271
279
  (0, import_react.createElement)(
272
280
  "p",
273
281
  { key: "n", style: { margin: "0 0 10px" } },
274
- "\u300C\u91CD\u8BD5\u52A0\u8F7D\u300D\u5728\u5F53\u524D\u9875\u9762\u91CD\u5EFA\u6302\u8F7D\uFF1B\u82E5\u6D4F\u89C8\u5668\u5DF2\u7F13\u5B58\u5931\u8D25\u7684\u6A21\u5757\uFF0C\u8BF7\u7528\u300C\u5237\u65B0\u9875\u9762\u91CD\u8BD5\u300D\u2014\u2014\u5B83\u4F1A\u6574\u9875\u5237\u65B0\uFF08\u4FDD\u7559\u5F53\u524D\u5730\u5740\uFF09\uFF0C\u672A\u4FDD\u5B58\u7684\u9875\u9762\u72B6\u6001\u4F1A\u4E22\u5931\u3002"
282
+ blocked ? "\u8BE5\u5BB9\u5668\u5DF2\u5C01\u9501\uFF08\u540C\u9875\u65E0\u6CD5\u5B89\u5168\u91CD\u6302\uFF09\uFF0C\u53EA\u80FD\u6574\u9875\u5237\u65B0\u6062\u590D\u2014\u2014\u70B9\u51FB\u300C\u5237\u65B0\u9875\u9762\u91CD\u8BD5\u300D\u4F1A\u91CD\u65B0\u52A0\u8F7D\u9875\u9762\uFF08\u4FDD\u7559\u5F53\u524D\u5730\u5740\uFF09\uFF0C\u672A\u4FDD\u5B58\u7684\u9875\u9762\u72B6\u6001\u4F1A\u4E22\u5931\u3002" : "\u300C\u91CD\u8BD5\u52A0\u8F7D\u300D\u5728\u5F53\u524D\u9875\u9762\u91CD\u5EFA\u6302\u8F7D\uFF1B\u82E5\u6D4F\u89C8\u5668\u5DF2\u7F13\u5B58\u5931\u8D25\u7684\u6A21\u5757\uFF0C\u8BF7\u7528\u300C\u5237\u65B0\u9875\u9762\u91CD\u8BD5\u300D\u2014\u2014\u5B83\u4F1A\u6574\u9875\u5237\u65B0\uFF08\u4FDD\u7559\u5F53\u524D\u5730\u5740\uFF09\uFF0C\u672A\u4FDD\u5B58\u7684\u9875\u9762\u72B6\u6001\u4F1A\u4E22\u5931\u3002"
275
283
  ),
276
- (0, import_react.createElement)("button", { key: "r", type: "button", style: BUTTON_STYLE, "data-fulgurjs-retry": "", onClick: retry }, "\u91CD\u8BD5\u52A0\u8F7D"),
284
+ blocked ? null : (0, import_react.createElement)("button", { key: "r", type: "button", style: BUTTON_STYLE, "data-fulgurjs-retry": "", onClick: retry }, "\u91CD\u8BD5\u52A0\u8F7D"),
277
285
  (0, import_react.createElement)("button", {
278
286
  key: "rl",
279
287
  type: "button",
@@ -283,10 +291,10 @@ function DefaultBridgeErrorView({ error, retry }) {
283
291
  }, "\u5237\u65B0\u9875\u9762\u91CD\u8BD5")
284
292
  ]);
285
293
  }
286
- function renderBridgeErrorNode(errorOpt, error, retry) {
294
+ function renderBridgeErrorNode(errorOpt, error, retry, blocked) {
287
295
  if (typeof errorOpt === "function") return errorOpt(error, retry);
288
296
  if (errorOpt !== void 0) return errorOpt;
289
- return (0, import_react.createElement)(DefaultBridgeErrorView, { error, retry });
297
+ return (0, import_react.createElement)(DefaultBridgeErrorView, { error, retry, blocked });
290
298
  }
291
299
  function createReactBridgeAppWithLoader(loadRemote) {
292
300
  return function createReactBridgeApp(spec, options = {}) {
@@ -371,7 +379,7 @@ function createReactBridgeAppWithLoader(loadRemote) {
371
379
  children.push((0, import_react.createElement)(import_react.Fragment, { key: "loading" }, options.fallback));
372
380
  }
373
381
  if (status === "error") {
374
- children.push((0, import_react.createElement)(import_react.Fragment, { key: "error" }, renderBridgeErrorNode(options.error, error, retry)));
382
+ children.push((0, import_react.createElement)(import_react.Fragment, { key: "error" }, renderBridgeErrorNode(options.error, error, retry, blockedRef.current)));
375
383
  }
376
384
  children.push((0, import_react.createElement)("div", {
377
385
  key: "bridge-root",
@@ -6,10 +6,10 @@ import {
6
6
  releaseBridgeSession,
7
7
  resolveBridgeContext,
8
8
  withBridgeTimeout
9
- } from "./chunk-LWJBHUJQ.js";
9
+ } from "./chunk-LE2G23E7.js";
10
10
  import {
11
11
  bridgeLifecycleError
12
- } from "./chunk-E55P4TIY.js";
12
+ } from "./chunk-DH2QMM4Y.js";
13
13
  import {
14
14
  provideAppContext
15
15
  } from "./chunk-TSYLDY6H.js";
@@ -53,7 +53,7 @@ var SECONDARY_BUTTON_STYLE = {
53
53
  fontSize: "13px",
54
54
  cursor: "pointer"
55
55
  };
56
- function DefaultBridgeErrorView({ error, retry }) {
56
+ function DefaultBridgeErrorView({ error, retry, blocked }) {
57
57
  const err = error;
58
58
  const code = err?.code ?? "UNKNOWN";
59
59
  const message = err?.message ?? String(error ?? "unknown error");
@@ -63,9 +63,9 @@ function DefaultBridgeErrorView({ error, retry }) {
63
63
  createElement(
64
64
  "p",
65
65
  { key: "n", style: { margin: "0 0 10px" } },
66
- "\u300C\u91CD\u8BD5\u52A0\u8F7D\u300D\u5728\u5F53\u524D\u9875\u9762\u91CD\u5EFA\u6302\u8F7D\uFF1B\u82E5\u6D4F\u89C8\u5668\u5DF2\u7F13\u5B58\u5931\u8D25\u7684\u6A21\u5757\uFF0C\u8BF7\u7528\u300C\u5237\u65B0\u9875\u9762\u91CD\u8BD5\u300D\u2014\u2014\u5B83\u4F1A\u6574\u9875\u5237\u65B0\uFF08\u4FDD\u7559\u5F53\u524D\u5730\u5740\uFF09\uFF0C\u672A\u4FDD\u5B58\u7684\u9875\u9762\u72B6\u6001\u4F1A\u4E22\u5931\u3002"
66
+ blocked ? "\u8BE5\u5BB9\u5668\u5DF2\u5C01\u9501\uFF08\u540C\u9875\u65E0\u6CD5\u5B89\u5168\u91CD\u6302\uFF09\uFF0C\u53EA\u80FD\u6574\u9875\u5237\u65B0\u6062\u590D\u2014\u2014\u70B9\u51FB\u300C\u5237\u65B0\u9875\u9762\u91CD\u8BD5\u300D\u4F1A\u91CD\u65B0\u52A0\u8F7D\u9875\u9762\uFF08\u4FDD\u7559\u5F53\u524D\u5730\u5740\uFF09\uFF0C\u672A\u4FDD\u5B58\u7684\u9875\u9762\u72B6\u6001\u4F1A\u4E22\u5931\u3002" : "\u300C\u91CD\u8BD5\u52A0\u8F7D\u300D\u5728\u5F53\u524D\u9875\u9762\u91CD\u5EFA\u6302\u8F7D\uFF1B\u82E5\u6D4F\u89C8\u5668\u5DF2\u7F13\u5B58\u5931\u8D25\u7684\u6A21\u5757\uFF0C\u8BF7\u7528\u300C\u5237\u65B0\u9875\u9762\u91CD\u8BD5\u300D\u2014\u2014\u5B83\u4F1A\u6574\u9875\u5237\u65B0\uFF08\u4FDD\u7559\u5F53\u524D\u5730\u5740\uFF09\uFF0C\u672A\u4FDD\u5B58\u7684\u9875\u9762\u72B6\u6001\u4F1A\u4E22\u5931\u3002"
67
67
  ),
68
- createElement("button", { key: "r", type: "button", style: BUTTON_STYLE, "data-fulgurjs-retry": "", onClick: retry }, "\u91CD\u8BD5\u52A0\u8F7D"),
68
+ blocked ? null : createElement("button", { key: "r", type: "button", style: BUTTON_STYLE, "data-fulgurjs-retry": "", onClick: retry }, "\u91CD\u8BD5\u52A0\u8F7D"),
69
69
  createElement("button", {
70
70
  key: "rl",
71
71
  type: "button",
@@ -75,10 +75,10 @@ function DefaultBridgeErrorView({ error, retry }) {
75
75
  }, "\u5237\u65B0\u9875\u9762\u91CD\u8BD5")
76
76
  ]);
77
77
  }
78
- function renderBridgeErrorNode(errorOpt, error, retry) {
78
+ function renderBridgeErrorNode(errorOpt, error, retry, blocked) {
79
79
  if (typeof errorOpt === "function") return errorOpt(error, retry);
80
80
  if (errorOpt !== void 0) return errorOpt;
81
- return createElement(DefaultBridgeErrorView, { error, retry });
81
+ return createElement(DefaultBridgeErrorView, { error, retry, blocked });
82
82
  }
83
83
  function createReactBridgeAppWithLoader(loadRemote) {
84
84
  return function createReactBridgeApp(spec, options = {}) {
@@ -163,7 +163,7 @@ function createReactBridgeAppWithLoader(loadRemote) {
163
163
  children.push(createElement(Fragment, { key: "loading" }, options.fallback));
164
164
  }
165
165
  if (status === "error") {
166
- children.push(createElement(Fragment, { key: "error" }, renderBridgeErrorNode(options.error, error, retry)));
166
+ children.push(createElement(Fragment, { key: "error" }, renderBridgeErrorNode(options.error, error, retry, blockedRef.current)));
167
167
  }
168
168
  children.push(createElement("div", {
169
169
  key: "bridge-root",
@@ -100,7 +100,7 @@ function bridgeLifecycleError(phase, spec, cause, extra) {
100
100
  const fixes = {
101
101
  getContext: "\u4FEE\u6CD5: \u2460 getContext \u5FC5\u987B\u662F\u540C\u6B65\u3001\u65E0\u526F\u4F5C\u7528\u7684 getter\uFF08\u4E0D\u5F97\u8FD4\u56DE Promise/thenable\uFF09\uFF1B\n \u2461 \u8FD4\u56DE\u503C\u987B\u662F\u5305\u542B\u672C\u6B21\u4F1A\u8BDD\u5FEB\u7167\u7684\u5BF9\u8C61\uFF08\u53D7\u63A7 sessionKey \u65F6\u987B\u542B\u76F8\u540C sessionKey\uFF09\uFF1B\n \u2462 \u5F02\u6B65\u83B7\u53D6\u7528\u6237\u8D44\u6599\u8BF7\u5728\u5BBF\u4E3B\u5B8C\u6210\u540E\u518D\u8BA9\u6865\u63A5\u7EC4\u4EF6\u8FDB\u5165\u53EF\u6302\u8F7D\u72B6\u6001\u3002",
102
102
  mount: "\u4FEE\u6CD5: \u2460 \u67E5\u770B\u6839\u56E0\u4E2D\u5B50\u5E94\u7528 mount \u7684\u539F\u59CB\u9519\u8BEF\uFF08\u5DE5\u5382\u629B\u9519\u6216\u9996\u6B21\u6E32\u67D3\u5931\u8D25\uFF09\uFF1B\n \u2461 \u540C\u4E00\u5BB9\u5668\u672A\u5378\u8F7D\u524D\u91CD\u590D mount \u662F\u5951\u7EA6\u8FDD\u4F8B\u2014\u2014\u5148 unmount \u518D mount\uFF1B\n \u2462 \u4FEE\u590D\u540E\u70B9\u51FB\u300C\u91CD\u8BD5\u52A0\u8F7D\u300D\u5728\u540C\u9875\u91CD\u5EFA\u6302\u8F7D\u3002",
103
- unmount: "\u4FEE\u6CD5: \u2460 \u6839\u56E0\u6765\u81EA\u5B50\u5E94\u7528 unmount \u5B9E\u73B0\uFF08app.unmount/root.unmount \u629B\u9519\uFF09\uFF1B\n \u2461 \u8BE5\u5BB9\u5668\u6E05\u7406\u72B6\u6001\u4E0D\u786E\u5B9A\u2014\u2014\u4E0D\u8981\u76F4\u63A5\u5728\u540C\u4E00 el \u4E0A\u542F\u52A8\u65B0\u5B9E\u4F8B\uFF1B\n \u2462 \u5237\u65B0\u9875\u9762\u53EF\u5F7B\u5E95\u6E05\u7406\uFF0C\u6B8B\u7559\u8D44\u6E90\u8BF7\u5982\u5B9E\u6392\u67E5\uFF08\u4E8B\u4EF6\u8BA2\u9605/\u5B9A\u65F6\u5668/\u5168\u5C40\u526F\u4F5C\u7528\uFF09\u3002"
103
+ unmount: "\u4FEE\u6CD5: \u2460 \u6839\u56E0\u6765\u81EA\u5B50\u5E94\u7528 unmount \u5B9E\u73B0\uFF08app.unmount/root.unmount \u629B\u9519\uFF09\uFF1B\n \u2461 \u8BE5\u5BB9\u5668\u6E05\u7406\u72B6\u6001\u4E0D\u786E\u5B9A\uFF0C\u63D2\u4EF6\u5DF2\u6301\u4E45\u5C01\u9501\u8BE5\u5BB9\u5668\u2014\u2014\u540C\u9875\u300C\u91CD\u8BD5\u52A0\u8F7D\u300D\u4E0E\n \u6362\u4F1A\u8BDD\u90FD\u4E0D\u4F1A\u5728\u6B64\u5BB9\u5668\u91CD\u65B0\u6302\u8F7D\uFF1B\n \u2462 \u53EA\u80FD\u6574\u9875\u5237\u65B0\u6062\u590D\uFF08\u300C\u5237\u65B0\u9875\u9762\u91CD\u8BD5\u300D\uFF09\uFF1B\u6B8B\u7559\u8D44\u6E90\uFF08\u4E8B\u4EF6\u8BA2\u9605/\u5B9A\u65F6\u5668/\u5168\u5C40\u526F\u4F5C\u7528\uFF09\u8BF7\u5982\u5B9E\u6392\u67E5\u3002"
104
104
  };
105
105
  return new FgError(
106
106
  BridgeErrorCodes.BRIDGE_LIFECYCLE_FAILED,
@@ -166,11 +166,7 @@ function resolveBridgeContext(spec, controlled, getContext) {
166
166
  throw bridgeLifecycleError("getContext", spec, e);
167
167
  }
168
168
  if (snapshot === null || typeof snapshot !== "object" || typeof snapshot.then === "function") {
169
- throw bridgeLifecycleError(
170
- "getContext",
171
- spec,
172
- `getContext \u8FD4\u56DE\u4E86${typeof snapshot.then === "function" ? " Promise/thenable" : "\u975E\u5BF9\u8C61\u503C\uFF08" + typeof snapshot + "\uFF09"}\uFF1B\u5B83\u5FC5\u987B\u662F\u540C\u6B65\u8FD4\u56DE\u5FEB\u7167\u5BF9\u8C61\u7684\u7EAF getter\u3002`
173
- );
169
+ throw bridgeLifecycleError("getContext", spec, describeContextValue(snapshot));
174
170
  }
175
171
  if (controlled !== void 0 && snapshot.sessionKey !== controlled) {
176
172
  throw bridgeSessionMismatchError(spec, controlled, snapshot.sessionKey, { reason: "getter-snapshot" });
@@ -193,6 +189,18 @@ function currentSessionKey() {
193
189
  const sk = (globalThis.__FULGURJS_APP_CONFIG__ ?? {}).sessionKey;
194
190
  return typeof sk === "string" && sk !== "" ? sk : void 0;
195
191
  }
192
+ function describeContextValue(snapshot) {
193
+ if (snapshot === null) {
194
+ return "getContext \u8FD4\u56DE\u4E86 null\u3002\u5B83\u5FC5\u987B\u662F\u540C\u6B65\u8FD4\u56DE\u5FEB\u7167\u5BF9\u8C61\u7684\u7EAF getter\uFF1A\u8FD4\u56DE\u503C\u5E94\u4E3A\u5305\u542B\u672C\u6B21\u4F1A\u8BDD\u5FEB\u7167\u7684\u5BF9\u8C61\uFF08\u53D7\u63A7 sessionKey \u65F6\u987B\u542B\u76F8\u540C sessionKey\uFF09\uFF0C\u4E0D\u80FD\u8FD4\u56DE null\u3002";
195
+ }
196
+ if (snapshot === void 0) {
197
+ return "getContext \u8FD4\u56DE\u4E86 undefined\u3002\u5B83\u5FC5\u987B\u662F\u540C\u6B65\u8FD4\u56DE\u5FEB\u7167\u5BF9\u8C61\u7684\u7EAF getter\uFF1A\u8FD4\u56DE\u503C\u5E94\u4E3A\u5305\u542B\u672C\u6B21\u4F1A\u8BDD\u5FEB\u7167\u7684\u5BF9\u8C61\uFF0C\u8BF7\u68C0\u67E5 getter \u662F\u5426\u6F0F\u5199 return \u6216\u8FD4\u56DE\u4E86\u672A\u521D\u59CB\u5316\u7684\u53D8\u91CF\u3002";
198
+ }
199
+ if (typeof snapshot.then === "function") {
200
+ return "getContext \u8FD4\u56DE\u4E86 Promise/thenable\u3002\u5B83\u5FC5\u987B\u662F\u540C\u6B65 getter\uFF0C\u4E0D\u5F97\u8FD4\u56DE Promise\uFF1A\u5F02\u6B65\u83B7\u53D6\u7528\u6237\u8D44\u6599\u8BF7\u5728\u5BBF\u4E3B\u5B8C\u6210\u540E\u518D\u8BA9\u6865\u63A5\u7EC4\u4EF6\u8FDB\u5165\u53EF\u6302\u8F7D\u72B6\u6001\u3002";
201
+ }
202
+ return `getContext \u8FD4\u56DE\u4E86\u975E\u5BF9\u8C61\u503C\uFF08${typeof snapshot}\uFF1A"${String(snapshot)}"\uFF09\u3002\u5B83\u5FC5\u987B\u662F\u540C\u6B65\u8FD4\u56DE\u5FEB\u7167\u5BF9\u8C61\u7684\u7EAF getter\uFF0C\u8FD4\u56DE\u503C\u5E94\u4E3A\u5BF9\u8C61\u800C\u4E0D\u662F\u539F\u59CB\u503C\u3002`;
203
+ }
196
204
  function assertControlledSessionKey(spec, value) {
197
205
  if (value === void 0 || value === null) return;
198
206
  if (typeof value === "string" && value !== "") return;
@@ -316,6 +324,7 @@ function createVueBridgeAppWithLoader(loadRemote) {
316
324
  const container = (0, import_vue.ref)(null);
317
325
  let generation = 0;
318
326
  let contract;
327
+ let containerBlocked = false;
319
328
  let acquiredSession;
320
329
  const releaseAcquired = () => {
321
330
  if (acquiredSession !== void 0) {
@@ -324,6 +333,7 @@ function createVueBridgeAppWithLoader(loadRemote) {
324
333
  }
325
334
  };
326
335
  const invalidate = () => {
336
+ if (containerBlocked) return false;
327
337
  generation++;
328
338
  const el = container.value;
329
339
  releaseAcquired();
@@ -334,7 +344,8 @@ function createVueBridgeAppWithLoader(loadRemote) {
334
344
  c.unmount(el);
335
345
  } catch (e) {
336
346
  const err = bridgeLifecycleError("unmount", spec, e instanceof Error ? e : String(e));
337
- console.error("[fulgurjs] \u6865\u63A5\u5E94\u7528\u5378\u8F7D\u5931\u8D25\uFF1A", err);
347
+ containerBlocked = true;
348
+ console.error("[fulgurjs] \u6865\u63A5\u5E94\u7528\u5378\u8F7D\u5931\u8D25\uFF0C\u8BE5\u5BB9\u5668\u5DF2\u5C01\u9501\uFF08\u540C\u9875\u53EA\u80FD\u5237\u65B0\u6062\u590D\uFF09\uFF1A", err);
338
349
  error.value = err;
339
350
  status.value = "error";
340
351
  return false;
@@ -405,7 +416,7 @@ function createVueBridgeAppWithLoader(loadRemote) {
405
416
  if (options.errorComponent) {
406
417
  children.push((0, import_vue.h)(options.errorComponent, { key: "error", error: err }));
407
418
  } else {
408
- children.push((0, import_vue.h)(BridgeErrorPlaceholder, { key: "error", error: err, retry }));
419
+ children.push((0, import_vue.h)(BridgeErrorPlaceholder, { key: "error", error: err, retry: containerBlocked ? void 0 : retry }));
409
420
  }
410
421
  }
411
422
  children.push((0, import_vue.h)("div", {
@@ -6,10 +6,10 @@ import {
6
6
  releaseBridgeSession,
7
7
  resolveBridgeContext,
8
8
  withBridgeTimeout
9
- } from "./chunk-LWJBHUJQ.js";
9
+ } from "./chunk-LE2G23E7.js";
10
10
  import {
11
11
  bridgeLifecycleError
12
- } from "./chunk-E55P4TIY.js";
12
+ } from "./chunk-DH2QMM4Y.js";
13
13
  import {
14
14
  provideAppContext
15
15
  } from "./chunk-TSYLDY6H.js";
@@ -102,6 +102,7 @@ function createVueBridgeAppWithLoader(loadRemote) {
102
102
  const container = ref(null);
103
103
  let generation = 0;
104
104
  let contract;
105
+ let containerBlocked = false;
105
106
  let acquiredSession;
106
107
  const releaseAcquired = () => {
107
108
  if (acquiredSession !== void 0) {
@@ -110,6 +111,7 @@ function createVueBridgeAppWithLoader(loadRemote) {
110
111
  }
111
112
  };
112
113
  const invalidate = () => {
114
+ if (containerBlocked) return false;
113
115
  generation++;
114
116
  const el = container.value;
115
117
  releaseAcquired();
@@ -120,7 +122,8 @@ function createVueBridgeAppWithLoader(loadRemote) {
120
122
  c.unmount(el);
121
123
  } catch (e) {
122
124
  const err = bridgeLifecycleError("unmount", spec, e instanceof Error ? e : String(e));
123
- console.error("[fulgurjs] \u6865\u63A5\u5E94\u7528\u5378\u8F7D\u5931\u8D25\uFF1A", err);
125
+ containerBlocked = true;
126
+ console.error("[fulgurjs] \u6865\u63A5\u5E94\u7528\u5378\u8F7D\u5931\u8D25\uFF0C\u8BE5\u5BB9\u5668\u5DF2\u5C01\u9501\uFF08\u540C\u9875\u53EA\u80FD\u5237\u65B0\u6062\u590D\uFF09\uFF1A", err);
124
127
  error.value = err;
125
128
  status.value = "error";
126
129
  return false;
@@ -191,7 +194,7 @@ function createVueBridgeAppWithLoader(loadRemote) {
191
194
  if (options.errorComponent) {
192
195
  children.push(h(options.errorComponent, { key: "error", error: err }));
193
196
  } else {
194
- children.push(h(BridgeErrorPlaceholder, { key: "error", error: err, retry }));
197
+ children.push(h(BridgeErrorPlaceholder, { key: "error", error: err, retry: containerBlocked ? void 0 : retry }));
195
198
  }
196
199
  }
197
200
  children.push(h("div", {
@@ -32,7 +32,7 @@ function bridgeLifecycleError(phase, spec, cause, extra) {
32
32
  const fixes = {
33
33
  getContext: "\u4FEE\u6CD5: \u2460 getContext \u5FC5\u987B\u662F\u540C\u6B65\u3001\u65E0\u526F\u4F5C\u7528\u7684 getter\uFF08\u4E0D\u5F97\u8FD4\u56DE Promise/thenable\uFF09\uFF1B\n \u2461 \u8FD4\u56DE\u503C\u987B\u662F\u5305\u542B\u672C\u6B21\u4F1A\u8BDD\u5FEB\u7167\u7684\u5BF9\u8C61\uFF08\u53D7\u63A7 sessionKey \u65F6\u987B\u542B\u76F8\u540C sessionKey\uFF09\uFF1B\n \u2462 \u5F02\u6B65\u83B7\u53D6\u7528\u6237\u8D44\u6599\u8BF7\u5728\u5BBF\u4E3B\u5B8C\u6210\u540E\u518D\u8BA9\u6865\u63A5\u7EC4\u4EF6\u8FDB\u5165\u53EF\u6302\u8F7D\u72B6\u6001\u3002",
34
34
  mount: "\u4FEE\u6CD5: \u2460 \u67E5\u770B\u6839\u56E0\u4E2D\u5B50\u5E94\u7528 mount \u7684\u539F\u59CB\u9519\u8BEF\uFF08\u5DE5\u5382\u629B\u9519\u6216\u9996\u6B21\u6E32\u67D3\u5931\u8D25\uFF09\uFF1B\n \u2461 \u540C\u4E00\u5BB9\u5668\u672A\u5378\u8F7D\u524D\u91CD\u590D mount \u662F\u5951\u7EA6\u8FDD\u4F8B\u2014\u2014\u5148 unmount \u518D mount\uFF1B\n \u2462 \u4FEE\u590D\u540E\u70B9\u51FB\u300C\u91CD\u8BD5\u52A0\u8F7D\u300D\u5728\u540C\u9875\u91CD\u5EFA\u6302\u8F7D\u3002",
35
- unmount: "\u4FEE\u6CD5: \u2460 \u6839\u56E0\u6765\u81EA\u5B50\u5E94\u7528 unmount \u5B9E\u73B0\uFF08app.unmount/root.unmount \u629B\u9519\uFF09\uFF1B\n \u2461 \u8BE5\u5BB9\u5668\u6E05\u7406\u72B6\u6001\u4E0D\u786E\u5B9A\u2014\u2014\u4E0D\u8981\u76F4\u63A5\u5728\u540C\u4E00 el \u4E0A\u542F\u52A8\u65B0\u5B9E\u4F8B\uFF1B\n \u2462 \u5237\u65B0\u9875\u9762\u53EF\u5F7B\u5E95\u6E05\u7406\uFF0C\u6B8B\u7559\u8D44\u6E90\u8BF7\u5982\u5B9E\u6392\u67E5\uFF08\u4E8B\u4EF6\u8BA2\u9605/\u5B9A\u65F6\u5668/\u5168\u5C40\u526F\u4F5C\u7528\uFF09\u3002"
35
+ unmount: "\u4FEE\u6CD5: \u2460 \u6839\u56E0\u6765\u81EA\u5B50\u5E94\u7528 unmount \u5B9E\u73B0\uFF08app.unmount/root.unmount \u629B\u9519\uFF09\uFF1B\n \u2461 \u8BE5\u5BB9\u5668\u6E05\u7406\u72B6\u6001\u4E0D\u786E\u5B9A\uFF0C\u63D2\u4EF6\u5DF2\u6301\u4E45\u5C01\u9501\u8BE5\u5BB9\u5668\u2014\u2014\u540C\u9875\u300C\u91CD\u8BD5\u52A0\u8F7D\u300D\u4E0E\n \u6362\u4F1A\u8BDD\u90FD\u4E0D\u4F1A\u5728\u6B64\u5BB9\u5668\u91CD\u65B0\u6302\u8F7D\uFF1B\n \u2462 \u53EA\u80FD\u6574\u9875\u5237\u65B0\u6062\u590D\uFF08\u300C\u5237\u65B0\u9875\u9762\u91CD\u8BD5\u300D\uFF09\uFF1B\u6B8B\u7559\u8D44\u6E90\uFF08\u4E8B\u4EF6\u8BA2\u9605/\u5B9A\u65F6\u5668/\u5168\u5C40\u526F\u4F5C\u7528\uFF09\u8BF7\u5982\u5B9E\u6392\u67E5\u3002"
36
36
  };
37
37
  return new FgError(
38
38
  BridgeErrorCodes.BRIDGE_LIFECYCLE_FAILED,
@@ -3,7 +3,7 @@ import {
3
3
  bridgeSessionMismatchError,
4
4
  invalidBridgeContractError,
5
5
  invalidSessionKeyError
6
- } from "./chunk-E55P4TIY.js";
6
+ } from "./chunk-DH2QMM4Y.js";
7
7
  import {
8
8
  clearAppContext
9
9
  } from "./chunk-TSYLDY6H.js";
@@ -39,11 +39,7 @@ function resolveBridgeContext(spec, controlled, getContext) {
39
39
  throw bridgeLifecycleError("getContext", spec, e);
40
40
  }
41
41
  if (snapshot === null || typeof snapshot !== "object" || typeof snapshot.then === "function") {
42
- throw bridgeLifecycleError(
43
- "getContext",
44
- spec,
45
- `getContext \u8FD4\u56DE\u4E86${typeof snapshot.then === "function" ? " Promise/thenable" : "\u975E\u5BF9\u8C61\u503C\uFF08" + typeof snapshot + "\uFF09"}\uFF1B\u5B83\u5FC5\u987B\u662F\u540C\u6B65\u8FD4\u56DE\u5FEB\u7167\u5BF9\u8C61\u7684\u7EAF getter\u3002`
46
- );
42
+ throw bridgeLifecycleError("getContext", spec, describeContextValue(snapshot));
47
43
  }
48
44
  if (controlled !== void 0 && snapshot.sessionKey !== controlled) {
49
45
  throw bridgeSessionMismatchError(spec, controlled, snapshot.sessionKey, { reason: "getter-snapshot" });
@@ -66,6 +62,18 @@ function currentSessionKey() {
66
62
  const sk = (globalThis.__FULGURJS_APP_CONFIG__ ?? {}).sessionKey;
67
63
  return typeof sk === "string" && sk !== "" ? sk : void 0;
68
64
  }
65
+ function describeContextValue(snapshot) {
66
+ if (snapshot === null) {
67
+ return "getContext \u8FD4\u56DE\u4E86 null\u3002\u5B83\u5FC5\u987B\u662F\u540C\u6B65\u8FD4\u56DE\u5FEB\u7167\u5BF9\u8C61\u7684\u7EAF getter\uFF1A\u8FD4\u56DE\u503C\u5E94\u4E3A\u5305\u542B\u672C\u6B21\u4F1A\u8BDD\u5FEB\u7167\u7684\u5BF9\u8C61\uFF08\u53D7\u63A7 sessionKey \u65F6\u987B\u542B\u76F8\u540C sessionKey\uFF09\uFF0C\u4E0D\u80FD\u8FD4\u56DE null\u3002";
68
+ }
69
+ if (snapshot === void 0) {
70
+ return "getContext \u8FD4\u56DE\u4E86 undefined\u3002\u5B83\u5FC5\u987B\u662F\u540C\u6B65\u8FD4\u56DE\u5FEB\u7167\u5BF9\u8C61\u7684\u7EAF getter\uFF1A\u8FD4\u56DE\u503C\u5E94\u4E3A\u5305\u542B\u672C\u6B21\u4F1A\u8BDD\u5FEB\u7167\u7684\u5BF9\u8C61\uFF0C\u8BF7\u68C0\u67E5 getter \u662F\u5426\u6F0F\u5199 return \u6216\u8FD4\u56DE\u4E86\u672A\u521D\u59CB\u5316\u7684\u53D8\u91CF\u3002";
71
+ }
72
+ if (typeof snapshot.then === "function") {
73
+ return "getContext \u8FD4\u56DE\u4E86 Promise/thenable\u3002\u5B83\u5FC5\u987B\u662F\u540C\u6B65 getter\uFF0C\u4E0D\u5F97\u8FD4\u56DE Promise\uFF1A\u5F02\u6B65\u83B7\u53D6\u7528\u6237\u8D44\u6599\u8BF7\u5728\u5BBF\u4E3B\u5B8C\u6210\u540E\u518D\u8BA9\u6865\u63A5\u7EC4\u4EF6\u8FDB\u5165\u53EF\u6302\u8F7D\u72B6\u6001\u3002";
74
+ }
75
+ return `getContext \u8FD4\u56DE\u4E86\u975E\u5BF9\u8C61\u503C\uFF08${typeof snapshot}\uFF1A"${String(snapshot)}"\uFF09\u3002\u5B83\u5FC5\u987B\u662F\u540C\u6B65\u8FD4\u56DE\u5FEB\u7167\u5BF9\u8C61\u7684\u7EAF getter\uFF0C\u8FD4\u56DE\u503C\u5E94\u4E3A\u5BF9\u8C61\u800C\u4E0D\u662F\u539F\u59CB\u503C\u3002`;
76
+ }
69
77
  function assertControlledSessionKey(spec, value) {
70
78
  if (value === void 0 || value === null) return;
71
79
  if (typeof value === "string" && value !== "") return;
@@ -8,7 +8,7 @@ import {
8
8
  releaseBridgeSession,
9
9
  resolveBridgeContext,
10
10
  withBridgeTimeout
11
- } from "./chunk-UJFCPQGN.js";
11
+ } from "./chunk-TOT3P7AK.js";
12
12
 
13
13
  // src/bridge-host-vue.ts
14
14
  import { defineComponent, h, onBeforeUnmount, onMounted, ref, shallowRef, toRaw, watch } from "vue";
@@ -97,6 +97,7 @@ function createVueBridgeAppWithLoader(loadRemote) {
97
97
  const container = ref(null);
98
98
  let generation = 0;
99
99
  let contract;
100
+ let containerBlocked = false;
100
101
  let acquiredSession;
101
102
  const releaseAcquired = () => {
102
103
  if (acquiredSession !== void 0) {
@@ -105,6 +106,7 @@ function createVueBridgeAppWithLoader(loadRemote) {
105
106
  }
106
107
  };
107
108
  const invalidate = () => {
109
+ if (containerBlocked) return false;
108
110
  generation++;
109
111
  const el = container.value;
110
112
  releaseAcquired();
@@ -115,7 +117,8 @@ function createVueBridgeAppWithLoader(loadRemote) {
115
117
  c.unmount(el);
116
118
  } catch (e) {
117
119
  const err = bridgeLifecycleError("unmount", spec, e instanceof Error ? e : String(e));
118
- console.error("[fulgurjs] \u6865\u63A5\u5E94\u7528\u5378\u8F7D\u5931\u8D25\uFF1A", err);
120
+ containerBlocked = true;
121
+ console.error("[fulgurjs] \u6865\u63A5\u5E94\u7528\u5378\u8F7D\u5931\u8D25\uFF0C\u8BE5\u5BB9\u5668\u5DF2\u5C01\u9501\uFF08\u540C\u9875\u53EA\u80FD\u5237\u65B0\u6062\u590D\uFF09\uFF1A", err);
119
122
  error.value = err;
120
123
  status.value = "error";
121
124
  return false;
@@ -186,7 +189,7 @@ function createVueBridgeAppWithLoader(loadRemote) {
186
189
  if (options.errorComponent) {
187
190
  children.push(h(options.errorComponent, { key: "error", error: err }));
188
191
  } else {
189
- children.push(h(BridgeErrorPlaceholder, { key: "error", error: err, retry }));
192
+ children.push(h(BridgeErrorPlaceholder, { key: "error", error: err, retry: containerBlocked ? void 0 : retry }));
190
193
  }
191
194
  }
192
195
  children.push(h("div", {