@fulgurjs/federation 2.0.1 → 2.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,55 @@
1
1
  # Changelog
2
2
 
3
+ ## 2.0.2(2026-09-22)
4
+
5
+ ### 修复(D6:双向宿主 devSharedSelf 开启后 prod 构建产物 chunk 循环崩溃)
6
+
7
+ - **缺陷**:双向联邦宿主(既 expose 又消费 remote)按文档口径设置 `devSharedSelf: true` 后,
8
+ `vite build` 成功但 prod 运行时崩溃——`SyntaxError: Unexpected token '<'`(chunk 被 SPA 回退)
9
+ + `TypeError: _e is not a function`(协商函数未初始化)。仅在「宿主 + 用户 manualChunks 强制
10
+ 分组(对象/函数形式)」组合下触发(实测 mes-zc admin:vue-vendor ⇄ antd-vue-vendor 环)。
11
+ - **根因**:`devSharedSelf` 使 node_modules 参与门面化,被 manualChunks 强制分组的包
12
+ (如 vue-vendor 组内 vue-router)内部的 shared 导入被改写为协商门面;门面为静态
13
+ `import` 运行时的 TLA 模块,被 rollup 按消费方归组拖入其他强制组 → 跨组静态环 →
14
+ 门面 TLA 求值顺序错位。
15
+ - **修复 1(门面形态参数化,virtual.ts)**:`genSharedFacade` / `genSharedNsFacade` /
16
+ `genBindingFacade` / `genRemoteBindingFacade` 新增 dynamic 形态——门面对运行时与 shared
17
+ 本体的依赖全部改为 TLA 内 `await import(...)`,命名空间门面以 `{ ...ns }` 复制阻断 rollup
18
+ 透传内联——门面 chunk 对外零静态依赖("汇"形态),与任何 manualChunks 分组正交,不可能成环。
19
+ **dynamic 仅在 devSharedSelf 宿主(build)启用;其余一切场景(纯 remote、dev serve)保持
20
+ 2.0.0 静态形态,产物与行为零变化**(硬约束;纯 remote 若启用动态化会在自动分包下出现
21
+ 「门面 TLA → 动态 import 本体 chunk ← 静态 import 门面」死锁,实测确认)。
22
+ - **修复 2(shared 闭包静态化,transform.ts + index.ts)**:devSharedSelf 宿主(build)下,
23
+ provide 键本体闭包内的模块(如 vue-router 包、vue-demi 转发层——经 shared 本体文件解析
24
+ 传递依赖)对 shared 键的导入**不做门面化**(同一 provide 闭包天然同实例)——斩断
25
+ 「fallback 动态 import 本体 chunk ← 本体消费方静态 import 门面」的 TLA 混合环(实机死锁:
26
+ 页面停在骨架屏、零报错)。别名转发层的 `export * from <key>` 因此保持静态、不再触发
27
+ ESM 门面化硬报错。纯 remote 不启用,行为零变化(硬约束)。
28
+ - **修复 3(manualChunks 包装注入,index.ts)**:devSharedSelf 宿主 + 用户配置了
29
+ manualChunks 时,插件包装注入归组函数——运行时隔离进 `fulgurjs-runtime` 组、协商门面按
30
+ shareKey 隔离进 `fulgurjs-shared-<key>` 组、远程绑定门面进 `fulgurjs-remote-facades-*` 组。
31
+ 对象形式的 specifier 解析延迟到 buildStart(走完整解析管线含 alias),解析失败丢组并告警。
32
+ - **修复 4(post 阶段 auto-import 兜底,index.ts)**:build 下 post.transform 不再跳过非
33
+ `.vue` 文件——unplugin-auto-import 等后置插件注入的 `import { ref } from 'vue'` 发生在
34
+ pre.transform 之后,此前会绕过门面化、静态绑定本地 vue 副本,与协商实例形成**双响应性
35
+ 系统**(实测:同一组件内 A ref 的赋值不触发渲染、B ref 的赋值正常;jsdelivr 级表现即
36
+ 「弹窗 model 置 true 却不渲染」)。pre 已改写过的文件由 `isPluginProcessedModule` 守卫
37
+ 拦下,不会双重改写。
38
+ - **新增诊断**:`BLD-006`——output 为数组形态时无法自动注入,三段式提示手工加隔离分支。
39
+ - **集成器**:宿主为双向(有 exposes 且有 remotes)时 vite.config 模板产出
40
+ `devSharedSelf: true`(落实 README 口径;须配合本版插件使用)。
41
+ - **测试**:+10(门面 dynamic/static 双形态断言 ×6、真实 vite build 产物形态用例 ×1——
42
+ 覆盖「宿主 + devSharedSelf + manualChunks 对象形式」这条此前零覆盖的路径,断言产物无环、
43
+ 门面隔离、"汇"形态、node_modules 门面化指向隔离 chunk;post 兜底源码契约 ×3)。
44
+
45
+ ### 已知边界
46
+
47
+ - devSharedSelf 宿主的协商门面 chunk 集中在插件专属组:与「门面分散在各业务 chunk」的
48
+ 旧形态相比,首屏会多下载所属 shareKey 的门面 chunk(未压缩量级 = 门面行数,gzip 后显著
49
+ 缩小);这是换取「与 manualChunks 共存」的结构性代价。
50
+ - 入口文件(index.html 直引的模块)内的 remote 导入在 build 下不参与改写(入口只内联 init
51
+ 即短路返回,既有边界):remote 导入请放在非入口模块。
52
+
3
53
  ## 2.0.1(2026-09-22)
4
54
 
5
55
  ### 变更(文档与包面,零运行时变化)
package/README.md CHANGED
@@ -174,7 +174,7 @@ import { federation, type FederationOptions } from '@fulgurjs/federation'
174
174
  | `manifest` | `boolean` | `true` | prod 构建生成 `fulgurjs-manifest.json`(preloadRemote 依赖它) |
175
175
  | `runtimePlugins` | `string[]` | `[]` | 运行时插件模块路径列表(写法见「运行时插件」) |
176
176
  | `dts` | `boolean \| { dir?: string; mode?: 'source' \| 'shim' }` | `true` | dev 下拉取远程 manifest 生成类型声明——宿主写 `import X from 'remote-a/X'` 获得类型。**产物写入 `src/fulgurjs/types/`(联邦产物集中一个文件夹;无 src 布局回退 `.fulgurjs/types`)**,src 布局项目 tsconfig 零配置即生效;`{ dir }` 自定义位置;`mode: 'source'`(默认)跨工程源码直连(补全/跳转直达远程源码,VSCode 打开生成物可能显示工程外文件诊断);`mode: 'shim'` 宽松占位(不引用源文件,IDE 全程干净,无源码级补全——见 §9.1.5) |
177
- | `devSharedSelf` | `boolean` | 纯远程 `true`;有 `remotes` 的宿主 `false` | dev 下自身源码(含依赖)是否参与 shared 协商改写。**双向联邦**(既 expose 又消费 remote)的宿主/远程需显式 `true`,否则 prod 双 vue 实例 |
177
+ | `devSharedSelf` | `boolean` | 纯远程 `true`;有 `remotes` 的宿主 `false` | dev 下自身源码(含依赖)是否参与 shared 协商改写。**双向联邦**(既 expose 又消费 remote)的宿主/远程**必设 `true`**,否则 prod 双 vue 实例(症状:被消费页面渲染上下文错乱 / `'ce'` / renderSlot null)。2.0.1 起 build 下该路径的协商门面自动隔离进插件专属 chunk(`fulgurjs-runtime` + `fulgurjs-shared-<key>`),与用户 `manualChunks` 强制分组正交、不再产生 chunk 循环依赖(D6 修复,症状曾是 `SyntaxError: Unexpected token '<'` + `TypeError: _e is not a function`) |
178
178
  | `automaticAsyncBoundary` | — | 恒为 `true` | 接受任意值:TLA 自动异步边界,无需手工 bootstrap |
179
179
  | `dataPrefetch` | — | 恒为 `true` | 接受任意值:`preloadRemote` 始终可用 |
180
180
  | `usedExports` / `ignoreUnusedSharedExports` | — | no-op | 接受并忽略(Rollup/Rolldown 原生 tree-shaking 已覆盖) |
@@ -373,7 +373,7 @@ export default defineRepoConfig({
373
373
  | `fulgurjs init --config <path>` | 校验配置(CFG 三段式报错)+ 输出各应用 `federation()` 粘贴块、NGINX no-cache 站点模板、8 条通用核对清单 |
374
374
  | `fulgurjs doctor --base <URL> --apps <a,b,c>` | 部署体检:remoteEntry/manifest/index.html 的 200/no-cache/JS 形态、CORS、chunk 抽样可达、版本 skew 预演。`--dev` 检查 dev 容器入口;`--json` 输出 JSON(CI 断言);`--chunk-sample N` 控制抽样数(默认 16)。**退出码:有 FAIL 即 1**,可直接做 CI 门禁 |
375
375
 
376
- ### 6. 错误码总表(30 个)
376
+ ### 6. 错误码总表(31 个)
377
377
 
378
378
  | 段 | 码 | 含义 |
379
379
  |---|---|---|
@@ -395,6 +395,7 @@ export default defineRepoConfig({
395
395
  | BLD 构建期 | `BLD-001` | expose 源文件解析失败 |
396
396
  | | `BLD-002` | 构建目标低于 es2022(TLA 需要) |
397
397
  | | `BLD-003` | expose 目标组件含必填 props(文档化核对项) |
398
+ | | `BLD-006` | output 数组形态下无法自动注入协商门面 chunk 隔离(需手工加分支) |
398
399
  | MFU 运行时 | `MFU-001` | 远程容器/模块加载失败(网络/超时/重试耗尽/熔断) |
399
400
  | | `MFU-002` | remoteEntry 自报名与配置名不一致 |
400
401
  | | `MFU-003` | strictVersion 版本不满足 |
@@ -697,7 +698,7 @@ const Panel = await loadRemote('shop/Panel', {
697
698
 
698
699
  运行时加载失败同样给排查指引(remote dev server 未启动 / 地址配错 / CORS / NGINX 回退),并携带统一错误码:
699
700
 
700
- 统一错误码体系(CFG/DEV/BLD/MFU 四段共 30 个)——**完整总表见上方 [API 参考 §6](#6-错误码总表30-个)**;报错文案一律「现象 → 根因 → 修法」三段式。
701
+ 统一错误码体系(CFG/DEV/BLD/MFU 四段共 31 个)——**完整总表见上方 [API 参考 §6](#6-错误码总表31-个)**;报错文案一律「现象 → 根因 → 修法」三段式。
701
702
 
702
703
  调试出口:`window.__FULGURJS_SCOPE__`(share 协商实时结果)、`window.__FULGURJS_INFO__`(remote 状态/耗时/错误)。
703
704
 
@@ -1,5 +1,5 @@
1
1
  // src/version.ts
2
- var RUNTIME_VERSION = "2.0.1";
2
+ var RUNTIME_VERSION = "2.0.2";
3
3
 
4
4
  export {
5
5
  RUNTIME_VERSION
package/dist/index.cjs CHANGED
@@ -43,7 +43,7 @@ var import_node_fs = __toESM(require("fs"), 1);
43
43
  var import_node_path = __toESM(require("path"), 1);
44
44
 
45
45
  // src/version.ts
46
- var RUNTIME_VERSION = "2.0.1";
46
+ var RUNTIME_VERSION = "2.0.2";
47
47
 
48
48
  // src/options.ts
49
49
  var DEFAULT_FILENAME = "fulgurjs-remoteEntry.js";
@@ -402,28 +402,45 @@ var import_node_path2 = __toESM(require("path"), 1);
402
402
  function jsonReplacer(_k, v) {
403
403
  return v;
404
404
  }
405
- function genSharedFacade(specifier, exportNames) {
405
+ function genSharedFacade(specifier, exportNames, dynamic = false) {
406
406
  const names = (exportNames ?? []).filter(
407
407
  (n) => n !== "default" && /^[A-Za-z_$][A-Za-z0-9_$]*$/.test(n)
408
408
  );
409
- if (names.length === 0) {
409
+ if (!dynamic) {
410
+ if (names.length === 0) {
411
+ return [
412
+ `import * as __fulgurjs_facade from ${JSON.stringify(specifier)};`,
413
+ `export * from ${JSON.stringify(specifier)};`,
414
+ `export default __fulgurjs_facade.default ?? __fulgurjs_facade;`,
415
+ ""
416
+ ].join("\n");
417
+ }
410
418
  return [
411
419
  `import * as __fulgurjs_facade from ${JSON.stringify(specifier)};`,
420
+ ...names.map((n) => `export const ${n} = __fulgurjs_facade[${JSON.stringify(n)}];`),
421
+ `export default __fulgurjs_facade.default ?? __fulgurjs_facade;`,
422
+ ""
423
+ ].join("\n");
424
+ }
425
+ if (names.length === 0) {
426
+ return [
427
+ `const __fulgurjs_facade = await import(${JSON.stringify(specifier)});`,
412
428
  `export * from ${JSON.stringify(specifier)};`,
413
429
  `export default __fulgurjs_facade.default ?? __fulgurjs_facade;`,
414
430
  ""
415
431
  ].join("\n");
416
432
  }
417
433
  return [
418
- `import * as __fulgurjs_facade from ${JSON.stringify(specifier)};`,
419
- ...names.map((n) => `export const ${n} = __fulgurjs_facade[${JSON.stringify(n)}];`),
420
- `export default __fulgurjs_facade.default ?? __fulgurjs_facade;`,
434
+ `const __fulgurjs_facade = await import(${JSON.stringify(specifier)});`,
435
+ `const __fulgurjs_ns = { ...__fulgurjs_facade };`,
436
+ ...names.map((n) => `export const ${n} = __fulgurjs_ns[${JSON.stringify(n)}];`),
437
+ `export default __fulgurjs_ns.default ?? __fulgurjs_ns;`,
421
438
  ""
422
439
  ].join("\n");
423
440
  }
424
- function genSharedNsFacade(item, loadShareCall, exportNames) {
441
+ function genSharedNsFacade(item, loadShareCall, exportNames, dynamic = false) {
425
442
  const lines = [
426
- `import { loadShare as __fulgurjs_loadShare, unwrapDefault as __fulgurjsU } from "virtual:fulgurjs-runtime";`,
443
+ dynamic ? `const { loadShare: __fulgurjs_loadShare, unwrapDefault: __fulgurjsU } = await import("virtual:fulgurjs-runtime");` : `import { loadShare as __fulgurjs_loadShare, unwrapDefault as __fulgurjsU } from "virtual:fulgurjs-runtime";`,
427
444
  `const __fulgurjs_m = await ${loadShareCall};`,
428
445
  `const __fulgurjs_d = __fulgurjsU(__fulgurjs_m);`,
429
446
  `export default __fulgurjs_d;`
@@ -437,9 +454,9 @@ function genSharedNsFacade(item, loadShareCall, exportNames) {
437
454
  lines.push("");
438
455
  return lines.join("\n");
439
456
  }
440
- function genBindingFacade(item, bindings, loadShareCall) {
457
+ function genBindingFacade(item, bindings, loadShareCall, dynamic = false) {
441
458
  const lines = [
442
- `import { loadShare as __fulgurjs_loadShare, unwrapDefault as __fulgurjsU } from "virtual:fulgurjs-runtime";`,
459
+ dynamic ? `const { loadShare: __fulgurjs_loadShare, unwrapDefault: __fulgurjsU } = await import("virtual:fulgurjs-runtime");` : `import { loadShare as __fulgurjs_loadShare, unwrapDefault as __fulgurjsU } from "virtual:fulgurjs-runtime";`,
443
460
  `const __fulgurjs_m = await ${loadShareCall};`
444
461
  ];
445
462
  const seen = /* @__PURE__ */ new Set();
@@ -455,9 +472,9 @@ function genBindingFacade(item, bindings, loadShareCall) {
455
472
  lines.push("");
456
473
  return lines.join("\n");
457
474
  }
458
- function genRemoteBindingFacade(remoteSpec, bindings) {
475
+ function genRemoteBindingFacade(remoteSpec, bindings, dynamic = false) {
459
476
  const lines = [
460
- `import { loadRemote as __fulgurjs_loadRemote, unwrapDefault as __fulgurjsU } from "virtual:fulgurjs-runtime";`,
477
+ dynamic ? `const { loadRemote: __fulgurjs_loadRemote, unwrapDefault: __fulgurjsU } = await import("virtual:fulgurjs-runtime");` : `import { loadRemote as __fulgurjs_loadRemote, unwrapDefault: __fulgurjsU } from "virtual:fulgurjs-runtime";`.replace("unwrapDefault: __fulgurjsU", "unwrapDefault as __fulgurjsU"),
461
478
  `const __fulgurjs_m = await __fulgurjs_loadRemote(${JSON.stringify(remoteSpec)});`
462
479
  ];
463
480
  const seen = /* @__PURE__ */ new Set();
@@ -814,6 +831,10 @@ function parseImportClause(clause) {
814
831
  return { ns: nsMatch?.[1] ?? null, bindings, defaultLocal };
815
832
  }
816
833
  var JS_EXT_RE = /\.(m|c)?[jt]sx?$/;
834
+ function inSharedClosure(moduleId, roots) {
835
+ if (!roots || roots.length === 0) return false;
836
+ return roots.some((r) => moduleId.startsWith(r.root));
837
+ }
817
838
  function isTransformableId(id, allowNodeModules = false) {
818
839
  const clean = id.split("?")[0];
819
840
  if (!JS_EXT_RE.test(clean) && !clean.endsWith(".vue")) return false;
@@ -864,6 +885,7 @@ function remoteFacadeSpecFor(ctx, remoteName, exposeName, bindings) {
864
885
  }
865
886
  async function transformModule(code, id, ctx) {
866
887
  const { options } = ctx;
888
+ const clean = id.split("?")[0];
867
889
  if (options.shared.length === 0 && options.remotes.length === 0) return null;
868
890
  const candidates = [];
869
891
  for (const s2 of options.shared) candidates.push(s2.configKey.replace(/\/$/, ""));
@@ -950,7 +972,8 @@ export { ${nsAs[1]} };`);
950
972
  while (code[stmtEnd] === ";") stmtEnd++;
951
973
  const head = code.slice(stmtStart, stmtStart + 24);
952
974
  if (/^\s*(import|export)\s+type[\s{]/.test(head)) continue;
953
- const shared2 = matcher ? matchShared(spec2, matcher) : null;
975
+ const matched2 = matcher ? matchShared(spec2, matcher) : null;
976
+ const shared2 = matched2 && inSharedClosure(clean, ctx.sharedClosureRoots) ? null : matched2;
954
977
  const firstSeg2 = spec2.split("/")[0];
955
978
  const remote2 = remotesByKey.get(firstSeg2);
956
979
  const exposeName2 = remote2 ? remoteExposeName(spec2, remote2.key) : null;
@@ -983,7 +1006,8 @@ export { ${nsAs[1]} };`);
983
1006
  const literal = specExpr.match(/^['"](.*)['"]$/s);
984
1007
  if (!literal) continue;
985
1008
  const spec = remap(literal[1]);
986
- const shared = matcher ? matchShared(spec, matcher) : null;
1009
+ const matched = matcher ? matchShared(spec, matcher) : null;
1010
+ const shared = matched && inSharedClosure(clean, ctx.sharedClosureRoots) ? null : matched;
987
1011
  const firstSeg = spec.split("/")[0];
988
1012
  const remote = remotesByKey.get(firstSeg);
989
1013
  const exposeName = remote ? remoteExposeName(spec, remote.key) : null;
@@ -1298,7 +1322,7 @@ function syncViteCacheMarker(root, pluginVersion, log) {
1298
1322
  }
1299
1323
 
1300
1324
  // src/runtime-code.gen.ts
1301
- var runtime_code_gen_default = 'var X=/^v?(\\d+)(?:\\.(\\d+))?(?:\\.(\\d+))?(?:-((?:[0-9A-Za-z-]+)(?:\\.[0-9A-Za-z-]+)*))?(?:\\+[0-9A-Za-z.-]+)?$/;function T(t){let n=X.exec(String(t).trim());return n?{major:Number(n[1]),minor:Number(n[2]??0),patch:Number(n[3]??0),pre:n[4]?n[4].split("."):[]}:null}function Y(t,n){if(t.length===0&&n.length===0)return 0;if(t.length===0)return 1;if(n.length===0)return-1;let o=Math.max(t.length,n.length);for(let r=0;r<o;r++){let l=t[r],m=n[r];if(l===void 0)return-1;if(m===void 0)return 1;let y=/^\\d+$/.test(l),E=/^\\d+$/.test(m);if(y&&E){let w=Number(l)-Number(m);if(w!==0)return w}else{if(y!==E)return y?-1:1;if(l!==m)return l<m?-1:1}}return 0}function v(t,n){let o=T(t),r=T(n);return!o||!r?t<n?-1:t>n?1:0:o.major!==r.major?o.major-r.major:o.minor!==r.minor?o.minor-r.minor:o.patch!==r.patch?o.patch-r.patch:Y(o.pre,r.pre)}var Z=/^[a-z]+[+:-]/i;function O(t,n){if(n===!1||n==null||n==="")return!0;let o=String(n).trim();return!o||o==="*"||o==="latest"||Z.test(o)?!0:o.split("||").some(r=>Q(t,r.trim()))}function Q(t,n){if(!n||n==="*")return!T(t)?.pre.length;let o=n.split(/\\s+-\\s+/);if(o.length===2){let m=o[0].trim(),y=o[1].trim();return!(!O(t,`>=${m}`)||!O(t,`<=${y}`))}let r=T(t);if(!r)return!1;let l=ee(n);if(l===null)return!0;for(let m of l)if(!ie(r,t,m))return!1;return!(r.pre.length>0&&!l.some(m=>m.ver.pre.length>0)&&!l.some(y=>y.ver.major===r.major&&y.ver.minor===r.minor&&y.ver.patch===r.patch))}function ee(t){let n=[],o=t.trim().split(/\\s+/).filter(Boolean);if(o.length===0)return null;for(let r of o){let l=/^(>=|<=|>|<|=|\\^|~)?(.*)$/.exec(r);if(!l)return null;let m=l[1],y=l[2],E=re(m,y);if(E===null)return null;n.push(...E)}return n}function re(t,n){let o=ne(n);if(!o)return null;let{ver:r,partial:l}=o;switch(t){case"^":{let m=te(r);return m?[{op:">=",ver:r},{op:"<",ver:m}]:null}case"~":{let m=l>=2?{major:r.major,minor:r.minor+1,patch:0,pre:[]}:{major:r.major+1,minor:0,patch:0,pre:[]};return[{op:">=",ver:r},{op:"<",ver:m}]}case">=":return[{op:">=",ver:r}];case">":return l===1?[{op:">=",ver:{major:r.major+1,minor:0,patch:0,pre:[]}}]:l===2?[{op:">=",ver:{major:r.major,minor:r.minor+1,patch:0,pre:[]}}]:[{op:">",ver:r}];case"<":return l===1?[{op:"<",ver:{major:r.major,minor:0,patch:0,pre:[]}}]:l===2?[{op:"<",ver:{major:r.major,minor:r.minor,patch:0,pre:[]}}]:[{op:"<",ver:r}];case"<=":return[{op:"<=",ver:r}];case"=":case void 0:return l===1?[{op:">=",ver:r},{op:"<",ver:{major:r.major+1,minor:0,patch:0,pre:[]}}]:l===2?[{op:">=",ver:r},{op:"<",ver:{major:r.major,minor:r.minor+1,patch:0,pre:[]}}]:[{op:"=",ver:r}];default:return null}}function te(t){return t.major>0?{major:t.major+1,minor:0,patch:0,pre:[]}:t.minor>0?{major:0,minor:t.minor+1,patch:0,pre:[]}:{major:0,minor:0,patch:t.patch+1,pre:[]}}function ne(t){let n=t.replace(/^v/,"").trim();if(!n||n==="*"||n==="x"||n==="X")return{ver:{major:0,minor:0,patch:0,pre:[]},partial:0};let o=n.split("."),r=[],l=0;for(let E of o.slice(0,3))if(/^\\d+$/.test(E))r.push(Number(E)),l++;else{if(E==="x"||E==="X"||E==="*")break;break}let m=n.split("-"),y=m.length>1?m.slice(1).join("-").split("+")[0].split("."):[];return l===0&&y.length===0?{ver:{major:0,minor:0,patch:0,pre:[]},partial:0}:{ver:{major:r[0]??0,minor:r[1]??0,patch:r[2]??0,pre:y},partial:l}}function oe(t,n){switch(n){case">=":return t>=0;case">":return t>0;case"<":return t<0;case"<=":return t<=0;case"=":return t===0}}function ie(t,n,o){let r=`${t.major}.${t.minor}.${t.patch}`+(t.pre.length?`-${t.pre.join(".")}`:"");if(o.upper)return!(!(v(r,`${o.ver.major}.${o.ver.minor}.${o.ver.patch}`+(o.ver.pre.length?`-${o.ver.pre.join(".")}`:""))>=0)||!(v(r,`${o.upper.major}.${o.upper.minor}.${o.upper.patch}`)<0));let l=v(r,`${o.ver.major}.${o.ver.minor}.${o.ver.patch}`+(o.ver.pre.length?`-${o.ver.pre.join(".")}`:"")),m=oe(l,o.op);return o.ver.pre.length>0&&t.pre.length===0&&(o.op===">"||o.op==="<")?!1:m}var g=class extends Error{code;details;constructor(n,o,r){super(`[fulgurjs:${n}] ${o}`),this.name="FgError",this.code=n,this.details=r}},S={REMOTE_LOAD_FAILED:"MFU-001",REMOTE_NAME_MISMATCH:"MFU-002",SHARE_STRICT_VERSION:"MFU-003",SHARE_NOT_AVAILABLE:"MFU-004",CONTAINER_REINIT_CONFLICT:"MFU-005",MODULE_NOT_EXPOSED:"MFU-006",PRELOAD_FAILED:"MFU-007",REMOTE_UNKNOWN:"MFU-008",EMPTY_EXPORTS:"MFU-009",SINGLETON_SKEW:"MFU-010"};var U="2.0.1";var A=15e3,P=2,ae=5,se=3e4;function ce(){let t={},n=new Map,o=[],r=new Map,l=new WeakMap,m={},y=()=>{for(let e of o)try{e.init?.(m)}catch(i){console.warn("[fulgurjs] runtimePlugin init failed:",e.name,i)}},E=e=>t[e]??={};function w(e){try{m.onRemoteError?.(e)}catch{}typeof window<"u"&&window.dispatchEvent(new CustomEvent("fulgurjs:error",{detail:e}))}function F(e="default"){return E(e),t}function V(e,i,a,c,R={}){let s=E(e||"default"),u=s[i]??={};u[a]||(u[a]={version:a,get:c,from:R.from??"unknown",eager:!!R.eager,loaded:!!R.loaded})}function I(e){for(let i of e){let a=n.get(i.name);n.set(i.name,{timeout:A,retries:P,...a,...i,state:a?.state??"idle",breakerState:a?.breakerState??{fails:0,openUntil:0},debug:a?.debug??{entry:i.entry,status:"idle"}})}}function D(e){I([e])}function H(e){o.push(...e),y()}async function K(e,i={}){let a=i.shareScope||"default",c=i.shareKey||e,s=E(a)[c]||{},u=Object.keys(s),d=i.requiredVersion,f=u.filter(p=>d===void 0||d===!1||O(p,d)),_;if(i.singleton&&u.length>0){let p=u.filter(h=>s[h].loaded);if(_=[...p.length?p:u].sort(v).pop(),u.length>1||!f.includes(_)){let h=s[_],j=`singleton skew "${c}": req "${d??"any"}" use ${_} from ${h.from}`;if(i.strictVersion){let M=new g(S.SHARE_STRICT_VERSION,j,{shareKey:c,requiredVersion:d});throw w({remote:h.from,error:M}),M}console.warn(`[fulgurjs:MFU-010] ${j}`)}}else if(_=[...f].sort(v).pop(),!_){if(i.strictVersion){let h=new g(S.SHARE_STRICT_VERSION,`no satisfying version for "${c}" (required "${d}") in share scope "${a}"`);throw w({remote:c,error:h}),h}if(i.fallback)return i.fallback();let p=new g(S.SHARE_NOT_AVAILABLE,`shared "${c}" (${d??"any"}) unavailable in scope "${a}" (no local fallback)`,{shareKey:c,requiredVersion:d});throw w({remote:c,error:p}),p}let $=s[_];if(m.resolveShare){let p=await m.resolveShare({shareKey:c,shareScope:a,requiredVersion:d,picked:$,available:Object.values(s)});p&&($=p)}return $.loaded=!0,$.get()}function q(e,i,a){return new Promise((c,R)=>{let s=setTimeout(()=>R(new Error(`timeout after ${i}ms: ${a}`)),i);e.then(u=>{clearTimeout(s),c(u)},u=>{clearTimeout(s),R(u)})})}let z=e=>new Promise(i=>setTimeout(i,e));function k(e,i){if(!e||typeof e.get!="function")throw new Error(`remoteEntry of "${i.name}" does not export a container interface (get/init)`);if(e.name&&i.name&&e.name!==i.name){let a=`remoteEntry self-reported name "${e.name}" mismatches configured name "${i.name}"`;if(i.promise)console.warn(`[fulgurjs] ${a} (promise-based remote, continuing)`);else throw Object.assign(new Error(a),{code:S.REMOTE_NAME_MISMATCH})}}async function L(e,i){return q(import(e),i.timeout??A,`load remoteEntry ${e}`)}async function x(e,i){let a=e.shareScope||"default";if(e.container){let s=l.get(e.container);if(s&&s!==a)throw new g(S.CONTAINER_REINIT_CONFLICT,`container "${e.name}" already initialized with share scope "${s}", cannot re-init with "${a}"`);return e.container}if(e.containerPromise)return e.containerPromise;let c=e.breakerState;if(c.openUntil>Date.now()){let s=new g(S.REMOTE_LOAD_FAILED,`circuit breaker open for remote "${e.name}" until ${new Date(c.openUntil).toISOString()}`,{remote:e.name});throw w({remote:e.name,error:s}),s}e.state="loading",e.debug.status="loading";let R=(async()=>{let s=[];if(e.promise)s.push(async()=>{let p=await e.promise(),h=typeof p=="string"?await L(p,e):p;return k(h,e),h});else for(let p of[e.entry,...e.fallback??[]])s.push(async()=>{let h=await L(p,e);return k(h,e),h});let u,d,f=!1,_=i?.retries??e.retries??P;for(let p of s){for(let h=0;h<=_;h++){let j=performance.now();try{u=await p(),e.lastLoadMs=Math.round(performance.now()-j),e.debug.lastLoadMs=e.lastLoadMs,f=!0;break}catch(M){if(d=M,M?.code)throw M;h<_&&await z(200*2**h)}}if(f)break}if(!f||!u){let p=[];throw/^https?:\\/\\//.test(e.entry)&&typeof location<"u"?(p.push(`1. is the remote dev server running? try opening ${e.entry} in the browser \\u2014 it must return JS, not HTML/an error`),p.push("2. is the URL correct in federation({ remotes })? dev and prod entries can differ"),p.push("3. CORS: the remote dev server must allow cross-origin requests (fulgurjs-federation enables server.cors automatically; a custom server config may have disabled it)")):(p.push(`1. is the remote deployed and reachable? try opening ${e.entry} in the browser \\u2014 it must return JS`),p.push("2. NGINX/CDN routing: the entry path must serve the remoteEntry JS file (check try_files / fallback rules)")),new g(S.REMOTE_LOAD_FAILED,`failed to load remote "${e.name}" from ${e.entry}: ${String(d?.message??d)}\n`+p.join(`\n`),{remote:e.name})}k(u,e);let $=l.get(u);if($&&$!==a)throw new g(S.CONTAINER_REINIT_CONFLICT,`container "${e.name}" already initialized with share scope "${$}", cannot re-init with "${a}"`);return typeof u.init=="function"&&await u.init(t),l.set(u,a),e.container=u,e.state="loaded",e.debug.status="loaded",c.fails=0,u})();e.containerPromise=R;try{return await R}catch(s){if(e.containerPromise=void 0,e.state="failed",e.debug.status="failed",e.debug.error=String(s?.message??s),c.fails+=1,c.fails>=ae&&(c.openUntil=Date.now()+se,c.fails=0),s instanceof g)throw w({remote:e.name,error:s}),s;if(s?.code)throw w({remote:e.name,error:s}),s;let u=new g(S.REMOTE_LOAD_FAILED,String(s?.message??s),{remote:e.name});throw w({remote:e.name,error:u}),u}}function N(e){let i=e.indexOf("/");return i===-1?{remote:e,module:""}:{remote:e.slice(0,i),module:G(e.slice(i+1))}}function G(e){return e?e.startsWith(".")?e:`./${e}`:""}async function J(e,i){let{remote:a,module:c}=N(e);m.beforeLoadRemote?.({remote:a,module:c});let R=n.get(a);if(!R)throw new g(S.REMOTE_UNKNOWN,`unknown remote "${a}". Register it via federation({ remotes }) or registerRemote().`,{remote:a});let s;try{s=await x(R,{retries:i?.retries})}catch(f){if(i?.fallbackModule)return console.error(`[fulgurjs] loadRemote("${e}") failed; returning fallbackModule (\\u663E\\u5F0F\\u964D\\u7EA7\\uFF0C\\u9519\\u8BEF\\u5DF2\\u900F\\u51FA)`,f),w({remote:a,error:f}),await i.fallbackModule();throw f}if(!c)return s;let u=`${a}@${R.shareScope||"default"}#${c}`;r.has(u)||r.set(u,s.get(c).catch(f=>{throw r.delete(u),f instanceof g||f?.code?f:new g(S.REMOTE_LOAD_FAILED,`failed to load module "${c}" from remote "${a}": ${String(f?.message??f)}`,{remote:a,module:c})}));let d;try{d=await r.get(u)}catch(f){if(i?.fallbackModule)return console.error(`[fulgurjs] loadRemote("${e}") failed; returning fallbackModule (\\u663E\\u5F0F\\u964D\\u7EA7\\uFF0C\\u9519\\u8BEF\\u5DF2\\u900F\\u51FA)`,f),w({remote:a,error:f}),await i.fallbackModule();throw f}if(m.afterLoadRemote?.({remote:a,module:c,module_ns:d}),d&&typeof d=="object"&&Object.keys(d).length===0){let f=new g(S.EMPTY_EXPORTS,`no exports: ${c} @ ${a}`,{remote:a,module:c});w({remote:a,error:f}),console.error(`[fulgurjs:MFU-009] ${f.message}`)}return d}function W(e){let i=n.get(e);if(!i)throw new g(S.REMOTE_UNKNOWN,`unknown remote "${e}"`,{remote:e});return x(i)}async function B(e,i={}){let{remote:a}=N(e),c=n.get(a);if(!c)throw new g(S.REMOTE_UNKNOWN,`unknown remote "${a}"`,{remote:a});let R=i.mode??"preload",s=(u,d)=>{if(typeof document>"u"||document.querySelector(`link[href="${u}"]`))return;let f=document.createElement("link");f.rel=d==="style"?"stylesheet":"modulepreload",f.href=u,R==="prefetch"&&(f.fetchPriority="low"),document.head.appendChild(f)};try{if(c.manifestUrl){let u=await fetch(c.manifestUrl,{cache:"no-cache"});if(u.ok){let d=await u.json();s(c.entry,"modulepreload");let f=d.exposes??{};for(let _ of Object.keys(f)){let $=f[_];$?.file&&s(new URL($.file,c.entry).href,"modulepreload");for(let p of $?.css??[])s(new URL(p,c.entry).href,"style")}return}}s(c.entry,"modulepreload")}catch(u){w({remote:a,error:new g(S.PRELOAD_FAILED,String(u?.message??u),{remote:a})})}}return typeof window>"u"||(window.__FULGURJS_SCOPE__=t,window.__FULGURJS_INFO__={get remotes(){let e={};for(let[i,a]of n)e[i]={...a.debug,entry:a.entry};return e},errors:[]}),{shareScopeMap:t,initSharing:F,registerShare:V,registerRemotes:I,registerRemote:D,registerPlugins:H,loadShare:K,loadRemote:J,getContainer:W,preloadRemote:B,parseSpec:N}}var C=globalThis,b=C.__FULGURJS_RUNTIME__??ce();C.__FULGURJS_RUNTIME__=b;try{Object.freeze(b)}catch{}var he=U;function ye(){return b}var Ee=b.initSharing,Re=b.registerShare,Se=b.registerRemotes,we=b.registerRemote,be=b.registerPlugins,_e=b.loadShare,$e=b.loadRemote,Me=b.getContainer,ve=b.preloadRemote,je=b.shareScopeMap;function Te(t){if(t&&typeof t=="object"&&"default"in t){let n=t.default;return n!==void 0?n:t}return t}var Oe=b;export{Oe as default,Me as getContainer,ye as getRuntime,Ee as initSharing,$e as loadRemote,_e as loadShare,ve as preloadRemote,be as registerPlugins,we as registerRemote,Se as registerRemotes,Re as registerShare,b as runtime,je as shareScopeMap,Te as unwrapDefault,he as version};\n';
1325
+ var runtime_code_gen_default = 'var X=/^v?(\\d+)(?:\\.(\\d+))?(?:\\.(\\d+))?(?:-((?:[0-9A-Za-z-]+)(?:\\.[0-9A-Za-z-]+)*))?(?:\\+[0-9A-Za-z.-]+)?$/;function T(t){let n=X.exec(String(t).trim());return n?{major:Number(n[1]),minor:Number(n[2]??0),patch:Number(n[3]??0),pre:n[4]?n[4].split("."):[]}:null}function Y(t,n){if(t.length===0&&n.length===0)return 0;if(t.length===0)return 1;if(n.length===0)return-1;let o=Math.max(t.length,n.length);for(let r=0;r<o;r++){let l=t[r],m=n[r];if(l===void 0)return-1;if(m===void 0)return 1;let y=/^\\d+$/.test(l),E=/^\\d+$/.test(m);if(y&&E){let w=Number(l)-Number(m);if(w!==0)return w}else{if(y!==E)return y?-1:1;if(l!==m)return l<m?-1:1}}return 0}function v(t,n){let o=T(t),r=T(n);return!o||!r?t<n?-1:t>n?1:0:o.major!==r.major?o.major-r.major:o.minor!==r.minor?o.minor-r.minor:o.patch!==r.patch?o.patch-r.patch:Y(o.pre,r.pre)}var Z=/^[a-z]+[+:-]/i;function O(t,n){if(n===!1||n==null||n==="")return!0;let o=String(n).trim();return!o||o==="*"||o==="latest"||Z.test(o)?!0:o.split("||").some(r=>Q(t,r.trim()))}function Q(t,n){if(!n||n==="*")return!T(t)?.pre.length;let o=n.split(/\\s+-\\s+/);if(o.length===2){let m=o[0].trim(),y=o[1].trim();return!(!O(t,`>=${m}`)||!O(t,`<=${y}`))}let r=T(t);if(!r)return!1;let l=ee(n);if(l===null)return!0;for(let m of l)if(!ie(r,t,m))return!1;return!(r.pre.length>0&&!l.some(m=>m.ver.pre.length>0)&&!l.some(y=>y.ver.major===r.major&&y.ver.minor===r.minor&&y.ver.patch===r.patch))}function ee(t){let n=[],o=t.trim().split(/\\s+/).filter(Boolean);if(o.length===0)return null;for(let r of o){let l=/^(>=|<=|>|<|=|\\^|~)?(.*)$/.exec(r);if(!l)return null;let m=l[1],y=l[2],E=re(m,y);if(E===null)return null;n.push(...E)}return n}function re(t,n){let o=ne(n);if(!o)return null;let{ver:r,partial:l}=o;switch(t){case"^":{let m=te(r);return m?[{op:">=",ver:r},{op:"<",ver:m}]:null}case"~":{let m=l>=2?{major:r.major,minor:r.minor+1,patch:0,pre:[]}:{major:r.major+1,minor:0,patch:0,pre:[]};return[{op:">=",ver:r},{op:"<",ver:m}]}case">=":return[{op:">=",ver:r}];case">":return l===1?[{op:">=",ver:{major:r.major+1,minor:0,patch:0,pre:[]}}]:l===2?[{op:">=",ver:{major:r.major,minor:r.minor+1,patch:0,pre:[]}}]:[{op:">",ver:r}];case"<":return l===1?[{op:"<",ver:{major:r.major,minor:0,patch:0,pre:[]}}]:l===2?[{op:"<",ver:{major:r.major,minor:r.minor,patch:0,pre:[]}}]:[{op:"<",ver:r}];case"<=":return[{op:"<=",ver:r}];case"=":case void 0:return l===1?[{op:">=",ver:r},{op:"<",ver:{major:r.major+1,minor:0,patch:0,pre:[]}}]:l===2?[{op:">=",ver:r},{op:"<",ver:{major:r.major,minor:r.minor+1,patch:0,pre:[]}}]:[{op:"=",ver:r}];default:return null}}function te(t){return t.major>0?{major:t.major+1,minor:0,patch:0,pre:[]}:t.minor>0?{major:0,minor:t.minor+1,patch:0,pre:[]}:{major:0,minor:0,patch:t.patch+1,pre:[]}}function ne(t){let n=t.replace(/^v/,"").trim();if(!n||n==="*"||n==="x"||n==="X")return{ver:{major:0,minor:0,patch:0,pre:[]},partial:0};let o=n.split("."),r=[],l=0;for(let E of o.slice(0,3))if(/^\\d+$/.test(E))r.push(Number(E)),l++;else{if(E==="x"||E==="X"||E==="*")break;break}let m=n.split("-"),y=m.length>1?m.slice(1).join("-").split("+")[0].split("."):[];return l===0&&y.length===0?{ver:{major:0,minor:0,patch:0,pre:[]},partial:0}:{ver:{major:r[0]??0,minor:r[1]??0,patch:r[2]??0,pre:y},partial:l}}function oe(t,n){switch(n){case">=":return t>=0;case">":return t>0;case"<":return t<0;case"<=":return t<=0;case"=":return t===0}}function ie(t,n,o){let r=`${t.major}.${t.minor}.${t.patch}`+(t.pre.length?`-${t.pre.join(".")}`:"");if(o.upper)return!(!(v(r,`${o.ver.major}.${o.ver.minor}.${o.ver.patch}`+(o.ver.pre.length?`-${o.ver.pre.join(".")}`:""))>=0)||!(v(r,`${o.upper.major}.${o.upper.minor}.${o.upper.patch}`)<0));let l=v(r,`${o.ver.major}.${o.ver.minor}.${o.ver.patch}`+(o.ver.pre.length?`-${o.ver.pre.join(".")}`:"")),m=oe(l,o.op);return o.ver.pre.length>0&&t.pre.length===0&&(o.op===">"||o.op==="<")?!1:m}var g=class extends Error{code;details;constructor(n,o,r){super(`[fulgurjs:${n}] ${o}`),this.name="FgError",this.code=n,this.details=r}},S={REMOTE_LOAD_FAILED:"MFU-001",REMOTE_NAME_MISMATCH:"MFU-002",SHARE_STRICT_VERSION:"MFU-003",SHARE_NOT_AVAILABLE:"MFU-004",CONTAINER_REINIT_CONFLICT:"MFU-005",MODULE_NOT_EXPOSED:"MFU-006",PRELOAD_FAILED:"MFU-007",REMOTE_UNKNOWN:"MFU-008",EMPTY_EXPORTS:"MFU-009",SINGLETON_SKEW:"MFU-010"};var U="2.0.2";var A=15e3,P=2,ae=5,se=3e4;function ce(){let t={},n=new Map,o=[],r=new Map,l=new WeakMap,m={},y=()=>{for(let e of o)try{e.init?.(m)}catch(i){console.warn("[fulgurjs] runtimePlugin init failed:",e.name,i)}},E=e=>t[e]??={};function w(e){try{m.onRemoteError?.(e)}catch{}typeof window<"u"&&window.dispatchEvent(new CustomEvent("fulgurjs:error",{detail:e}))}function F(e="default"){return E(e),t}function V(e,i,a,c,R={}){let s=E(e||"default"),u=s[i]??={};u[a]||(u[a]={version:a,get:c,from:R.from??"unknown",eager:!!R.eager,loaded:!!R.loaded})}function I(e){for(let i of e){let a=n.get(i.name);n.set(i.name,{timeout:A,retries:P,...a,...i,state:a?.state??"idle",breakerState:a?.breakerState??{fails:0,openUntil:0},debug:a?.debug??{entry:i.entry,status:"idle"}})}}function D(e){I([e])}function H(e){o.push(...e),y()}async function K(e,i={}){let a=i.shareScope||"default",c=i.shareKey||e,s=E(a)[c]||{},u=Object.keys(s),d=i.requiredVersion,f=u.filter(p=>d===void 0||d===!1||O(p,d)),_;if(i.singleton&&u.length>0){let p=u.filter(h=>s[h].loaded);if(_=[...p.length?p:u].sort(v).pop(),u.length>1||!f.includes(_)){let h=s[_],j=`singleton skew "${c}": req "${d??"any"}" use ${_} from ${h.from}`;if(i.strictVersion){let M=new g(S.SHARE_STRICT_VERSION,j,{shareKey:c,requiredVersion:d});throw w({remote:h.from,error:M}),M}console.warn(`[fulgurjs:MFU-010] ${j}`)}}else if(_=[...f].sort(v).pop(),!_){if(i.strictVersion){let h=new g(S.SHARE_STRICT_VERSION,`no satisfying version for "${c}" (required "${d}") in share scope "${a}"`);throw w({remote:c,error:h}),h}if(i.fallback)return i.fallback();let p=new g(S.SHARE_NOT_AVAILABLE,`shared "${c}" (${d??"any"}) unavailable in scope "${a}" (no local fallback)`,{shareKey:c,requiredVersion:d});throw w({remote:c,error:p}),p}let $=s[_];if(m.resolveShare){let p=await m.resolveShare({shareKey:c,shareScope:a,requiredVersion:d,picked:$,available:Object.values(s)});p&&($=p)}return $.loaded=!0,$.get()}function q(e,i,a){return new Promise((c,R)=>{let s=setTimeout(()=>R(new Error(`timeout after ${i}ms: ${a}`)),i);e.then(u=>{clearTimeout(s),c(u)},u=>{clearTimeout(s),R(u)})})}let z=e=>new Promise(i=>setTimeout(i,e));function k(e,i){if(!e||typeof e.get!="function")throw new Error(`remoteEntry of "${i.name}" does not export a container interface (get/init)`);if(e.name&&i.name&&e.name!==i.name){let a=`remoteEntry self-reported name "${e.name}" mismatches configured name "${i.name}"`;if(i.promise)console.warn(`[fulgurjs] ${a} (promise-based remote, continuing)`);else throw Object.assign(new Error(a),{code:S.REMOTE_NAME_MISMATCH})}}async function L(e,i){return q(import(e),i.timeout??A,`load remoteEntry ${e}`)}async function x(e,i){let a=e.shareScope||"default";if(e.container){let s=l.get(e.container);if(s&&s!==a)throw new g(S.CONTAINER_REINIT_CONFLICT,`container "${e.name}" already initialized with share scope "${s}", cannot re-init with "${a}"`);return e.container}if(e.containerPromise)return e.containerPromise;let c=e.breakerState;if(c.openUntil>Date.now()){let s=new g(S.REMOTE_LOAD_FAILED,`circuit breaker open for remote "${e.name}" until ${new Date(c.openUntil).toISOString()}`,{remote:e.name});throw w({remote:e.name,error:s}),s}e.state="loading",e.debug.status="loading";let R=(async()=>{let s=[];if(e.promise)s.push(async()=>{let p=await e.promise(),h=typeof p=="string"?await L(p,e):p;return k(h,e),h});else for(let p of[e.entry,...e.fallback??[]])s.push(async()=>{let h=await L(p,e);return k(h,e),h});let u,d,f=!1,_=i?.retries??e.retries??P;for(let p of s){for(let h=0;h<=_;h++){let j=performance.now();try{u=await p(),e.lastLoadMs=Math.round(performance.now()-j),e.debug.lastLoadMs=e.lastLoadMs,f=!0;break}catch(M){if(d=M,M?.code)throw M;h<_&&await z(200*2**h)}}if(f)break}if(!f||!u){let p=[];throw/^https?:\\/\\//.test(e.entry)&&typeof location<"u"?(p.push(`1. is the remote dev server running? try opening ${e.entry} in the browser \\u2014 it must return JS, not HTML/an error`),p.push("2. is the URL correct in federation({ remotes })? dev and prod entries can differ"),p.push("3. CORS: the remote dev server must allow cross-origin requests (fulgurjs-federation enables server.cors automatically; a custom server config may have disabled it)")):(p.push(`1. is the remote deployed and reachable? try opening ${e.entry} in the browser \\u2014 it must return JS`),p.push("2. NGINX/CDN routing: the entry path must serve the remoteEntry JS file (check try_files / fallback rules)")),new g(S.REMOTE_LOAD_FAILED,`failed to load remote "${e.name}" from ${e.entry}: ${String(d?.message??d)}\n`+p.join(`\n`),{remote:e.name})}k(u,e);let $=l.get(u);if($&&$!==a)throw new g(S.CONTAINER_REINIT_CONFLICT,`container "${e.name}" already initialized with share scope "${$}", cannot re-init with "${a}"`);return typeof u.init=="function"&&await u.init(t),l.set(u,a),e.container=u,e.state="loaded",e.debug.status="loaded",c.fails=0,u})();e.containerPromise=R;try{return await R}catch(s){if(e.containerPromise=void 0,e.state="failed",e.debug.status="failed",e.debug.error=String(s?.message??s),c.fails+=1,c.fails>=ae&&(c.openUntil=Date.now()+se,c.fails=0),s instanceof g)throw w({remote:e.name,error:s}),s;if(s?.code)throw w({remote:e.name,error:s}),s;let u=new g(S.REMOTE_LOAD_FAILED,String(s?.message??s),{remote:e.name});throw w({remote:e.name,error:u}),u}}function N(e){let i=e.indexOf("/");return i===-1?{remote:e,module:""}:{remote:e.slice(0,i),module:G(e.slice(i+1))}}function G(e){return e?e.startsWith(".")?e:`./${e}`:""}async function J(e,i){let{remote:a,module:c}=N(e);m.beforeLoadRemote?.({remote:a,module:c});let R=n.get(a);if(!R)throw new g(S.REMOTE_UNKNOWN,`unknown remote "${a}". Register it via federation({ remotes }) or registerRemote().`,{remote:a});let s;try{s=await x(R,{retries:i?.retries})}catch(f){if(i?.fallbackModule)return console.error(`[fulgurjs] loadRemote("${e}") failed; returning fallbackModule (\\u663E\\u5F0F\\u964D\\u7EA7\\uFF0C\\u9519\\u8BEF\\u5DF2\\u900F\\u51FA)`,f),w({remote:a,error:f}),await i.fallbackModule();throw f}if(!c)return s;let u=`${a}@${R.shareScope||"default"}#${c}`;r.has(u)||r.set(u,s.get(c).catch(f=>{throw r.delete(u),f instanceof g||f?.code?f:new g(S.REMOTE_LOAD_FAILED,`failed to load module "${c}" from remote "${a}": ${String(f?.message??f)}`,{remote:a,module:c})}));let d;try{d=await r.get(u)}catch(f){if(i?.fallbackModule)return console.error(`[fulgurjs] loadRemote("${e}") failed; returning fallbackModule (\\u663E\\u5F0F\\u964D\\u7EA7\\uFF0C\\u9519\\u8BEF\\u5DF2\\u900F\\u51FA)`,f),w({remote:a,error:f}),await i.fallbackModule();throw f}if(m.afterLoadRemote?.({remote:a,module:c,module_ns:d}),d&&typeof d=="object"&&Object.keys(d).length===0){let f=new g(S.EMPTY_EXPORTS,`no exports: ${c} @ ${a}`,{remote:a,module:c});w({remote:a,error:f}),console.error(`[fulgurjs:MFU-009] ${f.message}`)}return d}function W(e){let i=n.get(e);if(!i)throw new g(S.REMOTE_UNKNOWN,`unknown remote "${e}"`,{remote:e});return x(i)}async function B(e,i={}){let{remote:a}=N(e),c=n.get(a);if(!c)throw new g(S.REMOTE_UNKNOWN,`unknown remote "${a}"`,{remote:a});let R=i.mode??"preload",s=(u,d)=>{if(typeof document>"u"||document.querySelector(`link[href="${u}"]`))return;let f=document.createElement("link");f.rel=d==="style"?"stylesheet":"modulepreload",f.href=u,R==="prefetch"&&(f.fetchPriority="low"),document.head.appendChild(f)};try{if(c.manifestUrl){let u=await fetch(c.manifestUrl,{cache:"no-cache"});if(u.ok){let d=await u.json();s(c.entry,"modulepreload");let f=d.exposes??{};for(let _ of Object.keys(f)){let $=f[_];$?.file&&s(new URL($.file,c.entry).href,"modulepreload");for(let p of $?.css??[])s(new URL(p,c.entry).href,"style")}return}}s(c.entry,"modulepreload")}catch(u){w({remote:a,error:new g(S.PRELOAD_FAILED,String(u?.message??u),{remote:a})})}}return typeof window>"u"||(window.__FULGURJS_SCOPE__=t,window.__FULGURJS_INFO__={get remotes(){let e={};for(let[i,a]of n)e[i]={...a.debug,entry:a.entry};return e},errors:[]}),{shareScopeMap:t,initSharing:F,registerShare:V,registerRemotes:I,registerRemote:D,registerPlugins:H,loadShare:K,loadRemote:J,getContainer:W,preloadRemote:B,parseSpec:N}}var C=globalThis,b=C.__FULGURJS_RUNTIME__??ce();C.__FULGURJS_RUNTIME__=b;try{Object.freeze(b)}catch{}var he=U;function ye(){return b}var Ee=b.initSharing,Re=b.registerShare,Se=b.registerRemotes,we=b.registerRemote,be=b.registerPlugins,_e=b.loadShare,$e=b.loadRemote,Me=b.getContainer,ve=b.preloadRemote,je=b.shareScopeMap;function Te(t){if(t&&typeof t=="object"&&"default"in t){let n=t.default;return n!==void 0?n:t}return t}var Oe=b;export{Oe as default,Me as getContainer,ye as getRuntime,Ee as initSharing,$e as loadRemote,_e as loadShare,ve as preloadRemote,be as registerPlugins,we as registerRemote,Se as registerRemotes,Re as registerShare,b as runtime,je as shareScopeMap,Te as unwrapDefault,he as version};\n';
1302
1326
 
1303
1327
  // src/index.ts
1304
1328
  function readRuntimeCode() {
@@ -1339,6 +1363,29 @@ function injectInitScript(html, scriptSrc) {
1339
1363
  }
1340
1364
  return tag + html;
1341
1365
  }
1366
+ var RUNTIME_CHUNK_NAME = "fulgurjs-runtime";
1367
+ var REMOTE_FACADE_CHUNK_NAME = "fulgurjs-remote-facades";
1368
+ function facadeChunkOf(id) {
1369
+ const bare = id.split("?")[0];
1370
+ if (bare === "virtual:fulgurjs-runtime" || bare === "virtual:fulgurjs-runtime-proxy") {
1371
+ return RUNTIME_CHUNK_NAME;
1372
+ }
1373
+ if (bare.startsWith("virtual:fulgurjs-shared:")) {
1374
+ const body = bare.slice("virtual:fulgurjs-shared:".length);
1375
+ if (body.startsWith("__remote__/")) {
1376
+ const remoteName = body.slice("__remote__/".length).split("/")[0] || "unknown";
1377
+ return REMOTE_FACADE_CHUNK_NAME + "-" + remoteName.replace(/[^A-Za-z0-9_-]/g, "_");
1378
+ }
1379
+ const shareKey = body.split("?")[0];
1380
+ return "fulgurjs-shared-" + (shareKey.replace(/[^A-Za-z0-9_-]/g, "_") || "unknown");
1381
+ }
1382
+ if (bare.startsWith("virtual:fulgurjs-shared-ns:") || bare.startsWith("virtual:fulgurjs-cjs-ns:")) {
1383
+ const prefix = bare.startsWith("virtual:fulgurjs-shared-ns:") ? "virtual:fulgurjs-shared-ns:" : "virtual:fulgurjs-cjs-ns:";
1384
+ const shareKey = bare.slice(prefix.length);
1385
+ return "fulgurjs-shared-" + (shareKey.replace(/[^A-Za-z0-9_-]/g, "_") || "unknown");
1386
+ }
1387
+ return null;
1388
+ }
1342
1389
  function federation(options) {
1343
1390
  const warnedUnknownPrefixes = /* @__PURE__ */ new Set();
1344
1391
  let remoteSchemaPromise = null;
@@ -1349,7 +1396,10 @@ function federation(options) {
1349
1396
  exposeFiles: {},
1350
1397
  resolvedSharedPaths: /* @__PURE__ */ new Map(),
1351
1398
  entryAbsPaths: /* @__PURE__ */ new Set(),
1352
- entryInitInjected: /* @__PURE__ */ new Set()
1399
+ entryInitInjected: /* @__PURE__ */ new Set(),
1400
+ manualChunkGroups: /* @__PURE__ */ new Map(),
1401
+ sharedClosureRoots: [],
1402
+ facadeDynamic: false
1353
1403
  };
1354
1404
  const pre = {
1355
1405
  name: "fulgurjs:core",
@@ -1417,6 +1467,43 @@ export { default } from ${JSON.stringify(url)};
1417
1467
  ;
1418
1468
  extra.build = { target: "es2022" };
1419
1469
  }
1470
+ if (normalized.remotes.length > 0 && normalized.devSharedSelf) {
1471
+ state.facadeDynamic = true;
1472
+ const userOutput = userConfig.build?.rollupOptions?.output;
1473
+ if (Array.isArray(userOutput)) {
1474
+ console.warn(
1475
+ formatFulgurjsDiagnostic({
1476
+ code: "BLD-006",
1477
+ symptom: "build.rollupOptions.output is an array; fulgurjs cannot inject the shared-facade chunk guard automatically",
1478
+ cause: "devSharedSelf \u95E8\u9762\u5316 + manualChunks \u5F3A\u5236\u5206\u7EC4\u53EF\u80FD\u5F62\u6210 chunk \u5FAA\u73AF\u4F9D\u8D56\uFF08\u8FD0\u884C\u65F6 TypeError\uFF1A\u534F\u5546\u51FD\u6570\u672A\u521D\u59CB\u5316\uFF09",
1479
+ fix: `\u5728\u6BCF\u4E2A output \u9879\u7684 manualChunks \u6700\u524D\u9762\u52A0\u5206\u652F\uFF1Aif (id.startsWith('virtual:fulgurjs-')) return 'fulgurjs-shared-facades'`
1480
+ })
1481
+ );
1482
+ } else {
1483
+ const userManualChunks = userOutput?.manualChunks;
1484
+ if (typeof userManualChunks === "function") {
1485
+ const userFn = userManualChunks;
1486
+ const wrapped = (id, meta) => {
1487
+ const facade = facadeChunkOf(id);
1488
+ if (facade) return facade;
1489
+ return userFn(id, meta);
1490
+ };
1491
+ const extraBuild = extra.build ??= {};
1492
+ extraBuild.rollupOptions = { ...extraBuild.rollupOptions ?? {}, output: { manualChunks: wrapped } };
1493
+ } else if (userManualChunks && typeof userManualChunks === "object") {
1494
+ state.manualChunkSpecsPending = Object.entries(userManualChunks).flatMap(
1495
+ ([group, specs]) => specs.map((s) => [group, s])
1496
+ );
1497
+ const wrapped = (id) => {
1498
+ const facade = facadeChunkOf(id);
1499
+ if (facade) return facade;
1500
+ return state.manualChunkGroups.get(id.split("?")[0]) ?? state.manualChunkGroups.get(id);
1501
+ };
1502
+ const extraBuild = extra.build ??= {};
1503
+ extraBuild.rollupOptions = { ...extraBuild.rollupOptions ?? {}, output: { manualChunks: wrapped } };
1504
+ }
1505
+ }
1506
+ }
1420
1507
  }
1421
1508
  for (const w of normalized.warnings) console.warn(`[fulgurjs] ${w}`);
1422
1509
  return extra;
@@ -1521,7 +1608,7 @@ export { default } from ${JSON.stringify(url)};
1521
1608
  if (!names.includes(compat)) names.push(compat);
1522
1609
  }
1523
1610
  }
1524
- return genSharedNsFacade(item, serializeShareCallForFacade(item), names);
1611
+ return genSharedNsFacade(item, serializeShareCallForFacade(item), names, state.facadeDynamic);
1525
1612
  }
1526
1613
  if (clean.startsWith("virtual:fulgurjs-shared:") && state.normalized) {
1527
1614
  const body = clean.slice("virtual:fulgurjs-shared:".length);
@@ -1530,14 +1617,14 @@ export { default } from ${JSON.stringify(url)};
1530
1617
  const item2 = state.normalized.shared.find((x) => x.shareKey === body);
1531
1618
  if (item2 && item2.import !== false) {
1532
1619
  const names = /^(\.|\/)/.test(item2.import) ? [] : enumerateCjsExports(item2.import, state.normalized.root);
1533
- return genSharedFacade(item2.import, names);
1620
+ return genSharedFacade(item2.import, names, state.facadeDynamic);
1534
1621
  }
1535
1622
  return null;
1536
1623
  }
1537
1624
  const entry = getFacadeEntry(raw.slice(f + 3));
1538
1625
  if (!entry) return null;
1539
1626
  if (entry.remoteName && entry.exposeName) {
1540
- return genRemoteBindingFacade(entry.remoteName + "/" + entry.exposeName, entry.bindings);
1627
+ return genRemoteBindingFacade(entry.remoteName + "/" + entry.exposeName, entry.bindings, state.facadeDynamic);
1541
1628
  }
1542
1629
  const item = state.normalized.shared.find((x) => x.shareKey === entry.shareKey);
1543
1630
  if (!item || item.import === false) return null;
@@ -1550,7 +1637,7 @@ export { default } from ${JSON.stringify(url)};
1550
1637
  "fallback: () => import(" + JSON.stringify(item.import) + ")"
1551
1638
  ];
1552
1639
  const call = "__fulgurjs_loadShare(" + JSON.stringify(item.shareKey) + ", { " + opts.join(", ") + " })";
1553
- return genBindingFacade(item, entry.bindings, call);
1640
+ return genBindingFacade(item, entry.bindings, call, state.facadeDynamic);
1554
1641
  }
1555
1642
  return null;
1556
1643
  },
@@ -1571,7 +1658,8 @@ ${code}`, map: null };
1571
1658
  options: state.normalized,
1572
1659
  rewriteShared: true,
1573
1660
  allowNodeModules,
1574
- cjsRequireRewrite: true
1661
+ cjsRequireRewrite: true,
1662
+ sharedClosureRoots: state.sharedClosureRoots
1575
1663
  });
1576
1664
  }
1577
1665
  return null;
@@ -1583,7 +1671,8 @@ ${code}`, map: null };
1583
1671
  // 双角色宿主可显式 devSharedSelf: true 参与协商
1584
1672
  rewriteShared: state.command === "build" || state.normalized.devSharedSelf,
1585
1673
  allowNodeModules,
1586
- cjsRequireRewrite: state.command === "build"
1674
+ cjsRequireRewrite: state.command === "build",
1675
+ sharedClosureRoots: state.sharedClosureRoots
1587
1676
  });
1588
1677
  },
1589
1678
  transformIndexHtml: {
@@ -1608,6 +1697,68 @@ ${code}`, map: null };
1608
1697
  async buildStart() {
1609
1698
  if (state.command !== "build" || !state.normalized) return;
1610
1699
  const n = state.normalized;
1700
+ if (state.manualChunkSpecsPending) {
1701
+ for (const [group, specifier] of state.manualChunkSpecsPending) {
1702
+ try {
1703
+ const r = await this.resolve(specifier, import_node_path5.default.join(n.root, "index.html"));
1704
+ if (r?.id) {
1705
+ state.manualChunkGroups.set(r.id, group);
1706
+ state.manualChunkGroups.set(r.id.split("?")[0], group);
1707
+ } else {
1708
+ console.warn(
1709
+ `[fulgurjs] manualChunks: could not resolve "${specifier}" for group "${group}"; those modules will fall back to automatic chunking. (Their shared-negotiation facades are still guarded.)`
1710
+ );
1711
+ }
1712
+ } catch {
1713
+ console.warn(
1714
+ `[fulgurjs] manualChunks: resolving "${specifier}" (group "${group}") failed; those modules will fall back to automatic chunking.`
1715
+ );
1716
+ }
1717
+ }
1718
+ state.manualChunkSpecsPending = void 0;
1719
+ }
1720
+ if (n.remotes.length > 0 && n.devSharedSelf && state.sharedClosureRoots.length === 0) {
1721
+ const rootKeys = /* @__PURE__ */ new Map();
1722
+ const pkgRootOf = (file) => {
1723
+ const NM = "/node_modules/";
1724
+ const i = file.lastIndexOf(NM);
1725
+ if (i === -1) return null;
1726
+ const rest = file.slice(i + NM.length);
1727
+ const segs = rest.split("/");
1728
+ const pkgDir = segs[0].startsWith("@") ? segs.slice(0, 2).join("/") : segs[0];
1729
+ return file.slice(0, i + NM.length) + pkgDir + "/";
1730
+ };
1731
+ for (const item of n.shared) {
1732
+ if (item.import === false) continue;
1733
+ const selfFile = await this.resolve(item.import, import_node_path5.default.join(n.root, "index.html")).then(
1734
+ (r) => r?.id?.split("?")[0] ?? null
1735
+ ).catch(() => null);
1736
+ for (const alias of item.aliases) {
1737
+ if (alias.endsWith("/")) continue;
1738
+ let file = null;
1739
+ if (selfFile) {
1740
+ try {
1741
+ const req = (0, import_node_module2.createRequire)(selfFile);
1742
+ file = req.resolve(`${alias}/package.json`, { paths: [selfFile] }).replace(/\/package\.json$/, "");
1743
+ } catch {
1744
+ file = null;
1745
+ }
1746
+ }
1747
+ if (!file) {
1748
+ file = await this.resolve(alias, import_node_path5.default.join(n.root, "index.html")).then(
1749
+ (r) => r?.id?.split("?")[0] ?? null
1750
+ ).catch(() => null);
1751
+ }
1752
+ if (!file) continue;
1753
+ const root = pkgRootOf(file);
1754
+ if (!root) continue;
1755
+ let keys = rootKeys.get(root);
1756
+ if (!keys) rootKeys.set(root, keys = /* @__PURE__ */ new Set());
1757
+ keys.add(item.shareKey);
1758
+ }
1759
+ }
1760
+ state.sharedClosureRoots = [...rootKeys.entries()].map(([root, keys]) => ({ root, keys }));
1761
+ }
1611
1762
  if (n.exposes.length > 0) {
1612
1763
  for (const e of n.exposes) {
1613
1764
  const resolved = await this.resolve(e.import, import_node_path5.default.join(n.root, "index.html"));
@@ -1738,12 +1889,25 @@ ${code}`, map: null };
1738
1889
  return { code: code.split("virtual:fulgurjs-runtime").join("virtual:fulgurjs-runtime-proxy"), map: null };
1739
1890
  }
1740
1891
  if (isPluginProcessedModule(code)) return null;
1741
- if (state.command === "build" && !/\.vue(\?|$)/.test(id)) return null;
1742
1892
  if (/type=(style|template)/.test(id)) return null;
1743
1893
  const isJsLike = /\.(m|c)?[jt]sx?$/.test(clean) || clean.endsWith(".vue");
1744
1894
  if (!isJsLike) return null;
1745
1895
  const devRewriteAll = state.command === "serve" && state.normalized.devSharedSelf;
1746
- if (clean.includes("node_modules") && !id.includes(".vite/deps") && !devRewriteAll) return null;
1896
+ const isPureRemoteBuild = state.normalized.exposes.length > 0 && state.normalized.remotes.length === 0;
1897
+ if (state.command === "serve" && clean.includes("node_modules") && !id.includes(".vite/deps") && !devRewriteAll) {
1898
+ return null;
1899
+ }
1900
+ if (state.command === "build" && !/\.vue(\?|$)/.test(id)) {
1901
+ const quickCheck = /require\s*\(\s*["']|(?:from|import)\s*["']/.test(code);
1902
+ if (!quickCheck) return null;
1903
+ const allowNodeModules = isPureRemoteBuild;
1904
+ return transformModule(code, id, {
1905
+ options: state.normalized,
1906
+ rewriteShared: true,
1907
+ allowNodeModules,
1908
+ sharedClosureRoots: state.sharedClosureRoots
1909
+ });
1910
+ }
1747
1911
  const rewriteShared = state.command === "build" || state.normalized.devSharedSelf;
1748
1912
  const remapSpecifier = (spec) => {
1749
1913
  if (state.normalized.shared.some((s) => s.aliases.includes(spec))) return spec;
@@ -1757,7 +1921,13 @@ ${code}`, map: null };
1757
1921
  if (!cleanPath.startsWith("/")) return null;
1758
1922
  return state.resolvedSharedPaths.get(cleanPath) ?? null;
1759
1923
  };
1760
- return transformModule(code, id, { options: state.normalized, remapSpecifier, rewriteShared });
1924
+ return transformModule(code, id, {
1925
+ options: state.normalized,
1926
+ remapSpecifier,
1927
+ rewriteShared,
1928
+ allowNodeModules: state.command === "build" ? isPureRemoteBuild || state.normalized.devSharedSelf : void 0,
1929
+ sharedClosureRoots: state.sharedClosureRoots
1930
+ });
1761
1931
  }
1762
1932
  };
1763
1933
  function warmResolvedSharedPaths(server) {
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  RUNTIME_VERSION
3
- } from "./chunk-I5FNKR7E.js";
3
+ } from "./chunk-UDLQALHC.js";
4
4
 
5
5
  // src/index.ts
6
6
  import path5 from "path";
@@ -366,28 +366,45 @@ import path2 from "path";
366
366
  function jsonReplacer(_k, v) {
367
367
  return v;
368
368
  }
369
- function genSharedFacade(specifier, exportNames) {
369
+ function genSharedFacade(specifier, exportNames, dynamic = false) {
370
370
  const names = (exportNames ?? []).filter(
371
371
  (n) => n !== "default" && /^[A-Za-z_$][A-Za-z0-9_$]*$/.test(n)
372
372
  );
373
- if (names.length === 0) {
373
+ if (!dynamic) {
374
+ if (names.length === 0) {
375
+ return [
376
+ `import * as __fulgurjs_facade from ${JSON.stringify(specifier)};`,
377
+ `export * from ${JSON.stringify(specifier)};`,
378
+ `export default __fulgurjs_facade.default ?? __fulgurjs_facade;`,
379
+ ""
380
+ ].join("\n");
381
+ }
374
382
  return [
375
383
  `import * as __fulgurjs_facade from ${JSON.stringify(specifier)};`,
384
+ ...names.map((n) => `export const ${n} = __fulgurjs_facade[${JSON.stringify(n)}];`),
385
+ `export default __fulgurjs_facade.default ?? __fulgurjs_facade;`,
386
+ ""
387
+ ].join("\n");
388
+ }
389
+ if (names.length === 0) {
390
+ return [
391
+ `const __fulgurjs_facade = await import(${JSON.stringify(specifier)});`,
376
392
  `export * from ${JSON.stringify(specifier)};`,
377
393
  `export default __fulgurjs_facade.default ?? __fulgurjs_facade;`,
378
394
  ""
379
395
  ].join("\n");
380
396
  }
381
397
  return [
382
- `import * as __fulgurjs_facade from ${JSON.stringify(specifier)};`,
383
- ...names.map((n) => `export const ${n} = __fulgurjs_facade[${JSON.stringify(n)}];`),
384
- `export default __fulgurjs_facade.default ?? __fulgurjs_facade;`,
398
+ `const __fulgurjs_facade = await import(${JSON.stringify(specifier)});`,
399
+ `const __fulgurjs_ns = { ...__fulgurjs_facade };`,
400
+ ...names.map((n) => `export const ${n} = __fulgurjs_ns[${JSON.stringify(n)}];`),
401
+ `export default __fulgurjs_ns.default ?? __fulgurjs_ns;`,
385
402
  ""
386
403
  ].join("\n");
387
404
  }
388
- function genSharedNsFacade(item, loadShareCall, exportNames) {
405
+ function genSharedNsFacade(item, loadShareCall, exportNames, dynamic = false) {
389
406
  const lines = [
390
- `import { loadShare as __fulgurjs_loadShare, unwrapDefault as __fulgurjsU } from "virtual:fulgurjs-runtime";`,
407
+ dynamic ? `const { loadShare: __fulgurjs_loadShare, unwrapDefault: __fulgurjsU } = await import("virtual:fulgurjs-runtime");` : `import { loadShare as __fulgurjs_loadShare, unwrapDefault as __fulgurjsU } from "virtual:fulgurjs-runtime";`,
391
408
  `const __fulgurjs_m = await ${loadShareCall};`,
392
409
  `const __fulgurjs_d = __fulgurjsU(__fulgurjs_m);`,
393
410
  `export default __fulgurjs_d;`
@@ -401,9 +418,9 @@ function genSharedNsFacade(item, loadShareCall, exportNames) {
401
418
  lines.push("");
402
419
  return lines.join("\n");
403
420
  }
404
- function genBindingFacade(item, bindings, loadShareCall) {
421
+ function genBindingFacade(item, bindings, loadShareCall, dynamic = false) {
405
422
  const lines = [
406
- `import { loadShare as __fulgurjs_loadShare, unwrapDefault as __fulgurjsU } from "virtual:fulgurjs-runtime";`,
423
+ dynamic ? `const { loadShare: __fulgurjs_loadShare, unwrapDefault: __fulgurjsU } = await import("virtual:fulgurjs-runtime");` : `import { loadShare as __fulgurjs_loadShare, unwrapDefault as __fulgurjsU } from "virtual:fulgurjs-runtime";`,
407
424
  `const __fulgurjs_m = await ${loadShareCall};`
408
425
  ];
409
426
  const seen = /* @__PURE__ */ new Set();
@@ -419,9 +436,9 @@ function genBindingFacade(item, bindings, loadShareCall) {
419
436
  lines.push("");
420
437
  return lines.join("\n");
421
438
  }
422
- function genRemoteBindingFacade(remoteSpec, bindings) {
439
+ function genRemoteBindingFacade(remoteSpec, bindings, dynamic = false) {
423
440
  const lines = [
424
- `import { loadRemote as __fulgurjs_loadRemote, unwrapDefault as __fulgurjsU } from "virtual:fulgurjs-runtime";`,
441
+ dynamic ? `const { loadRemote: __fulgurjs_loadRemote, unwrapDefault: __fulgurjsU } = await import("virtual:fulgurjs-runtime");` : `import { loadRemote as __fulgurjs_loadRemote, unwrapDefault: __fulgurjsU } from "virtual:fulgurjs-runtime";`.replace("unwrapDefault: __fulgurjsU", "unwrapDefault as __fulgurjsU"),
425
442
  `const __fulgurjs_m = await __fulgurjs_loadRemote(${JSON.stringify(remoteSpec)});`
426
443
  ];
427
444
  const seen = /* @__PURE__ */ new Set();
@@ -778,6 +795,10 @@ function parseImportClause(clause) {
778
795
  return { ns: nsMatch?.[1] ?? null, bindings, defaultLocal };
779
796
  }
780
797
  var JS_EXT_RE = /\.(m|c)?[jt]sx?$/;
798
+ function inSharedClosure(moduleId, roots) {
799
+ if (!roots || roots.length === 0) return false;
800
+ return roots.some((r) => moduleId.startsWith(r.root));
801
+ }
781
802
  function isTransformableId(id, allowNodeModules = false) {
782
803
  const clean = id.split("?")[0];
783
804
  if (!JS_EXT_RE.test(clean) && !clean.endsWith(".vue")) return false;
@@ -828,6 +849,7 @@ function remoteFacadeSpecFor(ctx, remoteName, exposeName, bindings) {
828
849
  }
829
850
  async function transformModule(code, id, ctx) {
830
851
  const { options } = ctx;
852
+ const clean = id.split("?")[0];
831
853
  if (options.shared.length === 0 && options.remotes.length === 0) return null;
832
854
  const candidates = [];
833
855
  for (const s2 of options.shared) candidates.push(s2.configKey.replace(/\/$/, ""));
@@ -914,7 +936,8 @@ export { ${nsAs[1]} };`);
914
936
  while (code[stmtEnd] === ";") stmtEnd++;
915
937
  const head = code.slice(stmtStart, stmtStart + 24);
916
938
  if (/^\s*(import|export)\s+type[\s{]/.test(head)) continue;
917
- const shared2 = matcher ? matchShared(spec2, matcher) : null;
939
+ const matched2 = matcher ? matchShared(spec2, matcher) : null;
940
+ const shared2 = matched2 && inSharedClosure(clean, ctx.sharedClosureRoots) ? null : matched2;
918
941
  const firstSeg2 = spec2.split("/")[0];
919
942
  const remote2 = remotesByKey.get(firstSeg2);
920
943
  const exposeName2 = remote2 ? remoteExposeName(spec2, remote2.key) : null;
@@ -947,7 +970,8 @@ export { ${nsAs[1]} };`);
947
970
  const literal = specExpr.match(/^['"](.*)['"]$/s);
948
971
  if (!literal) continue;
949
972
  const spec = remap(literal[1]);
950
- const shared = matcher ? matchShared(spec, matcher) : null;
973
+ const matched = matcher ? matchShared(spec, matcher) : null;
974
+ const shared = matched && inSharedClosure(clean, ctx.sharedClosureRoots) ? null : matched;
951
975
  const firstSeg = spec.split("/")[0];
952
976
  const remote = remotesByKey.get(firstSeg);
953
977
  const exposeName = remote ? remoteExposeName(spec, remote.key) : null;
@@ -1262,7 +1286,7 @@ function syncViteCacheMarker(root, pluginVersion, log) {
1262
1286
  }
1263
1287
 
1264
1288
  // src/runtime-code.gen.ts
1265
- var runtime_code_gen_default = 'var X=/^v?(\\d+)(?:\\.(\\d+))?(?:\\.(\\d+))?(?:-((?:[0-9A-Za-z-]+)(?:\\.[0-9A-Za-z-]+)*))?(?:\\+[0-9A-Za-z.-]+)?$/;function T(t){let n=X.exec(String(t).trim());return n?{major:Number(n[1]),minor:Number(n[2]??0),patch:Number(n[3]??0),pre:n[4]?n[4].split("."):[]}:null}function Y(t,n){if(t.length===0&&n.length===0)return 0;if(t.length===0)return 1;if(n.length===0)return-1;let o=Math.max(t.length,n.length);for(let r=0;r<o;r++){let l=t[r],m=n[r];if(l===void 0)return-1;if(m===void 0)return 1;let y=/^\\d+$/.test(l),E=/^\\d+$/.test(m);if(y&&E){let w=Number(l)-Number(m);if(w!==0)return w}else{if(y!==E)return y?-1:1;if(l!==m)return l<m?-1:1}}return 0}function v(t,n){let o=T(t),r=T(n);return!o||!r?t<n?-1:t>n?1:0:o.major!==r.major?o.major-r.major:o.minor!==r.minor?o.minor-r.minor:o.patch!==r.patch?o.patch-r.patch:Y(o.pre,r.pre)}var Z=/^[a-z]+[+:-]/i;function O(t,n){if(n===!1||n==null||n==="")return!0;let o=String(n).trim();return!o||o==="*"||o==="latest"||Z.test(o)?!0:o.split("||").some(r=>Q(t,r.trim()))}function Q(t,n){if(!n||n==="*")return!T(t)?.pre.length;let o=n.split(/\\s+-\\s+/);if(o.length===2){let m=o[0].trim(),y=o[1].trim();return!(!O(t,`>=${m}`)||!O(t,`<=${y}`))}let r=T(t);if(!r)return!1;let l=ee(n);if(l===null)return!0;for(let m of l)if(!ie(r,t,m))return!1;return!(r.pre.length>0&&!l.some(m=>m.ver.pre.length>0)&&!l.some(y=>y.ver.major===r.major&&y.ver.minor===r.minor&&y.ver.patch===r.patch))}function ee(t){let n=[],o=t.trim().split(/\\s+/).filter(Boolean);if(o.length===0)return null;for(let r of o){let l=/^(>=|<=|>|<|=|\\^|~)?(.*)$/.exec(r);if(!l)return null;let m=l[1],y=l[2],E=re(m,y);if(E===null)return null;n.push(...E)}return n}function re(t,n){let o=ne(n);if(!o)return null;let{ver:r,partial:l}=o;switch(t){case"^":{let m=te(r);return m?[{op:">=",ver:r},{op:"<",ver:m}]:null}case"~":{let m=l>=2?{major:r.major,minor:r.minor+1,patch:0,pre:[]}:{major:r.major+1,minor:0,patch:0,pre:[]};return[{op:">=",ver:r},{op:"<",ver:m}]}case">=":return[{op:">=",ver:r}];case">":return l===1?[{op:">=",ver:{major:r.major+1,minor:0,patch:0,pre:[]}}]:l===2?[{op:">=",ver:{major:r.major,minor:r.minor+1,patch:0,pre:[]}}]:[{op:">",ver:r}];case"<":return l===1?[{op:"<",ver:{major:r.major,minor:0,patch:0,pre:[]}}]:l===2?[{op:"<",ver:{major:r.major,minor:r.minor,patch:0,pre:[]}}]:[{op:"<",ver:r}];case"<=":return[{op:"<=",ver:r}];case"=":case void 0:return l===1?[{op:">=",ver:r},{op:"<",ver:{major:r.major+1,minor:0,patch:0,pre:[]}}]:l===2?[{op:">=",ver:r},{op:"<",ver:{major:r.major,minor:r.minor+1,patch:0,pre:[]}}]:[{op:"=",ver:r}];default:return null}}function te(t){return t.major>0?{major:t.major+1,minor:0,patch:0,pre:[]}:t.minor>0?{major:0,minor:t.minor+1,patch:0,pre:[]}:{major:0,minor:0,patch:t.patch+1,pre:[]}}function ne(t){let n=t.replace(/^v/,"").trim();if(!n||n==="*"||n==="x"||n==="X")return{ver:{major:0,minor:0,patch:0,pre:[]},partial:0};let o=n.split("."),r=[],l=0;for(let E of o.slice(0,3))if(/^\\d+$/.test(E))r.push(Number(E)),l++;else{if(E==="x"||E==="X"||E==="*")break;break}let m=n.split("-"),y=m.length>1?m.slice(1).join("-").split("+")[0].split("."):[];return l===0&&y.length===0?{ver:{major:0,minor:0,patch:0,pre:[]},partial:0}:{ver:{major:r[0]??0,minor:r[1]??0,patch:r[2]??0,pre:y},partial:l}}function oe(t,n){switch(n){case">=":return t>=0;case">":return t>0;case"<":return t<0;case"<=":return t<=0;case"=":return t===0}}function ie(t,n,o){let r=`${t.major}.${t.minor}.${t.patch}`+(t.pre.length?`-${t.pre.join(".")}`:"");if(o.upper)return!(!(v(r,`${o.ver.major}.${o.ver.minor}.${o.ver.patch}`+(o.ver.pre.length?`-${o.ver.pre.join(".")}`:""))>=0)||!(v(r,`${o.upper.major}.${o.upper.minor}.${o.upper.patch}`)<0));let l=v(r,`${o.ver.major}.${o.ver.minor}.${o.ver.patch}`+(o.ver.pre.length?`-${o.ver.pre.join(".")}`:"")),m=oe(l,o.op);return o.ver.pre.length>0&&t.pre.length===0&&(o.op===">"||o.op==="<")?!1:m}var g=class extends Error{code;details;constructor(n,o,r){super(`[fulgurjs:${n}] ${o}`),this.name="FgError",this.code=n,this.details=r}},S={REMOTE_LOAD_FAILED:"MFU-001",REMOTE_NAME_MISMATCH:"MFU-002",SHARE_STRICT_VERSION:"MFU-003",SHARE_NOT_AVAILABLE:"MFU-004",CONTAINER_REINIT_CONFLICT:"MFU-005",MODULE_NOT_EXPOSED:"MFU-006",PRELOAD_FAILED:"MFU-007",REMOTE_UNKNOWN:"MFU-008",EMPTY_EXPORTS:"MFU-009",SINGLETON_SKEW:"MFU-010"};var U="2.0.1";var A=15e3,P=2,ae=5,se=3e4;function ce(){let t={},n=new Map,o=[],r=new Map,l=new WeakMap,m={},y=()=>{for(let e of o)try{e.init?.(m)}catch(i){console.warn("[fulgurjs] runtimePlugin init failed:",e.name,i)}},E=e=>t[e]??={};function w(e){try{m.onRemoteError?.(e)}catch{}typeof window<"u"&&window.dispatchEvent(new CustomEvent("fulgurjs:error",{detail:e}))}function F(e="default"){return E(e),t}function V(e,i,a,c,R={}){let s=E(e||"default"),u=s[i]??={};u[a]||(u[a]={version:a,get:c,from:R.from??"unknown",eager:!!R.eager,loaded:!!R.loaded})}function I(e){for(let i of e){let a=n.get(i.name);n.set(i.name,{timeout:A,retries:P,...a,...i,state:a?.state??"idle",breakerState:a?.breakerState??{fails:0,openUntil:0},debug:a?.debug??{entry:i.entry,status:"idle"}})}}function D(e){I([e])}function H(e){o.push(...e),y()}async function K(e,i={}){let a=i.shareScope||"default",c=i.shareKey||e,s=E(a)[c]||{},u=Object.keys(s),d=i.requiredVersion,f=u.filter(p=>d===void 0||d===!1||O(p,d)),_;if(i.singleton&&u.length>0){let p=u.filter(h=>s[h].loaded);if(_=[...p.length?p:u].sort(v).pop(),u.length>1||!f.includes(_)){let h=s[_],j=`singleton skew "${c}": req "${d??"any"}" use ${_} from ${h.from}`;if(i.strictVersion){let M=new g(S.SHARE_STRICT_VERSION,j,{shareKey:c,requiredVersion:d});throw w({remote:h.from,error:M}),M}console.warn(`[fulgurjs:MFU-010] ${j}`)}}else if(_=[...f].sort(v).pop(),!_){if(i.strictVersion){let h=new g(S.SHARE_STRICT_VERSION,`no satisfying version for "${c}" (required "${d}") in share scope "${a}"`);throw w({remote:c,error:h}),h}if(i.fallback)return i.fallback();let p=new g(S.SHARE_NOT_AVAILABLE,`shared "${c}" (${d??"any"}) unavailable in scope "${a}" (no local fallback)`,{shareKey:c,requiredVersion:d});throw w({remote:c,error:p}),p}let $=s[_];if(m.resolveShare){let p=await m.resolveShare({shareKey:c,shareScope:a,requiredVersion:d,picked:$,available:Object.values(s)});p&&($=p)}return $.loaded=!0,$.get()}function q(e,i,a){return new Promise((c,R)=>{let s=setTimeout(()=>R(new Error(`timeout after ${i}ms: ${a}`)),i);e.then(u=>{clearTimeout(s),c(u)},u=>{clearTimeout(s),R(u)})})}let z=e=>new Promise(i=>setTimeout(i,e));function k(e,i){if(!e||typeof e.get!="function")throw new Error(`remoteEntry of "${i.name}" does not export a container interface (get/init)`);if(e.name&&i.name&&e.name!==i.name){let a=`remoteEntry self-reported name "${e.name}" mismatches configured name "${i.name}"`;if(i.promise)console.warn(`[fulgurjs] ${a} (promise-based remote, continuing)`);else throw Object.assign(new Error(a),{code:S.REMOTE_NAME_MISMATCH})}}async function L(e,i){return q(import(e),i.timeout??A,`load remoteEntry ${e}`)}async function x(e,i){let a=e.shareScope||"default";if(e.container){let s=l.get(e.container);if(s&&s!==a)throw new g(S.CONTAINER_REINIT_CONFLICT,`container "${e.name}" already initialized with share scope "${s}", cannot re-init with "${a}"`);return e.container}if(e.containerPromise)return e.containerPromise;let c=e.breakerState;if(c.openUntil>Date.now()){let s=new g(S.REMOTE_LOAD_FAILED,`circuit breaker open for remote "${e.name}" until ${new Date(c.openUntil).toISOString()}`,{remote:e.name});throw w({remote:e.name,error:s}),s}e.state="loading",e.debug.status="loading";let R=(async()=>{let s=[];if(e.promise)s.push(async()=>{let p=await e.promise(),h=typeof p=="string"?await L(p,e):p;return k(h,e),h});else for(let p of[e.entry,...e.fallback??[]])s.push(async()=>{let h=await L(p,e);return k(h,e),h});let u,d,f=!1,_=i?.retries??e.retries??P;for(let p of s){for(let h=0;h<=_;h++){let j=performance.now();try{u=await p(),e.lastLoadMs=Math.round(performance.now()-j),e.debug.lastLoadMs=e.lastLoadMs,f=!0;break}catch(M){if(d=M,M?.code)throw M;h<_&&await z(200*2**h)}}if(f)break}if(!f||!u){let p=[];throw/^https?:\\/\\//.test(e.entry)&&typeof location<"u"?(p.push(`1. is the remote dev server running? try opening ${e.entry} in the browser \\u2014 it must return JS, not HTML/an error`),p.push("2. is the URL correct in federation({ remotes })? dev and prod entries can differ"),p.push("3. CORS: the remote dev server must allow cross-origin requests (fulgurjs-federation enables server.cors automatically; a custom server config may have disabled it)")):(p.push(`1. is the remote deployed and reachable? try opening ${e.entry} in the browser \\u2014 it must return JS`),p.push("2. NGINX/CDN routing: the entry path must serve the remoteEntry JS file (check try_files / fallback rules)")),new g(S.REMOTE_LOAD_FAILED,`failed to load remote "${e.name}" from ${e.entry}: ${String(d?.message??d)}\n`+p.join(`\n`),{remote:e.name})}k(u,e);let $=l.get(u);if($&&$!==a)throw new g(S.CONTAINER_REINIT_CONFLICT,`container "${e.name}" already initialized with share scope "${$}", cannot re-init with "${a}"`);return typeof u.init=="function"&&await u.init(t),l.set(u,a),e.container=u,e.state="loaded",e.debug.status="loaded",c.fails=0,u})();e.containerPromise=R;try{return await R}catch(s){if(e.containerPromise=void 0,e.state="failed",e.debug.status="failed",e.debug.error=String(s?.message??s),c.fails+=1,c.fails>=ae&&(c.openUntil=Date.now()+se,c.fails=0),s instanceof g)throw w({remote:e.name,error:s}),s;if(s?.code)throw w({remote:e.name,error:s}),s;let u=new g(S.REMOTE_LOAD_FAILED,String(s?.message??s),{remote:e.name});throw w({remote:e.name,error:u}),u}}function N(e){let i=e.indexOf("/");return i===-1?{remote:e,module:""}:{remote:e.slice(0,i),module:G(e.slice(i+1))}}function G(e){return e?e.startsWith(".")?e:`./${e}`:""}async function J(e,i){let{remote:a,module:c}=N(e);m.beforeLoadRemote?.({remote:a,module:c});let R=n.get(a);if(!R)throw new g(S.REMOTE_UNKNOWN,`unknown remote "${a}". Register it via federation({ remotes }) or registerRemote().`,{remote:a});let s;try{s=await x(R,{retries:i?.retries})}catch(f){if(i?.fallbackModule)return console.error(`[fulgurjs] loadRemote("${e}") failed; returning fallbackModule (\\u663E\\u5F0F\\u964D\\u7EA7\\uFF0C\\u9519\\u8BEF\\u5DF2\\u900F\\u51FA)`,f),w({remote:a,error:f}),await i.fallbackModule();throw f}if(!c)return s;let u=`${a}@${R.shareScope||"default"}#${c}`;r.has(u)||r.set(u,s.get(c).catch(f=>{throw r.delete(u),f instanceof g||f?.code?f:new g(S.REMOTE_LOAD_FAILED,`failed to load module "${c}" from remote "${a}": ${String(f?.message??f)}`,{remote:a,module:c})}));let d;try{d=await r.get(u)}catch(f){if(i?.fallbackModule)return console.error(`[fulgurjs] loadRemote("${e}") failed; returning fallbackModule (\\u663E\\u5F0F\\u964D\\u7EA7\\uFF0C\\u9519\\u8BEF\\u5DF2\\u900F\\u51FA)`,f),w({remote:a,error:f}),await i.fallbackModule();throw f}if(m.afterLoadRemote?.({remote:a,module:c,module_ns:d}),d&&typeof d=="object"&&Object.keys(d).length===0){let f=new g(S.EMPTY_EXPORTS,`no exports: ${c} @ ${a}`,{remote:a,module:c});w({remote:a,error:f}),console.error(`[fulgurjs:MFU-009] ${f.message}`)}return d}function W(e){let i=n.get(e);if(!i)throw new g(S.REMOTE_UNKNOWN,`unknown remote "${e}"`,{remote:e});return x(i)}async function B(e,i={}){let{remote:a}=N(e),c=n.get(a);if(!c)throw new g(S.REMOTE_UNKNOWN,`unknown remote "${a}"`,{remote:a});let R=i.mode??"preload",s=(u,d)=>{if(typeof document>"u"||document.querySelector(`link[href="${u}"]`))return;let f=document.createElement("link");f.rel=d==="style"?"stylesheet":"modulepreload",f.href=u,R==="prefetch"&&(f.fetchPriority="low"),document.head.appendChild(f)};try{if(c.manifestUrl){let u=await fetch(c.manifestUrl,{cache:"no-cache"});if(u.ok){let d=await u.json();s(c.entry,"modulepreload");let f=d.exposes??{};for(let _ of Object.keys(f)){let $=f[_];$?.file&&s(new URL($.file,c.entry).href,"modulepreload");for(let p of $?.css??[])s(new URL(p,c.entry).href,"style")}return}}s(c.entry,"modulepreload")}catch(u){w({remote:a,error:new g(S.PRELOAD_FAILED,String(u?.message??u),{remote:a})})}}return typeof window>"u"||(window.__FULGURJS_SCOPE__=t,window.__FULGURJS_INFO__={get remotes(){let e={};for(let[i,a]of n)e[i]={...a.debug,entry:a.entry};return e},errors:[]}),{shareScopeMap:t,initSharing:F,registerShare:V,registerRemotes:I,registerRemote:D,registerPlugins:H,loadShare:K,loadRemote:J,getContainer:W,preloadRemote:B,parseSpec:N}}var C=globalThis,b=C.__FULGURJS_RUNTIME__??ce();C.__FULGURJS_RUNTIME__=b;try{Object.freeze(b)}catch{}var he=U;function ye(){return b}var Ee=b.initSharing,Re=b.registerShare,Se=b.registerRemotes,we=b.registerRemote,be=b.registerPlugins,_e=b.loadShare,$e=b.loadRemote,Me=b.getContainer,ve=b.preloadRemote,je=b.shareScopeMap;function Te(t){if(t&&typeof t=="object"&&"default"in t){let n=t.default;return n!==void 0?n:t}return t}var Oe=b;export{Oe as default,Me as getContainer,ye as getRuntime,Ee as initSharing,$e as loadRemote,_e as loadShare,ve as preloadRemote,be as registerPlugins,we as registerRemote,Se as registerRemotes,Re as registerShare,b as runtime,je as shareScopeMap,Te as unwrapDefault,he as version};\n';
1289
+ var runtime_code_gen_default = 'var X=/^v?(\\d+)(?:\\.(\\d+))?(?:\\.(\\d+))?(?:-((?:[0-9A-Za-z-]+)(?:\\.[0-9A-Za-z-]+)*))?(?:\\+[0-9A-Za-z.-]+)?$/;function T(t){let n=X.exec(String(t).trim());return n?{major:Number(n[1]),minor:Number(n[2]??0),patch:Number(n[3]??0),pre:n[4]?n[4].split("."):[]}:null}function Y(t,n){if(t.length===0&&n.length===0)return 0;if(t.length===0)return 1;if(n.length===0)return-1;let o=Math.max(t.length,n.length);for(let r=0;r<o;r++){let l=t[r],m=n[r];if(l===void 0)return-1;if(m===void 0)return 1;let y=/^\\d+$/.test(l),E=/^\\d+$/.test(m);if(y&&E){let w=Number(l)-Number(m);if(w!==0)return w}else{if(y!==E)return y?-1:1;if(l!==m)return l<m?-1:1}}return 0}function v(t,n){let o=T(t),r=T(n);return!o||!r?t<n?-1:t>n?1:0:o.major!==r.major?o.major-r.major:o.minor!==r.minor?o.minor-r.minor:o.patch!==r.patch?o.patch-r.patch:Y(o.pre,r.pre)}var Z=/^[a-z]+[+:-]/i;function O(t,n){if(n===!1||n==null||n==="")return!0;let o=String(n).trim();return!o||o==="*"||o==="latest"||Z.test(o)?!0:o.split("||").some(r=>Q(t,r.trim()))}function Q(t,n){if(!n||n==="*")return!T(t)?.pre.length;let o=n.split(/\\s+-\\s+/);if(o.length===2){let m=o[0].trim(),y=o[1].trim();return!(!O(t,`>=${m}`)||!O(t,`<=${y}`))}let r=T(t);if(!r)return!1;let l=ee(n);if(l===null)return!0;for(let m of l)if(!ie(r,t,m))return!1;return!(r.pre.length>0&&!l.some(m=>m.ver.pre.length>0)&&!l.some(y=>y.ver.major===r.major&&y.ver.minor===r.minor&&y.ver.patch===r.patch))}function ee(t){let n=[],o=t.trim().split(/\\s+/).filter(Boolean);if(o.length===0)return null;for(let r of o){let l=/^(>=|<=|>|<|=|\\^|~)?(.*)$/.exec(r);if(!l)return null;let m=l[1],y=l[2],E=re(m,y);if(E===null)return null;n.push(...E)}return n}function re(t,n){let o=ne(n);if(!o)return null;let{ver:r,partial:l}=o;switch(t){case"^":{let m=te(r);return m?[{op:">=",ver:r},{op:"<",ver:m}]:null}case"~":{let m=l>=2?{major:r.major,minor:r.minor+1,patch:0,pre:[]}:{major:r.major+1,minor:0,patch:0,pre:[]};return[{op:">=",ver:r},{op:"<",ver:m}]}case">=":return[{op:">=",ver:r}];case">":return l===1?[{op:">=",ver:{major:r.major+1,minor:0,patch:0,pre:[]}}]:l===2?[{op:">=",ver:{major:r.major,minor:r.minor+1,patch:0,pre:[]}}]:[{op:">",ver:r}];case"<":return l===1?[{op:"<",ver:{major:r.major,minor:0,patch:0,pre:[]}}]:l===2?[{op:"<",ver:{major:r.major,minor:r.minor,patch:0,pre:[]}}]:[{op:"<",ver:r}];case"<=":return[{op:"<=",ver:r}];case"=":case void 0:return l===1?[{op:">=",ver:r},{op:"<",ver:{major:r.major+1,minor:0,patch:0,pre:[]}}]:l===2?[{op:">=",ver:r},{op:"<",ver:{major:r.major,minor:r.minor+1,patch:0,pre:[]}}]:[{op:"=",ver:r}];default:return null}}function te(t){return t.major>0?{major:t.major+1,minor:0,patch:0,pre:[]}:t.minor>0?{major:0,minor:t.minor+1,patch:0,pre:[]}:{major:0,minor:0,patch:t.patch+1,pre:[]}}function ne(t){let n=t.replace(/^v/,"").trim();if(!n||n==="*"||n==="x"||n==="X")return{ver:{major:0,minor:0,patch:0,pre:[]},partial:0};let o=n.split("."),r=[],l=0;for(let E of o.slice(0,3))if(/^\\d+$/.test(E))r.push(Number(E)),l++;else{if(E==="x"||E==="X"||E==="*")break;break}let m=n.split("-"),y=m.length>1?m.slice(1).join("-").split("+")[0].split("."):[];return l===0&&y.length===0?{ver:{major:0,minor:0,patch:0,pre:[]},partial:0}:{ver:{major:r[0]??0,minor:r[1]??0,patch:r[2]??0,pre:y},partial:l}}function oe(t,n){switch(n){case">=":return t>=0;case">":return t>0;case"<":return t<0;case"<=":return t<=0;case"=":return t===0}}function ie(t,n,o){let r=`${t.major}.${t.minor}.${t.patch}`+(t.pre.length?`-${t.pre.join(".")}`:"");if(o.upper)return!(!(v(r,`${o.ver.major}.${o.ver.minor}.${o.ver.patch}`+(o.ver.pre.length?`-${o.ver.pre.join(".")}`:""))>=0)||!(v(r,`${o.upper.major}.${o.upper.minor}.${o.upper.patch}`)<0));let l=v(r,`${o.ver.major}.${o.ver.minor}.${o.ver.patch}`+(o.ver.pre.length?`-${o.ver.pre.join(".")}`:"")),m=oe(l,o.op);return o.ver.pre.length>0&&t.pre.length===0&&(o.op===">"||o.op==="<")?!1:m}var g=class extends Error{code;details;constructor(n,o,r){super(`[fulgurjs:${n}] ${o}`),this.name="FgError",this.code=n,this.details=r}},S={REMOTE_LOAD_FAILED:"MFU-001",REMOTE_NAME_MISMATCH:"MFU-002",SHARE_STRICT_VERSION:"MFU-003",SHARE_NOT_AVAILABLE:"MFU-004",CONTAINER_REINIT_CONFLICT:"MFU-005",MODULE_NOT_EXPOSED:"MFU-006",PRELOAD_FAILED:"MFU-007",REMOTE_UNKNOWN:"MFU-008",EMPTY_EXPORTS:"MFU-009",SINGLETON_SKEW:"MFU-010"};var U="2.0.2";var A=15e3,P=2,ae=5,se=3e4;function ce(){let t={},n=new Map,o=[],r=new Map,l=new WeakMap,m={},y=()=>{for(let e of o)try{e.init?.(m)}catch(i){console.warn("[fulgurjs] runtimePlugin init failed:",e.name,i)}},E=e=>t[e]??={};function w(e){try{m.onRemoteError?.(e)}catch{}typeof window<"u"&&window.dispatchEvent(new CustomEvent("fulgurjs:error",{detail:e}))}function F(e="default"){return E(e),t}function V(e,i,a,c,R={}){let s=E(e||"default"),u=s[i]??={};u[a]||(u[a]={version:a,get:c,from:R.from??"unknown",eager:!!R.eager,loaded:!!R.loaded})}function I(e){for(let i of e){let a=n.get(i.name);n.set(i.name,{timeout:A,retries:P,...a,...i,state:a?.state??"idle",breakerState:a?.breakerState??{fails:0,openUntil:0},debug:a?.debug??{entry:i.entry,status:"idle"}})}}function D(e){I([e])}function H(e){o.push(...e),y()}async function K(e,i={}){let a=i.shareScope||"default",c=i.shareKey||e,s=E(a)[c]||{},u=Object.keys(s),d=i.requiredVersion,f=u.filter(p=>d===void 0||d===!1||O(p,d)),_;if(i.singleton&&u.length>0){let p=u.filter(h=>s[h].loaded);if(_=[...p.length?p:u].sort(v).pop(),u.length>1||!f.includes(_)){let h=s[_],j=`singleton skew "${c}": req "${d??"any"}" use ${_} from ${h.from}`;if(i.strictVersion){let M=new g(S.SHARE_STRICT_VERSION,j,{shareKey:c,requiredVersion:d});throw w({remote:h.from,error:M}),M}console.warn(`[fulgurjs:MFU-010] ${j}`)}}else if(_=[...f].sort(v).pop(),!_){if(i.strictVersion){let h=new g(S.SHARE_STRICT_VERSION,`no satisfying version for "${c}" (required "${d}") in share scope "${a}"`);throw w({remote:c,error:h}),h}if(i.fallback)return i.fallback();let p=new g(S.SHARE_NOT_AVAILABLE,`shared "${c}" (${d??"any"}) unavailable in scope "${a}" (no local fallback)`,{shareKey:c,requiredVersion:d});throw w({remote:c,error:p}),p}let $=s[_];if(m.resolveShare){let p=await m.resolveShare({shareKey:c,shareScope:a,requiredVersion:d,picked:$,available:Object.values(s)});p&&($=p)}return $.loaded=!0,$.get()}function q(e,i,a){return new Promise((c,R)=>{let s=setTimeout(()=>R(new Error(`timeout after ${i}ms: ${a}`)),i);e.then(u=>{clearTimeout(s),c(u)},u=>{clearTimeout(s),R(u)})})}let z=e=>new Promise(i=>setTimeout(i,e));function k(e,i){if(!e||typeof e.get!="function")throw new Error(`remoteEntry of "${i.name}" does not export a container interface (get/init)`);if(e.name&&i.name&&e.name!==i.name){let a=`remoteEntry self-reported name "${e.name}" mismatches configured name "${i.name}"`;if(i.promise)console.warn(`[fulgurjs] ${a} (promise-based remote, continuing)`);else throw Object.assign(new Error(a),{code:S.REMOTE_NAME_MISMATCH})}}async function L(e,i){return q(import(e),i.timeout??A,`load remoteEntry ${e}`)}async function x(e,i){let a=e.shareScope||"default";if(e.container){let s=l.get(e.container);if(s&&s!==a)throw new g(S.CONTAINER_REINIT_CONFLICT,`container "${e.name}" already initialized with share scope "${s}", cannot re-init with "${a}"`);return e.container}if(e.containerPromise)return e.containerPromise;let c=e.breakerState;if(c.openUntil>Date.now()){let s=new g(S.REMOTE_LOAD_FAILED,`circuit breaker open for remote "${e.name}" until ${new Date(c.openUntil).toISOString()}`,{remote:e.name});throw w({remote:e.name,error:s}),s}e.state="loading",e.debug.status="loading";let R=(async()=>{let s=[];if(e.promise)s.push(async()=>{let p=await e.promise(),h=typeof p=="string"?await L(p,e):p;return k(h,e),h});else for(let p of[e.entry,...e.fallback??[]])s.push(async()=>{let h=await L(p,e);return k(h,e),h});let u,d,f=!1,_=i?.retries??e.retries??P;for(let p of s){for(let h=0;h<=_;h++){let j=performance.now();try{u=await p(),e.lastLoadMs=Math.round(performance.now()-j),e.debug.lastLoadMs=e.lastLoadMs,f=!0;break}catch(M){if(d=M,M?.code)throw M;h<_&&await z(200*2**h)}}if(f)break}if(!f||!u){let p=[];throw/^https?:\\/\\//.test(e.entry)&&typeof location<"u"?(p.push(`1. is the remote dev server running? try opening ${e.entry} in the browser \\u2014 it must return JS, not HTML/an error`),p.push("2. is the URL correct in federation({ remotes })? dev and prod entries can differ"),p.push("3. CORS: the remote dev server must allow cross-origin requests (fulgurjs-federation enables server.cors automatically; a custom server config may have disabled it)")):(p.push(`1. is the remote deployed and reachable? try opening ${e.entry} in the browser \\u2014 it must return JS`),p.push("2. NGINX/CDN routing: the entry path must serve the remoteEntry JS file (check try_files / fallback rules)")),new g(S.REMOTE_LOAD_FAILED,`failed to load remote "${e.name}" from ${e.entry}: ${String(d?.message??d)}\n`+p.join(`\n`),{remote:e.name})}k(u,e);let $=l.get(u);if($&&$!==a)throw new g(S.CONTAINER_REINIT_CONFLICT,`container "${e.name}" already initialized with share scope "${$}", cannot re-init with "${a}"`);return typeof u.init=="function"&&await u.init(t),l.set(u,a),e.container=u,e.state="loaded",e.debug.status="loaded",c.fails=0,u})();e.containerPromise=R;try{return await R}catch(s){if(e.containerPromise=void 0,e.state="failed",e.debug.status="failed",e.debug.error=String(s?.message??s),c.fails+=1,c.fails>=ae&&(c.openUntil=Date.now()+se,c.fails=0),s instanceof g)throw w({remote:e.name,error:s}),s;if(s?.code)throw w({remote:e.name,error:s}),s;let u=new g(S.REMOTE_LOAD_FAILED,String(s?.message??s),{remote:e.name});throw w({remote:e.name,error:u}),u}}function N(e){let i=e.indexOf("/");return i===-1?{remote:e,module:""}:{remote:e.slice(0,i),module:G(e.slice(i+1))}}function G(e){return e?e.startsWith(".")?e:`./${e}`:""}async function J(e,i){let{remote:a,module:c}=N(e);m.beforeLoadRemote?.({remote:a,module:c});let R=n.get(a);if(!R)throw new g(S.REMOTE_UNKNOWN,`unknown remote "${a}". Register it via federation({ remotes }) or registerRemote().`,{remote:a});let s;try{s=await x(R,{retries:i?.retries})}catch(f){if(i?.fallbackModule)return console.error(`[fulgurjs] loadRemote("${e}") failed; returning fallbackModule (\\u663E\\u5F0F\\u964D\\u7EA7\\uFF0C\\u9519\\u8BEF\\u5DF2\\u900F\\u51FA)`,f),w({remote:a,error:f}),await i.fallbackModule();throw f}if(!c)return s;let u=`${a}@${R.shareScope||"default"}#${c}`;r.has(u)||r.set(u,s.get(c).catch(f=>{throw r.delete(u),f instanceof g||f?.code?f:new g(S.REMOTE_LOAD_FAILED,`failed to load module "${c}" from remote "${a}": ${String(f?.message??f)}`,{remote:a,module:c})}));let d;try{d=await r.get(u)}catch(f){if(i?.fallbackModule)return console.error(`[fulgurjs] loadRemote("${e}") failed; returning fallbackModule (\\u663E\\u5F0F\\u964D\\u7EA7\\uFF0C\\u9519\\u8BEF\\u5DF2\\u900F\\u51FA)`,f),w({remote:a,error:f}),await i.fallbackModule();throw f}if(m.afterLoadRemote?.({remote:a,module:c,module_ns:d}),d&&typeof d=="object"&&Object.keys(d).length===0){let f=new g(S.EMPTY_EXPORTS,`no exports: ${c} @ ${a}`,{remote:a,module:c});w({remote:a,error:f}),console.error(`[fulgurjs:MFU-009] ${f.message}`)}return d}function W(e){let i=n.get(e);if(!i)throw new g(S.REMOTE_UNKNOWN,`unknown remote "${e}"`,{remote:e});return x(i)}async function B(e,i={}){let{remote:a}=N(e),c=n.get(a);if(!c)throw new g(S.REMOTE_UNKNOWN,`unknown remote "${a}"`,{remote:a});let R=i.mode??"preload",s=(u,d)=>{if(typeof document>"u"||document.querySelector(`link[href="${u}"]`))return;let f=document.createElement("link");f.rel=d==="style"?"stylesheet":"modulepreload",f.href=u,R==="prefetch"&&(f.fetchPriority="low"),document.head.appendChild(f)};try{if(c.manifestUrl){let u=await fetch(c.manifestUrl,{cache:"no-cache"});if(u.ok){let d=await u.json();s(c.entry,"modulepreload");let f=d.exposes??{};for(let _ of Object.keys(f)){let $=f[_];$?.file&&s(new URL($.file,c.entry).href,"modulepreload");for(let p of $?.css??[])s(new URL(p,c.entry).href,"style")}return}}s(c.entry,"modulepreload")}catch(u){w({remote:a,error:new g(S.PRELOAD_FAILED,String(u?.message??u),{remote:a})})}}return typeof window>"u"||(window.__FULGURJS_SCOPE__=t,window.__FULGURJS_INFO__={get remotes(){let e={};for(let[i,a]of n)e[i]={...a.debug,entry:a.entry};return e},errors:[]}),{shareScopeMap:t,initSharing:F,registerShare:V,registerRemotes:I,registerRemote:D,registerPlugins:H,loadShare:K,loadRemote:J,getContainer:W,preloadRemote:B,parseSpec:N}}var C=globalThis,b=C.__FULGURJS_RUNTIME__??ce();C.__FULGURJS_RUNTIME__=b;try{Object.freeze(b)}catch{}var he=U;function ye(){return b}var Ee=b.initSharing,Re=b.registerShare,Se=b.registerRemotes,we=b.registerRemote,be=b.registerPlugins,_e=b.loadShare,$e=b.loadRemote,Me=b.getContainer,ve=b.preloadRemote,je=b.shareScopeMap;function Te(t){if(t&&typeof t=="object"&&"default"in t){let n=t.default;return n!==void 0?n:t}return t}var Oe=b;export{Oe as default,Me as getContainer,ye as getRuntime,Ee as initSharing,$e as loadRemote,_e as loadShare,ve as preloadRemote,be as registerPlugins,we as registerRemote,Se as registerRemotes,Re as registerShare,b as runtime,je as shareScopeMap,Te as unwrapDefault,he as version};\n';
1266
1290
 
1267
1291
  // src/index.ts
1268
1292
  function readRuntimeCode() {
@@ -1303,6 +1327,29 @@ function injectInitScript(html, scriptSrc) {
1303
1327
  }
1304
1328
  return tag + html;
1305
1329
  }
1330
+ var RUNTIME_CHUNK_NAME = "fulgurjs-runtime";
1331
+ var REMOTE_FACADE_CHUNK_NAME = "fulgurjs-remote-facades";
1332
+ function facadeChunkOf(id) {
1333
+ const bare = id.split("?")[0];
1334
+ if (bare === "virtual:fulgurjs-runtime" || bare === "virtual:fulgurjs-runtime-proxy") {
1335
+ return RUNTIME_CHUNK_NAME;
1336
+ }
1337
+ if (bare.startsWith("virtual:fulgurjs-shared:")) {
1338
+ const body = bare.slice("virtual:fulgurjs-shared:".length);
1339
+ if (body.startsWith("__remote__/")) {
1340
+ const remoteName = body.slice("__remote__/".length).split("/")[0] || "unknown";
1341
+ return REMOTE_FACADE_CHUNK_NAME + "-" + remoteName.replace(/[^A-Za-z0-9_-]/g, "_");
1342
+ }
1343
+ const shareKey = body.split("?")[0];
1344
+ return "fulgurjs-shared-" + (shareKey.replace(/[^A-Za-z0-9_-]/g, "_") || "unknown");
1345
+ }
1346
+ if (bare.startsWith("virtual:fulgurjs-shared-ns:") || bare.startsWith("virtual:fulgurjs-cjs-ns:")) {
1347
+ const prefix = bare.startsWith("virtual:fulgurjs-shared-ns:") ? "virtual:fulgurjs-shared-ns:" : "virtual:fulgurjs-cjs-ns:";
1348
+ const shareKey = bare.slice(prefix.length);
1349
+ return "fulgurjs-shared-" + (shareKey.replace(/[^A-Za-z0-9_-]/g, "_") || "unknown");
1350
+ }
1351
+ return null;
1352
+ }
1306
1353
  function federation(options) {
1307
1354
  const warnedUnknownPrefixes = /* @__PURE__ */ new Set();
1308
1355
  let remoteSchemaPromise = null;
@@ -1313,7 +1360,10 @@ function federation(options) {
1313
1360
  exposeFiles: {},
1314
1361
  resolvedSharedPaths: /* @__PURE__ */ new Map(),
1315
1362
  entryAbsPaths: /* @__PURE__ */ new Set(),
1316
- entryInitInjected: /* @__PURE__ */ new Set()
1363
+ entryInitInjected: /* @__PURE__ */ new Set(),
1364
+ manualChunkGroups: /* @__PURE__ */ new Map(),
1365
+ sharedClosureRoots: [],
1366
+ facadeDynamic: false
1317
1367
  };
1318
1368
  const pre = {
1319
1369
  name: "fulgurjs:core",
@@ -1381,6 +1431,43 @@ export { default } from ${JSON.stringify(url)};
1381
1431
  ;
1382
1432
  extra.build = { target: "es2022" };
1383
1433
  }
1434
+ if (normalized.remotes.length > 0 && normalized.devSharedSelf) {
1435
+ state.facadeDynamic = true;
1436
+ const userOutput = userConfig.build?.rollupOptions?.output;
1437
+ if (Array.isArray(userOutput)) {
1438
+ console.warn(
1439
+ formatFulgurjsDiagnostic({
1440
+ code: "BLD-006",
1441
+ symptom: "build.rollupOptions.output is an array; fulgurjs cannot inject the shared-facade chunk guard automatically",
1442
+ cause: "devSharedSelf \u95E8\u9762\u5316 + manualChunks \u5F3A\u5236\u5206\u7EC4\u53EF\u80FD\u5F62\u6210 chunk \u5FAA\u73AF\u4F9D\u8D56\uFF08\u8FD0\u884C\u65F6 TypeError\uFF1A\u534F\u5546\u51FD\u6570\u672A\u521D\u59CB\u5316\uFF09",
1443
+ fix: `\u5728\u6BCF\u4E2A output \u9879\u7684 manualChunks \u6700\u524D\u9762\u52A0\u5206\u652F\uFF1Aif (id.startsWith('virtual:fulgurjs-')) return 'fulgurjs-shared-facades'`
1444
+ })
1445
+ );
1446
+ } else {
1447
+ const userManualChunks = userOutput?.manualChunks;
1448
+ if (typeof userManualChunks === "function") {
1449
+ const userFn = userManualChunks;
1450
+ const wrapped = (id, meta) => {
1451
+ const facade = facadeChunkOf(id);
1452
+ if (facade) return facade;
1453
+ return userFn(id, meta);
1454
+ };
1455
+ const extraBuild = extra.build ??= {};
1456
+ extraBuild.rollupOptions = { ...extraBuild.rollupOptions ?? {}, output: { manualChunks: wrapped } };
1457
+ } else if (userManualChunks && typeof userManualChunks === "object") {
1458
+ state.manualChunkSpecsPending = Object.entries(userManualChunks).flatMap(
1459
+ ([group, specs]) => specs.map((s) => [group, s])
1460
+ );
1461
+ const wrapped = (id) => {
1462
+ const facade = facadeChunkOf(id);
1463
+ if (facade) return facade;
1464
+ return state.manualChunkGroups.get(id.split("?")[0]) ?? state.manualChunkGroups.get(id);
1465
+ };
1466
+ const extraBuild = extra.build ??= {};
1467
+ extraBuild.rollupOptions = { ...extraBuild.rollupOptions ?? {}, output: { manualChunks: wrapped } };
1468
+ }
1469
+ }
1470
+ }
1384
1471
  }
1385
1472
  for (const w of normalized.warnings) console.warn(`[fulgurjs] ${w}`);
1386
1473
  return extra;
@@ -1485,7 +1572,7 @@ export { default } from ${JSON.stringify(url)};
1485
1572
  if (!names.includes(compat)) names.push(compat);
1486
1573
  }
1487
1574
  }
1488
- return genSharedNsFacade(item, serializeShareCallForFacade(item), names);
1575
+ return genSharedNsFacade(item, serializeShareCallForFacade(item), names, state.facadeDynamic);
1489
1576
  }
1490
1577
  if (clean.startsWith("virtual:fulgurjs-shared:") && state.normalized) {
1491
1578
  const body = clean.slice("virtual:fulgurjs-shared:".length);
@@ -1494,14 +1581,14 @@ export { default } from ${JSON.stringify(url)};
1494
1581
  const item2 = state.normalized.shared.find((x) => x.shareKey === body);
1495
1582
  if (item2 && item2.import !== false) {
1496
1583
  const names = /^(\.|\/)/.test(item2.import) ? [] : enumerateCjsExports(item2.import, state.normalized.root);
1497
- return genSharedFacade(item2.import, names);
1584
+ return genSharedFacade(item2.import, names, state.facadeDynamic);
1498
1585
  }
1499
1586
  return null;
1500
1587
  }
1501
1588
  const entry = getFacadeEntry(raw.slice(f + 3));
1502
1589
  if (!entry) return null;
1503
1590
  if (entry.remoteName && entry.exposeName) {
1504
- return genRemoteBindingFacade(entry.remoteName + "/" + entry.exposeName, entry.bindings);
1591
+ return genRemoteBindingFacade(entry.remoteName + "/" + entry.exposeName, entry.bindings, state.facadeDynamic);
1505
1592
  }
1506
1593
  const item = state.normalized.shared.find((x) => x.shareKey === entry.shareKey);
1507
1594
  if (!item || item.import === false) return null;
@@ -1514,7 +1601,7 @@ export { default } from ${JSON.stringify(url)};
1514
1601
  "fallback: () => import(" + JSON.stringify(item.import) + ")"
1515
1602
  ];
1516
1603
  const call = "__fulgurjs_loadShare(" + JSON.stringify(item.shareKey) + ", { " + opts.join(", ") + " })";
1517
- return genBindingFacade(item, entry.bindings, call);
1604
+ return genBindingFacade(item, entry.bindings, call, state.facadeDynamic);
1518
1605
  }
1519
1606
  return null;
1520
1607
  },
@@ -1535,7 +1622,8 @@ ${code}`, map: null };
1535
1622
  options: state.normalized,
1536
1623
  rewriteShared: true,
1537
1624
  allowNodeModules,
1538
- cjsRequireRewrite: true
1625
+ cjsRequireRewrite: true,
1626
+ sharedClosureRoots: state.sharedClosureRoots
1539
1627
  });
1540
1628
  }
1541
1629
  return null;
@@ -1547,7 +1635,8 @@ ${code}`, map: null };
1547
1635
  // 双角色宿主可显式 devSharedSelf: true 参与协商
1548
1636
  rewriteShared: state.command === "build" || state.normalized.devSharedSelf,
1549
1637
  allowNodeModules,
1550
- cjsRequireRewrite: state.command === "build"
1638
+ cjsRequireRewrite: state.command === "build",
1639
+ sharedClosureRoots: state.sharedClosureRoots
1551
1640
  });
1552
1641
  },
1553
1642
  transformIndexHtml: {
@@ -1572,6 +1661,68 @@ ${code}`, map: null };
1572
1661
  async buildStart() {
1573
1662
  if (state.command !== "build" || !state.normalized) return;
1574
1663
  const n = state.normalized;
1664
+ if (state.manualChunkSpecsPending) {
1665
+ for (const [group, specifier] of state.manualChunkSpecsPending) {
1666
+ try {
1667
+ const r = await this.resolve(specifier, path5.join(n.root, "index.html"));
1668
+ if (r?.id) {
1669
+ state.manualChunkGroups.set(r.id, group);
1670
+ state.manualChunkGroups.set(r.id.split("?")[0], group);
1671
+ } else {
1672
+ console.warn(
1673
+ `[fulgurjs] manualChunks: could not resolve "${specifier}" for group "${group}"; those modules will fall back to automatic chunking. (Their shared-negotiation facades are still guarded.)`
1674
+ );
1675
+ }
1676
+ } catch {
1677
+ console.warn(
1678
+ `[fulgurjs] manualChunks: resolving "${specifier}" (group "${group}") failed; those modules will fall back to automatic chunking.`
1679
+ );
1680
+ }
1681
+ }
1682
+ state.manualChunkSpecsPending = void 0;
1683
+ }
1684
+ if (n.remotes.length > 0 && n.devSharedSelf && state.sharedClosureRoots.length === 0) {
1685
+ const rootKeys = /* @__PURE__ */ new Map();
1686
+ const pkgRootOf = (file) => {
1687
+ const NM = "/node_modules/";
1688
+ const i = file.lastIndexOf(NM);
1689
+ if (i === -1) return null;
1690
+ const rest = file.slice(i + NM.length);
1691
+ const segs = rest.split("/");
1692
+ const pkgDir = segs[0].startsWith("@") ? segs.slice(0, 2).join("/") : segs[0];
1693
+ return file.slice(0, i + NM.length) + pkgDir + "/";
1694
+ };
1695
+ for (const item of n.shared) {
1696
+ if (item.import === false) continue;
1697
+ const selfFile = await this.resolve(item.import, path5.join(n.root, "index.html")).then(
1698
+ (r) => r?.id?.split("?")[0] ?? null
1699
+ ).catch(() => null);
1700
+ for (const alias of item.aliases) {
1701
+ if (alias.endsWith("/")) continue;
1702
+ let file = null;
1703
+ if (selfFile) {
1704
+ try {
1705
+ const req = createRequire2(selfFile);
1706
+ file = req.resolve(`${alias}/package.json`, { paths: [selfFile] }).replace(/\/package\.json$/, "");
1707
+ } catch {
1708
+ file = null;
1709
+ }
1710
+ }
1711
+ if (!file) {
1712
+ file = await this.resolve(alias, path5.join(n.root, "index.html")).then(
1713
+ (r) => r?.id?.split("?")[0] ?? null
1714
+ ).catch(() => null);
1715
+ }
1716
+ if (!file) continue;
1717
+ const root = pkgRootOf(file);
1718
+ if (!root) continue;
1719
+ let keys = rootKeys.get(root);
1720
+ if (!keys) rootKeys.set(root, keys = /* @__PURE__ */ new Set());
1721
+ keys.add(item.shareKey);
1722
+ }
1723
+ }
1724
+ state.sharedClosureRoots = [...rootKeys.entries()].map(([root, keys]) => ({ root, keys }));
1725
+ }
1575
1726
  if (n.exposes.length > 0) {
1576
1727
  for (const e of n.exposes) {
1577
1728
  const resolved = await this.resolve(e.import, path5.join(n.root, "index.html"));
@@ -1702,12 +1853,25 @@ ${code}`, map: null };
1702
1853
  return { code: code.split("virtual:fulgurjs-runtime").join("virtual:fulgurjs-runtime-proxy"), map: null };
1703
1854
  }
1704
1855
  if (isPluginProcessedModule(code)) return null;
1705
- if (state.command === "build" && !/\.vue(\?|$)/.test(id)) return null;
1706
1856
  if (/type=(style|template)/.test(id)) return null;
1707
1857
  const isJsLike = /\.(m|c)?[jt]sx?$/.test(clean) || clean.endsWith(".vue");
1708
1858
  if (!isJsLike) return null;
1709
1859
  const devRewriteAll = state.command === "serve" && state.normalized.devSharedSelf;
1710
- if (clean.includes("node_modules") && !id.includes(".vite/deps") && !devRewriteAll) return null;
1860
+ const isPureRemoteBuild = state.normalized.exposes.length > 0 && state.normalized.remotes.length === 0;
1861
+ if (state.command === "serve" && clean.includes("node_modules") && !id.includes(".vite/deps") && !devRewriteAll) {
1862
+ return null;
1863
+ }
1864
+ if (state.command === "build" && !/\.vue(\?|$)/.test(id)) {
1865
+ const quickCheck = /require\s*\(\s*["']|(?:from|import)\s*["']/.test(code);
1866
+ if (!quickCheck) return null;
1867
+ const allowNodeModules = isPureRemoteBuild;
1868
+ return transformModule(code, id, {
1869
+ options: state.normalized,
1870
+ rewriteShared: true,
1871
+ allowNodeModules,
1872
+ sharedClosureRoots: state.sharedClosureRoots
1873
+ });
1874
+ }
1711
1875
  const rewriteShared = state.command === "build" || state.normalized.devSharedSelf;
1712
1876
  const remapSpecifier = (spec) => {
1713
1877
  if (state.normalized.shared.some((s) => s.aliases.includes(spec))) return spec;
@@ -1721,7 +1885,13 @@ ${code}`, map: null };
1721
1885
  if (!cleanPath.startsWith("/")) return null;
1722
1886
  return state.resolvedSharedPaths.get(cleanPath) ?? null;
1723
1887
  };
1724
- return transformModule(code, id, { options: state.normalized, remapSpecifier, rewriteShared });
1888
+ return transformModule(code, id, {
1889
+ options: state.normalized,
1890
+ remapSpecifier,
1891
+ rewriteShared,
1892
+ allowNodeModules: state.command === "build" ? isPureRemoteBuild || state.normalized.devSharedSelf : void 0,
1893
+ sharedClosureRoots: state.sharedClosureRoots
1894
+ });
1725
1895
  }
1726
1896
  };
1727
1897
  function warmResolvedSharedPaths(server) {
package/dist/runtime.js CHANGED
@@ -1,3 +1,3 @@
1
- var X=/^v?(\d+)(?:\.(\d+))?(?:\.(\d+))?(?:-((?:[0-9A-Za-z-]+)(?:\.[0-9A-Za-z-]+)*))?(?:\+[0-9A-Za-z.-]+)?$/;function T(t){let n=X.exec(String(t).trim());return n?{major:Number(n[1]),minor:Number(n[2]??0),patch:Number(n[3]??0),pre:n[4]?n[4].split("."):[]}:null}function Y(t,n){if(t.length===0&&n.length===0)return 0;if(t.length===0)return 1;if(n.length===0)return-1;let o=Math.max(t.length,n.length);for(let r=0;r<o;r++){let l=t[r],m=n[r];if(l===void 0)return-1;if(m===void 0)return 1;let y=/^\d+$/.test(l),E=/^\d+$/.test(m);if(y&&E){let w=Number(l)-Number(m);if(w!==0)return w}else{if(y!==E)return y?-1:1;if(l!==m)return l<m?-1:1}}return 0}function v(t,n){let o=T(t),r=T(n);return!o||!r?t<n?-1:t>n?1:0:o.major!==r.major?o.major-r.major:o.minor!==r.minor?o.minor-r.minor:o.patch!==r.patch?o.patch-r.patch:Y(o.pre,r.pre)}var Z=/^[a-z]+[+:-]/i;function O(t,n){if(n===!1||n==null||n==="")return!0;let o=String(n).trim();return!o||o==="*"||o==="latest"||Z.test(o)?!0:o.split("||").some(r=>Q(t,r.trim()))}function Q(t,n){if(!n||n==="*")return!T(t)?.pre.length;let o=n.split(/\s+-\s+/);if(o.length===2){let m=o[0].trim(),y=o[1].trim();return!(!O(t,`>=${m}`)||!O(t,`<=${y}`))}let r=T(t);if(!r)return!1;let l=ee(n);if(l===null)return!0;for(let m of l)if(!ie(r,t,m))return!1;return!(r.pre.length>0&&!l.some(m=>m.ver.pre.length>0)&&!l.some(y=>y.ver.major===r.major&&y.ver.minor===r.minor&&y.ver.patch===r.patch))}function ee(t){let n=[],o=t.trim().split(/\s+/).filter(Boolean);if(o.length===0)return null;for(let r of o){let l=/^(>=|<=|>|<|=|\^|~)?(.*)$/.exec(r);if(!l)return null;let m=l[1],y=l[2],E=re(m,y);if(E===null)return null;n.push(...E)}return n}function re(t,n){let o=ne(n);if(!o)return null;let{ver:r,partial:l}=o;switch(t){case"^":{let m=te(r);return m?[{op:">=",ver:r},{op:"<",ver:m}]:null}case"~":{let m=l>=2?{major:r.major,minor:r.minor+1,patch:0,pre:[]}:{major:r.major+1,minor:0,patch:0,pre:[]};return[{op:">=",ver:r},{op:"<",ver:m}]}case">=":return[{op:">=",ver:r}];case">":return l===1?[{op:">=",ver:{major:r.major+1,minor:0,patch:0,pre:[]}}]:l===2?[{op:">=",ver:{major:r.major,minor:r.minor+1,patch:0,pre:[]}}]:[{op:">",ver:r}];case"<":return l===1?[{op:"<",ver:{major:r.major,minor:0,patch:0,pre:[]}}]:l===2?[{op:"<",ver:{major:r.major,minor:r.minor,patch:0,pre:[]}}]:[{op:"<",ver:r}];case"<=":return[{op:"<=",ver:r}];case"=":case void 0:return l===1?[{op:">=",ver:r},{op:"<",ver:{major:r.major+1,minor:0,patch:0,pre:[]}}]:l===2?[{op:">=",ver:r},{op:"<",ver:{major:r.major,minor:r.minor+1,patch:0,pre:[]}}]:[{op:"=",ver:r}];default:return null}}function te(t){return t.major>0?{major:t.major+1,minor:0,patch:0,pre:[]}:t.minor>0?{major:0,minor:t.minor+1,patch:0,pre:[]}:{major:0,minor:0,patch:t.patch+1,pre:[]}}function ne(t){let n=t.replace(/^v/,"").trim();if(!n||n==="*"||n==="x"||n==="X")return{ver:{major:0,minor:0,patch:0,pre:[]},partial:0};let o=n.split("."),r=[],l=0;for(let E of o.slice(0,3))if(/^\d+$/.test(E))r.push(Number(E)),l++;else{if(E==="x"||E==="X"||E==="*")break;break}let m=n.split("-"),y=m.length>1?m.slice(1).join("-").split("+")[0].split("."):[];return l===0&&y.length===0?{ver:{major:0,minor:0,patch:0,pre:[]},partial:0}:{ver:{major:r[0]??0,minor:r[1]??0,patch:r[2]??0,pre:y},partial:l}}function oe(t,n){switch(n){case">=":return t>=0;case">":return t>0;case"<":return t<0;case"<=":return t<=0;case"=":return t===0}}function ie(t,n,o){let r=`${t.major}.${t.minor}.${t.patch}`+(t.pre.length?`-${t.pre.join(".")}`:"");if(o.upper)return!(!(v(r,`${o.ver.major}.${o.ver.minor}.${o.ver.patch}`+(o.ver.pre.length?`-${o.ver.pre.join(".")}`:""))>=0)||!(v(r,`${o.upper.major}.${o.upper.minor}.${o.upper.patch}`)<0));let l=v(r,`${o.ver.major}.${o.ver.minor}.${o.ver.patch}`+(o.ver.pre.length?`-${o.ver.pre.join(".")}`:"")),m=oe(l,o.op);return o.ver.pre.length>0&&t.pre.length===0&&(o.op===">"||o.op==="<")?!1:m}var g=class extends Error{code;details;constructor(n,o,r){super(`[fulgurjs:${n}] ${o}`),this.name="FgError",this.code=n,this.details=r}},S={REMOTE_LOAD_FAILED:"MFU-001",REMOTE_NAME_MISMATCH:"MFU-002",SHARE_STRICT_VERSION:"MFU-003",SHARE_NOT_AVAILABLE:"MFU-004",CONTAINER_REINIT_CONFLICT:"MFU-005",MODULE_NOT_EXPOSED:"MFU-006",PRELOAD_FAILED:"MFU-007",REMOTE_UNKNOWN:"MFU-008",EMPTY_EXPORTS:"MFU-009",SINGLETON_SKEW:"MFU-010"};var U="2.0.1";var A=15e3,P=2,ae=5,se=3e4;function ce(){let t={},n=new Map,o=[],r=new Map,l=new WeakMap,m={},y=()=>{for(let e of o)try{e.init?.(m)}catch(i){console.warn("[fulgurjs] runtimePlugin init failed:",e.name,i)}},E=e=>t[e]??={};function w(e){try{m.onRemoteError?.(e)}catch{}typeof window<"u"&&window.dispatchEvent(new CustomEvent("fulgurjs:error",{detail:e}))}function F(e="default"){return E(e),t}function V(e,i,a,c,R={}){let s=E(e||"default"),u=s[i]??={};u[a]||(u[a]={version:a,get:c,from:R.from??"unknown",eager:!!R.eager,loaded:!!R.loaded})}function I(e){for(let i of e){let a=n.get(i.name);n.set(i.name,{timeout:A,retries:P,...a,...i,state:a?.state??"idle",breakerState:a?.breakerState??{fails:0,openUntil:0},debug:a?.debug??{entry:i.entry,status:"idle"}})}}function D(e){I([e])}function H(e){o.push(...e),y()}async function K(e,i={}){let a=i.shareScope||"default",c=i.shareKey||e,s=E(a)[c]||{},u=Object.keys(s),d=i.requiredVersion,f=u.filter(p=>d===void 0||d===!1||O(p,d)),_;if(i.singleton&&u.length>0){let p=u.filter(h=>s[h].loaded);if(_=[...p.length?p:u].sort(v).pop(),u.length>1||!f.includes(_)){let h=s[_],j=`singleton skew "${c}": req "${d??"any"}" use ${_} from ${h.from}`;if(i.strictVersion){let M=new g(S.SHARE_STRICT_VERSION,j,{shareKey:c,requiredVersion:d});throw w({remote:h.from,error:M}),M}console.warn(`[fulgurjs:MFU-010] ${j}`)}}else if(_=[...f].sort(v).pop(),!_){if(i.strictVersion){let h=new g(S.SHARE_STRICT_VERSION,`no satisfying version for "${c}" (required "${d}") in share scope "${a}"`);throw w({remote:c,error:h}),h}if(i.fallback)return i.fallback();let p=new g(S.SHARE_NOT_AVAILABLE,`shared "${c}" (${d??"any"}) unavailable in scope "${a}" (no local fallback)`,{shareKey:c,requiredVersion:d});throw w({remote:c,error:p}),p}let $=s[_];if(m.resolveShare){let p=await m.resolveShare({shareKey:c,shareScope:a,requiredVersion:d,picked:$,available:Object.values(s)});p&&($=p)}return $.loaded=!0,$.get()}function q(e,i,a){return new Promise((c,R)=>{let s=setTimeout(()=>R(new Error(`timeout after ${i}ms: ${a}`)),i);e.then(u=>{clearTimeout(s),c(u)},u=>{clearTimeout(s),R(u)})})}let z=e=>new Promise(i=>setTimeout(i,e));function k(e,i){if(!e||typeof e.get!="function")throw new Error(`remoteEntry of "${i.name}" does not export a container interface (get/init)`);if(e.name&&i.name&&e.name!==i.name){let a=`remoteEntry self-reported name "${e.name}" mismatches configured name "${i.name}"`;if(i.promise)console.warn(`[fulgurjs] ${a} (promise-based remote, continuing)`);else throw Object.assign(new Error(a),{code:S.REMOTE_NAME_MISMATCH})}}async function L(e,i){return q(import(e),i.timeout??A,`load remoteEntry ${e}`)}async function x(e,i){let a=e.shareScope||"default";if(e.container){let s=l.get(e.container);if(s&&s!==a)throw new g(S.CONTAINER_REINIT_CONFLICT,`container "${e.name}" already initialized with share scope "${s}", cannot re-init with "${a}"`);return e.container}if(e.containerPromise)return e.containerPromise;let c=e.breakerState;if(c.openUntil>Date.now()){let s=new g(S.REMOTE_LOAD_FAILED,`circuit breaker open for remote "${e.name}" until ${new Date(c.openUntil).toISOString()}`,{remote:e.name});throw w({remote:e.name,error:s}),s}e.state="loading",e.debug.status="loading";let R=(async()=>{let s=[];if(e.promise)s.push(async()=>{let p=await e.promise(),h=typeof p=="string"?await L(p,e):p;return k(h,e),h});else for(let p of[e.entry,...e.fallback??[]])s.push(async()=>{let h=await L(p,e);return k(h,e),h});let u,d,f=!1,_=i?.retries??e.retries??P;for(let p of s){for(let h=0;h<=_;h++){let j=performance.now();try{u=await p(),e.lastLoadMs=Math.round(performance.now()-j),e.debug.lastLoadMs=e.lastLoadMs,f=!0;break}catch(M){if(d=M,M?.code)throw M;h<_&&await z(200*2**h)}}if(f)break}if(!f||!u){let p=[];throw/^https?:\/\//.test(e.entry)&&typeof location<"u"?(p.push(`1. is the remote dev server running? try opening ${e.entry} in the browser \u2014 it must return JS, not HTML/an error`),p.push("2. is the URL correct in federation({ remotes })? dev and prod entries can differ"),p.push("3. CORS: the remote dev server must allow cross-origin requests (fulgurjs-federation enables server.cors automatically; a custom server config may have disabled it)")):(p.push(`1. is the remote deployed and reachable? try opening ${e.entry} in the browser \u2014 it must return JS`),p.push("2. NGINX/CDN routing: the entry path must serve the remoteEntry JS file (check try_files / fallback rules)")),new g(S.REMOTE_LOAD_FAILED,`failed to load remote "${e.name}" from ${e.entry}: ${String(d?.message??d)}
1
+ var X=/^v?(\d+)(?:\.(\d+))?(?:\.(\d+))?(?:-((?:[0-9A-Za-z-]+)(?:\.[0-9A-Za-z-]+)*))?(?:\+[0-9A-Za-z.-]+)?$/;function T(t){let n=X.exec(String(t).trim());return n?{major:Number(n[1]),minor:Number(n[2]??0),patch:Number(n[3]??0),pre:n[4]?n[4].split("."):[]}:null}function Y(t,n){if(t.length===0&&n.length===0)return 0;if(t.length===0)return 1;if(n.length===0)return-1;let o=Math.max(t.length,n.length);for(let r=0;r<o;r++){let l=t[r],m=n[r];if(l===void 0)return-1;if(m===void 0)return 1;let y=/^\d+$/.test(l),E=/^\d+$/.test(m);if(y&&E){let w=Number(l)-Number(m);if(w!==0)return w}else{if(y!==E)return y?-1:1;if(l!==m)return l<m?-1:1}}return 0}function v(t,n){let o=T(t),r=T(n);return!o||!r?t<n?-1:t>n?1:0:o.major!==r.major?o.major-r.major:o.minor!==r.minor?o.minor-r.minor:o.patch!==r.patch?o.patch-r.patch:Y(o.pre,r.pre)}var Z=/^[a-z]+[+:-]/i;function O(t,n){if(n===!1||n==null||n==="")return!0;let o=String(n).trim();return!o||o==="*"||o==="latest"||Z.test(o)?!0:o.split("||").some(r=>Q(t,r.trim()))}function Q(t,n){if(!n||n==="*")return!T(t)?.pre.length;let o=n.split(/\s+-\s+/);if(o.length===2){let m=o[0].trim(),y=o[1].trim();return!(!O(t,`>=${m}`)||!O(t,`<=${y}`))}let r=T(t);if(!r)return!1;let l=ee(n);if(l===null)return!0;for(let m of l)if(!ie(r,t,m))return!1;return!(r.pre.length>0&&!l.some(m=>m.ver.pre.length>0)&&!l.some(y=>y.ver.major===r.major&&y.ver.minor===r.minor&&y.ver.patch===r.patch))}function ee(t){let n=[],o=t.trim().split(/\s+/).filter(Boolean);if(o.length===0)return null;for(let r of o){let l=/^(>=|<=|>|<|=|\^|~)?(.*)$/.exec(r);if(!l)return null;let m=l[1],y=l[2],E=re(m,y);if(E===null)return null;n.push(...E)}return n}function re(t,n){let o=ne(n);if(!o)return null;let{ver:r,partial:l}=o;switch(t){case"^":{let m=te(r);return m?[{op:">=",ver:r},{op:"<",ver:m}]:null}case"~":{let m=l>=2?{major:r.major,minor:r.minor+1,patch:0,pre:[]}:{major:r.major+1,minor:0,patch:0,pre:[]};return[{op:">=",ver:r},{op:"<",ver:m}]}case">=":return[{op:">=",ver:r}];case">":return l===1?[{op:">=",ver:{major:r.major+1,minor:0,patch:0,pre:[]}}]:l===2?[{op:">=",ver:{major:r.major,minor:r.minor+1,patch:0,pre:[]}}]:[{op:">",ver:r}];case"<":return l===1?[{op:"<",ver:{major:r.major,minor:0,patch:0,pre:[]}}]:l===2?[{op:"<",ver:{major:r.major,minor:r.minor,patch:0,pre:[]}}]:[{op:"<",ver:r}];case"<=":return[{op:"<=",ver:r}];case"=":case void 0:return l===1?[{op:">=",ver:r},{op:"<",ver:{major:r.major+1,minor:0,patch:0,pre:[]}}]:l===2?[{op:">=",ver:r},{op:"<",ver:{major:r.major,minor:r.minor+1,patch:0,pre:[]}}]:[{op:"=",ver:r}];default:return null}}function te(t){return t.major>0?{major:t.major+1,minor:0,patch:0,pre:[]}:t.minor>0?{major:0,minor:t.minor+1,patch:0,pre:[]}:{major:0,minor:0,patch:t.patch+1,pre:[]}}function ne(t){let n=t.replace(/^v/,"").trim();if(!n||n==="*"||n==="x"||n==="X")return{ver:{major:0,minor:0,patch:0,pre:[]},partial:0};let o=n.split("."),r=[],l=0;for(let E of o.slice(0,3))if(/^\d+$/.test(E))r.push(Number(E)),l++;else{if(E==="x"||E==="X"||E==="*")break;break}let m=n.split("-"),y=m.length>1?m.slice(1).join("-").split("+")[0].split("."):[];return l===0&&y.length===0?{ver:{major:0,minor:0,patch:0,pre:[]},partial:0}:{ver:{major:r[0]??0,minor:r[1]??0,patch:r[2]??0,pre:y},partial:l}}function oe(t,n){switch(n){case">=":return t>=0;case">":return t>0;case"<":return t<0;case"<=":return t<=0;case"=":return t===0}}function ie(t,n,o){let r=`${t.major}.${t.minor}.${t.patch}`+(t.pre.length?`-${t.pre.join(".")}`:"");if(o.upper)return!(!(v(r,`${o.ver.major}.${o.ver.minor}.${o.ver.patch}`+(o.ver.pre.length?`-${o.ver.pre.join(".")}`:""))>=0)||!(v(r,`${o.upper.major}.${o.upper.minor}.${o.upper.patch}`)<0));let l=v(r,`${o.ver.major}.${o.ver.minor}.${o.ver.patch}`+(o.ver.pre.length?`-${o.ver.pre.join(".")}`:"")),m=oe(l,o.op);return o.ver.pre.length>0&&t.pre.length===0&&(o.op===">"||o.op==="<")?!1:m}var g=class extends Error{code;details;constructor(n,o,r){super(`[fulgurjs:${n}] ${o}`),this.name="FgError",this.code=n,this.details=r}},S={REMOTE_LOAD_FAILED:"MFU-001",REMOTE_NAME_MISMATCH:"MFU-002",SHARE_STRICT_VERSION:"MFU-003",SHARE_NOT_AVAILABLE:"MFU-004",CONTAINER_REINIT_CONFLICT:"MFU-005",MODULE_NOT_EXPOSED:"MFU-006",PRELOAD_FAILED:"MFU-007",REMOTE_UNKNOWN:"MFU-008",EMPTY_EXPORTS:"MFU-009",SINGLETON_SKEW:"MFU-010"};var U="2.0.2";var A=15e3,P=2,ae=5,se=3e4;function ce(){let t={},n=new Map,o=[],r=new Map,l=new WeakMap,m={},y=()=>{for(let e of o)try{e.init?.(m)}catch(i){console.warn("[fulgurjs] runtimePlugin init failed:",e.name,i)}},E=e=>t[e]??={};function w(e){try{m.onRemoteError?.(e)}catch{}typeof window<"u"&&window.dispatchEvent(new CustomEvent("fulgurjs:error",{detail:e}))}function F(e="default"){return E(e),t}function V(e,i,a,c,R={}){let s=E(e||"default"),u=s[i]??={};u[a]||(u[a]={version:a,get:c,from:R.from??"unknown",eager:!!R.eager,loaded:!!R.loaded})}function I(e){for(let i of e){let a=n.get(i.name);n.set(i.name,{timeout:A,retries:P,...a,...i,state:a?.state??"idle",breakerState:a?.breakerState??{fails:0,openUntil:0},debug:a?.debug??{entry:i.entry,status:"idle"}})}}function D(e){I([e])}function H(e){o.push(...e),y()}async function K(e,i={}){let a=i.shareScope||"default",c=i.shareKey||e,s=E(a)[c]||{},u=Object.keys(s),d=i.requiredVersion,f=u.filter(p=>d===void 0||d===!1||O(p,d)),_;if(i.singleton&&u.length>0){let p=u.filter(h=>s[h].loaded);if(_=[...p.length?p:u].sort(v).pop(),u.length>1||!f.includes(_)){let h=s[_],j=`singleton skew "${c}": req "${d??"any"}" use ${_} from ${h.from}`;if(i.strictVersion){let M=new g(S.SHARE_STRICT_VERSION,j,{shareKey:c,requiredVersion:d});throw w({remote:h.from,error:M}),M}console.warn(`[fulgurjs:MFU-010] ${j}`)}}else if(_=[...f].sort(v).pop(),!_){if(i.strictVersion){let h=new g(S.SHARE_STRICT_VERSION,`no satisfying version for "${c}" (required "${d}") in share scope "${a}"`);throw w({remote:c,error:h}),h}if(i.fallback)return i.fallback();let p=new g(S.SHARE_NOT_AVAILABLE,`shared "${c}" (${d??"any"}) unavailable in scope "${a}" (no local fallback)`,{shareKey:c,requiredVersion:d});throw w({remote:c,error:p}),p}let $=s[_];if(m.resolveShare){let p=await m.resolveShare({shareKey:c,shareScope:a,requiredVersion:d,picked:$,available:Object.values(s)});p&&($=p)}return $.loaded=!0,$.get()}function q(e,i,a){return new Promise((c,R)=>{let s=setTimeout(()=>R(new Error(`timeout after ${i}ms: ${a}`)),i);e.then(u=>{clearTimeout(s),c(u)},u=>{clearTimeout(s),R(u)})})}let z=e=>new Promise(i=>setTimeout(i,e));function k(e,i){if(!e||typeof e.get!="function")throw new Error(`remoteEntry of "${i.name}" does not export a container interface (get/init)`);if(e.name&&i.name&&e.name!==i.name){let a=`remoteEntry self-reported name "${e.name}" mismatches configured name "${i.name}"`;if(i.promise)console.warn(`[fulgurjs] ${a} (promise-based remote, continuing)`);else throw Object.assign(new Error(a),{code:S.REMOTE_NAME_MISMATCH})}}async function L(e,i){return q(import(e),i.timeout??A,`load remoteEntry ${e}`)}async function x(e,i){let a=e.shareScope||"default";if(e.container){let s=l.get(e.container);if(s&&s!==a)throw new g(S.CONTAINER_REINIT_CONFLICT,`container "${e.name}" already initialized with share scope "${s}", cannot re-init with "${a}"`);return e.container}if(e.containerPromise)return e.containerPromise;let c=e.breakerState;if(c.openUntil>Date.now()){let s=new g(S.REMOTE_LOAD_FAILED,`circuit breaker open for remote "${e.name}" until ${new Date(c.openUntil).toISOString()}`,{remote:e.name});throw w({remote:e.name,error:s}),s}e.state="loading",e.debug.status="loading";let R=(async()=>{let s=[];if(e.promise)s.push(async()=>{let p=await e.promise(),h=typeof p=="string"?await L(p,e):p;return k(h,e),h});else for(let p of[e.entry,...e.fallback??[]])s.push(async()=>{let h=await L(p,e);return k(h,e),h});let u,d,f=!1,_=i?.retries??e.retries??P;for(let p of s){for(let h=0;h<=_;h++){let j=performance.now();try{u=await p(),e.lastLoadMs=Math.round(performance.now()-j),e.debug.lastLoadMs=e.lastLoadMs,f=!0;break}catch(M){if(d=M,M?.code)throw M;h<_&&await z(200*2**h)}}if(f)break}if(!f||!u){let p=[];throw/^https?:\/\//.test(e.entry)&&typeof location<"u"?(p.push(`1. is the remote dev server running? try opening ${e.entry} in the browser \u2014 it must return JS, not HTML/an error`),p.push("2. is the URL correct in federation({ remotes })? dev and prod entries can differ"),p.push("3. CORS: the remote dev server must allow cross-origin requests (fulgurjs-federation enables server.cors automatically; a custom server config may have disabled it)")):(p.push(`1. is the remote deployed and reachable? try opening ${e.entry} in the browser \u2014 it must return JS`),p.push("2. NGINX/CDN routing: the entry path must serve the remoteEntry JS file (check try_files / fallback rules)")),new g(S.REMOTE_LOAD_FAILED,`failed to load remote "${e.name}" from ${e.entry}: ${String(d?.message??d)}
2
2
  `+p.join(`
3
3
  `),{remote:e.name})}k(u,e);let $=l.get(u);if($&&$!==a)throw new g(S.CONTAINER_REINIT_CONFLICT,`container "${e.name}" already initialized with share scope "${$}", cannot re-init with "${a}"`);return typeof u.init=="function"&&await u.init(t),l.set(u,a),e.container=u,e.state="loaded",e.debug.status="loaded",c.fails=0,u})();e.containerPromise=R;try{return await R}catch(s){if(e.containerPromise=void 0,e.state="failed",e.debug.status="failed",e.debug.error=String(s?.message??s),c.fails+=1,c.fails>=ae&&(c.openUntil=Date.now()+se,c.fails=0),s instanceof g)throw w({remote:e.name,error:s}),s;if(s?.code)throw w({remote:e.name,error:s}),s;let u=new g(S.REMOTE_LOAD_FAILED,String(s?.message??s),{remote:e.name});throw w({remote:e.name,error:u}),u}}function N(e){let i=e.indexOf("/");return i===-1?{remote:e,module:""}:{remote:e.slice(0,i),module:G(e.slice(i+1))}}function G(e){return e?e.startsWith(".")?e:`./${e}`:""}async function J(e,i){let{remote:a,module:c}=N(e);m.beforeLoadRemote?.({remote:a,module:c});let R=n.get(a);if(!R)throw new g(S.REMOTE_UNKNOWN,`unknown remote "${a}". Register it via federation({ remotes }) or registerRemote().`,{remote:a});let s;try{s=await x(R,{retries:i?.retries})}catch(f){if(i?.fallbackModule)return console.error(`[fulgurjs] loadRemote("${e}") failed; returning fallbackModule (\u663E\u5F0F\u964D\u7EA7\uFF0C\u9519\u8BEF\u5DF2\u900F\u51FA)`,f),w({remote:a,error:f}),await i.fallbackModule();throw f}if(!c)return s;let u=`${a}@${R.shareScope||"default"}#${c}`;r.has(u)||r.set(u,s.get(c).catch(f=>{throw r.delete(u),f instanceof g||f?.code?f:new g(S.REMOTE_LOAD_FAILED,`failed to load module "${c}" from remote "${a}": ${String(f?.message??f)}`,{remote:a,module:c})}));let d;try{d=await r.get(u)}catch(f){if(i?.fallbackModule)return console.error(`[fulgurjs] loadRemote("${e}") failed; returning fallbackModule (\u663E\u5F0F\u964D\u7EA7\uFF0C\u9519\u8BEF\u5DF2\u900F\u51FA)`,f),w({remote:a,error:f}),await i.fallbackModule();throw f}if(m.afterLoadRemote?.({remote:a,module:c,module_ns:d}),d&&typeof d=="object"&&Object.keys(d).length===0){let f=new g(S.EMPTY_EXPORTS,`no exports: ${c} @ ${a}`,{remote:a,module:c});w({remote:a,error:f}),console.error(`[fulgurjs:MFU-009] ${f.message}`)}return d}function W(e){let i=n.get(e);if(!i)throw new g(S.REMOTE_UNKNOWN,`unknown remote "${e}"`,{remote:e});return x(i)}async function B(e,i={}){let{remote:a}=N(e),c=n.get(a);if(!c)throw new g(S.REMOTE_UNKNOWN,`unknown remote "${a}"`,{remote:a});let R=i.mode??"preload",s=(u,d)=>{if(typeof document>"u"||document.querySelector(`link[href="${u}"]`))return;let f=document.createElement("link");f.rel=d==="style"?"stylesheet":"modulepreload",f.href=u,R==="prefetch"&&(f.fetchPriority="low"),document.head.appendChild(f)};try{if(c.manifestUrl){let u=await fetch(c.manifestUrl,{cache:"no-cache"});if(u.ok){let d=await u.json();s(c.entry,"modulepreload");let f=d.exposes??{};for(let _ of Object.keys(f)){let $=f[_];$?.file&&s(new URL($.file,c.entry).href,"modulepreload");for(let p of $?.css??[])s(new URL(p,c.entry).href,"style")}return}}s(c.entry,"modulepreload")}catch(u){w({remote:a,error:new g(S.PRELOAD_FAILED,String(u?.message??u),{remote:a})})}}return typeof window>"u"||(window.__FULGURJS_SCOPE__=t,window.__FULGURJS_INFO__={get remotes(){let e={};for(let[i,a]of n)e[i]={...a.debug,entry:a.entry};return e},errors:[]}),{shareScopeMap:t,initSharing:F,registerShare:V,registerRemotes:I,registerRemote:D,registerPlugins:H,loadShare:K,loadRemote:J,getContainer:W,preloadRemote:B,parseSpec:N}}var C=globalThis,b=C.__FULGURJS_RUNTIME__??ce();C.__FULGURJS_RUNTIME__=b;try{Object.freeze(b)}catch{}var he=U;function ye(){return b}var Ee=b.initSharing,Re=b.registerShare,Se=b.registerRemotes,we=b.registerRemote,be=b.registerPlugins,_e=b.loadShare,$e=b.loadRemote,Me=b.getContainer,ve=b.preloadRemote,je=b.shareScopeMap;function Te(t){if(t&&typeof t=="object"&&"default"in t){let n=t.default;return n!==void 0?n:t}return t}var Oe=b;export{Oe as default,Me as getContainer,ye as getRuntime,Ee as initSharing,$e as loadRemote,_e as loadShare,ve as preloadRemote,be as registerPlugins,we as registerRemote,Se as registerRemotes,Re as registerShare,b as runtime,je as shareScopeMap,Te as unwrapDefault,he as version};
package/dist/vue.js CHANGED
@@ -2,7 +2,7 @@ import {
2
2
  ErrorCodes,
3
3
  FgError
4
4
  } from "./chunk-3VBYOVH4.js";
5
- import "./chunk-I5FNKR7E.js";
5
+ import "./chunk-UDLQALHC.js";
6
6
 
7
7
  // src/vue.ts
8
8
  import { defineAsyncComponent, defineComponent, h } from "vue";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fulgurjs/federation",
3
- "version": "2.0.1",
3
+ "version": "2.0.2",
4
4
  "type": "module",
5
5
  "description": "Vite Module Federation with full Webpack MF parity. Dev & production, no compromise.",
6
6
  "license": "MIT",