@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.
Files changed (103) hide show
  1. package/README.md +181 -4
  2. package/cli/index.mjs +22 -6
  3. package/dist/browser.cjs +1 -1
  4. package/dist/browser.mjs +68 -66
  5. package/dist/core.cjs +1 -1
  6. package/dist/core.mjs +459 -441
  7. package/dist/index.cjs +1 -1
  8. package/dist/index.mjs +31 -24
  9. package/dist/layout.cjs +1 -0
  10. package/dist/layout.css +1 -0
  11. package/dist/layout.mjs +719 -0
  12. package/dist/{router-view-impl-C1KG6mxu.mjs → router-view-impl-B1NzCGKV.mjs} +18 -18
  13. package/dist/router-view-impl-BvOToV_Z.cjs +1 -0
  14. package/dist/runtime.cjs +1 -1
  15. package/dist/runtime.mjs +40 -39
  16. package/dist/sdk.cjs +1 -1
  17. package/dist/sdk.mjs +92 -56
  18. package/dist/types/browser/index.d.ts +4 -0
  19. package/dist/types/core/index.d.ts +1 -1
  20. package/dist/types/index.d.ts +2 -0
  21. package/dist/types/layout/HostShell.vue.d.ts +528 -0
  22. package/dist/types/layout/ShellHeader.vue.d.ts +46 -0
  23. package/dist/types/layout/ShellMenu.vue.d.ts +12 -0
  24. package/dist/types/layout/ShellTabs.vue.d.ts +23 -0
  25. package/dist/types/layout/StandaloneMenuItem.vue.d.ts +11 -0
  26. package/dist/types/layout/StandaloneShell.vue.d.ts +40 -0
  27. package/dist/types/layout/index.d.ts +5 -0
  28. package/dist/types/layout/types.d.ts +65 -0
  29. package/dist/types/runtime/lifecycle.d.ts +1 -1
  30. package/dist/types/sdk/index.d.ts +65 -4
  31. package/dist/types/vue/index.d.ts +13 -2
  32. package/dist/types/vue/router-view-impl.d.ts +1 -1
  33. package/dist/types/watermark/FinWatermark.vue.d.ts +16 -0
  34. package/dist/types/watermark/config.d.ts +36 -0
  35. package/dist/types/watermark/index.d.ts +4 -0
  36. package/dist/vue.cjs +1 -1
  37. package/dist/vue.mjs +49 -35
  38. package/dist/watermark.cjs +2 -0
  39. package/dist/watermark.mjs +119 -0
  40. package/package.json +29 -4
  41. package/scaffold/base/index.html +2 -1
  42. package/scaffold/base/package.json.template +5 -1
  43. package/scaffold/base/pnpm-workspace.yaml +6 -0
  44. package/scaffold/base/scripts/check-runtime.mjs +43 -0
  45. package/scaffold/base/src/locales/en.ts +12 -0
  46. package/scaffold/base/src/locales/index.ts +7 -1
  47. package/scaffold/base/src/locales/zh-CN.ts +12 -0
  48. package/scaffold/base/src/main.ts +13 -5
  49. package/scaffold/base/src/router/demo.ts +6 -0
  50. package/scaffold/base/src/router/index.ts +13 -0
  51. package/scaffold/base/src/stores/demo.ts +12 -0
  52. package/scaffold/base/src/stores/index.ts +11 -0
  53. package/scaffold/base/src/utils/appConfig.ts +49 -0
  54. package/scaffold/base/src/utils/errorUtils.ts +109 -0
  55. package/scaffold/base/src/utils/requestUtils.ts +32 -11
  56. package/scaffold/base/src/utils/watermarkConfig.ts +18 -0
  57. package/scaffold/base/src/views/demo/index.vue +26 -0
  58. package/scaffold/host/.env.example +11 -3
  59. package/scaffold/host/src/App.vue +1 -13
  60. package/scaffold/host/src/bootstrap.ts +40 -8
  61. package/scaffold/host/src/hooks/usePlatformSession.ts +40 -8
  62. package/scaffold/host/src/layout/HostHeader.vue +65 -5
  63. package/scaffold/host/src/layout/HostLayout.vue +65 -21
  64. package/scaffold/host/src/layout/HostMenu.vue +11 -2
  65. package/scaffold/host/src/layout/HostTabs.vue +91 -8
  66. package/scaffold/host/src/layout/HostWorkspace.vue +29 -7
  67. package/scaffold/host/src/localPages.ts +45 -0
  68. package/scaffold/host/src/platform.ts +51 -14
  69. package/scaffold/host/src/router/guards.ts +128 -0
  70. package/scaffold/host/src/router/index.ts +25 -0
  71. package/scaffold/host/src/router/targets.ts +30 -0
  72. package/scaffold/host/src/router/workspace.ts +63 -0
  73. package/scaffold/host/src/styles/shell.css +776 -0
  74. package/scaffold/host/src/utils/request.ts +30 -3
  75. package/scaffold/host/src/views/home/index.vue +19 -0
  76. package/scaffold/host/src/views/login/components/LoginForm.vue +83 -0
  77. package/scaffold/host/src/views/login/index.vue +16 -0
  78. package/scaffold/host/src/views/not-found/index.vue +1 -0
  79. package/scaffold/host/src/views/profile/index.vue +24 -0
  80. package/scaffold/host/src/views/workspace/index.vue +11 -0
  81. package/scaffold/layouts/standard/host/src/layout/HostLayout.vue +116 -0
  82. package/scaffold/layouts/standard/host/src/styles/shell.css +168 -0
  83. package/scaffold/layouts/standard/vue/src/layout/StandaloneLayout.vue +26 -0
  84. package/scaffold/vue/src/App.vue +13 -7
  85. package/scaffold/vue/src/bootstrap.ts +25 -24
  86. package/scaffold/vue/src/bridge/auth.ts +23 -0
  87. package/scaffold/vue/src/bridge/session.ts +2 -2
  88. package/scaffold/vue/src/layout/Header.vue +15 -0
  89. package/scaffold/vue/src/layout/Sidebar.vue +21 -0
  90. package/scaffold/vue/src/layout/SidebarItem.vue +21 -0
  91. package/scaffold/vue/src/layout/StandaloneLayout.vue +34 -0
  92. package/scaffold/vue/src/main.ts +5 -2
  93. package/scaffold/vue/src/router/index.ts +9 -4
  94. package/scaffold/vue/src/router/menu.ts +38 -0
  95. package/scaffold/vue/src/views/demo/configs/table.ts +24 -0
  96. package/scaffold/vue/src/views/demo/hooks/useRecordNavigation.ts +32 -0
  97. package/scaffold/vue/src/views/demo/index.vue +17 -0
  98. package/scaffold/vue/src/views/{DetailView.vue → demo/modules/detail/index.vue} +15 -6
  99. package/scaffold/vue/src/views/demo/types.ts +5 -0
  100. package/dist/router-view-impl-CgLEalx4.cjs +0 -1
  101. package/scaffold/host/src/views/LoginView.vue +0 -38
  102. package/scaffold/vue/src/views/ListView.vue +0 -51
  103. /package/scaffold/vue/src/views/{NotFoundView.vue → not-found/index.vue} +0 -0
@@ -1,38 +1,38 @@
1
- import { defineComponent as w, shallowRef as v, provide as m, shallowReactive as R, onBeforeUnmount as O, h as d } from "vue";
2
- import { useRouter as E, START_LOCATION as f, routeLocationKey as g, viewDepthKey as L, RouterView as b, loadRouteLocation as D } from "vue-router";
1
+ import { defineComponent as w, shallowRef as v, provide as m, shallowReactive as R, onBeforeUnmount as O, h as f } from "vue";
2
+ import { useRouter as E, START_LOCATION as h, routeLocationKey as g, viewDepthKey as L, RouterView as b, loadRouteLocation as D } from "vue-router";
3
3
  import { useMicroTab as I } from "./vue.mjs";
4
- class h extends Error {
4
+ class d extends Error {
5
5
  constructor(o) {
6
6
  super(o), this.code = o;
7
7
  }
8
8
  }
9
9
  function T(c, o) {
10
- let e = c.resolve(o, f);
10
+ let e = c.resolve(o, h);
11
11
  const p = e, u = /* @__PURE__ */ new Set();
12
12
  for (let n = 0; n < 30; n++) {
13
- if (!e.matched.length) throw new h("NOT_FOUND");
13
+ if (!e.matched.length) throw new d("NOT_FOUND");
14
14
  const i = e.matched[e.matched.length - 1];
15
15
  if (!i.redirect) return e === p ? e : { ...e, redirectedFrom: p };
16
- if (u.has(e.fullPath)) throw new h("REDIRECT_LOOP");
16
+ if (u.has(e.fullPath)) throw new d("REDIRECT_LOOP");
17
17
  u.add(e.fullPath);
18
- const t = typeof i.redirect == "function" ? i.redirect(e, f) : i.redirect;
18
+ const t = typeof i.redirect == "function" ? i.redirect(e) : i.redirect;
19
19
  let a;
20
20
  if (typeof t == "string")
21
21
  if (t.includes("?") || t.includes("#")) {
22
- const r = c.resolve(t, f);
22
+ const r = c.resolve(t, h);
23
23
  a = { path: r.path, query: r.query, hash: r.hash };
24
24
  } else a = { path: t };
25
25
  else a = t;
26
26
  const s = "path" in a && a.path != null;
27
- if (!s && !("name" in a)) throw new h("RESOLVE_FAILED");
27
+ if (!s && !("name" in a)) throw new d("RESOLVE_FAILED");
28
28
  e = c.resolve({
29
29
  query: e.query,
30
30
  hash: e.hash,
31
31
  params: s ? {} : e.params,
32
32
  ...a
33
- }, f);
33
+ }, h);
34
34
  }
35
- throw new h("REDIRECT_LOOP");
35
+ throw new d("REDIRECT_LOOP");
36
36
  }
37
37
  const V = w({
38
38
  name: "MicroRouteViewImpl",
@@ -42,8 +42,8 @@ const V = w({
42
42
  const e = I(), p = E(), u = v(), n = v(), i = v(!1);
43
43
  let t = !1;
44
44
  const a = {};
45
- for (const r of Object.keys(f))
46
- Object.defineProperty(a, r, { enumerable: !0, get: () => (u.value ?? f)[r] });
45
+ for (const r of Object.keys(h))
46
+ Object.defineProperty(a, r, { enumerable: !0, get: () => (u.value ?? h)[r] });
47
47
  m(g, R(a)), m(L, 0);
48
48
  async function s() {
49
49
  if (t || i.value) return;
@@ -55,7 +55,7 @@ const V = w({
55
55
  const y = await D(l);
56
56
  t || (u.value = y);
57
57
  } catch (l) {
58
- t || (n.value = l instanceof h ? l.code : r);
58
+ t || (n.value = l instanceof d ? l.code : r);
59
59
  } finally {
60
60
  t || (i.value = !1);
61
61
  }
@@ -64,10 +64,10 @@ const V = w({
64
64
  t = !0;
65
65
  }), s(), () => {
66
66
  var r, l;
67
- return n.value ? ((r = o.error) == null ? void 0 : r.call(o, { tab: e, code: n.value, retry: s })) ?? d("div", { role: "alert", "data-micro-route-error": n.value }, [
68
- d("p", `页面加载失败(${n.value})`),
69
- d("button", { type: "button", onClick: s }, "重新加载")
70
- ]) : i.value || !u.value ? ((l = o.loading) == null ? void 0 : l.call(o, { tab: e })) ?? d("p", { role: "status" }, "页面加载中…") : d(b, { route: u.value, name: c.name, key: e.key });
67
+ return n.value ? ((r = o.error) == null ? void 0 : r.call(o, { tab: e, code: n.value, retry: s })) ?? f("div", { role: "alert", "data-micro-route-error": n.value }, [
68
+ f("p", `页面加载失败(${n.value})`),
69
+ f("button", { type: "button", onClick: s }, "重新加载")
70
+ ]) : i.value || !u.value ? ((l = o.loading) == null ? void 0 : l.call(o, { tab: e })) ?? f("p", { role: "status" }, "页面加载中…") : f(b, { route: u.value, name: c.name, key: e.key });
71
71
  };
72
72
  }
73
73
  });
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const t=require("vue"),u=require("vue-router"),O=require("./vue.cjs");class f extends Error{constructor(a){super(a),this.code=a}}function R(h,a){let e=h.resolve(a,u.START_LOCATION);const p=e,c=new Set;for(let i=0;i<30;i++){if(!e.matched.length)throw new f("NOT_FOUND");const l=e.matched[e.matched.length-1];if(!l.redirect)return e===p?e:{...e,redirectedFrom:p};if(c.has(e.fullPath))throw new f("REDIRECT_LOOP");c.add(e.fullPath);const r=typeof l.redirect=="function"?l.redirect(e):l.redirect;let n;if(typeof r=="string")if(r.includes("?")||r.includes("#")){const o=h.resolve(r,u.START_LOCATION);n={path:o.path,query:o.query,hash:o.hash}}else n={path:r};else n=r;const d="path"in n&&n.path!=null;if(!d&&!("name"in n))throw new f("RESOLVE_FAILED");e=h.resolve({query:e.query,hash:e.hash,params:d?{}:e.params,...n},u.START_LOCATION)}throw new f("REDIRECT_LOOP")}const w=t.defineComponent({name:"MicroRouteViewImpl",props:{name:{type:String,default:"default"}},slots:Object,setup(h,{slots:a}){const e=O.useMicroTab(),p=u.useRouter(),c=t.shallowRef(),i=t.shallowRef(),l=t.shallowRef(!1);let r=!1;const n={};for(const o of Object.keys(u.START_LOCATION))Object.defineProperty(n,o,{enumerable:!0,get:()=>(c.value??u.START_LOCATION)[o]});t.provide(u.routeLocationKey,t.shallowReactive(n)),t.provide(u.viewDepthKey,0);async function d(){if(r||l.value)return;l.value=!0,i.value=void 0;let o="RESOLVE_FAILED";try{const s=R(p,e.route);o="LOAD_FAILED";const v=await u.loadRouteLocation(s);r||(c.value=v)}catch(s){r||(i.value=s instanceof f?s.code:o)}finally{r||(l.value=!1)}}return t.onBeforeUnmount(()=>{r=!0}),d(),()=>{var o,s;return i.value?((o=a.error)==null?void 0:o.call(a,{tab:e,code:i.value,retry:d}))??t.h("div",{role:"alert","data-micro-route-error":i.value},[t.h("p",`页面加载失败(${i.value})`),t.h("button",{type:"button",onClick:d},"重新加载")]):l.value||!c.value?((s=a.loading)==null?void 0:s.call(a,{tab:e}))??t.h("p",{role:"status"},"页面加载中…"):t.h(u.RouterView,{route:c.value,name:h.name,key:e.key})}}});exports.MicroRouteViewImpl=w;
package/dist/runtime.cjs CHANGED
@@ -1 +1 @@
1
- "use strict";var $=Object.create;var N=Object.defineProperty;var J=Object.getOwnPropertyDescriptor;var O=Object.getOwnPropertyNames;var L=Object.getPrototypeOf,A=Object.prototype.hasOwnProperty;var F=(n,t,s,c)=>{if(t&&typeof t=="object"||typeof t=="function")for(let i of O(t))!A.call(n,i)&&i!==s&&N(n,i,{get:()=>t[i],enumerable:!(c=J(t,i))||c.enumerable});return n};var R=(n,t,s)=>(s=n!=null?$(L(n)):{},F(t||!n||!n.__esModule?N(s,"default",{value:n,enumerable:!0}):s,n));Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const U=new WeakMap;function b(){var n;return typeof window<"u"&&typeof((n=window.__WUJIE)==null?void 0:n.mount)=="function"}function S(n){var y;if(typeof window>"u"){const r=Promise.resolve();return()=>r}const t=window,s=(y=U.get(t))==null?void 0:y(),c=r=>{console.error("[fin-micro] 应用生命周期失败",r)};let i=(s==null?void 0:s.catch(()=>{}))??Promise.resolve(),f=!1,d,e;function o(){const r=e;if(!r||(e=void 0,!r.started))return i;try{i=Promise.resolve(n.unmount())}catch(u){i=Promise.reject(u)}return i.catch(c),i}function a(){if(f)return Promise.resolve();if(e)return e.ready;const r={started:!1,ready:Promise.resolve()};e=r;const u=async()=>{if(!(f||e!==r)){r.started=!0;try{await n.mount()}catch(v){throw e===r&&await o().catch(()=>{}),v}}};return r.ready=i.then(u,u),r.ready.catch(c),r.ready}function m(){return d||(f=!0,t.removeEventListener("unload",h),t.__WUJIE_MOUNT===a&&delete t.__WUJIE_MOUNT,t.__WUJIE_UNMOUNT===o&&delete t.__WUJIE_UNMOUNT,U.get(t)===m&&U.delete(t),d=o(),d)}function h(){m()}if(U.set(t,m),t.__WUJIE_MOUNT=a,t.__WUJIE_UNMOUNT=o,t.addEventListener("unload",h),b())try{Promise.resolve(t.__WUJIE.mount()).catch(c)}catch(r){c(r)}else a();return m}let k=0;function C(n,t={}){const s=t.mountTimeoutMs??3e4;if(!Number.isFinite(s)||s<=0||s>2147483647)throw new Error("mountTimeoutMs 必须在 (0, 2147483647] 范围内");const c=new Map;let i=!1,f;const d={async mount(e,o){if(i)throw new Error("Runtime 已销毁");const a=c.get(e);if(a!=null&&a.closing)return await a.closing,d.mount(e,o);if(a){if(a.element!==o)throw new Error(`应用 ${e} 已存在共享容器`);return a.ready}const m=n.apps.find(w=>w.appId===e);if(!m)throw new Error(`未知子应用: ${e}`);const h=n.bridge(e),y=`${e}__fin_micro_${++k}`,r=o.ownerDocument.createElement("div");r.style.height="100%",o.appendChild(r);const u=new AbortController;let v=!1,P,E;const j=new Promise((w,_)=>{E=_}),W=setTimeout(()=>E(new Error(`子应用 ${e} 加载超时`)),s),l={element:o,ready:Promise.resolve(),close(){return l.closing||(l.closing=Promise.resolve().then(async()=>{try{v&&await P(y)}finally{c.get(e)===l&&c.delete(e)}}),r.remove(),clearTimeout(W),u.abort(),E(new Error(`子应用 ${e} 挂载已中断`))),l.closing}};c.set(e,l);const p=(async()=>{const{startApp:w,destroyApp:_}=await import("wujie");if(u.signal.aborted)return;P=_,v=!0;const T=await w({name:y,url:m.entry,el:r,alive:!1,sync:!1,props:{finMicro:h},plugins:[{htmlLoader:g=>g}],fetch:(g,M)=>fetch(g,{...M,signal:u.signal}),loadError(g,M){E(new Error(`子应用 ${e} 加载失败 (${g}): ${M.message}`))}});u.signal.aborted&&typeof T=="function"&&await T()})();return l.ready=(async()=>{try{await Promise.race([j,p])}catch(w){throw await l.close().catch(_=>{console.error("[fin-micro] 应用挂载失败后的清理失败",_)}),w}finally{clearTimeout(W)}})(),l.ready},unmount(e){var o;return((o=c.get(e))==null?void 0:o.close())??Promise.resolve()},dispose(){return f||(i=!0,f=Promise.allSettled([...c.keys()].map(e=>d.unmount(e))).then(e=>{const o=e.find(a=>a.status==="rejected");if((o==null?void 0:o.status)==="rejected")throw o.reason}),f)}};return d}exports.createWujieRuntime=C;exports.isMicroFrontend=b;exports.setupWujieLifecycle=S;
1
+ "use strict";var J=Object.create;var W=Object.defineProperty;var O=Object.getOwnPropertyDescriptor;var L=Object.getOwnPropertyNames;var $=Object.getPrototypeOf,k=Object.prototype.hasOwnProperty;var A=(n,t,s,c)=>{if(t&&typeof t=="object"||typeof t=="function")for(let i of L(t))!k.call(n,i)&&i!==s&&W(n,i,{get:()=>t[i],enumerable:!(c=O(t,i))||c.enumerable});return n};var F=(n,t,s)=>(s=n!=null?J($(n)):{},A(t||!n||!n.__esModule?W(s,"default",{value:n,enumerable:!0}):s,n));Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const v=new WeakMap;function T(){var n;return typeof window<"u"&&typeof((n=window.__WUJIE)==null?void 0:n.mount)=="function"}function R(n){var y;if(typeof window>"u"){const r=Promise.resolve();return()=>r}const t=window,s=(y=v.get(t))==null?void 0:y(),c=r=>{console.error("[fin-micro] 应用生命周期失败")};let i=(s==null?void 0:s.catch(()=>{}))??Promise.resolve(),f=!1,d,e;function o(){const r=e;if(!r||(e=void 0,!r.started))return i;try{i=Promise.resolve(n.unmount())}catch(u){i=Promise.reject(u)}return i.catch(c),i}function a(){if(f)return Promise.resolve();if(e)return e.ready;const r={started:!1,ready:Promise.resolve()};e=r;const u=async()=>{if(!(f||e!==r)){r.started=!0;try{await n.mount()}catch(h){throw e===r&&await o().catch(()=>{}),h}}};return r.ready=i.then(u,u),r.ready.catch(c),r.ready}function m(){return d||(f=!0,t.removeEventListener("pagehide",g),t.__WUJIE_MOUNT===a&&delete t.__WUJIE_MOUNT,t.__WUJIE_UNMOUNT===o&&delete t.__WUJIE_UNMOUNT,v.get(t)===m&&v.delete(t),d=o(),d)}function g(r){r.persisted||m()}if(v.set(t,m),t.__WUJIE_MOUNT=a,t.__WUJIE_UNMOUNT=o,t.addEventListener("pagehide",g),T())try{Promise.resolve(t.__WUJIE.mount()).catch(c)}catch{c()}else a();return m}let S=0;function C(n,t={}){const s=t.mountTimeoutMs??3e4;if(!Number.isFinite(s)||s<=0||s>2147483647)throw new Error("mountTimeoutMs 必须在 (0, 2147483647] 范围内");const c=new Map;let i=!1,f;const d={async mount(e,o){if(i)throw new Error("Runtime 已销毁");const a=c.get(e);if(a!=null&&a.closing)return await a.closing,d.mount(e,o);if(a){if(a.element!==o)throw new Error(`应用 ${e} 已存在共享容器`);return a.ready}const m=n.apps.find(w=>w.appId===e);if(!m)throw new Error(`未知子应用: ${e}`);if(m.kind==="local")throw new Error("本地应用不能通过 Wujie 挂载");const g=n.bridge(e),y=`${e}__fin_micro_${++S}`,r=o.ownerDocument.createElement("div");r.style.height="100%",o.appendChild(r);const u=new AbortController;let h=!1,P,_;const j=new Promise((w,E)=>{_=E}),p=setTimeout(()=>_(new Error(`子应用 ${e} 加载超时`)),s),l={element:o,ready:Promise.resolve(),close(){return l.closing||(l.closing=Promise.resolve().then(async()=>{try{h&&await P(y)}finally{c.get(e)===l&&c.delete(e)}}),r.remove(),clearTimeout(p),u.abort(),_(new Error(`子应用 ${e} 挂载已中断`))),l.closing}};c.set(e,l);const N=(async()=>{const{startApp:w,destroyApp:E}=await import("wujie");if(u.signal.aborted)return;P=E,h=!0;const M=await w({name:y,url:m.entry,el:r,alive:!1,sync:!1,props:{finMicro:g},plugins:[{htmlLoader:U=>U}],fetch:(U,b)=>fetch(U,{...b,signal:u.signal}),loadError(){_(new Error("子应用加载失败"))}});u.signal.aborted&&typeof M=="function"&&await M()})();return l.ready=(async()=>{try{await Promise.race([j,N])}catch(w){throw await l.close().catch(()=>{console.error("[fin-micro] 应用挂载失败后的清理失败")}),w}finally{clearTimeout(p)}})(),l.ready},unmount(e){var o;return((o=c.get(e))==null?void 0:o.close())??Promise.resolve()},dispose(){return f||(i=!0,f=Promise.allSettled([...c.keys()].map(e=>d.unmount(e))).then(e=>{const o=e.find(a=>a.status==="rejected");if((o==null?void 0:o.status)==="rejected")throw o.reason}),f)}};return d}exports.createWujieRuntime=C;exports.isMicroFrontend=T;exports.setupWujieLifecycle=R;
package/dist/runtime.mjs CHANGED
@@ -1,16 +1,16 @@
1
- const U = /* @__PURE__ */ new WeakMap();
2
- function p() {
1
+ const v = /* @__PURE__ */ new WeakMap();
2
+ function J() {
3
3
  var u;
4
4
  return typeof window < "u" && typeof ((u = window.__WUJIE) == null ? void 0 : u.mount) == "function";
5
5
  }
6
- function b(u) {
6
+ function j(u) {
7
7
  var y;
8
8
  if (typeof window > "u") {
9
9
  const t = Promise.resolve();
10
10
  return () => t;
11
11
  }
12
- const n = window, l = (y = U.get(n)) == null ? void 0 : y(), i = (t) => {
13
- console.error("[fin-micro] 应用生命周期失败", t);
12
+ const n = window, l = (y = v.get(n)) == null ? void 0 : y(), i = (t) => {
13
+ console.error("[fin-micro] 应用生命周期失败");
14
14
  };
15
15
  let s = (l == null ? void 0 : l.catch(() => {
16
16
  })) ?? Promise.resolve(), f = !1, d, e;
@@ -34,31 +34,31 @@ function b(u) {
34
34
  t.started = !0;
35
35
  try {
36
36
  await u.mount();
37
- } catch (v) {
37
+ } catch (_) {
38
38
  throw e === t && await r().catch(() => {
39
- }), v;
39
+ }), _;
40
40
  }
41
41
  }
42
42
  };
43
43
  return t.ready = s.then(c, c), t.ready.catch(i), t.ready;
44
44
  }
45
45
  function m() {
46
- return d || (f = !0, n.removeEventListener("unload", g), n.__WUJIE_MOUNT === o && delete n.__WUJIE_MOUNT, n.__WUJIE_UNMOUNT === r && delete n.__WUJIE_UNMOUNT, U.get(n) === m && U.delete(n), d = r(), d);
46
+ return d || (f = !0, n.removeEventListener("pagehide", h), n.__WUJIE_MOUNT === o && delete n.__WUJIE_MOUNT, n.__WUJIE_UNMOUNT === r && delete n.__WUJIE_UNMOUNT, v.get(n) === m && v.delete(n), d = r(), d);
47
47
  }
48
- function g() {
49
- m();
48
+ function h(t) {
49
+ t.persisted || m();
50
50
  }
51
- if (U.set(n, m), n.__WUJIE_MOUNT = o, n.__WUJIE_UNMOUNT = r, n.addEventListener("unload", g), p())
51
+ if (v.set(n, m), n.__WUJIE_MOUNT = o, n.__WUJIE_UNMOUNT = r, n.addEventListener("pagehide", h), J())
52
52
  try {
53
53
  Promise.resolve(n.__WUJIE.mount()).catch(i);
54
- } catch (t) {
55
- i(t);
54
+ } catch {
55
+ i();
56
56
  }
57
57
  else o();
58
58
  return m;
59
59
  }
60
- let J = 0;
61
- function j(u, n = {}) {
60
+ let b = 0;
61
+ function O(u, n = {}) {
62
62
  const l = n.mountTimeoutMs ?? 3e4;
63
63
  if (!Number.isFinite(l) || l <= 0 || l > 2147483647) throw new Error("mountTimeoutMs 必须在 (0, 2147483647] 范围内");
64
64
  const i = /* @__PURE__ */ new Map();
@@ -75,56 +75,57 @@ function j(u, n = {}) {
75
75
  }
76
76
  const m = u.apps.find((w) => w.appId === e);
77
77
  if (!m) throw new Error(`未知子应用: ${e}`);
78
- const g = u.bridge(e), y = `${e}__fin_micro_${++J}`, t = r.ownerDocument.createElement("div");
78
+ if (m.kind === "local") throw new Error("本地应用不能通过 Wujie 挂载");
79
+ const h = u.bridge(e), y = `${e}__fin_micro_${++b}`, t = r.ownerDocument.createElement("div");
79
80
  t.style.height = "100%", r.appendChild(t);
80
81
  const c = new AbortController();
81
- let v = !1, M, E;
82
- const N = new Promise((w, _) => {
83
- E = _;
84
- }), T = setTimeout(() => E(new Error(`子应用 ${e} 加载超时`)), l), a = {
82
+ let _ = !1, P, g;
83
+ const W = new Promise((w, E) => {
84
+ g = E;
85
+ }), p = setTimeout(() => g(new Error(`子应用 ${e} 加载超时`)), l), a = {
85
86
  element: r,
86
87
  ready: Promise.resolve(),
87
88
  close() {
88
89
  return a.closing || (a.closing = Promise.resolve().then(async () => {
89
90
  try {
90
- v && await M(y);
91
+ _ && await P(y);
91
92
  } finally {
92
93
  i.get(e) === a && i.delete(e);
93
94
  }
94
- }), t.remove(), clearTimeout(T), c.abort(), E(new Error(`子应用 ${e} 挂载已中断`))), a.closing;
95
+ }), t.remove(), clearTimeout(p), c.abort(), g(new Error(`子应用 ${e} 挂载已中断`))), a.closing;
95
96
  }
96
97
  };
97
98
  i.set(e, a);
98
- const $ = (async () => {
99
- const { startApp: w, destroyApp: _ } = await import("wujie");
99
+ const T = (async () => {
100
+ const { startApp: w, destroyApp: E } = await import("wujie");
100
101
  if (c.signal.aborted) return;
101
- M = _, v = !0;
102
- const W = await w({
102
+ P = E, _ = !0;
103
+ const M = await w({
103
104
  name: y,
104
105
  url: m.entry,
105
106
  el: t,
106
107
  alive: !1,
107
108
  sync: !1,
108
- props: { finMicro: g },
109
+ props: { finMicro: h },
109
110
  // HTML 缓存会捕获旧 fetch/loadError;禁用这层缓存,避免重试沿用已中断的信号。
110
- plugins: [{ htmlLoader: (h) => h }],
111
+ plugins: [{ htmlLoader: (U) => U }],
111
112
  // 只中断资源读取;不触碰业务 bridge,更不自动重试业务写调用。
112
- fetch: (h, P) => fetch(h, { ...P, signal: c.signal }),
113
- loadError(h, P) {
114
- E(new Error(`子应用 ${e} 加载失败 (${h}): ${P.message}`));
113
+ fetch: (U, N) => fetch(U, { ...N, signal: c.signal }),
114
+ loadError() {
115
+ g(new Error("子应用加载失败"));
115
116
  }
116
117
  });
117
- c.signal.aborted && typeof W == "function" && await W();
118
+ c.signal.aborted && typeof M == "function" && await M();
118
119
  })();
119
120
  return a.ready = (async () => {
120
121
  try {
121
- await Promise.race([N, $]);
122
+ await Promise.race([W, T]);
122
123
  } catch (w) {
123
- throw await a.close().catch((_) => {
124
- console.error("[fin-micro] 应用挂载失败后的清理失败", _);
124
+ throw await a.close().catch(() => {
125
+ console.error("[fin-micro] 应用挂载失败后的清理失败");
125
126
  }), w;
126
127
  } finally {
127
- clearTimeout(T);
128
+ clearTimeout(p);
128
129
  }
129
130
  })(), a.ready;
130
131
  },
@@ -142,7 +143,7 @@ function j(u, n = {}) {
142
143
  return d;
143
144
  }
144
145
  export {
145
- j as createWujieRuntime,
146
- p as isMicroFrontend,
147
- b as setupWujieLifecycle
146
+ O as createWujieRuntime,
147
+ J as isMicroFrontend,
148
+ j as setupWujieLifecycle
148
149
  };
package/dist/sdk.cjs CHANGED
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});function u(){const t=new Map;return{on(e,n){let r=t.get(e);return r||t.set(e,r=new Set),r.add(n),()=>{r.delete(n),!r.size&&t.get(e)===r&&t.delete(e)}},emit(e,n){const r=t.get(e);if(r)for(const i of[...r]){if(t.get(e)!==r)break;r.has(i)&&i(n)}},clear(){t.clear()}}}class d extends Error{constructor(e,n){super(n),this.code=e,this.name="HostCallError"}}class f extends Error{constructor(e,n){super(n),this.code=e,this.name="NavigationError"}}class o extends Error{constructor(e){super(`Token 获取失败: ${e}`),this.code=e,this.name="TokenError"}}function a(t){return t===null||typeof t=="string"&&t.length>0&&t.length<=16384&&!/[\s\u0000-\u001f\u007f]/.test(t)}async function l(t={}){const e=t.bridge??c();if(!e)throw new o("NO_BRIDGE");const n=await e.callHostWithOptions("getToken",{signal:t.signal,timeoutMs:t.timeoutMs});if(!n||typeof n!="object")throw new o("INVALID_RESULT");const r=n;if(r.status==="unauthenticated")throw new o("UNAUTHENTICATED");if(r.status==="session-changed")throw new o("SESSION_CHANGED");if(r.status!=="authenticated"||!a(r.token))throw new o("INVALID_RESULT");return r.token}function g(t){const e=Object.freeze([...t.apps]);return{apps:e,async handler(n){if(!e.includes(n.appId))throw new Error("Token 能力未授权");const r=t.getSession();if(!r.authenticated)return{status:"unauthenticated"};const i=await t.provider(n),s=t.getSession();if(!n.isActive()||n.signal.aborted||!s.authenticated||s.revision!==r.revision)return{status:"session-changed"};if(!a(i))throw new Error("Token 格式无效");return{status:"authenticated",token:i}}}}function c(t){var n,r;const e=t??(typeof window>"u"?void 0:window);return(r=(n=e==null?void 0:e.$wujie)==null?void 0:n.props)==null?void 0:r.finMicro}exports.HostCallError=d;exports.NavigationError=f;exports.TokenError=o;exports.createNotificationBus=u;exports.createTokenCapability=g;exports.getMicroBridge=c;exports.getToken=l;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});function f(){const e=new Map;return{on(t,r){let n=e.get(t);return n||e.set(t,n=new Set),n.add(r),()=>{n.delete(r),!n.size&&e.get(t)===n&&e.delete(t)}},emit(t,r){const n=e.get(t);if(n)for(const i of[...n]){if(e.get(t)!==n)break;n.has(i)&&i(r)}},clear(){e.clear()}}}class d extends Error{constructor(t,r){super(r),this.code=t,this.name="HostCallError"}}class h extends Error{constructor(t,r){super(r),this.code=t,this.name="NavigationError"}}class o extends Error{constructor(t){super(`Token 获取失败: ${t}`),this.code=t,this.name="TokenError"}}function c(e){return e===null||typeof e=="string"&&e.length>0&&e.length<=16384&&!/[\s\u0000-\u001f\u007f]/.test(e)}async function g(e={}){const t=e.bridge??l();if(!t)throw new o("NO_BRIDGE");const r=await t.callHostWithOptions("getToken",{signal:e.signal,timeoutMs:e.timeoutMs});if(!r||typeof r!="object")throw new o("INVALID_RESULT");const n=r;if(n.status==="unauthenticated")throw new o("UNAUTHENTICATED");if(n.status==="session-changed")throw new o("SESSION_CHANGED");if(n.status!=="authenticated"||!c(n.token))throw new o("INVALID_RESULT");return n.token}function p(e){const t=Object.freeze([...e.apps]);return{apps:t,async handler(r){if(!t.includes(r.appId))throw new Error("Token 能力未授权");const n=e.getSession();if(!n.authenticated)return{status:"unauthenticated"};const i=await e.provider(r),a=e.getSession();if(!r.isActive()||r.signal.aborted||!a.authenticated||a.revision!==n.revision)return{status:"session-changed"};if(!c(i))throw new Error("Token 格式无效");return{status:"authenticated",token:i}}}}function w(e){const t=Object.freeze([...e.apps]),r=new WeakMap,n=i=>{if(!t.includes(i.appId)||!i.isActive()||i.signal.aborted)throw new Error("失效协调能力未授权或已释放")};return{beginAuthRequest:{apps:t,handler(i){n(i);const a=Object.freeze({request:"auth-request"});return r.set(a,{appId:i.appId,revision:e.getRevision()}),a}},reportAuthFailure:{apps:t,handler(i,a){if(n(i),!a||typeof a!="object")return!1;const s=r.get(a);return!s||s.appId!==i.appId||(r.delete(a),s.revision!==e.getRevision())?!1:(e.invalidate(),!0)}}}}function u(e,t){return!!(e!=null&&e.authenticated&&typeof t=="string"&&t.trim()&&e.permissions.includes(t))}function E(e,t){return Array.isArray(t)&&t.length>0&&t.some(r=>u(e,r))}function b(e,t){return Array.isArray(t)&&t.length>0&&t.every(r=>u(e,r))}function l(e){var r,n;const t=e??(typeof window>"u"?void 0:window);return(n=(r=t==null?void 0:t.$wujie)==null?void 0:r.props)==null?void 0:n.finMicro}exports.HostCallError=d;exports.NavigationError=h;exports.TokenError=o;exports.createAuthFailureCapabilities=w;exports.createNotificationBus=f;exports.createTokenCapability=p;exports.getMicroBridge=l;exports.getToken=g;exports.hasAll=b;exports.hasAny=E;exports.hasPermission=u;
package/dist/sdk.mjs CHANGED
@@ -1,82 +1,118 @@
1
- function u() {
2
- const t = /* @__PURE__ */ new Map();
1
+ function d() {
2
+ const e = /* @__PURE__ */ new Map();
3
3
  return {
4
- on(e, n) {
5
- let r = t.get(e);
6
- return r || t.set(e, r = /* @__PURE__ */ new Set()), r.add(n), () => {
7
- r.delete(n), !r.size && t.get(e) === r && t.delete(e);
4
+ on(t, r) {
5
+ let n = e.get(t);
6
+ return n || e.set(t, n = /* @__PURE__ */ new Set()), n.add(r), () => {
7
+ n.delete(r), !n.size && e.get(t) === n && e.delete(t);
8
8
  };
9
9
  },
10
- emit(e, n) {
11
- const r = t.get(e);
12
- if (r)
13
- for (const s of [...r]) {
14
- if (t.get(e) !== r) break;
15
- r.has(s) && s(n);
10
+ emit(t, r) {
11
+ const n = e.get(t);
12
+ if (n)
13
+ for (const a of [...n]) {
14
+ if (e.get(t) !== n) break;
15
+ n.has(a) && a(r);
16
16
  }
17
17
  },
18
18
  clear() {
19
- t.clear();
19
+ e.clear();
20
20
  }
21
21
  };
22
22
  }
23
- class f extends Error {
23
+ class l extends Error {
24
24
  /** 使用稳定 code 与对外 message 创建错误。 */
25
- constructor(e, n) {
26
- super(n), this.code = e, this.name = "HostCallError";
25
+ constructor(t, r) {
26
+ super(r), this.code = t, this.name = "HostCallError";
27
27
  }
28
28
  }
29
- class d extends Error {
29
+ class h extends Error {
30
30
  /** 创建公开错误。message 只包含稳定描述,不传递守卫原始 cause。 */
31
- constructor(e, n) {
32
- super(n), this.code = e, this.name = "NavigationError";
31
+ constructor(t, r) {
32
+ super(r), this.code = t, this.name = "NavigationError";
33
33
  }
34
34
  }
35
- class o extends Error {
36
- constructor(e) {
37
- super(`Token 获取失败: ${e}`), this.code = e, this.name = "TokenError";
35
+ class s extends Error {
36
+ constructor(t) {
37
+ super(`Token 获取失败: ${t}`), this.code = t, this.name = "TokenError";
38
38
  }
39
39
  }
40
- function a(t) {
41
- return t === null || typeof t == "string" && t.length > 0 && t.length <= 16384 && !/[\s\u0000-\u001f\u007f]/.test(t);
40
+ function u(e) {
41
+ return e === null || typeof e == "string" && e.length > 0 && e.length <= 16384 && !/[\s\u0000-\u001f\u007f]/.test(e);
42
42
  }
43
- async function h(t = {}) {
44
- const e = t.bridge ?? c();
45
- if (!e) throw new o("NO_BRIDGE");
46
- const n = await e.callHostWithOptions("getToken", { signal: t.signal, timeoutMs: t.timeoutMs });
47
- if (!n || typeof n != "object") throw new o("INVALID_RESULT");
48
- const r = n;
49
- if (r.status === "unauthenticated") throw new o("UNAUTHENTICATED");
50
- if (r.status === "session-changed") throw new o("SESSION_CHANGED");
51
- if (r.status !== "authenticated" || !a(r.token)) throw new o("INVALID_RESULT");
52
- return r.token;
43
+ async function g(e = {}) {
44
+ const t = e.bridge ?? f();
45
+ if (!t) throw new s("NO_BRIDGE");
46
+ const r = await t.callHostWithOptions("getToken", { signal: e.signal, timeoutMs: e.timeoutMs });
47
+ if (!r || typeof r != "object") throw new s("INVALID_RESULT");
48
+ const n = r;
49
+ if (n.status === "unauthenticated") throw new s("UNAUTHENTICATED");
50
+ if (n.status === "session-changed") throw new s("SESSION_CHANGED");
51
+ if (n.status !== "authenticated" || !u(n.token)) throw new s("INVALID_RESULT");
52
+ return n.token;
53
53
  }
54
- function l(t) {
55
- const e = Object.freeze([...t.apps]);
54
+ function w(e) {
55
+ const t = Object.freeze([...e.apps]);
56
56
  return {
57
- apps: e,
58
- async handler(n) {
59
- if (!e.includes(n.appId)) throw new Error("Token 能力未授权");
60
- const r = t.getSession();
61
- if (!r.authenticated) return { status: "unauthenticated" };
62
- const s = await t.provider(n), i = t.getSession();
63
- if (!n.isActive() || n.signal.aborted || !i.authenticated || i.revision !== r.revision) return { status: "session-changed" };
64
- if (!a(s)) throw new Error("Token 格式无效");
65
- return { status: "authenticated", token: s };
57
+ apps: t,
58
+ async handler(r) {
59
+ if (!t.includes(r.appId)) throw new Error("Token 能力未授权");
60
+ const n = e.getSession();
61
+ if (!n.authenticated) return { status: "unauthenticated" };
62
+ const a = await e.provider(r), i = e.getSession();
63
+ if (!r.isActive() || r.signal.aborted || !i.authenticated || i.revision !== n.revision) return { status: "session-changed" };
64
+ if (!u(a)) throw new Error("Token 格式无效");
65
+ return { status: "authenticated", token: a };
66
66
  }
67
67
  };
68
68
  }
69
- function c(t) {
70
- var n, r;
71
- const e = t ?? (typeof window > "u" ? void 0 : window);
72
- return (r = (n = e == null ? void 0 : e.$wujie) == null ? void 0 : n.props) == null ? void 0 : r.finMicro;
69
+ function p(e) {
70
+ const t = Object.freeze([...e.apps]), r = /* @__PURE__ */ new WeakMap(), n = (a) => {
71
+ if (!t.includes(a.appId) || !a.isActive() || a.signal.aborted) throw new Error("失效协调能力未授权或已释放");
72
+ };
73
+ return {
74
+ beginAuthRequest: {
75
+ apps: t,
76
+ handler(a) {
77
+ n(a);
78
+ const i = Object.freeze({ request: "auth-request" });
79
+ return r.set(i, { appId: a.appId, revision: e.getRevision() }), i;
80
+ }
81
+ },
82
+ reportAuthFailure: {
83
+ apps: t,
84
+ handler(a, i) {
85
+ if (n(a), !i || typeof i != "object") return !1;
86
+ const o = r.get(i);
87
+ return !o || o.appId !== a.appId || (r.delete(i), o.revision !== e.getRevision()) ? !1 : (e.invalidate(), !0);
88
+ }
89
+ }
90
+ };
91
+ }
92
+ function c(e, t) {
93
+ return !!(e != null && e.authenticated && typeof t == "string" && t.trim() && e.permissions.includes(t));
94
+ }
95
+ function E(e, t) {
96
+ return Array.isArray(t) && t.length > 0 && t.some((r) => c(e, r));
97
+ }
98
+ function A(e, t) {
99
+ return Array.isArray(t) && t.length > 0 && t.every((r) => c(e, r));
100
+ }
101
+ function f(e) {
102
+ var r, n;
103
+ const t = e ?? (typeof window > "u" ? void 0 : window);
104
+ return (n = (r = t == null ? void 0 : t.$wujie) == null ? void 0 : r.props) == null ? void 0 : n.finMicro;
73
105
  }
74
106
  export {
75
- f as HostCallError,
76
- d as NavigationError,
77
- o as TokenError,
78
- u as createNotificationBus,
79
- l as createTokenCapability,
80
- c as getMicroBridge,
81
- h as getToken
107
+ l as HostCallError,
108
+ h as NavigationError,
109
+ s as TokenError,
110
+ p as createAuthFailureCapabilities,
111
+ d as createNotificationBus,
112
+ w as createTokenCapability,
113
+ f as getMicroBridge,
114
+ g as getToken,
115
+ A as hasAll,
116
+ E as hasAny,
117
+ c as hasPermission
82
118
  };
@@ -6,6 +6,10 @@ export interface MicroBrowserOptions {
6
6
  window?: Pick<Window, 'location' | 'history' | 'sessionStorage' | 'addEventListener' | 'removeEventListener'>;
7
7
  /** sessionStorage 键,默认 fin-micro:tabs:v1;同源多个工作台应分别设置。 */
8
8
  storageKey?: string;
9
+ /** false 时仅恢复/持久化页签,不读写 URL 或监听历史;地址栏交由宿主路由适配层。 */
10
+ url?: boolean;
11
+ /** 宿主路由已校验的首次深链;恢复时优先于存储,仍须通过 core 授权。 */
12
+ initialLocation?: (Pick<OpenTab, 'appId' | 'tabId' | 'route'> & Partial<Pick<OpenTab, 'title' | 'activeMenuId'>>) | null;
9
13
  /** 存储、URL 编解码或 history 写入错误回调;保留有效页签,编码失败保留原 URL,回调异常被隔离。 */
10
14
  onError?: (error: Error) => void;
11
15
  }
@@ -35,7 +35,7 @@ export interface MicroHostOptions<C extends CapabilityContract<C>> {
35
35
  }
36
36
  /**
37
37
  * 创建无框架的页签宿主。
38
- * @param apps 应用注册表,appId 不可重复且 entry 必须为 HTTP(S)。
38
+ * @param apps 应用注册表,appId 不可重复;远端 entry 必须为 HTTP(S),local 不配置执行地址。
39
39
  * @param options 显式能力与应用白名单;泛型 C 仅提供编译检查,不代替运行时业务校验。
40
40
  * @returns 宿主控制器;使用结束先释放 browser/runtime,再 dispose 宿主。
41
41
  * @throws 应用重复、URL 非法;同步导航错误由各方法抛出,callHost 则始终 Promise 拒绝。
@@ -4,3 +4,5 @@ export * from './core';
4
4
  export * from './runtime';
5
5
  export * from './vue';
6
6
  export * from './browser';
7
+ /** 宿主真实路由模板依赖的能力协议:local 页面、认证能力及仅存储浏览器连接器。 */
8
+ export declare const hostRouterProtocol = 1;