@axewo/fin-micro 1.0.0 → 2.0.1
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/README.md +181 -4
- package/cli/index.mjs +22 -6
- package/dist/browser.cjs +1 -1
- package/dist/browser.mjs +68 -66
- package/dist/core.cjs +1 -1
- package/dist/core.mjs +459 -441
- package/dist/index.cjs +1 -1
- package/dist/index.mjs +31 -24
- package/dist/layout.cjs +1 -0
- package/dist/layout.css +1 -0
- package/dist/layout.mjs +719 -0
- package/dist/{router-view-impl-C1KG6mxu.mjs → router-view-impl-B1NzCGKV.mjs} +18 -18
- package/dist/router-view-impl-BvOToV_Z.cjs +1 -0
- package/dist/runtime.cjs +1 -1
- package/dist/runtime.mjs +40 -39
- package/dist/sdk.cjs +1 -1
- package/dist/sdk.mjs +92 -56
- package/dist/types/browser/index.d.ts +4 -0
- package/dist/types/core/index.d.ts +1 -1
- package/dist/types/index.d.ts +2 -0
- package/dist/types/layout/HostShell.vue.d.ts +528 -0
- package/dist/types/layout/ShellHeader.vue.d.ts +46 -0
- package/dist/types/layout/ShellMenu.vue.d.ts +12 -0
- package/dist/types/layout/ShellTabs.vue.d.ts +23 -0
- package/dist/types/layout/StandaloneMenuItem.vue.d.ts +11 -0
- package/dist/types/layout/StandaloneShell.vue.d.ts +40 -0
- package/dist/types/layout/index.d.ts +5 -0
- package/dist/types/layout/types.d.ts +65 -0
- package/dist/types/runtime/lifecycle.d.ts +1 -1
- package/dist/types/sdk/index.d.ts +65 -4
- package/dist/types/vue/index.d.ts +13 -2
- package/dist/types/vue/router-view-impl.d.ts +1 -1
- package/dist/types/watermark/FinWatermark.vue.d.ts +16 -0
- package/dist/types/watermark/config.d.ts +36 -0
- package/dist/types/watermark/index.d.ts +4 -0
- package/dist/vue.cjs +1 -1
- package/dist/vue.mjs +49 -35
- package/dist/watermark.cjs +2 -0
- package/dist/watermark.mjs +119 -0
- package/package.json +29 -4
- package/scaffold/base/index.html +2 -1
- package/scaffold/base/package.json.template +5 -1
- package/scaffold/base/pnpm-workspace.yaml +6 -0
- package/scaffold/base/scripts/check-runtime.mjs +43 -0
- package/scaffold/base/src/locales/en.ts +12 -0
- package/scaffold/base/src/locales/index.ts +7 -1
- package/scaffold/base/src/locales/zh-CN.ts +12 -0
- package/scaffold/base/src/main.ts +13 -5
- package/scaffold/base/src/router/demo.ts +6 -0
- package/scaffold/base/src/router/index.ts +13 -0
- package/scaffold/base/src/stores/demo.ts +12 -0
- package/scaffold/base/src/stores/index.ts +11 -0
- package/scaffold/base/src/utils/appConfig.ts +49 -0
- package/scaffold/base/src/utils/errorUtils.ts +109 -0
- package/scaffold/base/src/utils/requestUtils.ts +32 -11
- package/scaffold/base/src/utils/watermarkConfig.ts +18 -0
- package/scaffold/base/src/views/demo/index.vue +26 -0
- package/scaffold/host/.env.example +11 -3
- package/scaffold/host/src/App.vue +1 -13
- package/scaffold/host/src/bootstrap.ts +40 -8
- package/scaffold/host/src/hooks/usePlatformSession.ts +40 -8
- package/scaffold/host/src/layout/HostHeader.vue +65 -5
- package/scaffold/host/src/layout/HostLayout.vue +65 -21
- package/scaffold/host/src/layout/HostMenu.vue +11 -2
- package/scaffold/host/src/layout/HostTabs.vue +91 -8
- package/scaffold/host/src/layout/HostWorkspace.vue +29 -7
- package/scaffold/host/src/localPages.ts +45 -0
- package/scaffold/host/src/platform.ts +51 -14
- package/scaffold/host/src/router/guards.ts +128 -0
- package/scaffold/host/src/router/index.ts +25 -0
- package/scaffold/host/src/router/targets.ts +30 -0
- package/scaffold/host/src/router/workspace.ts +63 -0
- package/scaffold/host/src/styles/shell.css +776 -0
- package/scaffold/host/src/utils/request.ts +30 -3
- package/scaffold/host/src/views/home/index.vue +19 -0
- package/scaffold/host/src/views/login/components/LoginForm.vue +83 -0
- package/scaffold/host/src/views/login/index.vue +16 -0
- package/scaffold/host/src/views/not-found/index.vue +1 -0
- package/scaffold/host/src/views/profile/index.vue +24 -0
- package/scaffold/host/src/views/workspace/index.vue +11 -0
- package/scaffold/layouts/standard/host/src/layout/HostLayout.vue +116 -0
- package/scaffold/layouts/standard/host/src/styles/shell.css +168 -0
- package/scaffold/layouts/standard/vue/src/layout/StandaloneLayout.vue +26 -0
- package/scaffold/vue/src/App.vue +13 -7
- package/scaffold/vue/src/bootstrap.ts +25 -24
- package/scaffold/vue/src/bridge/auth.ts +23 -0
- package/scaffold/vue/src/bridge/session.ts +2 -2
- package/scaffold/vue/src/layout/Header.vue +15 -0
- package/scaffold/vue/src/layout/Sidebar.vue +21 -0
- package/scaffold/vue/src/layout/SidebarItem.vue +21 -0
- package/scaffold/vue/src/layout/StandaloneLayout.vue +34 -0
- package/scaffold/vue/src/main.ts +5 -2
- package/scaffold/vue/src/router/index.ts +9 -4
- package/scaffold/vue/src/router/menu.ts +38 -0
- package/scaffold/vue/src/views/demo/configs/table.ts +24 -0
- package/scaffold/vue/src/views/demo/hooks/useRecordNavigation.ts +32 -0
- package/scaffold/vue/src/views/demo/index.vue +17 -0
- package/scaffold/vue/src/views/{DetailView.vue → demo/modules/detail/index.vue} +15 -6
- package/scaffold/vue/src/views/demo/types.ts +5 -0
- package/dist/router-view-impl-CgLEalx4.cjs +0 -1
- package/scaffold/host/src/views/LoginView.vue +0 -38
- package/scaffold/vue/src/views/ListView.vue +0 -51
- /package/scaffold/vue/src/views/{NotFoundView.vue → not-found/index.vue} +0 -0
package/dist/core.mjs
CHANGED
|
@@ -1,640 +1,658 @@
|
|
|
1
|
-
import { createNotificationBus as
|
|
2
|
-
function
|
|
3
|
-
var
|
|
4
|
-
const
|
|
5
|
-
for (const
|
|
6
|
-
let
|
|
7
|
-
if (!Array.isArray(
|
|
1
|
+
import { createNotificationBus as We, NavigationError as p, HostCallError as z } from "./sdk.mjs";
|
|
2
|
+
function Ze(Ne, R = {}) {
|
|
3
|
+
var Ae;
|
|
4
|
+
const X = /* @__PURE__ */ new Map(), pe = /* @__PURE__ */ new Map(), x = (e) => typeof e == "string" && !!e.trim() && !/[\u0000-\u001f\u007f]/.test(e), de = (e) => x(e) && e.startsWith("/") && !e.startsWith("//") && !e.includes("\\"), we = (e) => e.split(/[?#]/, 1)[0];
|
|
5
|
+
for (const e of Ne) {
|
|
6
|
+
let s = function(r) {
|
|
7
|
+
if (!Array.isArray(r)) throw new Error("menus 必须为数组");
|
|
8
8
|
return Object.freeze(
|
|
9
|
-
|
|
10
|
-
if (!
|
|
9
|
+
r.map((a) => {
|
|
10
|
+
if (!a || !x(a.menuId) || !x(a.name) || c.has(a.menuId))
|
|
11
11
|
throw new Error("菜单标识/名称无效或菜单标识重复");
|
|
12
|
-
if (
|
|
13
|
-
|
|
12
|
+
if (c.add(a.menuId), a.icon !== void 0 && (typeof a.icon != "string" || !/^[A-Za-z][A-Za-z0-9-]{0,63}$/.test(a.icon)))
|
|
13
|
+
throw new Error("菜单图标标识无效");
|
|
14
|
+
if (a.children !== void 0) {
|
|
15
|
+
if (a.target !== void 0 || !Array.isArray(a.children) || !a.children.length)
|
|
14
16
|
throw new Error("菜单分组需要非空 children 且不能配置 target");
|
|
15
17
|
return Object.freeze({
|
|
16
|
-
menuId:
|
|
17
|
-
name:
|
|
18
|
-
|
|
18
|
+
menuId: a.menuId,
|
|
19
|
+
name: a.name,
|
|
20
|
+
...a.icon === void 0 ? {} : { icon: a.icon },
|
|
21
|
+
children: s(a.children)
|
|
19
22
|
});
|
|
20
23
|
}
|
|
21
|
-
if (!
|
|
24
|
+
if (!a.target || !x(a.target.tabId) || !de(a.target.route))
|
|
22
25
|
throw new Error("菜单叶节点需要有效 target");
|
|
23
|
-
return h.add(
|
|
24
|
-
menuId:
|
|
25
|
-
name:
|
|
26
|
-
|
|
26
|
+
return h.add(a.menuId), b.push({ pathPrefix: we(a.target.route), menuId: a.menuId }), Object.freeze({
|
|
27
|
+
menuId: a.menuId,
|
|
28
|
+
name: a.name,
|
|
29
|
+
...a.icon === void 0 ? {} : { icon: a.icon },
|
|
30
|
+
target: Object.freeze({ tabId: a.target.tabId, route: a.target.route })
|
|
27
31
|
});
|
|
28
32
|
})
|
|
29
33
|
);
|
|
30
34
|
};
|
|
31
|
-
if (
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
35
|
+
if (X.has(e.appId)) throw new Error(`重复的 appId: ${e.appId}`);
|
|
36
|
+
if (e.kind === "local") {
|
|
37
|
+
if (e.entry !== void 0) throw new Error("本地应用不能配置 entry");
|
|
38
|
+
} else {
|
|
39
|
+
if (e.kind !== void 0 && e.kind !== "remote") throw new Error("未知应用类型");
|
|
40
|
+
const r = new URL(e.entry);
|
|
41
|
+
if (!["http:", "https:"].includes(r.protocol)) throw new Error("子应用地址必须使用 HTTP(S)");
|
|
42
|
+
}
|
|
43
|
+
const c = /* @__PURE__ */ new Set(), h = /* @__PURE__ */ new Set(), b = [], u = e.menus === void 0 ? void 0 : s(e.menus);
|
|
44
|
+
if (e.menuRoutes !== void 0 && !Array.isArray(e.menuRoutes))
|
|
36
45
|
throw new Error("menuRoutes 必须为数组");
|
|
37
|
-
const
|
|
38
|
-
if (!
|
|
46
|
+
const o = (Ae = e.menuRoutes) == null ? void 0 : Ae.map((r) => {
|
|
47
|
+
if (!r || !de(r.pathPrefix) || /[?#]/.test(r.pathPrefix) || !h.has(r.menuId))
|
|
39
48
|
throw new Error("菜单归属规则需要有效路径与本应用可导航叶节点");
|
|
40
|
-
return Object.freeze({ pathPrefix:
|
|
49
|
+
return Object.freeze({ pathPrefix: r.pathPrefix, menuId: r.menuId });
|
|
41
50
|
});
|
|
42
|
-
|
|
43
|
-
const
|
|
44
|
-
for (const
|
|
45
|
-
if (
|
|
51
|
+
b.push(...(o ?? []).map((r) => ({ ...r })));
|
|
52
|
+
const t = /* @__PURE__ */ new Map();
|
|
53
|
+
for (const r of b) {
|
|
54
|
+
if (r.pathPrefix = r.pathPrefix.replace(/\/+$/, "") || "/", t.has(r.pathPrefix) && t.get(r.pathPrefix) !== r.menuId)
|
|
46
55
|
throw new Error("菜单归属前缀冲突");
|
|
47
|
-
|
|
56
|
+
t.set(r.pathPrefix, r.menuId);
|
|
48
57
|
}
|
|
49
|
-
|
|
58
|
+
pe.set(e.appId, {
|
|
50
59
|
leaves: h,
|
|
51
|
-
routes:
|
|
52
|
-
}),
|
|
53
|
-
|
|
60
|
+
routes: b.sort((r, a) => a.pathPrefix.length - r.pathPrefix.length)
|
|
61
|
+
}), X.set(
|
|
62
|
+
e.appId,
|
|
54
63
|
Object.freeze({
|
|
55
|
-
appId:
|
|
56
|
-
name:
|
|
57
|
-
entry:
|
|
58
|
-
...
|
|
59
|
-
...
|
|
64
|
+
appId: e.appId,
|
|
65
|
+
name: e.name,
|
|
66
|
+
...e.kind === "local" ? { kind: "local" } : { ...e.kind ? { kind: e.kind } : {}, entry: e.entry },
|
|
67
|
+
...u ? { menus: u } : {},
|
|
68
|
+
...o ? { menuRoutes: Object.freeze(o) } : {}
|
|
60
69
|
})
|
|
61
70
|
);
|
|
62
71
|
}
|
|
63
|
-
const
|
|
64
|
-
on(
|
|
65
|
-
return
|
|
72
|
+
const ae = We(), Re = Object.freeze({ source: "host" }), le = {
|
|
73
|
+
on(e, s) {
|
|
74
|
+
return ae.on(e, ({ payload: c, metadata: h }) => Z(() => s(c, h)));
|
|
66
75
|
},
|
|
67
|
-
emit(
|
|
68
|
-
|
|
76
|
+
emit(e, s) {
|
|
77
|
+
ae.emit(e, { payload: s, metadata: Re });
|
|
69
78
|
},
|
|
70
|
-
clear: () =>
|
|
71
|
-
},
|
|
72
|
-
if (!Number.isFinite(
|
|
79
|
+
clear: () => ae.clear()
|
|
80
|
+
}, ie = R.callTimeoutMs ?? 3e4;
|
|
81
|
+
if (!Number.isFinite(ie) || ie <= 0 || ie > 2147483647)
|
|
73
82
|
throw new Error("callTimeoutMs 必须为不超过2147483647的正有限数");
|
|
74
|
-
const
|
|
75
|
-
function
|
|
76
|
-
if (!
|
|
83
|
+
const K = /* @__PURE__ */ new Set();
|
|
84
|
+
function ke(e, s) {
|
|
85
|
+
if (!e || typeof e.authenticated != "boolean" || !Array.isArray(e.permissions) || !e.permissions.every((c) => typeof c == "string") || e.user !== void 0 && (!e.user || typeof e.user.id != "string" || e.user.name !== void 0 && typeof e.user.name != "string"))
|
|
77
86
|
throw new Error("会话快照无效");
|
|
78
87
|
return Object.freeze({
|
|
79
|
-
authenticated:
|
|
80
|
-
permissions: Object.freeze([...
|
|
81
|
-
...
|
|
82
|
-
revision:
|
|
88
|
+
authenticated: e.authenticated,
|
|
89
|
+
permissions: Object.freeze([...e.permissions]),
|
|
90
|
+
...e.user ? { user: Object.freeze({ id: e.user.id, ...e.user.name !== void 0 ? { name: e.user.name } : {} }) } : {},
|
|
91
|
+
revision: s
|
|
83
92
|
});
|
|
84
93
|
}
|
|
85
|
-
let
|
|
86
|
-
function
|
|
87
|
-
|
|
88
|
-
const
|
|
89
|
-
for (const
|
|
90
|
-
if (
|
|
91
|
-
|
|
94
|
+
let ee = ke(R.session ?? { authenticated: !1, permissions: [] }, 0);
|
|
95
|
+
function xe(e) {
|
|
96
|
+
j(), ee = ke(e, ee.revision + 1);
|
|
97
|
+
const s = ee;
|
|
98
|
+
for (const c of [...K]) {
|
|
99
|
+
if (s !== ee) break;
|
|
100
|
+
K.has(c) && Z(() => c(s));
|
|
92
101
|
}
|
|
93
|
-
return
|
|
102
|
+
return s;
|
|
94
103
|
}
|
|
95
|
-
const
|
|
96
|
-
Object.entries(R.capabilities ?? {}).filter(([,
|
|
97
|
-
const
|
|
104
|
+
const te = /* @__PURE__ */ new Set(), re = /* @__PURE__ */ new Map(), ve = new Map(
|
|
105
|
+
Object.entries(R.capabilities ?? {}).filter(([, e]) => e !== void 0).map(([e, s]) => {
|
|
106
|
+
const c = s;
|
|
98
107
|
return [
|
|
99
|
-
|
|
100
|
-
{ handler:
|
|
108
|
+
e,
|
|
109
|
+
{ handler: c.handler, apps: c.apps ? new Set(c.apps) : void 0 }
|
|
101
110
|
];
|
|
102
111
|
})
|
|
103
|
-
),
|
|
104
|
-
let
|
|
105
|
-
const
|
|
106
|
-
var
|
|
112
|
+
), B = /* @__PURE__ */ new Map(), G = /* @__PURE__ */ new Map();
|
|
113
|
+
let d = { tabs: [], activeTabId: null }, be = 0, D = !1, W = 0, Ee = Promise.resolve();
|
|
114
|
+
const oe = /* @__PURE__ */ new Map(), U = /* @__PURE__ */ new Map(), _e = (e) => {
|
|
115
|
+
var s;
|
|
107
116
|
try {
|
|
108
|
-
(
|
|
117
|
+
(s = R.onError) == null || s.call(R, e);
|
|
109
118
|
} catch {
|
|
110
119
|
}
|
|
111
|
-
},
|
|
120
|
+
}, Z = (e) => {
|
|
112
121
|
try {
|
|
113
|
-
|
|
114
|
-
} catch (
|
|
115
|
-
|
|
122
|
+
e();
|
|
123
|
+
} catch (s) {
|
|
124
|
+
_e(s);
|
|
116
125
|
}
|
|
117
|
-
},
|
|
118
|
-
if (
|
|
119
|
-
},
|
|
120
|
-
|
|
121
|
-
for (const
|
|
122
|
-
|
|
126
|
+
}, j = () => {
|
|
127
|
+
if (D) throw new Error("MicroHost 已销毁");
|
|
128
|
+
}, ce = () => ({ tabs: [...d.tabs], activeTabId: d.activeTabId }), ne = () => {
|
|
129
|
+
W++;
|
|
130
|
+
for (const e of [...te])
|
|
131
|
+
te.has(e) && Z(() => e(ce()));
|
|
123
132
|
};
|
|
124
|
-
function
|
|
125
|
-
return
|
|
126
|
-
|
|
133
|
+
function me(e) {
|
|
134
|
+
return j(), te.add(e), () => {
|
|
135
|
+
te.delete(e);
|
|
127
136
|
};
|
|
128
137
|
}
|
|
129
|
-
const
|
|
130
|
-
function q(
|
|
131
|
-
if (!
|
|
132
|
-
const
|
|
133
|
-
appId:
|
|
134
|
-
tabId:
|
|
135
|
-
title:
|
|
136
|
-
route:
|
|
137
|
-
...
|
|
138
|
+
const ue = R.canNavigate, ge = R.canOpen;
|
|
139
|
+
function q(e) {
|
|
140
|
+
if (!ge) return;
|
|
141
|
+
const s = Object.freeze({
|
|
142
|
+
appId: e.appId,
|
|
143
|
+
tabId: e.tabId,
|
|
144
|
+
title: e.title,
|
|
145
|
+
route: e.route,
|
|
146
|
+
...e.activeMenuId !== void 0 ? { activeMenuId: e.activeMenuId } : {}
|
|
138
147
|
});
|
|
139
148
|
try {
|
|
140
|
-
const
|
|
141
|
-
if (
|
|
142
|
-
|
|
149
|
+
const c = ge(s);
|
|
150
|
+
if (c === !0) return;
|
|
151
|
+
c && (typeof c == "object" || typeof c == "function") && Promise.resolve(c).catch(() => {
|
|
143
152
|
});
|
|
144
153
|
} catch {
|
|
145
154
|
}
|
|
146
|
-
throw new
|
|
155
|
+
throw new p("FORBIDDEN", "无权访问该页面(权限策略必须同步返回 true)");
|
|
147
156
|
}
|
|
148
|
-
function
|
|
149
|
-
var
|
|
150
|
-
if (
|
|
157
|
+
function he(e, s = !1) {
|
|
158
|
+
var o;
|
|
159
|
+
if (j(), !e || !x(e.title) || e.title.length > 500)
|
|
151
160
|
throw new Error("页签标题无效");
|
|
152
|
-
if (!
|
|
153
|
-
if (!
|
|
161
|
+
if (!X.has(e.appId)) throw new Error(`未知子应用: ${e.appId}`);
|
|
162
|
+
if (!x(e.tabId) || !de(e.route))
|
|
154
163
|
throw new Error("需要 tabId 与应用内绝对路由");
|
|
155
|
-
const
|
|
156
|
-
if (
|
|
164
|
+
const c = pe.get(e.appId);
|
|
165
|
+
if (e.activeMenuId !== void 0 && !c.leaves.has(e.activeMenuId))
|
|
157
166
|
throw new Error("activeMenuId 必须指向本应用可导航叶节点");
|
|
158
|
-
const
|
|
159
|
-
(
|
|
160
|
-
)) == null ? void 0 :
|
|
161
|
-
let u =
|
|
162
|
-
if (u && (u.appId !==
|
|
167
|
+
const h = we(e.route), b = e.activeMenuId ?? ((o = c.routes.find(
|
|
168
|
+
(t) => t.pathPrefix === "/" || h === t.pathPrefix || h.startsWith(`${t.pathPrefix}/`)
|
|
169
|
+
)) == null ? void 0 : o.menuId);
|
|
170
|
+
let u = d.tabs.find((t) => t.tabId === e.tabId);
|
|
171
|
+
if (u && (u.appId !== e.appId || u.route !== e.route && !s))
|
|
163
172
|
throw new Error("tabId 已绑定到其他页面");
|
|
164
|
-
return u && u.route !==
|
|
165
|
-
appId:
|
|
166
|
-
tabId:
|
|
167
|
-
title:
|
|
168
|
-
route:
|
|
169
|
-
...
|
|
170
|
-
key: `${
|
|
173
|
+
return u && u.route !== e.route && (u = void 0), q(u ?? { ...e, activeMenuId: b }), u || (u = Object.freeze({
|
|
174
|
+
appId: e.appId,
|
|
175
|
+
tabId: e.tabId,
|
|
176
|
+
title: e.title,
|
|
177
|
+
route: e.route,
|
|
178
|
+
...b !== void 0 ? { activeMenuId: b } : {},
|
|
179
|
+
key: `${e.tabId}:${++be}`
|
|
171
180
|
})), u;
|
|
172
181
|
}
|
|
173
|
-
function
|
|
174
|
-
const
|
|
175
|
-
return
|
|
176
|
-
tabs:
|
|
177
|
-
activeTabId:
|
|
178
|
-
},
|
|
182
|
+
function He(e) {
|
|
183
|
+
const s = he(e);
|
|
184
|
+
return d = {
|
|
185
|
+
tabs: d.tabs.includes(s) ? d.tabs : [...d.tabs, s],
|
|
186
|
+
activeTabId: s.tabId
|
|
187
|
+
}, ne(), s;
|
|
179
188
|
}
|
|
180
|
-
function
|
|
181
|
-
if (
|
|
189
|
+
function Fe(e, s, c) {
|
|
190
|
+
if (j(), typeof s.title != "string" || !s.title.trim() || s.title.length > 500 || /[\u0000-\u001f\u007f]/.test(s.title))
|
|
182
191
|
throw new Error("页签标题无效");
|
|
183
|
-
const
|
|
184
|
-
(u) => u.tabId ===
|
|
192
|
+
const h = d.tabs.find(
|
|
193
|
+
(u) => u.tabId === e && (!c || u.key === c)
|
|
185
194
|
);
|
|
186
|
-
if (!
|
|
187
|
-
const
|
|
188
|
-
return
|
|
195
|
+
if (!h) return;
|
|
196
|
+
const b = Object.freeze({ ...h, title: s.title });
|
|
197
|
+
return d = { ...d, tabs: d.tabs.map((u) => u === h ? b : u) }, ne(), b;
|
|
189
198
|
}
|
|
190
|
-
function $e(
|
|
191
|
-
|
|
192
|
-
const
|
|
193
|
-
return
|
|
199
|
+
function $e(e) {
|
|
200
|
+
j();
|
|
201
|
+
const s = d.tabs.find((c) => c.tabId === e);
|
|
202
|
+
return s ? (q(s), d = { ...d, activeTabId: e }, ne(), !0) : !1;
|
|
194
203
|
}
|
|
195
|
-
function Ce(
|
|
204
|
+
function Ce(e, s) {
|
|
196
205
|
var u;
|
|
197
|
-
|
|
198
|
-
const
|
|
199
|
-
(
|
|
206
|
+
j();
|
|
207
|
+
const c = d.tabs.findIndex(
|
|
208
|
+
(o) => o.tabId === e && (!s || o.key === s)
|
|
200
209
|
);
|
|
201
|
-
if (
|
|
202
|
-
const
|
|
203
|
-
if (
|
|
204
|
-
tabs:
|
|
205
|
-
activeTabId:
|
|
206
|
-
},
|
|
207
|
-
for (const
|
|
208
|
-
|
|
210
|
+
if (c < 0) return !1;
|
|
211
|
+
const h = d.tabs[c], b = d.tabs.filter((o) => o !== h);
|
|
212
|
+
if (d = {
|
|
213
|
+
tabs: b,
|
|
214
|
+
activeTabId: d.activeTabId === e ? ((u = b[Math.min(c, b.length - 1)]) == null ? void 0 : u.tabId) ?? null : d.activeTabId
|
|
215
|
+
}, Oe(h.key), !b.some((o) => o.appId === h.appId)) {
|
|
216
|
+
for (const o of [...G.get(h.appId) ?? []]) Z(o);
|
|
217
|
+
G.delete(h.appId), re.delete(h.appId);
|
|
209
218
|
}
|
|
210
|
-
return
|
|
219
|
+
return ne(), !0;
|
|
211
220
|
}
|
|
212
|
-
function
|
|
213
|
-
|
|
214
|
-
for (const
|
|
215
|
-
|
|
221
|
+
function Oe(e) {
|
|
222
|
+
oe.delete(e), U.delete(e);
|
|
223
|
+
for (const s of [...B.get(e) ?? []]) Z(s);
|
|
224
|
+
B.delete(e);
|
|
216
225
|
}
|
|
217
|
-
function
|
|
218
|
-
return
|
|
226
|
+
function Ve(e) {
|
|
227
|
+
return Y(e);
|
|
219
228
|
}
|
|
220
|
-
function
|
|
229
|
+
function Y(e, s, c, h = !1, b, u = !1) {
|
|
230
|
+
var o;
|
|
221
231
|
try {
|
|
222
|
-
if (
|
|
223
|
-
if (!
|
|
224
|
-
throw new
|
|
225
|
-
const
|
|
226
|
-
...
|
|
227
|
-
..."target" in
|
|
228
|
-
..."anchor" in
|
|
229
|
-
},
|
|
230
|
-
if (["activate", "refresh", "close"].includes(
|
|
231
|
-
throw new
|
|
232
|
-
if ("target" in
|
|
233
|
-
throw new
|
|
234
|
-
if (
|
|
235
|
-
if (!Array.isArray(
|
|
236
|
-
throw new
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
(
|
|
240
|
-
var
|
|
232
|
+
if (D) throw new p("HOST_DISPOSED", "MicroHost 已销毁");
|
|
233
|
+
if (!e || !["open", "activate", "refresh", "close", "closeMany", "back"].includes(e.type))
|
|
234
|
+
throw new p("INVALID_OPERATION", "导航命令无效");
|
|
235
|
+
const t = {
|
|
236
|
+
...e,
|
|
237
|
+
..."target" in e && e.target ? { target: { ...e.target } } : {},
|
|
238
|
+
..."anchor" in e && e.anchor ? { anchor: { ...e.anchor } } : {}
|
|
239
|
+
}, r = (n) => !!n && x(n.tabId) && (n.key === void 0 || x(n.key));
|
|
240
|
+
if (["activate", "refresh", "close"].includes(t.type) && (!("target" in t) || !r(t.target)))
|
|
241
|
+
throw new p("INVALID_OPERATION", "导航需要合法目标引用");
|
|
242
|
+
if ("target" in t && t.target !== void 0 && !r(t.target) || "anchor" in t && t.anchor !== void 0 && !r(t.anchor))
|
|
243
|
+
throw new p("INVALID_OPERATION", "导航引用无效");
|
|
244
|
+
if (t.type === "closeMany" && t.exclude !== void 0) {
|
|
245
|
+
if (!Array.isArray(t.exclude) || !t.exclude.every(r))
|
|
246
|
+
throw new p("INVALID_OPERATION", "批量排除引用无效");
|
|
247
|
+
t.exclude = Object.freeze(
|
|
248
|
+
t.exclude.map(
|
|
249
|
+
(n) => {
|
|
250
|
+
var g;
|
|
241
251
|
return Object.freeze({
|
|
242
|
-
tabId:
|
|
243
|
-
...
|
|
252
|
+
tabId: n.tabId,
|
|
253
|
+
...n.key !== void 0 ? { key: n.key } : { key: (g = d.tabs.find((k) => k.tabId === n.tabId)) == null ? void 0 : g.key }
|
|
244
254
|
});
|
|
245
255
|
}
|
|
246
256
|
)
|
|
247
257
|
);
|
|
248
258
|
}
|
|
249
|
-
if (
|
|
250
|
-
const
|
|
251
|
-
if (!
|
|
252
|
-
|
|
253
|
-
appId:
|
|
254
|
-
tabId:
|
|
255
|
-
title:
|
|
256
|
-
route:
|
|
257
|
-
...
|
|
259
|
+
if (t.type === "open") {
|
|
260
|
+
const n = t.input;
|
|
261
|
+
if (!n) throw new p("INVALID_OPERATION", "导航目标无效");
|
|
262
|
+
t.input = Object.freeze({
|
|
263
|
+
appId: n.appId,
|
|
264
|
+
tabId: n.tabId,
|
|
265
|
+
title: n.title,
|
|
266
|
+
route: n.route,
|
|
267
|
+
...n.activeMenuId !== void 0 ? { activeMenuId: n.activeMenuId } : {}
|
|
258
268
|
});
|
|
259
269
|
}
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
270
|
+
if ("closeFallback" in t && t.closeFallback !== void 0) {
|
|
271
|
+
if (!r(t.closeFallback)) throw new p("INVALID_OPERATION", "关闭回落引用无效");
|
|
272
|
+
const n = t.closeFallback;
|
|
273
|
+
t.closeFallback = Object.freeze({ tabId: n.tabId, key: n.key ?? ((o = d.tabs.find((g) => g.tabId === n.tabId)) == null ? void 0 : o.key) });
|
|
274
|
+
}
|
|
275
|
+
"fallback" in t && t.fallback && (t.fallback = Object.freeze({ ...t.fallback })), "target" in t && t.target && Object.freeze(t.target), "anchor" in t && t.anchor && Object.freeze(t.anchor), Object.freeze(t);
|
|
276
|
+
const a = (n) => d.tabs.find(
|
|
277
|
+
(g) => n ? g.tabId === n.tabId && (!n.key || g.key === n.key) : g.tabId === d.activeTabId
|
|
278
|
+
), w = "target" in t ? a(t.target) : void 0, v = t.type === "closeMany" && t.scope !== "all" ? t.anchor ? a(t.anchor) : c ? d.tabs.find((n) => n.key === c) : a() : void 0, S = a(), f = t.type === "open" ? d.tabs.find((n) => n.tabId === t.input.tabId) : void 0, I = u && c ? d.tabs.find((n) => n.key === c) : void 0, E = I && s ? Object.freeze({ appId: s, tab: Object.freeze({ ...I }) }) : void 0, _ = u && t.type === "open" && !!s && t.input.appId !== s, L = () => {
|
|
279
|
+
if (!(!_ || t.type !== "open")) {
|
|
265
280
|
try {
|
|
266
|
-
const
|
|
267
|
-
if (
|
|
268
|
-
|
|
281
|
+
const n = E && (ue == null ? void 0 : ue(E, t.input));
|
|
282
|
+
if (n === !0) return;
|
|
283
|
+
n && (typeof n == "object" || typeof n == "function") && Promise.resolve(n).catch(() => {
|
|
269
284
|
});
|
|
270
285
|
} catch {
|
|
271
286
|
}
|
|
272
|
-
throw new
|
|
287
|
+
throw new p("FORBIDDEN", "无权跨应用导航(权限策略必须同步返回 true)");
|
|
273
288
|
}
|
|
274
|
-
},
|
|
275
|
-
if (
|
|
276
|
-
throw new
|
|
277
|
-
if (
|
|
278
|
-
throw new
|
|
279
|
-
const
|
|
280
|
-
(
|
|
281
|
-
var
|
|
282
|
-
return
|
|
289
|
+
}, H = (n) => !s || n.appId === s;
|
|
290
|
+
if (w && !H(w) || v && !H(v) || t.type === "open" && s && t.input.appId !== s && !_ || t.type === "back" && t.fallback && s && t.fallback.appId !== s)
|
|
291
|
+
throw new p("FORBIDDEN", "页面只能操作本应用");
|
|
292
|
+
if (t.type === "closeMany" && !["all", "others", "left", "right"].includes(t.scope))
|
|
293
|
+
throw new p("INVALID_OPERATION", "批量范围无效");
|
|
294
|
+
const F = v ? d.tabs.indexOf(v) : -1, J = t.type === "closeMany" ? d.tabs.filter(
|
|
295
|
+
(n, g) => {
|
|
296
|
+
var k;
|
|
297
|
+
return H(n) && !((k = t.exclude) != null && k.some((C) => C.tabId === n.tabId && C.key === n.key)) && (t.scope === "all" || F >= 0 && (t.scope === "others" ? n.key !== v.key : t.scope === "left" ? g < F : g > F));
|
|
283
298
|
}
|
|
284
|
-
) : [],
|
|
285
|
-
var
|
|
286
|
-
const
|
|
287
|
-
status:
|
|
299
|
+
) : [], m = t.type === "back" ? w ?? (!("target" in t) || !t.target ? S : void 0) : w, $ = async () => {
|
|
300
|
+
var Te, Pe, De, Me, je, Se;
|
|
301
|
+
const n = (i) => ({
|
|
302
|
+
status: i,
|
|
288
303
|
affected: []
|
|
289
304
|
});
|
|
290
|
-
if (
|
|
291
|
-
if ((
|
|
292
|
-
if (
|
|
293
|
-
throw new
|
|
294
|
-
if (
|
|
295
|
-
return
|
|
296
|
-
if (
|
|
297
|
-
const
|
|
298
|
-
if (
|
|
299
|
-
throw new
|
|
300
|
-
if (
|
|
301
|
-
const
|
|
302
|
-
let y = [...
|
|
305
|
+
if (D) throw new p("HOST_DISPOSED", "MicroHost 已销毁");
|
|
306
|
+
if ((Te = t.signal) != null && Te.aborted) return n("stale");
|
|
307
|
+
if (c && !h && (b != null && b() || !d.tabs.some((i) => i.key === c)))
|
|
308
|
+
throw new p("PAGE_RELEASED", "页面上下文已释放");
|
|
309
|
+
if (t.type === "open" && (f ? !d.tabs.some((i) => i.key === f.key) : d.tabs.some((i) => i.tabId === t.input.tabId)) || m && !d.tabs.some((i) => i.key === m.key) || v && !d.tabs.some((i) => i.key === v.key) || J.some((i) => !d.tabs.some((O) => O.key === i.key)))
|
|
310
|
+
return n("stale");
|
|
311
|
+
if (t.type !== "open" && t.type !== "closeMany" && !m) return n("noop");
|
|
312
|
+
const g = W;
|
|
313
|
+
if (L(), c && !h && (b != null && b() || !d.tabs.some((i) => i.key === c)))
|
|
314
|
+
throw new p("PAGE_RELEASED", "页面上下文已释放");
|
|
315
|
+
if (W !== g || D || (Pe = t.signal) != null && Pe.aborted) return n("stale");
|
|
316
|
+
const k = d, C = W;
|
|
317
|
+
let y = [...d.tabs], l, M = [], V = d.activeTabId;
|
|
303
318
|
try {
|
|
304
|
-
if (
|
|
305
|
-
...
|
|
306
|
-
key: `${
|
|
307
|
-
}), y = y.map((
|
|
308
|
-
const
|
|
309
|
-
if (y = y.filter((
|
|
310
|
-
const
|
|
311
|
-
|
|
312
|
-
const
|
|
313
|
-
|
|
314
|
-
} else
|
|
319
|
+
if (t.type === "open" && (l = he(t.input, !0), f && f.key !== l.key ? (M = [f], y = y.map((i) => i.key === f.key ? l : i)) : y.some((i) => i.key === l.key) || y.push(l), V = l.tabId), t.type === "activate" && (l = m, q(l), V = l.tabId), t.type === "refresh" && (q(m), M = [m], l = Object.freeze({
|
|
320
|
+
...m,
|
|
321
|
+
key: `${m.tabId}:${++be}`
|
|
322
|
+
}), y = y.map((i) => i.key === m.key ? l : i)), (t.type === "close" || t.type === "back") && (M = [m]), t.type === "closeMany" && (M = J), M.length && t.type !== "refresh" && t.type !== "open") {
|
|
323
|
+
const i = new Set(M.map((A) => A.key)), O = k.tabs.findIndex((A) => A.tabId === k.activeTabId);
|
|
324
|
+
if (y = y.filter((A) => !i.has(A.key)), t.type === "back") {
|
|
325
|
+
const A = U.get(m.key);
|
|
326
|
+
l = y.find((P) => P.key === A && H(P)), !l && t.fallback && (l = he(t.fallback), i.has(l.key) && (l = Object.freeze({ ...l, key: `${l.tabId}:${++be}` })), y.some((P) => P.key === l.key) || y.push(l));
|
|
327
|
+
const T = k.tabs.filter((P) => H(P)), N = T.findIndex((P) => P.key === m.key);
|
|
328
|
+
l ?? (l = T.slice(0, N).reverse().find((P) => y.some((se) => se.key === P.key)) ?? T.slice(N + 1).find((P) => y.some((se) => se.key === P.key))), l ?? (l = y[Math.min(O, y.length - 1)]), l && q(l), V = (l == null ? void 0 : l.tabId) ?? null;
|
|
329
|
+
} else if (M.some((A) => A.tabId === V)) {
|
|
330
|
+
const A = "closeFallback" in t ? t.closeFallback : void 0, T = A ? y.find((N) => N.tabId === A.tabId && N.key === A.key && H(N)) : void 0;
|
|
331
|
+
T && (q(T), l = T), V = ((De = T ?? y[Math.min(O, y.length - 1)]) == null ? void 0 : De.tabId) ?? null;
|
|
332
|
+
}
|
|
315
333
|
}
|
|
316
|
-
} catch (
|
|
317
|
-
throw
|
|
334
|
+
} catch (i) {
|
|
335
|
+
throw i instanceof p ? i : new p("INVALID_OPERATION", "导航参数无效");
|
|
318
336
|
}
|
|
319
|
-
if (y.length ===
|
|
320
|
-
return
|
|
321
|
-
const
|
|
322
|
-
|
|
323
|
-
for (const
|
|
324
|
-
for (const
|
|
325
|
-
let
|
|
326
|
-
const
|
|
327
|
-
let
|
|
337
|
+
if (y.length === k.tabs.length && y.every((i, O) => i.key === k.tabs[O].key) && V === k.activeTabId)
|
|
338
|
+
return n("noop");
|
|
339
|
+
const Ie = [...M], fe = k.tabs.find((i) => i.tabId === k.activeTabId);
|
|
340
|
+
fe && fe.tabId !== V && !Ie.some((i) => i.key === fe.key) && Ie.push(fe);
|
|
341
|
+
for (const i of Ie)
|
|
342
|
+
for (const O of [...oe.get(i.key) ?? []]) {
|
|
343
|
+
let A;
|
|
344
|
+
const T = t.signal;
|
|
345
|
+
let N = () => {
|
|
328
346
|
};
|
|
329
347
|
try {
|
|
330
|
-
const
|
|
331
|
-
if (!
|
|
332
|
-
const
|
|
333
|
-
|
|
348
|
+
const P = Promise.resolve(O({ operation: t, tab: i })), se = new Promise((Le) => {
|
|
349
|
+
if (!T) return;
|
|
350
|
+
const ze = () => Le();
|
|
351
|
+
T.addEventListener("abort", ze, { once: !0 }), N = () => T.removeEventListener("abort", ze), T.aborted && Le();
|
|
334
352
|
});
|
|
335
|
-
|
|
353
|
+
A = await Promise.race([P, se]);
|
|
336
354
|
} catch {
|
|
337
|
-
if (
|
|
338
|
-
throw new
|
|
355
|
+
if (T != null && T.aborted) return n("stale");
|
|
356
|
+
throw new p("GUARD_FAILED", "离页守卫执行失败");
|
|
339
357
|
} finally {
|
|
340
|
-
|
|
358
|
+
N();
|
|
341
359
|
}
|
|
342
|
-
if (
|
|
343
|
-
if (
|
|
360
|
+
if (W !== C || D || (Me = t.signal) != null && Me.aborted) return n("stale");
|
|
361
|
+
if (A === !1) return n("cancelled");
|
|
344
362
|
}
|
|
345
|
-
if (
|
|
346
|
-
if (
|
|
347
|
-
if (
|
|
348
|
-
if (
|
|
349
|
-
if (
|
|
350
|
-
const
|
|
351
|
-
|
|
363
|
+
if (W !== C || D || (je = t.signal) != null && je.aborted) return n("stale");
|
|
364
|
+
if (b != null && b()) throw new p("PAGE_RELEASED", "页面上下文已释放");
|
|
365
|
+
if (L(), l && q(l), b != null && b()) throw new p("PAGE_RELEASED", "页面上下文已释放");
|
|
366
|
+
if (W !== C || D || (Se = t.signal) != null && Se.aborted) return n("stale");
|
|
367
|
+
if (d = { tabs: y, activeTabId: V }, t.type === "open" && l && c && !_ && l.key !== c && !U.has(l.key) && U.set(l.key, c), t.type === "refresh" && l) {
|
|
368
|
+
const i = U.get(m.key);
|
|
369
|
+
i && U.set(l.key, i);
|
|
352
370
|
}
|
|
353
|
-
for (const
|
|
354
|
-
for (const
|
|
355
|
-
if (!y.some((
|
|
356
|
-
for (const
|
|
357
|
-
|
|
371
|
+
for (const i of M) Oe(i.key);
|
|
372
|
+
for (const i of new Set(M.map((O) => O.appId)))
|
|
373
|
+
if (!y.some((O) => O.appId === i)) {
|
|
374
|
+
for (const O of [...G.get(i) ?? []]) Z(O);
|
|
375
|
+
G.delete(i), re.delete(i);
|
|
358
376
|
}
|
|
359
|
-
const
|
|
360
|
-
...
|
|
361
|
-
...y.filter((
|
|
377
|
+
const ye = [
|
|
378
|
+
...M,
|
|
379
|
+
...y.filter((i) => !k.tabs.some((O) => O.key === i.key))
|
|
362
380
|
];
|
|
363
|
-
return !
|
|
381
|
+
return !ye.length && l && ye.push(l), ne(), {
|
|
364
382
|
status: "committed",
|
|
365
|
-
affected:
|
|
366
|
-
...
|
|
383
|
+
affected: ye.map((i) => ({ tabId: i.tabId, key: i.key })),
|
|
384
|
+
...l ? { tab: l } : {}
|
|
367
385
|
};
|
|
368
|
-
},
|
|
369
|
-
return
|
|
370
|
-
}),
|
|
371
|
-
} catch (
|
|
372
|
-
return Promise.reject(
|
|
386
|
+
}, Q = Ee.then($);
|
|
387
|
+
return Ee = Q.catch(() => {
|
|
388
|
+
}), Q;
|
|
389
|
+
} catch (t) {
|
|
390
|
+
return Promise.reject(t);
|
|
373
391
|
}
|
|
374
392
|
}
|
|
375
|
-
function Be(
|
|
376
|
-
if (
|
|
377
|
-
const
|
|
378
|
-
if (
|
|
379
|
-
let
|
|
380
|
-
const
|
|
393
|
+
function Be(e) {
|
|
394
|
+
if (j(), !X.has(e)) throw new Error(`未知子应用: ${e}`);
|
|
395
|
+
const s = re.get(e);
|
|
396
|
+
if (s) return s;
|
|
397
|
+
let c = !0;
|
|
398
|
+
const h = /* @__PURE__ */ new Set([
|
|
381
399
|
() => {
|
|
382
|
-
|
|
400
|
+
c = !1;
|
|
383
401
|
}
|
|
384
402
|
]);
|
|
385
|
-
|
|
386
|
-
async function
|
|
387
|
-
const
|
|
388
|
-
if (
|
|
389
|
-
if (
|
|
390
|
-
throw new
|
|
391
|
-
if (!
|
|
403
|
+
G.set(e, h);
|
|
404
|
+
async function b(o, t, r, a = {}) {
|
|
405
|
+
const w = () => {
|
|
406
|
+
if (D) throw new z("HOST_DISPOSED", "MicroHost 已销毁");
|
|
407
|
+
if (r && (r.released() || !d.tabs.some((L) => L.key === r.key)))
|
|
408
|
+
throw new z("PAGE_RELEASED", "页面上下文已释放");
|
|
409
|
+
if (!c) throw new z("BRIDGE_RELEASED", "应用 bridge 已释放");
|
|
392
410
|
};
|
|
393
|
-
|
|
394
|
-
const
|
|
395
|
-
if (!
|
|
396
|
-
if (
|
|
397
|
-
throw new
|
|
398
|
-
const
|
|
399
|
-
if (!Number.isFinite(
|
|
411
|
+
w();
|
|
412
|
+
const v = ve.get(o);
|
|
413
|
+
if (!v) throw new z("UNKNOWN_CAPABILITY", `未注册宿主能力: ${o}`);
|
|
414
|
+
if (v.apps && !v.apps.has(e))
|
|
415
|
+
throw new z("FORBIDDEN", `应用无权调用宿主能力: ${o}`);
|
|
416
|
+
const S = a.timeoutMs ?? ie;
|
|
417
|
+
if (!Number.isFinite(S) || S <= 0 || S > 2147483647)
|
|
400
418
|
throw new TypeError("timeoutMs 必须为不超过2147483647的正有限数");
|
|
401
|
-
const
|
|
402
|
-
if (
|
|
403
|
-
const I = new AbortController(),
|
|
404
|
-
appId:
|
|
419
|
+
const f = a.signal;
|
|
420
|
+
if (f != null && f.aborted) throw new z("CANCELLED", "宿主能力调用已取消");
|
|
421
|
+
const I = new AbortController(), E = r ? d.tabs.find((L) => L.key === r.key) : void 0, _ = Object.freeze({
|
|
422
|
+
appId: e,
|
|
405
423
|
signal: I.signal,
|
|
406
|
-
...
|
|
407
|
-
isActive: () => !I.signal.aborted && !
|
|
424
|
+
...E ? { tab: Object.freeze({ ...E }) } : {},
|
|
425
|
+
isActive: () => !I.signal.aborted && !D && c && (!r || !r.released() && d.tabs.some((L) => L.key === r.key))
|
|
408
426
|
});
|
|
409
|
-
return new Promise((
|
|
410
|
-
let
|
|
411
|
-
const
|
|
412
|
-
|
|
413
|
-
},
|
|
414
|
-
|
|
415
|
-
},
|
|
427
|
+
return new Promise((L, H) => {
|
|
428
|
+
let F = !1, J;
|
|
429
|
+
const m = () => {
|
|
430
|
+
J !== void 0 && clearTimeout(J), f == null || f.removeEventListener("abort", Q), h.delete(n), r == null || r.cleanups.delete(n);
|
|
431
|
+
}, $ = (k) => {
|
|
432
|
+
F || (F = !0, m(), H(k), I.abort());
|
|
433
|
+
}, Q = () => $(new z("CANCELLED", "宿主能力调用已取消")), n = () => {
|
|
416
434
|
try {
|
|
417
|
-
|
|
418
|
-
} catch (
|
|
419
|
-
|
|
435
|
+
w();
|
|
436
|
+
} catch (k) {
|
|
437
|
+
$(k);
|
|
420
438
|
}
|
|
421
439
|
};
|
|
422
|
-
if (
|
|
423
|
-
|
|
440
|
+
if (h.add(n), r == null || r.cleanups.add(n), f == null || f.addEventListener("abort", Q, { once: !0 }), J = setTimeout(() => $(new z("TIMEOUT", "宿主能力调用超时")), S), f != null && f.aborted) {
|
|
441
|
+
Q();
|
|
424
442
|
return;
|
|
425
443
|
}
|
|
426
|
-
let
|
|
444
|
+
let g;
|
|
427
445
|
try {
|
|
428
|
-
|
|
446
|
+
g = v.handler(_, ...t);
|
|
429
447
|
} catch {
|
|
430
|
-
|
|
448
|
+
$(new z("HANDLER_FAILED", `宿主能力执行失败: ${o}`));
|
|
431
449
|
return;
|
|
432
450
|
}
|
|
433
|
-
Promise.resolve(
|
|
434
|
-
if (!
|
|
451
|
+
Promise.resolve(g).then((k) => {
|
|
452
|
+
if (!F) {
|
|
435
453
|
try {
|
|
436
|
-
|
|
437
|
-
} catch (
|
|
438
|
-
|
|
454
|
+
w();
|
|
455
|
+
} catch (C) {
|
|
456
|
+
$(C);
|
|
439
457
|
return;
|
|
440
458
|
}
|
|
441
|
-
|
|
459
|
+
F = !0, m(), L(k);
|
|
442
460
|
}
|
|
443
|
-
}, () =>
|
|
461
|
+
}, () => $(new z("HANDLER_FAILED", `宿主能力执行失败: ${o}`)));
|
|
444
462
|
});
|
|
445
463
|
}
|
|
446
464
|
const u = {
|
|
447
|
-
appId:
|
|
448
|
-
getState:
|
|
449
|
-
callHost(
|
|
450
|
-
return
|
|
465
|
+
appId: e,
|
|
466
|
+
getState: ce,
|
|
467
|
+
callHost(o, ...t) {
|
|
468
|
+
return b(o, t);
|
|
451
469
|
},
|
|
452
|
-
callHostWithOptions(
|
|
453
|
-
return
|
|
470
|
+
callHostWithOptions(o, t, ...r) {
|
|
471
|
+
return b(o, r, void 0, t);
|
|
454
472
|
},
|
|
455
473
|
protocol() {
|
|
456
|
-
if (
|
|
474
|
+
if (j(), !c) throw new Error("应用 bridge 已释放");
|
|
457
475
|
return Object.freeze({
|
|
458
476
|
version: "1.0",
|
|
459
|
-
capabilities: Object.freeze([...ve].filter(([,
|
|
477
|
+
capabilities: Object.freeze([...ve].filter(([, o]) => !o.apps || o.apps.has(e)).map(([o]) => o)),
|
|
460
478
|
features: Object.freeze(["call-options", "session", "event-metadata", "navigate-to"])
|
|
461
479
|
});
|
|
462
480
|
},
|
|
463
|
-
negotiate(
|
|
464
|
-
const
|
|
465
|
-
return Object.freeze({ compatible: (!
|
|
481
|
+
negotiate(o = {}) {
|
|
482
|
+
const t = u.protocol(), r = Object.freeze((o.capabilities ?? []).filter((a) => !t.capabilities.includes(a)));
|
|
483
|
+
return Object.freeze({ compatible: (!o.version || o.version === t.version) && !r.length, protocol: t, missingCapabilities: r });
|
|
466
484
|
},
|
|
467
485
|
getSession() {
|
|
468
|
-
if (
|
|
469
|
-
return
|
|
486
|
+
if (j(), !c) throw new Error("应用 bridge 已释放");
|
|
487
|
+
return ee;
|
|
470
488
|
},
|
|
471
|
-
subscribeSession(
|
|
472
|
-
const
|
|
473
|
-
|
|
489
|
+
subscribeSession(o) {
|
|
490
|
+
const t = u.getSession(), r = (w) => o(w), a = () => {
|
|
491
|
+
K.delete(r), h.delete(a);
|
|
474
492
|
};
|
|
475
|
-
return
|
|
493
|
+
return K.add(r), h.add(a), Z(() => o(t)), a;
|
|
476
494
|
},
|
|
477
|
-
subscribe(
|
|
478
|
-
if (!
|
|
479
|
-
const
|
|
480
|
-
|
|
495
|
+
subscribe(o) {
|
|
496
|
+
if (!c) throw new Error("应用 bridge 已释放");
|
|
497
|
+
const t = me(o), r = () => {
|
|
498
|
+
t(), h.delete(r);
|
|
481
499
|
};
|
|
482
|
-
return
|
|
500
|
+
return h.add(r), r;
|
|
483
501
|
},
|
|
484
|
-
ready(
|
|
485
|
-
const
|
|
486
|
-
const
|
|
487
|
-
(
|
|
502
|
+
ready(o) {
|
|
503
|
+
const t = (a) => {
|
|
504
|
+
const w = a.tabs.find(
|
|
505
|
+
(v) => v.tabId === a.activeTabId && v.appId === e
|
|
488
506
|
);
|
|
489
|
-
|
|
490
|
-
},
|
|
507
|
+
w && o(w);
|
|
508
|
+
}, r = u.subscribe(t);
|
|
491
509
|
try {
|
|
492
|
-
|
|
493
|
-
} catch (
|
|
494
|
-
throw
|
|
510
|
+
t(ce());
|
|
511
|
+
} catch (a) {
|
|
512
|
+
throw r(), a;
|
|
495
513
|
}
|
|
496
|
-
return
|
|
514
|
+
return r;
|
|
497
515
|
},
|
|
498
|
-
bindPage(
|
|
499
|
-
const
|
|
500
|
-
if (!
|
|
501
|
-
return u.page(
|
|
516
|
+
bindPage(o) {
|
|
517
|
+
const t = d.tabs.find((r) => r.tabId === o && r.appId === e);
|
|
518
|
+
if (!t) throw new Error("页面不属于该应用");
|
|
519
|
+
return u.page(t.key);
|
|
502
520
|
},
|
|
503
|
-
page(
|
|
504
|
-
if (
|
|
505
|
-
const
|
|
506
|
-
if (!
|
|
507
|
-
let
|
|
508
|
-
const
|
|
509
|
-
if (
|
|
510
|
-
if (
|
|
511
|
-
throw new
|
|
512
|
-
},
|
|
513
|
-
var
|
|
514
|
-
|
|
521
|
+
page(o) {
|
|
522
|
+
if (j(), !c) throw new Error("应用 bridge 已释放");
|
|
523
|
+
const t = d.tabs.find((f) => f.key === o && f.appId === e);
|
|
524
|
+
if (!t) throw new Error("页面上下文不存在或不属于该应用");
|
|
525
|
+
let r = !1;
|
|
526
|
+
const a = /* @__PURE__ */ new Set(), w = () => {
|
|
527
|
+
if (D) throw new p("HOST_DISPOSED", "MicroHost 已销毁");
|
|
528
|
+
if (r || !d.tabs.some((f) => f.key === o))
|
|
529
|
+
throw new p("PAGE_RELEASED", "页面上下文已释放");
|
|
530
|
+
}, v = () => {
|
|
531
|
+
var f;
|
|
532
|
+
r = !0, a.forEach((I) => I()), a.clear(), (f = B.get(o)) == null || f.delete(v);
|
|
515
533
|
};
|
|
516
|
-
let
|
|
517
|
-
return
|
|
534
|
+
let S = B.get(o);
|
|
535
|
+
return S || B.set(o, S = /* @__PURE__ */ new Set()), S.add(v), {
|
|
518
536
|
get tab() {
|
|
519
|
-
return
|
|
537
|
+
return d.tabs.find((f) => f.key === o) ?? t;
|
|
520
538
|
},
|
|
521
|
-
callHost(
|
|
522
|
-
return
|
|
539
|
+
callHost(f, ...I) {
|
|
540
|
+
return b(f, I, { key: o, released: () => r, cleanups: a });
|
|
523
541
|
},
|
|
524
|
-
callHostWithOptions(
|
|
525
|
-
return
|
|
542
|
+
callHostWithOptions(f, I, ...E) {
|
|
543
|
+
return b(f, E, { key: o, released: () => r, cleanups: a }, I);
|
|
526
544
|
},
|
|
527
|
-
async openTab(
|
|
528
|
-
|
|
529
|
-
const I = await
|
|
530
|
-
{ type: "open", input:
|
|
531
|
-
t,
|
|
545
|
+
async openTab(f) {
|
|
546
|
+
w();
|
|
547
|
+
const I = await Y(
|
|
548
|
+
{ type: "open", input: f },
|
|
532
549
|
e,
|
|
550
|
+
o,
|
|
533
551
|
!1,
|
|
534
|
-
() =>
|
|
552
|
+
() => r
|
|
535
553
|
);
|
|
536
554
|
if (I.tab) return I.tab;
|
|
537
|
-
const
|
|
538
|
-
(
|
|
555
|
+
const E = d.tabs.find(
|
|
556
|
+
(_) => _.tabId === f.tabId && _.appId === e
|
|
539
557
|
);
|
|
540
|
-
if (I.status === "noop" &&
|
|
541
|
-
throw new
|
|
558
|
+
if (I.status === "noop" && E) return E;
|
|
559
|
+
throw new p(
|
|
542
560
|
I.status === "cancelled" ? "CANCELLED" : "STALE",
|
|
543
561
|
"导航未提交"
|
|
544
562
|
);
|
|
545
563
|
},
|
|
546
|
-
async navigateTo(
|
|
547
|
-
return
|
|
548
|
-
{ type: "open", input:
|
|
549
|
-
t,
|
|
564
|
+
async navigateTo(f, I = {}) {
|
|
565
|
+
return w(), Y(
|
|
566
|
+
{ type: "open", input: f, signal: I.signal },
|
|
550
567
|
e,
|
|
568
|
+
o,
|
|
551
569
|
!1,
|
|
552
|
-
() =>
|
|
570
|
+
() => r,
|
|
553
571
|
!0
|
|
554
572
|
);
|
|
555
573
|
},
|
|
556
574
|
// 释放后仅允许关闭捕获的原 key;所有守卫仍然执行,不能误关同 id 新生命周期。
|
|
557
575
|
async closeCurrent() {
|
|
558
|
-
return
|
|
559
|
-
{ type: "close", target: { tabId:
|
|
560
|
-
|
|
576
|
+
return D ? !1 : (await Y(
|
|
577
|
+
{ type: "close", target: { tabId: t.tabId, key: o } },
|
|
578
|
+
e,
|
|
561
579
|
void 0,
|
|
562
580
|
!0
|
|
563
581
|
)).status === "committed";
|
|
564
582
|
},
|
|
565
|
-
beforeLeave(
|
|
566
|
-
if (
|
|
567
|
-
throw new
|
|
568
|
-
let I =
|
|
569
|
-
I ||
|
|
570
|
-
const
|
|
571
|
-
I.delete(
|
|
583
|
+
beforeLeave(f) {
|
|
584
|
+
if (w(), typeof f != "function")
|
|
585
|
+
throw new p("INVALID_OPERATION", "离页守卫必须为函数");
|
|
586
|
+
let I = oe.get(o);
|
|
587
|
+
I || oe.set(o, I = /* @__PURE__ */ new Set()), I.add(f);
|
|
588
|
+
const E = () => {
|
|
589
|
+
I.delete(f), a.delete(E);
|
|
572
590
|
};
|
|
573
|
-
return
|
|
591
|
+
return a.add(E), E;
|
|
574
592
|
},
|
|
575
593
|
async refreshCurrent() {
|
|
576
|
-
return
|
|
577
|
-
{ type: "refresh", target: { tabId:
|
|
578
|
-
t,
|
|
594
|
+
return w(), Y(
|
|
595
|
+
{ type: "refresh", target: { tabId: t.tabId, key: o } },
|
|
579
596
|
e,
|
|
597
|
+
o,
|
|
580
598
|
!1,
|
|
581
|
-
() =>
|
|
599
|
+
() => r
|
|
582
600
|
);
|
|
583
601
|
},
|
|
584
|
-
async back(
|
|
585
|
-
return
|
|
586
|
-
{ type: "back", target: { tabId:
|
|
587
|
-
t,
|
|
602
|
+
async back(f) {
|
|
603
|
+
return w(), Y(
|
|
604
|
+
{ type: "back", target: { tabId: t.tabId, key: o }, fallback: f },
|
|
588
605
|
e,
|
|
606
|
+
o,
|
|
589
607
|
!1,
|
|
590
|
-
() =>
|
|
608
|
+
() => r
|
|
591
609
|
);
|
|
592
610
|
},
|
|
593
|
-
async operate(
|
|
594
|
-
return
|
|
611
|
+
async operate(f) {
|
|
612
|
+
return w(), Y(f, e, o, !1, () => r);
|
|
595
613
|
},
|
|
596
|
-
emit(
|
|
597
|
-
|
|
614
|
+
emit(f, I) {
|
|
615
|
+
w(), ae.emit(f, { payload: I, metadata: Object.freeze({ source: "app", appId: e, tabKey: o }) });
|
|
598
616
|
},
|
|
599
|
-
on(
|
|
600
|
-
|
|
601
|
-
const
|
|
602
|
-
return
|
|
603
|
-
|
|
617
|
+
on(f, I) {
|
|
618
|
+
w();
|
|
619
|
+
const E = le.on(f, I);
|
|
620
|
+
return a.add(E), () => {
|
|
621
|
+
E(), a.delete(E);
|
|
604
622
|
};
|
|
605
623
|
},
|
|
606
|
-
dispose:
|
|
624
|
+
dispose: v
|
|
607
625
|
};
|
|
608
626
|
}
|
|
609
627
|
};
|
|
610
|
-
return
|
|
628
|
+
return re.set(e, u), u;
|
|
611
629
|
}
|
|
612
630
|
function Ge() {
|
|
613
|
-
if (!
|
|
614
|
-
|
|
615
|
-
for (const
|
|
616
|
-
|
|
617
|
-
for (const
|
|
618
|
-
|
|
631
|
+
if (!D) {
|
|
632
|
+
D = !0;
|
|
633
|
+
for (const e of B.values()) [...e].forEach((s) => s());
|
|
634
|
+
B.clear(), oe.clear(), U.clear();
|
|
635
|
+
for (const e of G.values()) [...e].forEach((s) => s());
|
|
636
|
+
G.clear(), te.clear(), K.clear(), re.clear(), le.clear(), d = { tabs: [], activeTabId: null };
|
|
619
637
|
}
|
|
620
638
|
}
|
|
621
639
|
return {
|
|
622
640
|
/** 注册应用的冻结元信息;不暴露 capabilities 注册表。 */
|
|
623
|
-
apps: [...
|
|
624
|
-
getState:
|
|
625
|
-
subscribe:
|
|
626
|
-
openTab:
|
|
641
|
+
apps: [...X.values()],
|
|
642
|
+
getState: ce,
|
|
643
|
+
subscribe: me,
|
|
644
|
+
openTab: He,
|
|
627
645
|
activateTab: $e,
|
|
628
646
|
closeTab: Ce,
|
|
629
|
-
updateTab:
|
|
630
|
-
updateSession:
|
|
631
|
-
operate:
|
|
647
|
+
updateTab: Fe,
|
|
648
|
+
updateSession: xe,
|
|
649
|
+
operate: Ve,
|
|
632
650
|
bridge: Be,
|
|
633
651
|
/** 宿主侧业务事件总线;无响应广播,来源元信息由宿主生成,异常通过 onError 隔离。 */
|
|
634
|
-
bus:
|
|
652
|
+
bus: le,
|
|
635
653
|
dispose: Ge
|
|
636
654
|
};
|
|
637
655
|
}
|
|
638
656
|
export {
|
|
639
|
-
|
|
657
|
+
Ze as createMicroHost
|
|
640
658
|
};
|