@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.
- package/CHANGELOG.md +7 -0
- package/README.en.md +2 -0
- package/README.md +3 -3
- package/dist/{application-core-DWI3eKme.d.ts → application-core-C72tVRT7.d.ts} +1 -1
- package/dist/{application-core-BuhXQmLF.d.cts → application-core-Coa0CIre.d.cts} +1 -1
- package/dist/bridge-app-react.d.cts +2 -2
- package/dist/bridge-app-react.d.ts +2 -2
- package/dist/bridge-app-react.js +1 -1
- package/dist/bridge-app-vue.d.cts +2 -2
- package/dist/bridge-app-vue.d.ts +2 -2
- package/dist/bridge-app-vue.js +1 -1
- package/dist/{bridge-core-77BT1__I.d.cts → bridge-core-CGFET9Qi.d.cts} +2 -1
- package/dist/{bridge-core-CoQRVgnZ.d.ts → bridge-core-Dm6ABUxQ.d.ts} +2 -1
- package/dist/bridge-core.cjs +4 -1
- package/dist/bridge-core.d.cts +1 -1
- package/dist/bridge-core.d.ts +1 -1
- package/dist/bridge-core.js +1 -1
- package/dist/bridge-host-react.cjs +4 -1
- package/dist/bridge-host-react.d.cts +2 -2
- package/dist/bridge-host-react.d.ts +2 -2
- package/dist/bridge-host-react.js +1 -1
- package/dist/bridge-host-vue.cjs +42 -5
- package/dist/bridge-host-vue.d.cts +12 -4
- package/dist/bridge-host-vue.d.ts +12 -4
- package/dist/bridge-host-vue.js +40 -5
- package/dist/bridge-session-auto.cjs +121 -0
- package/dist/bridge-session-auto.d.cts +21 -0
- package/dist/bridge-session-auto.d.ts +21 -0
- package/dist/bridge-session-auto.js +88 -0
- package/dist/{chunk-HDRZBSND.js → chunk-2MWIIRQZ.js} +4 -1
- package/dist/cli.js +53 -10
- package/dist/index.cjs +4 -3
- package/dist/index.js +4 -3
- package/dist/react-adapter.d.cts +2 -2
- package/dist/react-adapter.d.ts +2 -2
- package/dist/react.d.ts +2 -2
- package/dist/{remote-types-COmBhjRc.d.ts → remote-types-CMtfvLcH.d.ts} +1 -1
- package/dist/{remote-types-CStGOJwu.d.cts → remote-types-Cf4SSzus.d.cts} +1 -1
- package/dist/runtime-entry.d.ts +2 -2
- package/dist/runtime.js +13 -13
- package/dist/vue-adapter.d.cts +2 -2
- package/dist/vue-adapter.d.ts +2 -2
- package/dist/vue.d.ts +10 -3
- package/dist/vue.js +2 -1
- package/docs/en/reference/api.md +15 -4
- package/docs/en/reference/errors.md +1 -1
- package/docs/en/reference/types.md +4 -2
- package/docs/zh/reference/api.md +16 -6
- package/docs/zh/reference/errors.md +1 -1
- package/docs/zh/reference/types.md +4 -2
- package/package.json +6 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
# 当前发布说明
|
|
2
2
|
|
|
3
|
+
## 6.12.0
|
|
4
|
+
|
|
5
|
+
- Vue 宿主桥接新增 session 身份 getter,插件自动管理登录代次、同会话恢复、换号和登出;token刷新不作为换代依据,移除应用登录流程中的手工 renew/clear 接线。自动会话仅 Vue 宿主;React 宿主仍使用显式受控 sessionKey。
|
|
6
|
+
- setup 允许只声明 onSession/globalComponents/pageProviders,不再强制默认导出空函数;错误默认导出与空模块仍严格拒绝。
|
|
7
|
+
- init 接入计划支持 --application 复用已有统一装配;复杂入口输出真实依赖与逐步整理清单,不猜测业务代码;补齐单一路径首次接入指南。
|
|
8
|
+
- 新增自动会话完整回归(身份生命周期、token 轮换不重挂、离页登出、多实例共享、非法 getter、代次冲突与存储降级)。
|
|
9
|
+
|
|
3
10
|
## 6.11.7
|
|
4
11
|
|
|
5
12
|
- 新增接入代码统一集中在 src/fulgurjs:host/ 管宿主挂载与上下文,exposes/ 管远程装配与对外内容,types/ 管自动声明;根部只按需保留 setup.ts。
|
package/README.en.md
CHANGED
|
@@ -11,6 +11,8 @@ To reduce duplicated standalone/bridge startup code, see [application assembly a
|
|
|
11
11
|
|
|
12
12
|
For existing projects, `fulgurjs init --plan` previews wiring and `--write` explicitly applies it. Complex business assembly remains an explicit manual task. Unified `/vue` and `/react` imports support tree shaking without internal import paths.
|
|
13
13
|
|
|
14
|
+
For an existing complete application, follow [one end-to-end integration path](https://github.com/chenmingye/fulgurjs-federation/blob/master/docs/en/guide/first-integration.md) before consulting individual APIs.
|
|
15
|
+
|
|
14
16
|
## Quick start
|
|
15
17
|
|
|
16
18
|
**New project** (recommended): scaffold a fully runnable federation workspace from a template:
|
package/README.md
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
[English](https://github.com/chenmingye/fulgurjs-federation/blob/master/README.en.md) | **[完整文档中心](https://github.com/chenmingye/fulgurjs-federation/blob/master/docs/README.md)**(中文 [docs/zh](https://github.com/chenmingye/fulgurjs-federation/blob/master/docs/zh/README.md) · English [docs/en](https://github.com/chenmingye/fulgurjs-federation/blob/master/docs/en/README.md))
|
|
8
8
|
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
第一次接入完整应用,从[一条完整接入流程](https://github.com/chenmingye/fulgurjs-federation/blob/master/docs/zh/guide/first-integration.md)开始;统一装配与预检参考[已有应用接入](https://github.com/chenmingye/fulgurjs-federation/blob/master/docs/zh/guide/existing-apps.md)。
|
|
11
11
|
|
|
12
12
|
已有工程可先用 `fulgurjs init --plan` 预览接线,审查后再用 `--write`;复杂业务装配会明确列出人工待办。统一 `/vue`、`/react` 入口支持按使用裁剪,不需要改用内部路径。
|
|
13
13
|
|
|
@@ -43,7 +43,7 @@ export default {
|
|
|
43
43
|
// Vue 应用代码统一入口 @fulgurjs/federation/vue
|
|
44
44
|
import { loadRemote, remoteComponent } from '@fulgurjs/federation/vue'
|
|
45
45
|
const RemoteButton = remoteComponent('remote-a/Button')
|
|
46
|
-
const math = await loadRemote
|
|
46
|
+
const math = await loadRemote('remote-a/math')
|
|
47
47
|
```
|
|
48
48
|
|
|
49
49
|
```tsx
|
|
@@ -71,7 +71,7 @@ import { loadRemote, loadShare } from '@fulgurjs/federation/runtime'
|
|
|
71
71
|
|
|
72
72
|
- **组件与模块**:`remoteComponent`(Vue/React)、`useLoadRemote`、`RemoteErrorBoundary`、`loadRemote` —— 失败显式错误态可重试,不静默兜底。
|
|
73
73
|
- **逐页接入**:`definePages` + `createHostPages`(宿主页面路由表 → 远程页面),CLI `check-pages` 启动期契约核对。
|
|
74
|
-
- **完整子应用桥接**:`defineBridgeApp
|
|
74
|
+
- **完整子应用桥接**:`defineApplication`(独立/嵌入共用装配;自定义契约可用 `defineBridgeApp`)+ `createVueBridgeApp` / `createReactBridgeApp`(宿主);挂载/卸载、会话代次、卸载失败封锁。
|
|
75
75
|
- **URL 同步**:`createVueBridgeNavigation` / `createReactBridgeNavigation`(宿主)+ Vue 工厂返回 `{ app, router }` / `createReactBridgeRouter`(子应用);深链刷新、守卫取消、query/hash 保留。
|
|
76
76
|
- **共享依赖**:singleton / requiredVersion / strictVersion / shareScope / eager,同步与异步裁决,React 18/19 多版本隔离。
|
|
77
77
|
- **远程类型**:提供方随构建产出可分发声明(SFC 真实 props/泛型/重载),宿主 dev 自动同步——普通 import 与 `loadRemote`/`remoteComponent`/桥接工厂共用一套类型,拼错入口编译期报错;CLI `types` 供 CI 在 typecheck 前同步校验。
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ReactElement } from 'react';
|
|
2
|
-
import { B as BridgeChildRoute, a as BridgeApp } from './bridge-core-
|
|
3
|
-
import { A as Application } from './application-core-
|
|
2
|
+
import { B as BridgeChildRoute, a as BridgeApp } from './bridge-core-CGFET9Qi.cjs';
|
|
3
|
+
import { A as Application } from './application-core-Coa0CIre.cjs';
|
|
4
4
|
import './context.cjs';
|
|
5
5
|
|
|
6
6
|
/**
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ReactElement } from 'react';
|
|
2
|
-
import { B as BridgeChildRoute, a as BridgeApp } from './bridge-core-
|
|
3
|
-
import { A as Application } from './application-core-
|
|
2
|
+
import { B as BridgeChildRoute, a as BridgeApp } from './bridge-core-Dm6ABUxQ.js';
|
|
3
|
+
import { A as Application } from './application-core-C72tVRT7.js';
|
|
4
4
|
import './context.js';
|
|
5
5
|
|
|
6
6
|
/**
|
package/dist/bridge-app-react.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { App } from 'vue';
|
|
2
|
-
import { B as BridgeChildRoute, V as VueRouterLike, a as BridgeApp } from './bridge-core-
|
|
3
|
-
import { A as Application } from './application-core-
|
|
2
|
+
import { B as BridgeChildRoute, V as VueRouterLike, a as BridgeApp } from './bridge-core-CGFET9Qi.cjs';
|
|
3
|
+
import { A as Application } from './application-core-Coa0CIre.cjs';
|
|
4
4
|
import './context.cjs';
|
|
5
5
|
|
|
6
6
|
/**
|
package/dist/bridge-app-vue.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { App } from 'vue';
|
|
2
|
-
import { B as BridgeChildRoute, V as VueRouterLike, a as BridgeApp } from './bridge-core-
|
|
3
|
-
import { A as Application } from './application-core-
|
|
2
|
+
import { B as BridgeChildRoute, V as VueRouterLike, a as BridgeApp } from './bridge-core-Dm6ABUxQ.js';
|
|
3
|
+
import { A as Application } from './application-core-C72tVRT7.js';
|
|
4
4
|
import './context.js';
|
|
5
5
|
|
|
6
6
|
/**
|
package/dist/bridge-app-vue.js
CHANGED
|
@@ -106,6 +106,7 @@ interface BridgeContextResolution {
|
|
|
106
106
|
* 挂载前校验会话与上下文快照(同步、无副作用;只在全部通过后由调用方 provide)。
|
|
107
107
|
*
|
|
108
108
|
* - getter 抛错/返回非对象/thenable → MFU-016(phase: getContext);
|
|
109
|
+
* - 自动会话可补入缺省的快照sessionKey;显式矛盾仍拒绝;
|
|
109
110
|
* - 受控 sessionKey 与快照或现有 AppContext 不一致 → MFU-017(不写任何全局状态);
|
|
110
111
|
* - 新会话(与全局当前 sessionKey 不同)先 clearAppContext 清旧账号残留,
|
|
111
112
|
* 避免 provideAppContext 顶层 merge 留下旧账号独有字段(BR06)。
|
|
@@ -116,7 +117,7 @@ interface BridgeContextResolution {
|
|
|
116
117
|
* controlled 语义:非空字符串 = 受控校验;undefined = 不启用受控校验(快照照常提供,
|
|
117
118
|
* 远程 onSession 由 runtime 按 AppContext.sessionKey 判定);null 由调用方先行短路。
|
|
118
119
|
*/
|
|
119
|
-
declare function resolveBridgeContext(spec: string, controlled: string | undefined, getContext: (() => Partial<AppContext> & Record<string, unknown>) | undefined): BridgeContextResolution;
|
|
120
|
+
declare function resolveBridgeContext(spec: string, controlled: string | undefined, getContext: (() => Partial<AppContext> & Record<string, unknown>) | undefined, managedSession?: boolean): BridgeContextResolution;
|
|
120
121
|
/** 受控 sessionKey 受控值合法性:只接受 undefined / null / 非空字符串(任务书 BN10) */
|
|
121
122
|
declare function assertControlledSessionKey(spec: string, value: unknown): void;
|
|
122
123
|
/** 适配层参数校验(与 vue/react 适配器同口径:retries 0-10 整数、timeout 正有限数) */
|
|
@@ -106,6 +106,7 @@ interface BridgeContextResolution {
|
|
|
106
106
|
* 挂载前校验会话与上下文快照(同步、无副作用;只在全部通过后由调用方 provide)。
|
|
107
107
|
*
|
|
108
108
|
* - getter 抛错/返回非对象/thenable → MFU-016(phase: getContext);
|
|
109
|
+
* - 自动会话可补入缺省的快照sessionKey;显式矛盾仍拒绝;
|
|
109
110
|
* - 受控 sessionKey 与快照或现有 AppContext 不一致 → MFU-017(不写任何全局状态);
|
|
110
111
|
* - 新会话(与全局当前 sessionKey 不同)先 clearAppContext 清旧账号残留,
|
|
111
112
|
* 避免 provideAppContext 顶层 merge 留下旧账号独有字段(BR06)。
|
|
@@ -116,7 +117,7 @@ interface BridgeContextResolution {
|
|
|
116
117
|
* controlled 语义:非空字符串 = 受控校验;undefined = 不启用受控校验(快照照常提供,
|
|
117
118
|
* 远程 onSession 由 runtime 按 AppContext.sessionKey 判定);null 由调用方先行短路。
|
|
118
119
|
*/
|
|
119
|
-
declare function resolveBridgeContext(spec: string, controlled: string | undefined, getContext: (() => Partial<AppContext> & Record<string, unknown>) | undefined): BridgeContextResolution;
|
|
120
|
+
declare function resolveBridgeContext(spec: string, controlled: string | undefined, getContext: (() => Partial<AppContext> & Record<string, unknown>) | undefined, managedSession?: boolean): BridgeContextResolution;
|
|
120
121
|
/** 受控 sessionKey 受控值合法性:只接受 undefined / null / 非空字符串(任务书 BN10) */
|
|
121
122
|
declare function assertControlledSessionKey(spec: string, value: unknown): void;
|
|
122
123
|
/** 适配层参数校验(与 vue/react 适配器同口径:retries 0-10 整数、timeout 正有限数) */
|
package/dist/bridge-core.cjs
CHANGED
|
@@ -159,7 +159,7 @@ function releaseBridgeSession(sessionKey) {
|
|
|
159
159
|
if (n <= 1) activeBridgeSessions.delete(sessionKey);
|
|
160
160
|
else activeBridgeSessions.set(sessionKey, n - 1);
|
|
161
161
|
}
|
|
162
|
-
function resolveBridgeContext(spec, controlled, getContext) {
|
|
162
|
+
function resolveBridgeContext(spec, controlled, getContext, managedSession = false) {
|
|
163
163
|
if (getContext) {
|
|
164
164
|
let snapshot;
|
|
165
165
|
try {
|
|
@@ -170,6 +170,9 @@ function resolveBridgeContext(spec, controlled, getContext) {
|
|
|
170
170
|
if (snapshot === null || typeof snapshot !== "object" || typeof snapshot.then === "function") {
|
|
171
171
|
throw bridgeLifecycleError("getContext", spec, describeContextValue(snapshot));
|
|
172
172
|
}
|
|
173
|
+
if (managedSession && controlled !== void 0 && snapshot.sessionKey === void 0) {
|
|
174
|
+
snapshot = { ...snapshot, sessionKey: controlled };
|
|
175
|
+
}
|
|
173
176
|
if (controlled !== void 0 && snapshot.sessionKey !== controlled) {
|
|
174
177
|
throw bridgeSessionMismatchError(spec, controlled, snapshot.sessionKey, { reason: "getter-snapshot" });
|
|
175
178
|
}
|
package/dist/bridge-core.d.cts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import './context.cjs';
|
|
2
|
-
export { a as BridgeApp, c as BridgeContextResolution, d as acquireBridgeSession, e as assertBridgeContract, f as assertBridgeOptions, g as assertControlledSessionKey, h as hasBridgeMount, m as markBridgeMount, r as releaseBridgeSession, i as resolveBridgeContext, w as withBridgeTimeout } from './bridge-core-
|
|
2
|
+
export { a as BridgeApp, c as BridgeContextResolution, d as acquireBridgeSession, e as assertBridgeContract, f as assertBridgeOptions, g as assertControlledSessionKey, h as hasBridgeMount, m as markBridgeMount, r as releaseBridgeSession, i as resolveBridgeContext, w as withBridgeTimeout } from './bridge-core-CGFET9Qi.cjs';
|
package/dist/bridge-core.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import './context.js';
|
|
2
|
-
export { a as BridgeApp, c as BridgeContextResolution, d as acquireBridgeSession, e as assertBridgeContract, f as assertBridgeOptions, g as assertControlledSessionKey, h as hasBridgeMount, m as markBridgeMount, r as releaseBridgeSession, i as resolveBridgeContext, w as withBridgeTimeout } from './bridge-core-
|
|
2
|
+
export { a as BridgeApp, c as BridgeContextResolution, d as acquireBridgeSession, e as assertBridgeContract, f as assertBridgeOptions, g as assertControlledSessionKey, h as hasBridgeMount, m as markBridgeMount, r as releaseBridgeSession, i as resolveBridgeContext, w as withBridgeTimeout } from './bridge-core-Dm6ABUxQ.js';
|
package/dist/bridge-core.js
CHANGED
|
@@ -208,7 +208,7 @@ function releaseBridgeSession(sessionKey) {
|
|
|
208
208
|
if (n <= 1) activeBridgeSessions.delete(sessionKey);
|
|
209
209
|
else activeBridgeSessions.set(sessionKey, n - 1);
|
|
210
210
|
}
|
|
211
|
-
function resolveBridgeContext(spec, controlled, getContext) {
|
|
211
|
+
function resolveBridgeContext(spec, controlled, getContext, managedSession = false) {
|
|
212
212
|
if (getContext) {
|
|
213
213
|
let snapshot;
|
|
214
214
|
try {
|
|
@@ -219,6 +219,9 @@ function resolveBridgeContext(spec, controlled, getContext) {
|
|
|
219
219
|
if (snapshot === null || typeof snapshot !== "object" || typeof snapshot.then === "function") {
|
|
220
220
|
throw bridgeLifecycleError("getContext", spec, describeContextValue(snapshot));
|
|
221
221
|
}
|
|
222
|
+
if (managedSession && controlled !== void 0 && snapshot.sessionKey === void 0) {
|
|
223
|
+
snapshot = { ...snapshot, sessionKey: controlled };
|
|
224
|
+
}
|
|
222
225
|
if (controlled !== void 0 && snapshot.sessionKey !== controlled) {
|
|
223
226
|
throw bridgeSessionMismatchError(spec, controlled, snapshot.sessionKey, { reason: "getter-snapshot" });
|
|
224
227
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { ReactNode, ComponentType } from 'react';
|
|
2
2
|
import { AppContext } from './context.cjs';
|
|
3
|
-
import { b as BridgeHostRouting } from './bridge-core-
|
|
4
|
-
import { F as FgBridgeEntry, a as FgBridgeAppProps } from './remote-types-
|
|
3
|
+
import { b as BridgeHostRouting } from './bridge-core-CGFET9Qi.cjs';
|
|
4
|
+
import { F as FgBridgeEntry, a as FgBridgeAppProps } from './remote-types-Cf4SSzus.cjs';
|
|
5
5
|
import { FgTypeAuto } from '@fulgurjs/federation/internal/registry.js';
|
|
6
6
|
|
|
7
7
|
/**
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { ReactNode, ComponentType } from 'react';
|
|
2
2
|
import { AppContext } from './context.js';
|
|
3
|
-
import { b as BridgeHostRouting } from './bridge-core-
|
|
4
|
-
import { F as FgBridgeEntry, a as FgBridgeAppProps } from './remote-types-
|
|
3
|
+
import { b as BridgeHostRouting } from './bridge-core-Dm6ABUxQ.js';
|
|
4
|
+
import { F as FgBridgeEntry, a as FgBridgeAppProps } from './remote-types-CMtfvLcH.js';
|
|
5
5
|
import { FgTypeAuto } from '@fulgurjs/federation/internal/registry.js';
|
|
6
6
|
|
|
7
7
|
/**
|
package/dist/bridge-host-vue.cjs
CHANGED
|
@@ -208,7 +208,7 @@ function releaseBridgeSession(sessionKey) {
|
|
|
208
208
|
if (n <= 1) activeBridgeSessions.delete(sessionKey);
|
|
209
209
|
else activeBridgeSessions.set(sessionKey, n - 1);
|
|
210
210
|
}
|
|
211
|
-
function resolveBridgeContext(spec, controlled, getContext) {
|
|
211
|
+
function resolveBridgeContext(spec, controlled, getContext, managedSession = false) {
|
|
212
212
|
if (getContext) {
|
|
213
213
|
let snapshot;
|
|
214
214
|
try {
|
|
@@ -219,6 +219,9 @@ function resolveBridgeContext(spec, controlled, getContext) {
|
|
|
219
219
|
if (snapshot === null || typeof snapshot !== "object" || typeof snapshot.then === "function") {
|
|
220
220
|
throw bridgeLifecycleError("getContext", spec, describeContextValue(snapshot));
|
|
221
221
|
}
|
|
222
|
+
if (managedSession && controlled !== void 0 && snapshot.sessionKey === void 0) {
|
|
223
|
+
snapshot = { ...snapshot, sessionKey: controlled };
|
|
224
|
+
}
|
|
222
225
|
if (controlled !== void 0 && snapshot.sessionKey !== controlled) {
|
|
223
226
|
throw bridgeSessionMismatchError(spec, controlled, snapshot.sessionKey, { reason: "getter-snapshot" });
|
|
224
227
|
}
|
|
@@ -633,9 +636,16 @@ var BridgeErrorPlaceholder = /* @__PURE__ */ (0, import_vue.defineComponent)({
|
|
|
633
636
|
};
|
|
634
637
|
}
|
|
635
638
|
});
|
|
636
|
-
function createVueBridgeAppWithLoader(loadRemote) {
|
|
639
|
+
function createVueBridgeAppWithLoader(loadRemote, automaticSession) {
|
|
637
640
|
return function createVueBridgeApp(spec, options = {}) {
|
|
638
641
|
assertBridgeOptions(`createVueBridgeApp("${spec}")`, options);
|
|
642
|
+
if (options.session !== void 0 && typeof options.session !== "function") {
|
|
643
|
+
throw new TypeError("createVueBridgeApp \u7684 session \u5FC5\u987B\u662F\u540C\u6B65\u8EAB\u4EFD getter\uFF0C\u4F8B\u5982 session: () => auth.userId\uFF1B\u5DF2\u9000\u51FA\u8FD4\u56DE null\uFF0C\u8EAB\u4EFD\u6062\u590D\u4E2D\u8FD4\u56DE undefined\u3002");
|
|
644
|
+
}
|
|
645
|
+
if (options.session && !automaticSession) throw new Error("Vue\u6865\u63A5\u5165\u53E3\u672A\u7ED1\u5B9A\u81EA\u52A8\u4F1A\u8BDD\u5B9E\u73B0\uFF1B\u8BF7\u4ECE @fulgurjs/federation/vue \u5BFC\u5165\uFF0C\u4E0D\u76F4\u63A5\u8C03\u7528\u5185\u90E8\u5DE5\u5382\u3002");
|
|
646
|
+
if (options.sessionStorageKey !== void 0 && (!options.session || typeof options.sessionStorageKey !== "string" || !options.sessionStorageKey.trim())) {
|
|
647
|
+
throw new TypeError("sessionStorageKey \u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32\uFF0C\u5E76\u4E0E session \u8EAB\u4EFD getter \u4E00\u8D77\u914D\u7F6E\uFF1B\u540C\u4E00\u5BBF\u4E3B\u7684\u8FDC\u7A0B\u4F7F\u7528\u76F8\u540C\u952E\u3002");
|
|
648
|
+
}
|
|
639
649
|
const componentName = "FulgurjsBridge_" + spec.replace(/[^A-Za-z0-9_-]/g, "_");
|
|
640
650
|
return (0, import_vue.defineComponent)({
|
|
641
651
|
name: componentName,
|
|
@@ -649,6 +659,8 @@ function createVueBridgeAppWithLoader(loadRemote) {
|
|
|
649
659
|
routing: { type: Object, required: false, default: void 0 }
|
|
650
660
|
},
|
|
651
661
|
setup(props) {
|
|
662
|
+
const managedSession = options.session ? automaticSession(options.session, options.sessionStorageKey ?? "fulgurjs-bridge-session") : void 0;
|
|
663
|
+
const currentSession = () => managedSession ? managedSession.sessionKey.value : props.sessionKey;
|
|
652
664
|
const status = (0, import_vue.ref)("idle");
|
|
653
665
|
const error = (0, import_vue.shallowRef)(void 0);
|
|
654
666
|
const container = (0, import_vue.ref)(null);
|
|
@@ -692,9 +704,19 @@ function createVueBridgeAppWithLoader(loadRemote) {
|
|
|
692
704
|
const run = async (myGeneration) => {
|
|
693
705
|
const el = container.value;
|
|
694
706
|
if (!el) return;
|
|
695
|
-
const sk =
|
|
707
|
+
const sk = currentSession();
|
|
696
708
|
status.value = "pending";
|
|
697
709
|
error.value = void 0;
|
|
710
|
+
if (managedSession && props.sessionKey !== void 0) {
|
|
711
|
+
error.value = bridgeHostError("getContext", spec, new Error("session \u81EA\u52A8\u7BA1\u7406\u4E0E sessionKey prop \u4E0D\u80FD\u540C\u65F6\u8BBE\u7F6E\uFF1B\u4FDD\u7559 session \u8EAB\u4EFD getter\uFF0C\u79FB\u9664\u624B\u5DE5\u4EE3\u6B21\u7ED1\u5B9A\u3002"));
|
|
712
|
+
status.value = "error";
|
|
713
|
+
return;
|
|
714
|
+
}
|
|
715
|
+
if (managedSession?.error.value !== void 0) {
|
|
716
|
+
error.value = bridgeHostError("getContext", spec, managedSession.error.value);
|
|
717
|
+
status.value = "error";
|
|
718
|
+
return;
|
|
719
|
+
}
|
|
698
720
|
if (sk === null) {
|
|
699
721
|
status.value = "idle";
|
|
700
722
|
return;
|
|
@@ -707,7 +729,12 @@ function createVueBridgeAppWithLoader(loadRemote) {
|
|
|
707
729
|
acquireBridgeSession(spec, controlled);
|
|
708
730
|
acquiredSession = controlled;
|
|
709
731
|
}
|
|
710
|
-
const resolution = resolveBridgeContext(
|
|
732
|
+
const resolution = resolveBridgeContext(
|
|
733
|
+
spec,
|
|
734
|
+
controlled,
|
|
735
|
+
options.getContext ?? (managedSession ? () => ({}) : void 0),
|
|
736
|
+
!!managedSession
|
|
737
|
+
);
|
|
711
738
|
if (resolution.provide) provideAppContext(resolution.provide);
|
|
712
739
|
const load = loadRemote(spec, { retries: options.retries });
|
|
713
740
|
const mod = options.timeout !== void 0 ? await withBridgeTimeout(load, options.timeout, spec) : await load;
|
|
@@ -751,7 +778,17 @@ function createVueBridgeAppWithLoader(loadRemote) {
|
|
|
751
778
|
const myGeneration = generation;
|
|
752
779
|
void run(myGeneration);
|
|
753
780
|
});
|
|
754
|
-
|
|
781
|
+
if (managedSession) {
|
|
782
|
+
(0, import_vue.watch)(() => [currentSession(), managedSession.error.value, props.sessionKey], (after, before) => {
|
|
783
|
+
const released = invalidate();
|
|
784
|
+
if (after[0] === null && typeof before[0] === "string") clearAppContext();
|
|
785
|
+
if (!released) return;
|
|
786
|
+
const ticket = generation;
|
|
787
|
+
void Promise.resolve().then(() => {
|
|
788
|
+
if (ticket === generation && !containerBlocked) void run(ticket);
|
|
789
|
+
});
|
|
790
|
+
}, { flush: "sync" });
|
|
791
|
+
} else (0, import_vue.watch)(() => props.sessionKey, () => {
|
|
755
792
|
start();
|
|
756
793
|
});
|
|
757
794
|
(0, import_vue.watch)(() => routingKey(props.routing), (after, before) => {
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { DefineComponent, Component } from 'vue';
|
|
2
2
|
import { AppContext } from './context.cjs';
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
3
|
+
import { createAutomaticBridgeSession } from './bridge-session-auto.cjs';
|
|
4
|
+
import { b as BridgeHostRouting } from './bridge-core-CGFET9Qi.cjs';
|
|
5
|
+
import { a as FgBridgeAppProps, F as FgBridgeEntry } from './remote-types-Cf4SSzus.cjs';
|
|
5
6
|
import { FgTypeAuto } from '@fulgurjs/federation/internal/registry.js';
|
|
6
7
|
|
|
7
8
|
/**
|
|
8
|
-
* Vue
|
|
9
|
+
* Vue 宿主桥接工厂(公开入口 /vue 导出 createVueBridgeApp)。
|
|
9
10
|
*
|
|
10
11
|
* 定位:接收注入的 loadRemote(不静态引用运行时内核,dist 壳绑定),返回一个
|
|
11
12
|
* 包装组件 `{ appProps: P; sessionKey?: string | null }`,负责:
|
|
@@ -33,6 +34,13 @@ interface VueBridgeAppOptions {
|
|
|
33
34
|
timeout?: number;
|
|
34
35
|
/** 无副作用的同步 getter:首次、重试及换会话的实际加载前返回本次所需上下文快照 */
|
|
35
36
|
getContext?: () => Partial<AppContext> & Record<string, unknown>;
|
|
37
|
+
/**
|
|
38
|
+
* 自动会话:响应式地返回非敏感用户标识;null=已退出,undefined=用户资料恢复中。
|
|
39
|
+
* 同身份刷新/token轮换不换代,换身份自动重挂。不要再传 sessionKey prop 或在上下文里手填代次。
|
|
40
|
+
*/
|
|
41
|
+
session?: () => string | number | null | undefined;
|
|
42
|
+
/** 自动会话命名空间;同一宿主的多个远程应使用同一键,默认 fulgurjs-bridge-session。 */
|
|
43
|
+
sessionStorageKey?: string;
|
|
36
44
|
}
|
|
37
45
|
/**
|
|
38
46
|
* 构建 Vue 宿主桥接工厂(dist 壳与 dev 门面绑定各自运行时的 loadRemote 后导出)。
|
|
@@ -44,6 +52,6 @@ type FgVueBridgeWrapperResolved<P0, S extends string> = DefineComponent<{
|
|
|
44
52
|
routing?: BridgeHostRouting;
|
|
45
53
|
}, {}, unknown>;
|
|
46
54
|
type FgVueBridgeWrapper<S extends string> = FgVueBridgeWrapperResolved<FgTypeAuto, S>;
|
|
47
|
-
declare function createVueBridgeAppWithLoader(loadRemote: LoadRemoteFn): <P0 = FgTypeAuto, S extends string = string>(spec: S & FgBridgeEntry<S>, options?: VueBridgeAppOptions) => FgVueBridgeWrapperResolved<P0, S>;
|
|
55
|
+
declare function createVueBridgeAppWithLoader(loadRemote: LoadRemoteFn, automaticSession?: typeof createAutomaticBridgeSession): <P0 = FgTypeAuto, S extends string = string>(spec: S & FgBridgeEntry<S>, options?: VueBridgeAppOptions) => FgVueBridgeWrapperResolved<P0, S>;
|
|
48
56
|
|
|
49
57
|
export { type FgVueBridgeWrapper, type FgVueBridgeWrapperResolved, type VueBridgeAppOptions, createVueBridgeAppWithLoader };
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { DefineComponent, Component } from 'vue';
|
|
2
2
|
import { AppContext } from './context.js';
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
3
|
+
import { createAutomaticBridgeSession } from './bridge-session-auto.js';
|
|
4
|
+
import { b as BridgeHostRouting } from './bridge-core-Dm6ABUxQ.js';
|
|
5
|
+
import { a as FgBridgeAppProps, F as FgBridgeEntry } from './remote-types-CMtfvLcH.js';
|
|
5
6
|
import { FgTypeAuto } from '@fulgurjs/federation/internal/registry.js';
|
|
6
7
|
|
|
7
8
|
/**
|
|
8
|
-
* Vue
|
|
9
|
+
* Vue 宿主桥接工厂(公开入口 /vue 导出 createVueBridgeApp)。
|
|
9
10
|
*
|
|
10
11
|
* 定位:接收注入的 loadRemote(不静态引用运行时内核,dist 壳绑定),返回一个
|
|
11
12
|
* 包装组件 `{ appProps: P; sessionKey?: string | null }`,负责:
|
|
@@ -33,6 +34,13 @@ interface VueBridgeAppOptions {
|
|
|
33
34
|
timeout?: number;
|
|
34
35
|
/** 无副作用的同步 getter:首次、重试及换会话的实际加载前返回本次所需上下文快照 */
|
|
35
36
|
getContext?: () => Partial<AppContext> & Record<string, unknown>;
|
|
37
|
+
/**
|
|
38
|
+
* 自动会话:响应式地返回非敏感用户标识;null=已退出,undefined=用户资料恢复中。
|
|
39
|
+
* 同身份刷新/token轮换不换代,换身份自动重挂。不要再传 sessionKey prop 或在上下文里手填代次。
|
|
40
|
+
*/
|
|
41
|
+
session?: () => string | number | null | undefined;
|
|
42
|
+
/** 自动会话命名空间;同一宿主的多个远程应使用同一键,默认 fulgurjs-bridge-session。 */
|
|
43
|
+
sessionStorageKey?: string;
|
|
36
44
|
}
|
|
37
45
|
/**
|
|
38
46
|
* 构建 Vue 宿主桥接工厂(dist 壳与 dev 门面绑定各自运行时的 loadRemote 后导出)。
|
|
@@ -44,6 +52,6 @@ type FgVueBridgeWrapperResolved<P0, S extends string> = DefineComponent<{
|
|
|
44
52
|
routing?: BridgeHostRouting;
|
|
45
53
|
}, {}, unknown>;
|
|
46
54
|
type FgVueBridgeWrapper<S extends string> = FgVueBridgeWrapperResolved<FgTypeAuto, S>;
|
|
47
|
-
declare function createVueBridgeAppWithLoader(loadRemote: LoadRemoteFn): <P0 = FgTypeAuto, S extends string = string>(spec: S & FgBridgeEntry<S>, options?: VueBridgeAppOptions) => FgVueBridgeWrapperResolved<P0, S>;
|
|
55
|
+
declare function createVueBridgeAppWithLoader(loadRemote: LoadRemoteFn, automaticSession?: typeof createAutomaticBridgeSession): <P0 = FgTypeAuto, S extends string = string>(spec: S & FgBridgeEntry<S>, options?: VueBridgeAppOptions) => FgVueBridgeWrapperResolved<P0, S>;
|
|
48
56
|
|
|
49
57
|
export { type FgVueBridgeWrapper, type FgVueBridgeWrapperResolved, type VueBridgeAppOptions, createVueBridgeAppWithLoader };
|
package/dist/bridge-host-vue.js
CHANGED
|
@@ -10,11 +10,12 @@ import {
|
|
|
10
10
|
releaseBridgeSession,
|
|
11
11
|
resolveBridgeContext,
|
|
12
12
|
withBridgeTimeout
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-2MWIIRQZ.js";
|
|
14
14
|
import {
|
|
15
15
|
bridgeHostError
|
|
16
16
|
} from "./chunk-GVWC7J7Q.js";
|
|
17
17
|
import {
|
|
18
|
+
clearAppContext,
|
|
18
19
|
provideAppContext
|
|
19
20
|
} from "./chunk-TSYLDY6H.js";
|
|
20
21
|
import "./chunk-OF2JCXTZ.js";
|
|
@@ -92,9 +93,16 @@ var BridgeErrorPlaceholder = /* @__PURE__ */ defineComponent({
|
|
|
92
93
|
};
|
|
93
94
|
}
|
|
94
95
|
});
|
|
95
|
-
function createVueBridgeAppWithLoader(loadRemote) {
|
|
96
|
+
function createVueBridgeAppWithLoader(loadRemote, automaticSession) {
|
|
96
97
|
return function createVueBridgeApp(spec, options = {}) {
|
|
97
98
|
assertBridgeOptions(`createVueBridgeApp("${spec}")`, options);
|
|
99
|
+
if (options.session !== void 0 && typeof options.session !== "function") {
|
|
100
|
+
throw new TypeError("createVueBridgeApp \u7684 session \u5FC5\u987B\u662F\u540C\u6B65\u8EAB\u4EFD getter\uFF0C\u4F8B\u5982 session: () => auth.userId\uFF1B\u5DF2\u9000\u51FA\u8FD4\u56DE null\uFF0C\u8EAB\u4EFD\u6062\u590D\u4E2D\u8FD4\u56DE undefined\u3002");
|
|
101
|
+
}
|
|
102
|
+
if (options.session && !automaticSession) throw new Error("Vue\u6865\u63A5\u5165\u53E3\u672A\u7ED1\u5B9A\u81EA\u52A8\u4F1A\u8BDD\u5B9E\u73B0\uFF1B\u8BF7\u4ECE @fulgurjs/federation/vue \u5BFC\u5165\uFF0C\u4E0D\u76F4\u63A5\u8C03\u7528\u5185\u90E8\u5DE5\u5382\u3002");
|
|
103
|
+
if (options.sessionStorageKey !== void 0 && (!options.session || typeof options.sessionStorageKey !== "string" || !options.sessionStorageKey.trim())) {
|
|
104
|
+
throw new TypeError("sessionStorageKey \u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32\uFF0C\u5E76\u4E0E session \u8EAB\u4EFD getter \u4E00\u8D77\u914D\u7F6E\uFF1B\u540C\u4E00\u5BBF\u4E3B\u7684\u8FDC\u7A0B\u4F7F\u7528\u76F8\u540C\u952E\u3002");
|
|
105
|
+
}
|
|
98
106
|
const componentName = "FulgurjsBridge_" + spec.replace(/[^A-Za-z0-9_-]/g, "_");
|
|
99
107
|
return defineComponent({
|
|
100
108
|
name: componentName,
|
|
@@ -108,6 +116,8 @@ function createVueBridgeAppWithLoader(loadRemote) {
|
|
|
108
116
|
routing: { type: Object, required: false, default: void 0 }
|
|
109
117
|
},
|
|
110
118
|
setup(props) {
|
|
119
|
+
const managedSession = options.session ? automaticSession(options.session, options.sessionStorageKey ?? "fulgurjs-bridge-session") : void 0;
|
|
120
|
+
const currentSession = () => managedSession ? managedSession.sessionKey.value : props.sessionKey;
|
|
111
121
|
const status = ref("idle");
|
|
112
122
|
const error = shallowRef(void 0);
|
|
113
123
|
const container = ref(null);
|
|
@@ -151,9 +161,19 @@ function createVueBridgeAppWithLoader(loadRemote) {
|
|
|
151
161
|
const run = async (myGeneration) => {
|
|
152
162
|
const el = container.value;
|
|
153
163
|
if (!el) return;
|
|
154
|
-
const sk =
|
|
164
|
+
const sk = currentSession();
|
|
155
165
|
status.value = "pending";
|
|
156
166
|
error.value = void 0;
|
|
167
|
+
if (managedSession && props.sessionKey !== void 0) {
|
|
168
|
+
error.value = bridgeHostError("getContext", spec, new Error("session \u81EA\u52A8\u7BA1\u7406\u4E0E sessionKey prop \u4E0D\u80FD\u540C\u65F6\u8BBE\u7F6E\uFF1B\u4FDD\u7559 session \u8EAB\u4EFD getter\uFF0C\u79FB\u9664\u624B\u5DE5\u4EE3\u6B21\u7ED1\u5B9A\u3002"));
|
|
169
|
+
status.value = "error";
|
|
170
|
+
return;
|
|
171
|
+
}
|
|
172
|
+
if (managedSession?.error.value !== void 0) {
|
|
173
|
+
error.value = bridgeHostError("getContext", spec, managedSession.error.value);
|
|
174
|
+
status.value = "error";
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
157
177
|
if (sk === null) {
|
|
158
178
|
status.value = "idle";
|
|
159
179
|
return;
|
|
@@ -166,7 +186,12 @@ function createVueBridgeAppWithLoader(loadRemote) {
|
|
|
166
186
|
acquireBridgeSession(spec, controlled);
|
|
167
187
|
acquiredSession = controlled;
|
|
168
188
|
}
|
|
169
|
-
const resolution = resolveBridgeContext(
|
|
189
|
+
const resolution = resolveBridgeContext(
|
|
190
|
+
spec,
|
|
191
|
+
controlled,
|
|
192
|
+
options.getContext ?? (managedSession ? () => ({}) : void 0),
|
|
193
|
+
!!managedSession
|
|
194
|
+
);
|
|
170
195
|
if (resolution.provide) provideAppContext(resolution.provide);
|
|
171
196
|
const load = loadRemote(spec, { retries: options.retries });
|
|
172
197
|
const mod = options.timeout !== void 0 ? await withBridgeTimeout(load, options.timeout, spec) : await load;
|
|
@@ -210,7 +235,17 @@ function createVueBridgeAppWithLoader(loadRemote) {
|
|
|
210
235
|
const myGeneration = generation;
|
|
211
236
|
void run(myGeneration);
|
|
212
237
|
});
|
|
213
|
-
|
|
238
|
+
if (managedSession) {
|
|
239
|
+
watch(() => [currentSession(), managedSession.error.value, props.sessionKey], (after, before) => {
|
|
240
|
+
const released = invalidate();
|
|
241
|
+
if (after[0] === null && typeof before[0] === "string") clearAppContext();
|
|
242
|
+
if (!released) return;
|
|
243
|
+
const ticket = generation;
|
|
244
|
+
void Promise.resolve().then(() => {
|
|
245
|
+
if (ticket === generation && !containerBlocked) void run(ticket);
|
|
246
|
+
});
|
|
247
|
+
}, { flush: "sync" });
|
|
248
|
+
} else watch(() => props.sessionKey, () => {
|
|
214
249
|
start();
|
|
215
250
|
});
|
|
216
251
|
watch(() => routingKey(props.routing), (after, before) => {
|