@fulgurjs/federation 2.0.3 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -34,7 +34,7 @@ __export(index_exports, {
34
34
  federation: () => federation
35
35
  });
36
36
  module.exports = __toCommonJS(index_exports);
37
- var import_node_path5 = __toESM(require("path"), 1);
37
+ var import_node_path6 = __toESM(require("path"), 1);
38
38
  var import_node_module2 = require("module");
39
39
 
40
40
  // src/options.ts
@@ -43,7 +43,33 @@ 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.3";
46
+ var RUNTIME_VERSION = "2.1.0";
47
+
48
+ // src/dev-cors.ts
49
+ function normalizeDevCorsOrigins(input) {
50
+ if (input === void 0 || input === "*") return { ok: true, value: input };
51
+ if (!Array.isArray(input) || input.length === 0) {
52
+ return { ok: false, reason: '\u5FC5\u987B\u662F "*" \u6216\u975E\u7A7A\u6570\u7EC4' };
53
+ }
54
+ for (const item of input) {
55
+ if (typeof item !== "string" || !/^https?:\/\/[^/]+$/i.test(item)) {
56
+ return { ok: false, reason: `\u6765\u6E90\u5FC5\u987B\u662F http(s)://host[:port] \u5F62\u6001\uFF08\u65E0\u8DEF\u5F84\uFF09\uFF0Cgot: ${JSON.stringify(item)}` };
57
+ }
58
+ }
59
+ return { ok: true, value: input };
60
+ }
61
+ function corsHeadersFor(origin, allowed) {
62
+ if (allowed === void 0 || allowed === "*") {
63
+ return { "Access-Control-Allow-Origin": "*" };
64
+ }
65
+ if (!origin || !allowed.includes(origin)) return {};
66
+ return { "Access-Control-Allow-Origin": origin, Vary: "Origin" };
67
+ }
68
+ function isNonLoopbackHost(host) {
69
+ if (host === void 0 || host === false) return false;
70
+ const h = host === true ? "0.0.0.0" : String(host);
71
+ return !["localhost", "127.0.0.1", "::1", "[::1]"].includes(h.toLowerCase());
72
+ }
47
73
 
48
74
  // src/options.ts
49
75
  var DEFAULT_FILENAME = "fulgurjs-remoteEntry.js";
@@ -300,6 +326,41 @@ function validateOptions(options) {
300
326
  // or split: { '${key}': { dev: 'http://localhost:5101', prod: '/${key}' } }`
301
327
  );
302
328
  }
329
+ if (cfg.timeout !== void 0 && (typeof cfg.timeout !== "number" || !Number.isFinite(cfg.timeout) || cfg.timeout <= 0)) {
330
+ configError(
331
+ `CFG-009: remotes["${key}"].timeout must be a finite positive number (ms)`,
332
+ cfg.timeout,
333
+ "e.g. 15000\uFF08\u7701\u7565\u7528\u9ED8\u8BA4 15s\uFF09",
334
+ `remotes: { '${key}': { external: '\u2026', timeout: 15000 } }`
335
+ );
336
+ }
337
+ if (cfg.retries !== void 0 && (typeof cfg.retries !== "number" || !Number.isInteger(cfg.retries) || cfg.retries < 0 || cfg.retries > 10)) {
338
+ configError(
339
+ `CFG-009: remotes["${key}"].retries must be an integer in 0..10`,
340
+ cfg.retries,
341
+ "e.g. 2\uFF08\u7701\u7565\u7528\u9ED8\u8BA4 2\uFF1B\u4E0A\u9650 10 \u9632\u9000\u907F\u98CE\u66B4\uFF09",
342
+ `remotes: { '${key}': { external: '\u2026', retries: 2 } }`
343
+ );
344
+ }
345
+ const brk = cfg.breaker;
346
+ if (brk) {
347
+ if (brk.threshold !== void 0 && (typeof brk.threshold !== "number" || !Number.isFinite(brk.threshold) || brk.threshold <= 0)) {
348
+ configError(
349
+ `CFG-009: remotes["${key}"].breaker.threshold must be a finite positive number`,
350
+ brk.threshold,
351
+ "e.g. 5\uFF08\u8FDE\u7EED\u5931\u8D25 5 \u6B21\u540E\u7194\u65AD\uFF09",
352
+ `remotes: { '${key}': { external: '\u2026', breaker: { threshold: 5, resetMs: 30000 } } }`
353
+ );
354
+ }
355
+ if (brk.resetMs !== void 0 && (typeof brk.resetMs !== "number" || !Number.isFinite(brk.resetMs) || brk.resetMs <= 0)) {
356
+ configError(
357
+ `CFG-009: remotes["${key}"].breaker.resetMs must be a finite positive number (ms)`,
358
+ brk.resetMs,
359
+ "e.g. 30000\uFF08\u7194\u65AD 30s \u540E\u534A\u5F00\uFF09",
360
+ `remotes: { '${key}': { external: '\u2026', breaker: { threshold: 5, resetMs: 30000 } } }`
361
+ );
362
+ }
363
+ }
303
364
  for (const slot of ["dev", "prod", "external"]) {
304
365
  const v = cfg[slot];
305
366
  if (v !== void 0 && typeof v !== "string") {
@@ -318,6 +379,23 @@ function validateOptions(options) {
318
379
  }
319
380
  }
320
381
  }
382
+ const corsCheck = normalizeDevCorsOrigins(options.devCorsOrigins);
383
+ if (!corsCheck.ok) {
384
+ configError(
385
+ `CFG-010: devCorsOrigins ${corsCheck.reason}`,
386
+ options.devCorsOrigins,
387
+ `'*'\uFF08\u5168\u653E\u5F00\uFF09\u6216\u6765\u6E90 allowlist \u6570\u7EC4`,
388
+ `devCorsOrigins: ['http://localhost:5100', 'http://127.0.0.1:5100']`
389
+ );
390
+ }
391
+ if (options.devFsRoot !== void 0 && typeof options.devFsRoot !== "boolean") {
392
+ configError(
393
+ "`devFsRoot` must be a boolean",
394
+ options.devFsRoot,
395
+ "true\uFF08dev manifest \u643A\u5E26 fsRoot\uFF0C\u73B0\u72B6\u9ED8\u8BA4\uFF09\u6216 false\uFF08\u4E0D\u66B4\u9732\u672C\u673A\u8DEF\u5F84\uFF09",
396
+ `devFsRoot: false`
397
+ );
398
+ }
321
399
  }
322
400
  function normalizeOptions(options, root, command) {
323
401
  const warnings = [];
@@ -389,7 +467,9 @@ function normalizeOptions(options, root, command) {
389
467
  pkgDependencies,
390
468
  warnings,
391
469
  // dev 改写开关:默认纯 remote 参与 shared 协商,宿主(有 remotes)不参与;可显式覆盖
392
- devSharedSelf: options.devSharedSelf ?? remotes.length === 0
470
+ devSharedSelf: options.devSharedSelf ?? remotes.length === 0,
471
+ devCorsOrigins: options.devCorsOrigins,
472
+ devFsRoot: options.devFsRoot ?? true
393
473
  };
394
474
  }
395
475
 
@@ -398,6 +478,145 @@ var import_es_module_lexer = require("es-module-lexer");
398
478
  var import_magic_string = __toESM(require("magic-string"), 1);
399
479
  var import_node_path2 = __toESM(require("path"), 1);
400
480
 
481
+ // src/manifest.ts
482
+ var MANIFEST_SCHEMA_VERSION = 1;
483
+ var isPlainObject = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
484
+ function validAssetRef(v) {
485
+ if (typeof v !== "string" || v.length === 0) return false;
486
+ if (/[\s\u0000-\u001f]/.test(v)) return false;
487
+ if (/^https?:\/\/[^/@\s]+:[^/@\s]+@/.test(v)) return false;
488
+ return true;
489
+ }
490
+ function validExposeName(v) {
491
+ return typeof v === "string" && /^\.[\w./-]+$/.test(v);
492
+ }
493
+ function parseManifest(input) {
494
+ const issues = [];
495
+ if (!isPlainObject(input)) {
496
+ return { issues: [{ field: "$", message: "manifest \u5FC5\u987B\u662F JSON \u5BF9\u8C61", got: typeof input }] };
497
+ }
498
+ const m = input;
499
+ let schemaVersion = MANIFEST_SCHEMA_VERSION;
500
+ if (m.schemaVersion !== void 0) {
501
+ if (typeof m.schemaVersion !== "number" || !Number.isInteger(m.schemaVersion)) {
502
+ issues.push({ field: "schemaVersion", message: "\u5FC5\u987B\u662F\u6574\u6570", got: m.schemaVersion });
503
+ } else if (m.schemaVersion !== MANIFEST_SCHEMA_VERSION) {
504
+ return {
505
+ issues: [
506
+ {
507
+ field: "schemaVersion",
508
+ message: `\u4E0D\u652F\u6301\u7684 manifest \u4E3B\u7248\u672C\uFF08\u5F53\u524D\u6D88\u8D39\u7AEF\u652F\u6301 ${MANIFEST_SCHEMA_VERSION}\uFF09`,
509
+ got: m.schemaVersion
510
+ }
511
+ ],
512
+ unsupportedVersion: m.schemaVersion
513
+ };
514
+ }
515
+ }
516
+ if (typeof m.name !== "string" || m.name.length === 0) {
517
+ issues.push({ field: "name", message: "\u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32", got: m.name });
518
+ }
519
+ const exposes = m.exposes;
520
+ const shared = m.shared;
521
+ const sharedIssues = validateShared(shared);
522
+ issues.push(...sharedIssues);
523
+ if (Array.isArray(exposes)) {
524
+ if (m.devServer !== true) {
525
+ issues.push({ field: "devServer", message: "dev \u6570\u7EC4\u5F62\u6001 exposes \u5FC5\u987B\u4F34\u968F devServer: true", got: m.devServer });
526
+ }
527
+ if (typeof m.base !== "string" || !/^\/(?:.*\/)?$/.test(m.base)) {
528
+ issues.push({ field: "base", message: "\u5FC5\u987B\u662F\u4EE5 / \u5F00\u5934\u4E14 / \u7ED3\u5C3E\u7684\u8DEF\u5F84", got: m.base });
529
+ }
530
+ if (!validAssetRef(m.entry)) {
531
+ issues.push({ field: "entry", message: "\u5FC5\u987B\u662F\u5408\u6CD5\u8D44\u6E90\u5730\u5740", got: m.entry });
532
+ }
533
+ for (const [i, e] of exposes.entries()) {
534
+ if (!isPlainObject(e)) {
535
+ issues.push({ field: `exposes[${i}]`, message: "\u5FC5\u987B\u662F\u5BF9\u8C61", got: typeof e });
536
+ continue;
537
+ }
538
+ if (!validExposeName(e.name)) {
539
+ issues.push({ field: `exposes[${i}].name`, message: '\u5FC5\u987B\u662F "./xxx" \u5F62\u6001\u7684 expose \u540D', got: e.name });
540
+ }
541
+ if (typeof e.src !== "string" || e.src.length === 0) {
542
+ issues.push({ field: `exposes[${i}].src`, message: "dev \u5F62\u6001\u5FC5\u987B\u63D0\u4F9B\u6E90\u7801\u76F8\u5BF9\u8DEF\u5F84", got: e.src });
543
+ }
544
+ if (!validAssetRef(e.file)) {
545
+ issues.push({ field: `exposes[${i}].file`, message: "\u5FC5\u987B\u662F\u53EF\u8BF7\u6C42\u7684\u6A21\u5757\u5730\u5740", got: e.file });
546
+ }
547
+ }
548
+ } else if (isPlainObject(exposes)) {
549
+ if (!validAssetRef(m.entry)) {
550
+ issues.push({ field: "entry", message: "\u5FC5\u987B\u662F\u5408\u6CD5\u8D44\u6E90\u5730\u5740\uFF08\u76F8\u5BF9\u57FA\u51C6 = \u6240\u5728\u76EE\u5F55\uFF09", got: m.entry });
551
+ }
552
+ for (const [key, v] of Object.entries(exposes)) {
553
+ if (!validExposeName(key)) {
554
+ issues.push({ field: `exposes["${key}"]`, message: '\u952E\u5FC5\u987B\u662F "./xxx" \u5F62\u6001\u7684 expose \u540D' });
555
+ }
556
+ if (!isPlainObject(v)) {
557
+ issues.push({ field: `exposes["${key}"]`, message: "\u503C\u5FC5\u987B\u662F\u5BF9\u8C61", got: typeof v });
558
+ continue;
559
+ }
560
+ if (!validAssetRef(v.file)) {
561
+ issues.push({ field: `exposes["${key}"].file`, message: "\u5FC5\u987B\u662F\u8D44\u6E90\u8DEF\u5F84\uFF08\u76F8\u5BF9 entry \u76EE\u5F55\uFF09", got: v.file });
562
+ }
563
+ if (v.css !== void 0) {
564
+ if (!Array.isArray(v.css)) {
565
+ issues.push({ field: `exposes["${key}"].css`, message: "\u5FC5\u987B\u662F\u5B57\u7B26\u4E32\u6570\u7EC4", got: typeof v.css });
566
+ } else {
567
+ v.css.forEach((css, i) => {
568
+ if (!validAssetRef(css)) {
569
+ issues.push({ field: `exposes["${key}"].css[${i}]`, message: "\u5FC5\u987B\u662F\u8D44\u6E90\u8DEF\u5F84", got: css });
570
+ }
571
+ });
572
+ }
573
+ }
574
+ }
575
+ } else {
576
+ issues.push({ field: "exposes", message: "\u5FC5\u987B\u662F\u6570\u7EC4\uFF08dev\uFF09\u6216\u5BF9\u8C61\uFF08prod\uFF09", got: typeof exposes });
577
+ }
578
+ if (issues.length > 0) return { issues };
579
+ return { manifest: input, issues };
580
+ }
581
+ function validateShared(shared) {
582
+ if (shared === void 0) return [];
583
+ const issues = [];
584
+ if (!Array.isArray(shared)) {
585
+ return [{ field: "shared", message: "\u5FC5\u987B\u662F\u6570\u7EC4", got: typeof shared }];
586
+ }
587
+ for (const [i, s] of shared.entries()) {
588
+ if (!isPlainObject(s)) {
589
+ issues.push({ field: `shared[${i}]`, message: "\u5FC5\u987B\u662F\u5BF9\u8C61", got: typeof s });
590
+ continue;
591
+ }
592
+ if (typeof s.name !== "string" || s.name.length === 0) {
593
+ issues.push({ field: `shared[${i}].name`, message: "\u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32", got: s.name });
594
+ }
595
+ if (typeof s.version !== "string" || s.version.length === 0) {
596
+ issues.push({ field: `shared[${i}].version`, message: "\u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32", got: s.version });
597
+ }
598
+ }
599
+ return issues;
600
+ }
601
+ function isDevManifest(m) {
602
+ return Array.isArray(m.exposes);
603
+ }
604
+ function normalizeExposes(manifest) {
605
+ const out = /* @__PURE__ */ new Map();
606
+ if (isDevManifest(manifest)) {
607
+ for (const e of manifest.exposes) {
608
+ if (!validExposeName(e.name)) continue;
609
+ out.set(e.name, { name: e.name, file: e.file, css: [], src: e.src });
610
+ }
611
+ } else {
612
+ for (const [key, v] of Object.entries(manifest.exposes)) {
613
+ if (!validExposeName(key)) continue;
614
+ out.set(key, { name: key, file: v.file, css: Array.isArray(v.css) ? v.css.filter((c) => typeof c === "string") : [] });
615
+ }
616
+ }
617
+ return out;
618
+ }
619
+
401
620
  // src/virtual.ts
402
621
  function jsonReplacer(_k, v) {
403
622
  return v;
@@ -696,17 +915,33 @@ function genBuildRemoteEntry(options, exposeAbsPaths) {
696
915
  ""
697
916
  ].join("\n");
698
917
  }
918
+ function genApiFacade() {
919
+ return [
920
+ "export {",
921
+ " initSharing, registerShare, registerRemotes, registerRemote, registerPlugins,",
922
+ " loadShare, loadRemote, getContainer, preloadRemote, parseSpec,",
923
+ " getRuntime, shareScopeMap, unwrapDefault, version,",
924
+ '} from "virtual:fulgurjs-runtime";',
925
+ 'export { definePages, validatePages } from "@fulgurjs/federation/pages";',
926
+ 'export { default as remoteSchema } from "virtual:fulgurjs-remote-schema";',
927
+ ""
928
+ ].join("\n");
929
+ }
699
930
  function genDevManifest(options, base) {
700
931
  const b = base.endsWith("/") ? base : `${base}/`;
701
932
  return {
933
+ schemaVersion: MANIFEST_SCHEMA_VERSION,
702
934
  id: options.name,
703
935
  name: options.name,
704
936
  version: options.pkgDependencies?.["fulgurjs"] ?? "0.0.0",
705
937
  devServer: true,
706
938
  base: b,
707
939
  entry: `${b}@fulgurjs-entry.js`,
708
- /** 本地联调时供宿主端 dts 类型直连(见 dts.ts);远程不在本机时宿主回退 any 桩 */
709
- fsRoot: options.root,
940
+ /**
941
+ * 本地联调时供宿主端 dts 类型直连(见 dts.ts);远程不在本机时宿主回退 any 桩。
942
+ * WP5:devFsRoot: false 时不写入(本机路径不外发);该字段永不进入 prod manifest。
943
+ */
944
+ ...options.devFsRoot === false ? {} : { fsRoot: options.root },
710
945
  exposes: options.exposes.map((e) => ({
711
946
  name: e.name,
712
947
  src: e.import,
@@ -728,6 +963,7 @@ function genDevManifest(options, base) {
728
963
  }
729
964
  function genProdManifest(options, exposeFiles, entryFile) {
730
965
  return {
966
+ schemaVersion: MANIFEST_SCHEMA_VERSION,
731
967
  id: options.name,
732
968
  name: options.name,
733
969
  entry: entryFile,
@@ -909,6 +1145,7 @@ async function transformModule(code, id, ctx) {
909
1145
  cjsEdited = true;
910
1146
  }
911
1147
  if (!cjsEdited) return null;
1148
+ ctx.onRewrite?.();
912
1149
  return { code, map: null };
913
1150
  }
914
1151
  await ensureLexer();
@@ -1031,6 +1268,7 @@ export { ${nsAs[1]} };`);
1031
1268
  }
1032
1269
  }
1033
1270
  if (!edited) return null;
1271
+ ctx.onRewrite?.();
1034
1272
  if (usesRuntimeHelpers) {
1035
1273
  const runtimeSpec = JSON.stringify(ctx.devUrls?.runtime ?? "virtual:fulgurjs-runtime");
1036
1274
  s.prepend(
@@ -1056,7 +1294,22 @@ async function fetchManifest(devEntry, attempts = 30, delayMs = 2e3) {
1056
1294
  for (let i = 0; i < attempts; i++) {
1057
1295
  try {
1058
1296
  const res = await fetch(manifestUrl, { signal: AbortSignal.timeout(3e3) });
1059
- if (res.ok) return await res.json();
1297
+ if (res.ok) {
1298
+ const parsed = parseManifest(await res.json());
1299
+ if (parsed.unsupportedVersion) {
1300
+ console.warn(
1301
+ `[fulgurjs] dts: remote manifest schemaVersion=${parsed.unsupportedVersion} \u4E0D\u88AB\u5F53\u524D\u63D2\u4EF6\u652F\u6301\uFF08\u672C\u673A\u652F\u6301 1\uFF09\uFF1B\u7C7B\u578B\u6620\u5C04\u8DF3\u8FC7\u3002\u8BF7\u5BF9\u9F50\u5BBF\u4E3B\u4E0E\u8FDC\u7A0B\u7684 @fulgurjs/federation \u7248\u672C\u3002`
1302
+ );
1303
+ return null;
1304
+ }
1305
+ if (parsed.issues.length > 0) {
1306
+ console.warn(
1307
+ `[fulgurjs] dts: remote manifest \u5951\u7EA6\u6821\u9A8C\u5931\u8D25\uFF08${manifestUrl.href}\uFF09\uFF1A` + parsed.issues.map((x) => `${x.field}: ${x.message}`).join("\uFF1B") + `\u3002\u7C7B\u578B\u6620\u5C04\u8DF3\u8FC7\u3002`
1308
+ );
1309
+ return null;
1310
+ }
1311
+ return parsed.manifest;
1312
+ }
1060
1313
  } catch {
1061
1314
  }
1062
1315
  await new Promise((r) => setTimeout(r, delayMs));
@@ -1119,7 +1372,7 @@ function resolveDtsMode(dtsOpt) {
1119
1372
  return (typeof dtsOpt === "object" ? dtsOpt.mode : void 0) ?? "source";
1120
1373
  }
1121
1374
  function buildShimModule(abs, moduleSpecifier) {
1122
- const lines = [`declare module '${moduleSpecifier}' {`];
1375
+ const lines = [`declare module ${JSON.stringify(moduleSpecifier)} {`];
1123
1376
  if (abs.endsWith(".vue")) {
1124
1377
  lines.push(` import type { DefineComponent } from 'vue'`);
1125
1378
  lines.push(` const component: DefineComponent<Record<string, unknown>, Record<string, unknown>, any>`);
@@ -1156,9 +1409,18 @@ async function generateDevTypes(options, _server) {
1156
1409
  continue;
1157
1410
  }
1158
1411
  const remoteRoot = manifest.fsRoot;
1159
- if (!remoteRoot || !import_node_fs2.default.existsSync(remoteRoot)) {
1412
+ if (!remoteRoot) {
1160
1413
  console.warn(
1161
- `[fulgurjs] dts: remote "${remote.key}" is not on this machine; type mapping skipped (module types fall back to any).`
1414
+ `[fulgurjs] dts: remote "${remote.key}" \u7684 manifest \u672A\u643A\u5E26 fsRoot\uFF08devFsRoot: false \u6216\u8FDC\u7A0B\u63D2\u4EF6\u7248\u672C\u8FC7\u65E7\uFF09\uFF1B\u7C7B\u578B\u6620\u5C04\u964D\u7EA7\u4E3A any \u6869\u3002\u540C\u673A\u8054\u8C03\u9700\u8FDC\u7A0B devFsRoot: true\uFF08\u9ED8\u8BA4\uFF09\u5E76\u91CD\u542F\u5176 dev server\u3002`
1415
+ );
1416
+ continue;
1417
+ }
1418
+ let realRoot;
1419
+ try {
1420
+ realRoot = import_node_fs2.default.realpathSync(remoteRoot);
1421
+ } catch {
1422
+ console.warn(
1423
+ `[fulgurjs] dts: remote "${remote.key}" is not on this machine (fsRoot unreachable); type mapping skipped (module types fall back to any).`
1162
1424
  );
1163
1425
  continue;
1164
1426
  }
@@ -1166,45 +1428,78 @@ async function generateDevTypes(options, _server) {
1166
1428
  `// \u81EA\u52A8\u751F\u6210\uFF1Afulgurjs-federation dev \u7C7B\u578B\u76F4\u8FDE\uFF08remote: ${remote.name}\uFF0Cmode: ${mode}\uFF09`,
1167
1429
  `// \u91CD\u65B0\u751F\u6210\uFF1A\u91CD\u542F host dev server`
1168
1430
  ];
1431
+ let accepted = 0;
1169
1432
  for (const expose of manifest.exposes ?? []) {
1170
- const abs = import_node_path3.default.join(remoteRoot, expose.src.replace(/^\//, ""));
1171
- if (!import_node_fs2.default.existsSync(abs)) continue;
1172
- const rel = import_node_path3.default.relative(outDir, abs).split(import_node_path3.default.sep).join("/");
1173
- const importPath = abs.endsWith(".vue") ? sourceImportPath(rel) : stripTsExtension(sourceImportPath(rel));
1433
+ const skipped = (reason) => console.warn(`[fulgurjs] dts: remote "${remote.key}" expose ${JSON.stringify(expose.name)} \u8DF3\u8FC7\uFF1A${reason}`);
1434
+ const src = expose.src;
1435
+ if (!src || typeof src !== "string") {
1436
+ skipped("src \u7F3A\u5931");
1437
+ continue;
1438
+ }
1439
+ if (src.startsWith("/") || /^[a-z]+:/i.test(src)) {
1440
+ skipped(`src \u5FC5\u987B\u662F\u76F8\u5BF9\u8DEF\u5F84\uFF0Cgot ${JSON.stringify(src)}`);
1441
+ continue;
1442
+ }
1443
+ if (src.split("/").includes("..")) {
1444
+ skipped(`src \u4E0D\u5F97\u5305\u542B ..\uFF0Cgot ${JSON.stringify(src)}`);
1445
+ continue;
1446
+ }
1447
+ const abs = import_node_path3.default.join(realRoot, src);
1448
+ let realAbs;
1449
+ try {
1450
+ realAbs = import_node_fs2.default.realpathSync(abs);
1451
+ } catch {
1452
+ skipped(`\u6E90\u6587\u4EF6\u4E0D\u5B58\u5728\uFF08${src}\uFF09`);
1453
+ continue;
1454
+ }
1455
+ if (import_node_path3.default.relative(realRoot, realAbs).startsWith("..")) {
1456
+ skipped(`\u89E3\u6790\u7ED3\u679C\u8D8A\u51FA fsRoot\uFF08${src} \u2192 ${realAbs}\uFF09`);
1457
+ continue;
1458
+ }
1459
+ if (!import_node_fs2.default.existsSync(realAbs)) continue;
1460
+ const rel = import_node_path3.default.relative(outDir, realAbs).split(import_node_path3.default.sep).join("/");
1461
+ const importPath = realAbs.endsWith(".vue") ? sourceImportPath(rel) : stripTsExtension(sourceImportPath(rel));
1174
1462
  const moduleSpecifier = `${remote.key}/${expose.name.replace(/^\.\//, "")}`;
1463
+ const moduleLiteral = JSON.stringify(moduleSpecifier);
1464
+ const importLiteral = JSON.stringify(importPath);
1175
1465
  lines.push("");
1176
1466
  if (mode === "shim") {
1177
- lines.push(buildShimModule(abs, moduleSpecifier));
1467
+ lines.push(buildShimModule(realAbs, moduleSpecifier));
1468
+ accepted++;
1178
1469
  continue;
1179
1470
  }
1180
- if (abs.endsWith(".vue")) {
1181
- lines.push(`declare module '${moduleSpecifier}' {`);
1471
+ if (realAbs.endsWith(".vue")) {
1472
+ lines.push(`declare module ${moduleLiteral} {`);
1182
1473
  lines.push(` import type { DefineComponent } from 'vue'`);
1183
1474
  lines.push(` const component: DefineComponent<Record<string, unknown>, Record<string, unknown>, unknown>`);
1184
1475
  lines.push(` export default component`);
1185
- lines.push(` export * from '${importPath}'`);
1476
+ lines.push(` export * from ${importLiteral}`);
1186
1477
  lines.push(`}`);
1187
1478
  } else {
1188
- lines.push(`declare module '${moduleSpecifier}' {`);
1189
- const names = extractTsExportNames(import_node_fs2.default.readFileSync(abs, "utf8"));
1479
+ lines.push(`declare module ${moduleLiteral} {`);
1480
+ const names = extractTsExportNames(import_node_fs2.default.readFileSync(realAbs, "utf8"));
1190
1481
  if (names.length > 0) {
1191
- lines.push(` export { ${names.join(", ")} } from '${importPath}'`);
1482
+ lines.push(` export { ${names.join(", ")} } from ${importLiteral}`);
1192
1483
  } else {
1193
- lines.push(` export * from '${importPath}'`);
1484
+ lines.push(` export * from ${importLiteral}`);
1194
1485
  }
1195
- if (sourceHasDefaultExport(abs)) lines.push(` export { default } from '${importPath}'`);
1486
+ if (sourceHasDefaultExport(realAbs)) lines.push(` export { default } from ${importLiteral}`);
1196
1487
  lines.push(`}`);
1197
1488
  }
1489
+ accepted++;
1198
1490
  }
1199
- import_node_fs2.default.writeFileSync(import_node_path3.default.join(outDir, `${remote.key}.d.ts`), `${lines.join("\n")}
1491
+ if (accepted > 0) {
1492
+ import_node_fs2.default.writeFileSync(import_node_path3.default.join(outDir, `${remote.key}.d.ts`), `${lines.join("\n")}
1200
1493
  `);
1494
+ }
1201
1495
  console.log(
1202
- `[fulgurjs] dts: generated ${dir}/${remote.key}.d.ts (${manifest.exposes?.length ?? 0} exposes, mode=${mode}). \u786E\u4FDD tsconfig include \u5305\u542B "${dir}" \u4EE5\u83B7\u5F97\u7C7B\u578B\u8865\u5168\u3002`
1496
+ `[fulgurjs] dts: generated ${dir}/${remote.key}.d.ts (${accepted}/${manifest.exposes?.length ?? 0} exposes, mode=${mode}). \u786E\u4FDD tsconfig include \u5305\u542B "${dir}" \u4EE5\u83B7\u5F97\u7C7B\u578B\u8865\u5168\u3002`
1203
1497
  );
1204
1498
  }
1205
1499
  }
1206
1500
 
1207
1501
  // src/diagnostics.ts
1502
+ var import_node_path4 = __toESM(require("path"), 1);
1208
1503
  function formatFulgurjsDiagnostic(input) {
1209
1504
  const ctx = input.details ? `
1210
1505
  \u4E0A\u4E0B\u6587\uFF1A${JSON.stringify(input.details)}` : "";
@@ -1227,6 +1522,33 @@ async function isPortReachable(host, port, timeoutMs = 800) {
1227
1522
  socket.connect(port, host);
1228
1523
  });
1229
1524
  }
1525
+ var __debugEnvCache = "";
1526
+ var __debugEnabledCache = {};
1527
+ function debugEnabled(category) {
1528
+ const spec = process.env.FULGURJS_DEBUG ?? process.env.DEBUG ?? "";
1529
+ if (spec !== __debugEnvCache) {
1530
+ __debugEnvCache = spec;
1531
+ __debugEnabledCache = {};
1532
+ }
1533
+ if (category in __debugEnabledCache) return __debugEnabledCache[category];
1534
+ const patterns = spec.split(",").map((x) => x.trim()).filter(Boolean);
1535
+ const enabled = patterns.some((p) => p === "fulgurjs" || p === "fulgurjs:*" || p === `fulgurjs:${category}`);
1536
+ __debugEnabledCache[category] = enabled;
1537
+ return enabled;
1538
+ }
1539
+ function debugLog(category, data) {
1540
+ if (!debugEnabled(category)) return;
1541
+ console.error(`[fulgurjs:debug:${category}] ${JSON.stringify(data)}`);
1542
+ }
1543
+ function redactModulePath(id, root) {
1544
+ const clean = id.split("?")[0];
1545
+ try {
1546
+ const rel = import_node_path4.default.relative(root, clean);
1547
+ if (rel && !rel.startsWith("..") && !import_node_path4.default.isAbsolute(rel)) return rel;
1548
+ } catch {
1549
+ }
1550
+ return clean.split("/").pop() ?? clean;
1551
+ }
1230
1552
 
1231
1553
  // src/remote-schema.ts
1232
1554
  function manifestUrlOf(devEntry) {
@@ -1253,8 +1575,35 @@ async function probeRemotesAndBuildSchema(options) {
1253
1575
  try {
1254
1576
  const res = await fetch(u, { signal: AbortSignal.timeout(3e3) });
1255
1577
  if (!res.ok) throw new Error(`HTTP ${res.status}`);
1256
- const manifest = await res.json();
1257
- const exposes = (manifest?.exposes ?? []).map((e) => e.name);
1578
+ const parsed = parseManifest(await res.json());
1579
+ if (parsed.unsupportedVersion) {
1580
+ schema[remote.key] = { exposes: [], exists: false };
1581
+ console.warn(
1582
+ formatFulgurjsDiagnostic({
1583
+ code: "DEV-002",
1584
+ symptom: `remote "${remote.key}" \u7684 manifest schemaVersion=${parsed.unsupportedVersion} \u4E0D\u53D7\u652F\u6301\uFF08\u672C\u673A\u652F\u6301 1\uFF09`,
1585
+ cause: "\u5BBF\u4E3B\u4E0E\u8FDC\u7A0B\u7684 @fulgurjs/federation \u5927\u7248\u672C\u4E0D\u4E00\u81F4",
1586
+ fix: "\u5BF9\u9F50\u5BBF\u4E3B\u4E0E\u8FDC\u7A0B\u7684 @fulgurjs/federation \u7248\u672C\u540E\u91CD\u542F dev server",
1587
+ details: { remote: remote.key, url: u.href }
1588
+ })
1589
+ );
1590
+ continue;
1591
+ }
1592
+ if (parsed.issues.length > 0 || !parsed.manifest) {
1593
+ schema[remote.key] = { exposes: [], exists: false };
1594
+ console.warn(
1595
+ formatFulgurjsDiagnostic({
1596
+ code: "DEV-002",
1597
+ symptom: `remote "${remote.key}" \u7684 dev manifest \u5951\u7EA6\u6821\u9A8C\u5931\u8D25\uFF08${u.href}\uFF09`,
1598
+ cause: parsed.issues.map((x) => `${x.field}: ${x.message}`).join("\uFF1B"),
1599
+ fix: "\u6838\u5BF9 remote \u7684 federation \u914D\u7F6E exposes\uFF0C\u5E76\u786E\u8BA4 @fulgurjs/federation \u7248\u672C\u4E0E\u5BBF\u4E3B\u4E00\u81F4",
1600
+ details: { remote: remote.key, url: u.href, issues: parsed.issues.slice(0, 5) }
1601
+ })
1602
+ );
1603
+ continue;
1604
+ }
1605
+ const manifest = parsed.manifest;
1606
+ const exposes = [...normalizeExposes(manifest).keys()];
1258
1607
  schema[remote.key] = { exposes, exists: true };
1259
1608
  if (exposes.length === 0) {
1260
1609
  console.warn(
@@ -1263,11 +1612,11 @@ async function probeRemotesAndBuildSchema(options) {
1263
1612
  symptom: `remote "${remote.key}" \u7684 dev manifest \u53EF\u8FBE\u4F46 exposes \u4E3A\u7A7A\uFF08${u.href}\uFF09`,
1264
1613
  cause: "remote \u4FA7 federation({ exposes }) \u4E3A\u7A7A\uFF0C\u6216\u5176\u63D2\u4EF6\u7248\u672C\u8FC7\u65E7\u5BFC\u81F4 manifest \u7F3A\u5B57\u6BB5",
1265
1614
  fix: "\u6838\u5BF9 remote \u7684 federation \u914D\u7F6E exposes\uFF0C\u5E76\u786E\u8BA4 @fulgurjs/federation \u7248\u672C\u4E0E\u5BBF\u4E3B\u4E00\u81F4",
1266
- details: { remote: remote.key, url: u.href, pluginVersion: manifest?.buildInfo?.version }
1615
+ details: { remote: remote.key, url: u.href, pluginVersion: manifest.version }
1267
1616
  })
1268
1617
  );
1269
1618
  }
1270
- const remoteVersion = manifest?.buildInfo?.version;
1619
+ const remoteVersion = manifest.version;
1271
1620
  if (remoteVersion && remoteVersion !== options.pluginVersion) {
1272
1621
  console.warn(
1273
1622
  formatFulgurjsDiagnostic({
@@ -1303,17 +1652,17 @@ function genEmptyRemoteSchemaModule() {
1303
1652
 
1304
1653
  // src/vite-cache.ts
1305
1654
  var import_node_fs3 = __toESM(require("fs"), 1);
1306
- var import_node_path4 = __toESM(require("path"), 1);
1655
+ var import_node_path5 = __toESM(require("path"), 1);
1307
1656
  function syncViteCacheMarker(root, pluginVersion, log) {
1308
- const viteDir = import_node_path4.default.join(root, "node_modules", ".vite");
1309
- const marker = import_node_path4.default.join(viteDir, "fulgurjs-version.txt");
1657
+ const viteDir = import_node_path5.default.join(root, "node_modules", ".vite");
1658
+ const marker = import_node_path5.default.join(viteDir, "fulgurjs-version.txt");
1310
1659
  try {
1311
1660
  if (import_node_fs3.default.existsSync(viteDir)) {
1312
1661
  const prev = import_node_fs3.default.existsSync(marker) ? import_node_fs3.default.readFileSync(marker, "utf8").trim() : "";
1313
1662
  if (prev === pluginVersion) return;
1314
1663
  import_node_fs3.default.rmSync(viteDir, { recursive: true, force: true });
1315
1664
  log(
1316
- `[fulgurjs] \u63D2\u4EF6\u7248\u672C\u53D8\u5316\uFF08${prev || "\u65E0\u8BB0\u5F55"} \u2192 ${pluginVersion}\uFF09\uFF0C\u5DF2\u81EA\u52A8\u6E05\u9664 ${import_node_path4.default.relative(root, viteDir)} \u9884\u6784\u5EFA\u7F13\u5B58\uFF08\u907F\u514D\u65E7\u95E8\u9762\u7B7E\u540D 404 / DEV-009\uFF09\u3002\u672C\u6B21\u542F\u52A8\u5C06\u91CD\u65B0\u9884\u6784\u5EFA\uFF0C\u9996\u8F6E 30~60s \u5C5E\u6682\u6001\uFF08DEV-010\uFF09\u3002`
1665
+ `[fulgurjs] \u63D2\u4EF6\u7248\u672C\u53D8\u5316\uFF08${prev || "\u65E0\u8BB0\u5F55"} \u2192 ${pluginVersion}\uFF09\uFF0C\u5DF2\u81EA\u52A8\u6E05\u9664 ${import_node_path5.default.relative(root, viteDir)} \u9884\u6784\u5EFA\u7F13\u5B58\uFF08\u907F\u514D\u65E7\u95E8\u9762\u7B7E\u540D 404 / DEV-009\uFF09\u3002\u672C\u6B21\u542F\u52A8\u5C06\u91CD\u65B0\u9884\u6784\u5EFA\uFF0C\u9996\u8F6E 30~60s \u5C5E\u6682\u6001\uFF08DEV-010\uFF09\u3002`
1317
1666
  );
1318
1667
  }
1319
1668
  import_node_fs3.default.mkdirSync(viteDir, { recursive: true });
@@ -1326,7 +1675,7 @@ function syncViteCacheMarker(root, pluginVersion, log) {
1326
1675
  }
1327
1676
 
1328
1677
  // src/runtime-code.gen.ts
1329
- var runtime_code_gen_default = 'var re=/^v?(\\d+)(?:\\.(\\d+))?(?:\\.(\\d+))?(?:-((?:[0-9A-Za-z-]+)(?:\\.[0-9A-Za-z-]+)*))?(?:\\+[0-9A-Za-z.-]+)?$/;function P(t){let n=re.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 te(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 m=t[r],d=n[r];if(m===void 0)return-1;if(d===void 0)return 1;let S=/^\\d+$/.test(m),w=/^\\d+$/.test(d);if(S&&w){let L=Number(m)-Number(d);if(L!==0)return L}else{if(S!==w)return S?-1:1;if(m!==d)return m<d?-1:1}}return 0}function T(t,n){let o=P(t),r=P(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:te(o.pre,r.pre)}var ne=/^[a-z]+[+:-]/i;function N(t,n){if(n===!1||n==null||n==="")return!0;let o=String(n).trim();return!o||o==="*"||o==="latest"||ne.test(o)?!0:o.split("||").some(r=>oe(t,r.trim()))}function oe(t,n){if(!n||n==="*")return!P(t)?.pre.length;let o=n.split(/\\s+-\\s+/);if(o.length===2){let d=o[0].trim(),S=o[1].trim();return!(!N(t,`>=${d}`)||!N(t,`<=${S}`))}let r=P(t);if(!r)return!1;let m=ie(n);if(m===null)return!0;for(let d of m)if(!ue(r,t,d))return!1;return!(r.pre.length>0&&!m.some(d=>d.ver.pre.length>0)&&!m.some(S=>S.ver.major===r.major&&S.ver.minor===r.minor&&S.ver.patch===r.patch))}function ie(t){let n=[],o=t.trim().split(/\\s+/).filter(Boolean);if(o.length===0)return null;for(let r of o){let m=/^(>=|<=|>|<|=|\\^|~)?(.*)$/.exec(r);if(!m)return null;let d=m[1],S=m[2],w=se(d,S);if(w===null)return null;n.push(...w)}return n}function se(t,n){let o=ce(n);if(!o)return null;let{ver:r,partial:m}=o;switch(t){case"^":{let d=ae(r);return d?[{op:">=",ver:r},{op:"<",ver:d}]:null}case"~":{let d=m>=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:d}]}case">=":return[{op:">=",ver:r}];case">":return m===1?[{op:">=",ver:{major:r.major+1,minor:0,patch:0,pre:[]}}]:m===2?[{op:">=",ver:{major:r.major,minor:r.minor+1,patch:0,pre:[]}}]:[{op:">",ver:r}];case"<":return m===1?[{op:"<",ver:{major:r.major,minor:0,patch:0,pre:[]}}]:m===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 m===1?[{op:">=",ver:r},{op:"<",ver:{major:r.major+1,minor:0,patch:0,pre:[]}}]:m===2?[{op:">=",ver:r},{op:"<",ver:{major:r.major,minor:r.minor+1,patch:0,pre:[]}}]:[{op:"=",ver:r}];default:return null}}function ae(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 ce(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=[],m=0;for(let w of o.slice(0,3))if(/^\\d+$/.test(w))r.push(Number(w)),m++;else{if(w==="x"||w==="X"||w==="*")break;break}let d=n.split("-"),S=d.length>1?d.slice(1).join("-").split("+")[0].split("."):[];return m===0&&S.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:S},partial:m}}function le(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 ue(t,n,o){let r=`${t.major}.${t.minor}.${t.patch}`+(t.pre.length?`-${t.pre.join(".")}`:"");if(o.upper)return!(!(T(r,`${o.ver.major}.${o.ver.minor}.${o.ver.patch}`+(o.ver.pre.length?`-${o.ver.pre.join(".")}`:""))>=0)||!(T(r,`${o.upper.major}.${o.upper.minor}.${o.upper.patch}`)<0));let m=T(r,`${o.ver.major}.${o.ver.minor}.${o.ver.patch}`+(o.ver.pre.length?`-${o.ver.pre.join(".")}`:"")),d=le(m,o.op);return o.ver.pre.length>0&&t.pre.length===0&&(o.op===">"||o.op==="<")?!1:d}var R=class extends Error{code;details;constructor(n,o,r){super(`[fulgurjs:${n}] ${o}`),this.name="FgError",this.code=n,this.details=r}},b={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 V="2.0.3";var H=15e3,K=2,me=5,fe=3e4;function pe(){let t={},n=new Map,o=[],r=new Map,m=new Map,d=new WeakMap,S=new WeakMap,w={},L=()=>{for(let e of o)try{e.init?.(w)}catch(i){console.warn("[fulgurjs] runtimePlugin init failed:",e.name,i)}},I=e=>t[e]??={};function $(e){try{w.onRemoteError?.(e)}catch{}typeof window<"u"&&window.dispatchEvent(new CustomEvent("fulgurjs:error",{detail:e}))}function z(e="default"){return I(e),t}function W(e,i,s,l,h={}){let c=I(e||"default"),f=c[i]??={};f[s]||(f[s]={version:s,get:l,from:h.from??"unknown",eager:!!h.eager,loaded:!!h.loaded})}function A(e){for(let i of e){let s=n.get(i.name);n.set(i.name,{timeout:H,retries:K,...s,...i,state:s?.state??"idle",breakerState:s?.breakerState??{fails:0,openUntil:0},debug:s?.debug??{entry:i.entry,status:"idle"}})}}function G(e){A([e])}function J(e){o.push(...e),L()}async function B(e,i={}){let s=i.shareScope||"default",l=i.shareKey||e,c=I(s)[l]||{},f=Object.keys(c),y=i.requiredVersion,g=f.filter(a=>y===void 0||y===!1||N(a,y)),u;if(i.singleton&&f.length>0){let a=f.filter(p=>c[p].loaded);if(u=[...a.length?a:f].sort(T).pop(),f.length>1||!g.includes(u)){let p=c[u],j=`singleton skew "${l}": req "${y??"any"}" use ${u} from ${p.from}`;if(i.strictVersion){let _=new R(b.SHARE_STRICT_VERSION,j,{shareKey:l,requiredVersion:y});throw $({remote:p.from,error:_}),_}console.warn(`[fulgurjs:MFU-010] ${j}`)}}else if(u=[...g].sort(T).pop(),!u){if(i.strictVersion){let p=new R(b.SHARE_STRICT_VERSION,`no satisfying version for "${l}" (required "${y}") in share scope "${s}"`);throw $({remote:l,error:p}),p}if(i.fallback)return i.fallback();let a=new R(b.SHARE_NOT_AVAILABLE,`shared "${l}" (${y??"any"}) unavailable in scope "${s}" (no local fallback)`,{shareKey:l,requiredVersion:y});throw $({remote:l,error:a}),a}let E=c[u];if(w.resolveShare){let a=await w.resolveShare({shareKey:l,shareScope:s,requiredVersion:y,picked:E,available:Object.values(c)});a&&(E=a)}return E.loaded=!0,E.get()}function X(e,i,s){return new Promise((l,h)=>{let c=setTimeout(()=>h(new Error(`timeout after ${i}ms: ${s}`)),i);e.then(f=>{clearTimeout(c),l(f)},f=>{clearTimeout(c),h(f)})})}let Y=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 s=`remoteEntry self-reported name "${e.name}" mismatches configured name "${i.name}"`;if(i.promise)console.warn(`[fulgurjs] ${s} (promise-based remote, continuing)`);else throw Object.assign(new Error(s),{code:b.REMOTE_NAME_MISMATCH})}}async function x(e,i){return X(import(e),i.timeout??H,`load remoteEntry ${e}`)}async function C(e,i){let s=e.shareScope||"default";if(e.container){let c=S.get(e.container);if(c&&c!==s)throw new R(b.CONTAINER_REINIT_CONFLICT,`container "${e.name}" already initialized with share scope "${c}", cannot re-init with "${s}"`);return e.container}if(e.containerPromise)return e.containerPromise;let l=e.breakerState;if(l.openUntil>Date.now()){let c=new R(b.REMOTE_LOAD_FAILED,`circuit breaker open for remote "${e.name}" until ${new Date(l.openUntil).toISOString()}`,{remote:e.name});throw $({remote:e.name,error:c}),c}e.state="loading",e.debug.status="loading";let h=(async()=>{let c=[];if(e.promise)c.push(async()=>{let a=await e.promise(),p=typeof a=="string"?await x(a,e):a;return k(p,e),p});else for(let a of[e.entry,...e.fallback??[]])c.push(async()=>{let p=await x(a,e);return k(p,e),p});let f,y,g=!1,u=i?.retries??e.retries??K;for(let a of c){for(let p=0;p<=u;p++){let j=performance.now();try{f=await a(),e.lastLoadMs=Math.round(performance.now()-j),e.debug.lastLoadMs=e.lastLoadMs,g=!0;break}catch(_){if(y=_,_?.code)throw _;p<u&&await Y(200*2**p)}}if(g)break}if(!g||!f){let a=[];throw/^https?:\\/\\//.test(e.entry)&&typeof location<"u"?(a.push(`1. is the remote dev server running? try opening ${e.entry} in the browser \\u2014 it must return JS, not HTML/an error`),a.push("2. is the URL correct in federation({ remotes })? dev and prod entries can differ"),a.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)")):(a.push(`1. is the remote deployed and reachable? try opening ${e.entry} in the browser \\u2014 it must return JS`),a.push("2. NGINX/CDN routing: the entry path must serve the remoteEntry JS file (check try_files / fallback rules)")),new R(b.REMOTE_LOAD_FAILED,`failed to load remote "${e.name}" from ${e.entry}: ${String(y?.message??y)}\n`+a.join(`\n`),{remote:e.name})}k(f,e);let E=S.get(f);if(E&&E!==s)throw new R(b.CONTAINER_REINIT_CONFLICT,`container "${e.name}" already initialized with share scope "${E}", cannot re-init with "${s}"`);return typeof f.init=="function"&&await f.init(t),S.set(f,s),e.container=f,e.state="loaded",e.debug.status="loaded",l.fails=0,f})();e.containerPromise=h;try{return await h}catch(c){if(e.containerPromise=void 0,e.state="failed",e.debug.status="failed",e.debug.error=String(c?.message??c),l.fails+=1,l.fails>=me&&(l.openUntil=Date.now()+fe,l.fails=0),c instanceof R)throw $({remote:e.name,error:c}),c;if(c?.code)throw $({remote:e.name,error:c}),c;let f=new R(b.REMOTE_LOAD_FAILED,String(c?.message??c),{remote:e.name});throw $({remote:e.name,error:f}),f}}function U(e){let i=e.indexOf("/");return i===-1?{remote:e,module:""}:{remote:e.slice(0,i),module:F(e.slice(i+1))}}function F(e){return e?e.startsWith(".")?e:`./${e}`:""}async function Z(e,i){let{remote:s,module:l}=U(e);w.beforeLoadRemote?.({remote:s,module:l});let h=n.get(s);if(!h)throw new R(b.REMOTE_UNKNOWN,`unknown remote "${s}". Register it via federation({ remotes }) or registerRemote().`,{remote:s});let c;try{let g=l&&h.manifestUrl?D(e):Promise.resolve();[c]=await Promise.all([C(h,{retries:i?.retries}),g])}catch(g){if(i?.fallbackModule)return console.error(`[fulgurjs] loadRemote("${e}") failed; returning fallbackModule (\\u663E\\u5F0F\\u964D\\u7EA7\\uFF0C\\u9519\\u8BEF\\u5DF2\\u900F\\u51FA)`,g),$({remote:s,error:g}),await i.fallbackModule();throw g}if(!l)return c;let f=`${s}@${h.shareScope||"default"}#${l}`;r.has(f)||r.set(f,c.get(l).catch(g=>{throw r.delete(f),g instanceof R||g?.code?g:new R(b.REMOTE_LOAD_FAILED,`failed to load module "${l}" from remote "${s}": ${String(g?.message??g)}`,{remote:s,module:l})}));let y;try{y=await r.get(f)}catch(g){if(i?.fallbackModule)return console.error(`[fulgurjs] loadRemote("${e}") failed; returning fallbackModule (\\u663E\\u5F0F\\u964D\\u7EA7\\uFF0C\\u9519\\u8BEF\\u5DF2\\u900F\\u51FA)`,g),$({remote:s,error:g}),await i.fallbackModule();throw g}if(w.afterLoadRemote?.({remote:s,module:l,module_ns:y}),y&&typeof y=="object"&&Object.keys(y).length===0){let g=new R(b.EMPTY_EXPORTS,`no exports: ${l} @ ${s}`,{remote:s,module:l});$({remote:s,error:g}),console.error(`[fulgurjs:MFU-009] ${g.message}`)}return y}function Q(e){let i=n.get(e);if(!i)throw new R(b.REMOTE_UNKNOWN,`unknown remote "${e}"`,{remote:e});return C(i)}async function D(e,i={}){let{remote:s,module:l}=U(e),h=n.get(s);if(!h)throw new R(b.REMOTE_UNKNOWN,`unknown remote "${s}"`,{remote:s});let c=i.mode??"preload",f=(u,E)=>{if(u.sheet)return Promise.resolve();let a=d.get(u);if(a)return a;let p=new Promise(j=>{let _=()=>{u.removeEventListener("load",_),u.removeEventListener("error",v),j()},v=()=>{$({remote:s,error:new R(b.PRELOAD_FAILED,`failed to load remote stylesheet ${E}`,{remote:s})}),_()};u.addEventListener("load",_,{once:!0}),u.addEventListener("error",v,{once:!0}),u.sheet&&_()});return d.set(u,p),p},y=(u,E)=>{if(typeof document>"u")return Promise.resolve();let a=document.querySelector(`link[href="${u}"]`);if(a)return E==="style"&&c==="preload"?d.get(a)??Promise.resolve():Promise.resolve();let p=document.createElement("link");p.rel=E==="style"?"stylesheet":"modulepreload",p.href=u,c==="prefetch"&&(p.fetchPriority="low");let j=E==="style"?f(p,u):Promise.resolve();return document.head.appendChild(p),E==="style"&&c==="preload"?j:Promise.resolve()},g=u=>{let E=typeof document<"u"?document.baseURI:void 0,a=new URL(h.entry,E||"http://fulgurjs.invalid/");return new URL(u,a).href};try{if(h.manifestUrl){let u=m.get(h.manifestUrl);u||(u=fetch(h.manifestUrl,{cache:"no-cache"}).then(a=>a.ok?a.json():void 0),m.set(h.manifestUrl,u),u.then(a=>{a||m.delete(h.manifestUrl)},()=>m.delete(h.manifestUrl)));let E=await u;if(E){await y(h.entry,"modulepreload");let a=E.exposes,p=Array.isArray(a)?a.filter(v=>v&&typeof v=="object").map(v=>[String(v.name??""),v]):a&&typeof a=="object"?Object.entries(a):[],j=l?p.filter(([v,O])=>F(String(O?.name??v))===l):p,_=[];for(let[,v]of j)if(typeof v?.file=="string"&&await y(g(v.file),"modulepreload"),Array.isArray(v?.css))for(let O of v.css){if(typeof O!="string")continue;let ee=y(g(O),"style");c==="preload"&&_.push(ee)}await Promise.all(_);return}}await y(h.entry,"modulepreload")}catch(u){$({remote:s,error:new R(b.PRELOAD_FAILED,String(u?.message??u),{remote:s})})}}return typeof window>"u"||(window.__FULGURJS_SCOPE__=t,window.__FULGURJS_INFO__={get remotes(){let e={};for(let[i,s]of n)e[i]={...s.debug,entry:s.entry};return e},errors:[]}),{shareScopeMap:t,initSharing:z,registerShare:W,registerRemotes:A,registerRemote:G,registerPlugins:J,loadShare:B,loadRemote:Z,getContainer:Q,preloadRemote:D,parseSpec:U}}var q=globalThis,M=q.__FULGURJS_RUNTIME__??pe();q.__FULGURJS_RUNTIME__=M;try{Object.freeze(M)}catch{}var we=V;function be(){return M}var ve=M.initSharing,_e=M.registerShare,Me=M.registerRemotes,$e=M.registerRemote,je=M.registerPlugins,Te=M.loadShare,Le=M.loadRemote,Oe=M.getContainer,Pe=M.preloadRemote,Ne=M.shareScopeMap;function Ie(t){if(t&&typeof t=="object"&&"default"in t){let n=t.default;return n!==void 0?n:t}return t}var ke=M;export{ke as default,Oe as getContainer,be as getRuntime,ve as initSharing,Le as loadRemote,Te as loadShare,Pe as preloadRemote,je as registerPlugins,$e as registerRemote,Me as registerRemotes,_e as registerShare,M as runtime,Ne as shareScopeMap,Ie as unwrapDefault,we as version};\n';
1678
+ var runtime_code_gen_default = 'var oe=/^v?(\\d+)(?:\\.(\\d+))?(?:\\.(\\d+))?(?:-((?:[0-9A-Za-z-]+)(?:\\.[0-9A-Za-z-]+)*))?(?:\\+[0-9A-Za-z.-]+)?$/;function I(o){let i=oe.exec(String(o).trim());return i?{major:Number(i[1]),minor:Number(i[2]??0),patch:Number(i[3]??0),pre:i[4]?i[4].split("."):[]}:null}function ie(o,i){if(o.length===0&&i.length===0)return 0;if(o.length===0)return 1;if(i.length===0)return-1;let s=Math.max(o.length,i.length);for(let n=0;n<s;n++){let f=o[n],y=i[n];if(f===void 0)return-1;if(y===void 0)return 1;let R=/^\\d+$/.test(f),w=/^\\d+$/.test(y);if(R&&w){let T=Number(f)-Number(y);if(T!==0)return T}else{if(R!==w)return R?-1:1;if(f!==y)return f<y?-1:1}}return 0}function j(o,i){let s=I(o),n=I(i);return!s||!n?o<i?-1:o>i?1:0:s.major!==n.major?s.major-n.major:s.minor!==n.minor?s.minor-n.minor:s.patch!==n.patch?s.patch-n.patch:ie(s.pre,n.pre)}var se=/^[a-z]+[+:-]/i;function P(o,i){if(i===!1||i==null||i==="")return!0;let s=String(i).trim();return!s||s==="*"||s==="latest"||se.test(s)?!0:s.split("||").some(n=>ae(o,n.trim()))}function ae(o,i){if(!i||i==="*")return!I(o)?.pre.length;let s=i.split(/\\s+-\\s+/);if(s.length===2){let y=s[0].trim(),R=s[1].trim();return!(!P(o,`>=${y}`)||!P(o,`<=${R}`))}let n=I(o);if(!n)return!1;let f=ce(i);if(f===null)return!0;for(let y of f)if(!pe(n,o,y))return!1;return!(n.pre.length>0&&!f.some(y=>y.ver.pre.length>0)&&!f.some(R=>R.ver.major===n.major&&R.ver.minor===n.minor&&R.ver.patch===n.patch))}function ce(o){let i=[],s=o.trim().split(/\\s+/).filter(Boolean);if(s.length===0)return null;for(let n of s){let f=/^(>=|<=|>|<|=|\\^|~)?(.*)$/.exec(n);if(!f)return null;let y=f[1],R=f[2],w=le(y,R);if(w===null)return null;i.push(...w)}return i}function le(o,i){let s=me(i);if(!s)return null;let{ver:n,partial:f}=s;switch(o){case"^":{let y=ue(n);return y?[{op:">=",ver:n},{op:"<",ver:y}]:null}case"~":{let y=f>=2?{major:n.major,minor:n.minor+1,patch:0,pre:[]}:{major:n.major+1,minor:0,patch:0,pre:[]};return[{op:">=",ver:n},{op:"<",ver:y}]}case">=":return[{op:">=",ver:n}];case">":return f===1?[{op:">=",ver:{major:n.major+1,minor:0,patch:0,pre:[]}}]:f===2?[{op:">=",ver:{major:n.major,minor:n.minor+1,patch:0,pre:[]}}]:[{op:">",ver:n}];case"<":return f===1?[{op:"<",ver:{major:n.major,minor:0,patch:0,pre:[]}}]:f===2?[{op:"<",ver:{major:n.major,minor:n.minor,patch:0,pre:[]}}]:[{op:"<",ver:n}];case"<=":return[{op:"<=",ver:n}];case"=":case void 0:return f===1?[{op:">=",ver:n},{op:"<",ver:{major:n.major+1,minor:0,patch:0,pre:[]}}]:f===2?[{op:">=",ver:n},{op:"<",ver:{major:n.major,minor:n.minor+1,patch:0,pre:[]}}]:[{op:"=",ver:n}];default:return null}}function ue(o){return o.major>0?{major:o.major+1,minor:0,patch:0,pre:[]}:o.minor>0?{major:0,minor:o.minor+1,patch:0,pre:[]}:{major:0,minor:0,patch:o.patch+1,pre:[]}}function me(o){let i=o.replace(/^v/,"").trim();if(!i||i==="*"||i==="x"||i==="X")return{ver:{major:0,minor:0,patch:0,pre:[]},partial:0};let s=i.split("."),n=[],f=0;for(let w of s.slice(0,3))if(/^\\d+$/.test(w))n.push(Number(w)),f++;else{if(w==="x"||w==="X"||w==="*")break;break}let y=i.split("-"),R=y.length>1?y.slice(1).join("-").split("+")[0].split("."):[];return f===0&&R.length===0?{ver:{major:0,minor:0,patch:0,pre:[]},partial:0}:{ver:{major:n[0]??0,minor:n[1]??0,patch:n[2]??0,pre:R},partial:f}}function fe(o,i){switch(i){case">=":return o>=0;case">":return o>0;case"<":return o<0;case"<=":return o<=0;case"=":return o===0}}function pe(o,i,s){let n=`${o.major}.${o.minor}.${o.patch}`+(o.pre.length?`-${o.pre.join(".")}`:"");if(s.upper)return!(!(j(n,`${s.ver.major}.${s.ver.minor}.${s.ver.patch}`+(s.ver.pre.length?`-${s.ver.pre.join(".")}`:""))>=0)||!(j(n,`${s.upper.major}.${s.upper.minor}.${s.upper.patch}`)<0));let f=j(n,`${s.ver.major}.${s.ver.minor}.${s.ver.patch}`+(s.ver.pre.length?`-${s.ver.pre.join(".")}`:"")),y=fe(f,s.op);return s.ver.pre.length>0&&o.pre.length===0&&(s.op===">"||s.op==="<")?!1:y}var b=class extends Error{code;details;constructor(i,s,n){super(`[fulgurjs:${i}] ${s}`),this.name="FgError",this.code=i,this.details=n}},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 q="2.1.0";var x=15e3,z=2,de=5,ge=3e4,he=4e3,ye=.2;function Ee(){let o=Object.create(null),i=new Map,s=[],n=new Map,f=new Map,y=new WeakMap,R=new WeakMap,w={},T=()=>{for(let e of s)try{e.init?.(w)}catch(t){console.warn("[fulgurjs] runtimePlugin init failed:",e.name,t)}},N=e=>o[e]??=Object.create(null);function $(e){try{w.onRemoteError?.(e)}catch{}typeof window<"u"&&window.dispatchEvent(new CustomEvent("fulgurjs:error",{detail:e}))}function B(e="default"){return N(e),o}function J(e,t,r,l,h={}){let a=N(e||"default"),p=Object.hasOwn(a,t)?a[t]:void 0,d=p&&typeof p=="object"?p:void 0;d||(d=Object.create(null),a[t]=d),!(Object.hasOwn(d,r)&&d[r])&&(d[r]={version:r,get:l,from:h.from??"unknown",eager:!!h.eager,loaded:!!h.loaded})}function G(e){let t=(r,l,h)=>{if(r===void 0)return;if(!(typeof r=="number"&&(h?Number.isInteger(r)&&r>=0&&r<=10:Number.isFinite(r)&&r>0)))throw new Error(`[fulgurjs] registerRemote("${e.name}"): ${l} must be a ${h?"integer 0..10":"finite positive number"}, got ${String(r)}`)};t(e.timeout,"timeout"),t(e.retries,"retries",!0),e.breaker&&(t(e.breaker.threshold,"breaker.threshold"),t(e.breaker.resetMs,"breaker.resetMs"))}function F(e){for(let t of e){G(t);let r=i.get(t.name);i.set(t.name,{timeout:x,retries:z,...r,...t,breakerThreshold:t.breaker?.threshold??r?.breakerThreshold??de,breakerResetMs:t.breaker?.resetMs??r?.breakerResetMs??ge,state:r?.state??"idle",breakerState:r?.breakerState??{fails:0,openUntil:0},entryInflight:r?.entryInflight??new Map,debug:r?.debug??{entry:t.entry,status:"idle"}})}}function X(e){F([e])}function Y(e){s.push(...e),T()}async function Z(e,t={}){let r=t.shareScope||"default",l=t.shareKey||e,a=N(r)[l]||{},p=Object.keys(a),d=t.requiredVersion,g=p.filter(c=>d===void 0||d===!1||P(c,d)),m;if(t.singleton&&p.length>0){let c=p.filter(u=>a[u].loaded);if(m=[...c.length?c:p].sort(j).pop(),p.length>1||!g.includes(m)){let u=a[m],k=`singleton skew "${l}": req "${d??"any"}" use ${m} from ${u.from}`;if(t.strictVersion){let v=new b(S.SHARE_STRICT_VERSION,k,{shareKey:l,requiredVersion:d});throw $({remote:u.from,error:v}),v}console.warn(`[fulgurjs:MFU-010] ${k}`)}}else if(m=[...g].sort(j).pop(),!m){if(t.strictVersion){let u=new b(S.SHARE_STRICT_VERSION,`no satisfying version for "${l}" (required "${d}") in share scope "${r}"`);throw $({remote:l,error:u}),u}if(t.fallback)return t.fallback();let c=new b(S.SHARE_NOT_AVAILABLE,`shared "${l}" (${d??"any"}) unavailable in scope "${r}" (no local fallback)`,{shareKey:l,requiredVersion:d});throw $({remote:l,error:c}),c}let E=a[m];if(w.resolveShare){let c=await w.resolveShare({shareKey:l,shareScope:r,requiredVersion:d,picked:E,available:Object.values(a)});c&&(E=c)}return E.loaded=!0,E.get()}function Q(e){try{let t=new URL(e,typeof location<"u"?location.href:"http://f.invalid");return t.protocol+"//"+t.host+t.pathname}catch{return String(e).replace(/[?#].*$/,"")}}function C(e,t,r){return new Promise((l,h)=>{let a=setTimeout(()=>h(new Error(`timeout after ${t}ms: ${r}`)),t);e.then(p=>{clearTimeout(a),l(p)},p=>{clearTimeout(a),h(p)})})}let ee=e=>new Promise(t=>setTimeout(t,e));function A(e,t){if(!e||typeof e.get!="function")throw new Error(`remoteEntry of "${t.name}" does not export a container interface (get/init)`);if(e.name&&t.name&&e.name!==t.name){let r=`remoteEntry self-reported name "${e.name}" mismatches configured name "${t.name}"`;if(t.promise)console.warn(`[fulgurjs] ${r} (promise-based remote, continuing)`);else throw Object.assign(new Error(r),{code:S.REMOTE_NAME_MISMATCH})}}async function D(e,t){let r=t.entryInflight.get(e),l=r??import(e);return r||(t.entryInflight.set(e,l),l.catch(()=>t.entryInflight.delete(e))),C(l,t.timeout??x,`load remoteEntry ${e}`)}async function V(e,t){let r=e.shareScope||"default";if(e.container){let a=R.get(e.container);if(a&&a!==r)throw new b(S.CONTAINER_REINIT_CONFLICT,`container "${e.name}" already initialized with share scope "${a}", cannot re-init with "${r}"`);return e.container}if(e.containerPromise)return e.containerPromise;let l=e.breakerState;if(l.openUntil>Date.now()){let a=new b(S.REMOTE_LOAD_FAILED,`circuit breaker open for remote "${e.name}" until ${new Date(l.openUntil).toISOString()}`,{remote:e.name});throw $({remote:e.name,error:a}),a}e.state="loading",e.debug.status="loading";let h=(async()=>{let a=[];if(e.promise)a.push(async()=>{let c=await C(e.promise(),e.timeout??x,`resolve promise remote "${e.name}"`),u=typeof c=="string"?await D(c,e):c;return A(u,e),u});else for(let c of[e.entry,...e.fallback??[]])a.push(async()=>{let u=await D(c,e);return A(u,e),u});let p,d,g=!1,m=t?.retries??e.retries??z;for(let c of a){for(let u=0;u<=m;u++){let k=performance.now();try{p=await c(),e.lastLoadMs=Math.round(performance.now()-k),e.debug.lastLoadMs=e.lastLoadMs,g=!0;break}catch(v){if(d=v,v?.code)throw v;u<m&&await ee(Math.min(he,200*2**u)*(1-ye*(1-2*Math.random())))}}if(g)break}if(!g||!p){let c=Q(e.entry),u=[];throw/^https?:\\/\\//.test(e.entry)&&typeof location<"u"?(u.push(`1. is the remote dev server running? open ${c} in a browser \\u2014 it must return JS, not HTML`),u.push("2. is the URL correct in federation({ remotes })? dev/prod entries can differ"),u.push("3. CORS: the remote dev server must allow cross-origin requests (check its server.cors)")):(u.push(`1. is the remote deployed? open ${c} in a browser \\u2014 it must return JS`),u.push("2. NGINX/CDN routing: the entry path must serve the remoteEntry JS (check try_files)")),new b(S.REMOTE_LOAD_FAILED,`failed to load remote "${e.name}" from ${c}: ${String(d?.message??d)}\n`+u.join(`\n`),{remote:e.name})}A(p,e);let E=R.get(p);if(E&&E!==r)throw new b(S.CONTAINER_REINIT_CONFLICT,`container "${e.name}" already initialized with share scope "${E}", cannot re-init with "${r}"`);return typeof p.init=="function"&&await p.init(o),R.set(p,r),e.container=p,e.state="loaded",e.debug.status="loaded",l.fails=0,p})();e.containerPromise=h;try{return await h}catch(a){if(e.containerPromise=void 0,e.state="failed",e.debug.status="failed",e.debug.error=String(a?.message??a),l.fails+=1,l.fails>=e.breakerThreshold&&(l.openUntil=Date.now()+e.breakerResetMs,l.fails=0),a instanceof b)throw $({remote:e.name,error:a}),a;if(a?.code)throw $({remote:e.name,error:a}),a;let p=new b(S.REMOTE_LOAD_FAILED,String(a?.message??a),{remote:e.name});throw $({remote:e.name,error:p}),p}}function U(e){let t=e.indexOf("/");return t===-1?{remote:e,module:""}:{remote:e.slice(0,t),module:H(e.slice(t+1))}}function H(e){return e?e.startsWith(".")?e:`./${e}`:""}async function re(e,t){let{remote:r,module:l}=U(e);try{w.beforeLoadRemote?.({remote:r,module:l})}catch(g){console.warn("[fulgurjs] beforeLoadRemote hook error (ignored):",g)}let h=i.get(r);if(!h)throw new b(S.REMOTE_UNKNOWN,`unknown remote "${r}". Register it via federation({ remotes }) or registerRemote().`,{remote:r});let a;try{let g=l&&h.manifestUrl?K(e):Promise.resolve();[a]=await Promise.all([V(h,{retries:t?.retries}),g])}catch(g){if(t?.fallbackModule)return console.error(`[fulgurjs] loadRemote("${e}") failed; returning fallbackModule (\\u663E\\u5F0F\\u964D\\u7EA7\\uFF0C\\u9519\\u8BEF\\u5DF2\\u900F\\u51FA)`,g),$({remote:r,error:g}),await t.fallbackModule();throw g}if(!l)return a;let p=`${r}@${h.shareScope||"default"}#${l}`;n.has(p)||n.set(p,a.get(l).catch(g=>{throw n.delete(p),g instanceof b||g?.code?g:new b(S.REMOTE_LOAD_FAILED,`failed to load module "${l}" from remote "${r}": ${String(g?.message??g)}`,{remote:r,module:l})}));let d;try{d=await n.get(p)}catch(g){if(t?.fallbackModule)return console.error(`[fulgurjs] loadRemote("${e}") failed; returning fallbackModule (\\u663E\\u5F0F\\u964D\\u7EA7\\uFF0C\\u9519\\u8BEF\\u5DF2\\u900F\\u51FA)`,g),$({remote:r,error:g}),await t.fallbackModule();throw g}try{w.afterLoadRemote?.({remote:r,module:l,module_ns:d})}catch(g){console.warn("[fulgurjs] afterLoadRemote hook error (ignored):",g)}if(d&&typeof d=="object"&&Object.keys(d).length===0){let g=new b(S.EMPTY_EXPORTS,`no exports: ${l} @ ${r}`,{remote:r,module:l});$({remote:r,error:g}),console.error(`[fulgurjs:MFU-009] ${g.message}`)}return d}function te(e){let t=i.get(e);if(!t)throw new b(S.REMOTE_UNKNOWN,`unknown remote "${e}"`,{remote:e});return V(t)}async function K(e,t={}){let{remote:r,module:l}=U(e),h=i.get(r);if(!h)throw new b(S.REMOTE_UNKNOWN,`unknown remote "${r}"`,{remote:r});let a=t.mode??"preload",p=(m,E)=>{if(m.sheet)return Promise.resolve();let c=y.get(m);if(c)return c;let u=new Promise(k=>{let v=()=>{m.removeEventListener("load",v),m.removeEventListener("error",O),k()},O=()=>{$({remote:r,error:new b(S.PRELOAD_FAILED,`failed to load remote stylesheet ${E}`,{remote:r})}),v()};m.addEventListener("load",v,{once:!0}),m.addEventListener("error",O,{once:!0}),m.sheet&&v()});return y.set(m,u),u},d=(m,E)=>{if(typeof document>"u")return Promise.resolve();let c=document.querySelector(`link[href="${m}"]`);if(c)return E==="style"&&a==="preload"?y.get(c)??Promise.resolve():Promise.resolve();let u=document.createElement("link");u.rel=E==="style"?"stylesheet":"modulepreload",u.href=m,a==="prefetch"&&(u.fetchPriority="low");let k=E==="style"?p(u,m):Promise.resolve();return document.head.appendChild(u),E==="style"&&a==="preload"?k:Promise.resolve()},g=m=>{let E=typeof document<"u"?document.baseURI:void 0,c=new URL(h.entry,E||"http://fulgurjs.invalid/");return!c.pathname.endsWith("/")&&!c.pathname.split("/").pop().includes(".")&&(c.pathname+="/"),new URL(m,c).href};try{if(h.manifestUrl){let m=f.get(h.manifestUrl);m||(m=fetch(h.manifestUrl,{cache:"no-cache",signal:AbortSignal.timeout(8e3)}).then(c=>c.ok?c.json():void 0),f.set(h.manifestUrl,m),m.then(c=>{c||f.delete(h.manifestUrl)},()=>f.delete(h.manifestUrl)));let E=await m;if(E){let c=E.schemaVersion;if(typeof c=="number"&&(!Number.isInteger(c)||c>1)){$({remote:r,error:new b(S.PRELOAD_FAILED,`unsupported manifest schemaVersion ${String(c)} (expected 1)`,{remote:r})}),await d(h.entry,"modulepreload");return}await d(h.entry,"modulepreload");let u=E.exposes,k=Array.isArray(u)?u.filter(_=>_&&typeof _=="object").map(_=>[String(_.name??""),_]):u&&typeof u=="object"?Object.entries(u):[],v=l?k.filter(([_,L])=>H(String(L?.name??_))===l):k,O=[];for(let[,_]of v)if(typeof _?.file=="string"&&await d(g(_.file),"modulepreload"),Array.isArray(_?.css))for(let L of _.css){if(typeof L!="string")continue;let ne=d(g(L),"style");a==="preload"&&O.push(ne)}await Promise.all(O);return}}await d(h.entry,"modulepreload")}catch(m){$({remote:r,error:new b(S.PRELOAD_FAILED,String(m?.message??m),{remote:r})})}}return typeof window>"u"||(window.__FULGURJS_SCOPE__=o,window.__FULGURJS_INFO__={get remotes(){let e={};for(let[t,r]of i)e[t]={...r.debug,entry:r.entry};return e},errors:[]}),{shareScopeMap:o,initSharing:B,registerShare:J,registerRemotes:F,registerRemote:X,registerPlugins:Y,loadShare:Z,loadRemote:re,getContainer:te,preloadRemote:K,parseSpec:U}}var W=globalThis,M=W.__FULGURJS_RUNTIME__??Ee();W.__FULGURJS_RUNTIME__=M;try{Object.freeze(M)}catch{}var _e=q;function ke(){return M}var je=M.initSharing,Oe=M.registerShare,Te=M.registerRemotes,Le=M.registerRemote,Ie=M.registerPlugins,Pe=M.loadShare,Ne=M.loadRemote,Ae=M.getContainer,Ue=M.preloadRemote,xe=M.parseSpec,Fe=M.shareScopeMap;function Ce(o){if(o&&typeof o=="object"&&"default"in o){let i=o.default;return i!==void 0?i:o}return o}var De=M;export{De as default,Ae as getContainer,ke as getRuntime,je as initSharing,Ne as loadRemote,Pe as loadShare,xe as parseSpec,Ue as preloadRemote,Ie as registerPlugins,Le as registerRemote,Te as registerRemotes,Oe as registerShare,M as runtime,Fe as shareScopeMap,Ce as unwrapDefault,_e as version};\n';
1330
1679
 
1331
1680
  // src/index.ts
1332
1681
  function readRuntimeCode() {
@@ -1343,7 +1692,7 @@ function enumerateCjsExports(packageName, appRoot) {
1343
1692
  if (cached) return cached;
1344
1693
  let names = [];
1345
1694
  try {
1346
- const appRequire = (0, import_node_module2.createRequire)(import_node_path5.default.join(appRoot, "package.json"));
1695
+ const appRequire = (0, import_node_module2.createRequire)(import_node_path6.default.join(appRoot, "package.json"));
1347
1696
  const mod = appRequire(packageName);
1348
1697
  names = Object.keys(mod);
1349
1698
  } catch {
@@ -1403,14 +1752,19 @@ function federation(options) {
1403
1752
  entryInitInjected: /* @__PURE__ */ new Set(),
1404
1753
  manualChunkGroups: /* @__PURE__ */ new Map(),
1405
1754
  sharedClosureRoots: [],
1406
- facadeDynamic: false
1755
+ facadeDynamic: false,
1756
+ transformedModules: /* @__PURE__ */ new Set()
1757
+ };
1758
+ const recordRewritten = (id) => {
1759
+ state.transformedModules.add(id);
1760
+ state.transformedModules.add(id.split("?")[0]);
1407
1761
  };
1408
1762
  const pre = {
1409
1763
  name: "fulgurjs:core",
1410
1764
  enforce: "pre",
1411
1765
  async config(userConfig, env) {
1412
1766
  state.command = env.command;
1413
- const root = import_node_path5.default.resolve(userConfig.root ?? process.cwd());
1767
+ const root = import_node_path6.default.resolve(userConfig.root ?? process.cwd());
1414
1768
  const normalized = normalizeOptions(options, root, env.command);
1415
1769
  state.normalized = normalized;
1416
1770
  const extra = {};
@@ -1455,10 +1809,34 @@ export { default } from ${JSON.stringify(url)};
1455
1809
  }
1456
1810
  if (env.command === "serve") {
1457
1811
  syncViteCacheMarker(root, normalized.pluginVersion, (msg) => console.warn(msg));
1812
+ const corsOption = normalized.devCorsOrigins && normalized.devCorsOrigins !== "*" ? { origin: normalized.devCorsOrigins } : true;
1458
1813
  extra.server = {
1459
1814
  ...userConfig.server ?? {},
1460
- cors: userConfig.server?.cors ?? true
1815
+ cors: userConfig.server?.cors ?? corsOption
1461
1816
  };
1817
+ const host = userConfig.server?.host;
1818
+ if (isNonLoopbackHost(host)) {
1819
+ if (!normalized.devCorsOrigins || normalized.devCorsOrigins === "*") {
1820
+ console.warn(
1821
+ formatFulgurjsDiagnostic({
1822
+ code: "DEV-011",
1823
+ symptom: `server.host=${String(host)} \u975E loopback \u4E14 dev \u8DE8\u6E90\u7B56\u7565\u4E3A\u901A\u914D\uFF08*\uFF09\uFF1A\u4EFB\u4F55\u80FD\u8BBF\u95EE\u8BE5\u673A\u7684\u6765\u6E90\u90FD\u53EF\u62C9\u53D6\u672C\u5E94\u7528\u8054\u90A6\u7AEF\u70B9\u4E0E\u6E90\u7801\u6A21\u5757`,
1824
+ cause: "devCorsOrigins \u672A\u914D\u7F6E\u65F6\u4FDD\u6301\u73B0\u72B6\u517C\u5BB9\uFF08*\uFF09\uFF1B\u8DE8\u673A\u5F00\u53D1\u66B4\u9732\u9762\u968F\u4E4B\u6269\u5927",
1825
+ fix: `\u6309\u5BBF\u4E3B\u6765\u6E90\u663E\u5F0F\u6536\u7D27\uFF1AdevCorsOrigins: ['http://<host>:<port>', ...]\uFF08\u6216\u786E\u8BA4\u8BE5\u673A\u5904\u4E8E\u53EF\u4FE1\u7F51\u7EDC\uFF09`
1826
+ })
1827
+ );
1828
+ }
1829
+ if (normalized.devFsRoot) {
1830
+ console.warn(
1831
+ formatFulgurjsDiagnostic({
1832
+ code: "DEV-012",
1833
+ symptom: `server.host=${String(host)} \u975E loopback \u4E14 dev manifest \u643A\u5E26 fsRoot\uFF08remote \u6839\u76EE\u5F55\u672C\u673A\u7EDD\u5BF9\u8DEF\u5F84\uFF09`,
1834
+ cause: "fsRoot \u4F9B\u540C\u673A\u8054\u8C03\u7684\u5BBF\u4E3B dts \u7C7B\u578B\u76F4\u8FDE\uFF1B2.x \u9ED8\u8BA4 true \u4FDD\u6301\u73B0\u72B6\uFF0C\u4E0B\u4E2A\u4E3B\u7248\u672C\u62DF\u6539\u4E3A\u663E\u5F0F\u5F00\u542F",
1835
+ fix: `\u540C\u673A\u8054\u8C03\u65E0\u9700\u52A8\u4F5C\uFF1B\u8DE8\u673A/\u4E0D\u53EF\u4FE1\u7F51\u7EDC\u53EF devFsRoot: false\uFF08\u5BBF\u4E3B dts \u5C06\u964D\u7EA7\u4E3A any \u6869\u5E76\u6709\u660E\u786E\u63D0\u793A\uFF09`
1836
+ })
1837
+ );
1838
+ }
1839
+ }
1462
1840
  } else {
1463
1841
  const userTarget = userConfig.build?.target;
1464
1842
  if (userTarget) {
@@ -1473,6 +1851,12 @@ export { default } from ${JSON.stringify(url)};
1473
1851
  }
1474
1852
  if (normalized.remotes.length > 0 && normalized.devSharedSelf) {
1475
1853
  state.facadeDynamic = true;
1854
+ const userMc = userConfig.build?.rollupOptions?.output?.manualChunks;
1855
+ debugLog("facade", {
1856
+ stage: "config",
1857
+ facadeDynamic: true,
1858
+ manualChunks: Array.isArray(userConfig.build?.rollupOptions?.output) ? "array" : typeof userMc
1859
+ });
1476
1860
  const userOutput = userConfig.build?.rollupOptions?.output;
1477
1861
  if (Array.isArray(userOutput)) {
1478
1862
  console.warn(
@@ -1540,7 +1924,7 @@ export { default } from ${JSON.stringify(url)};
1540
1924
  }
1541
1925
  }
1542
1926
  },
1543
- resolveId(source) {
1927
+ resolveId(source, importer) {
1544
1928
  let s = source;
1545
1929
  if (s.startsWith("/@id/")) s = s.slice(5);
1546
1930
  if (s.startsWith("__x00__")) s = "\0" + s.slice(7);
@@ -1548,6 +1932,16 @@ export { default } from ${JSON.stringify(url)};
1548
1932
  const bare = q === -1 ? s : s.slice(0, q);
1549
1933
  const query = q === -1 ? "" : s.slice(q);
1550
1934
  const bareClean = bare.startsWith("\0") ? bare.slice(1) : bare;
1935
+ if (state.normalized && importer) {
1936
+ const impClean = importer.split("?")[0];
1937
+ const isOurVirtual = impClean.startsWith("virtual:fulgurjs-") || impClean.startsWith("\0virtual:fulgurjs-");
1938
+ if (!isOurVirtual && !impClean.includes("/node_modules/.vite/") && !state.sharedClosureRoots.some((r) => impClean.startsWith(r.root)) && (state.transformedModules.has(importer) || state.transformedModules.has(impClean))) {
1939
+ const hit = state.normalized.shared.find((sh) => sh.aliases.includes(bareClean));
1940
+ if (hit) {
1941
+ return RESOLVED.sharedNsFacade(hit.shareKey) + query;
1942
+ }
1943
+ }
1944
+ }
1551
1945
  const n = state.normalized;
1552
1946
  if (n && !bare.startsWith("\0") && !bareClean.startsWith(".") && !bareClean.startsWith("/") && !bareClean.startsWith("virtual:")) {
1553
1947
  const slash = bareClean.indexOf("/");
@@ -1566,6 +1960,7 @@ export { default } from ${JSON.stringify(url)};
1566
1960
  if (bareClean === RUNTIME_PROXY_VIRTUAL_ID) return RESOLVED.runtimeProxy;
1567
1961
  if (bareClean === INIT_VIRTUAL_ID) return RESOLVED.init;
1568
1962
  if (bareClean === "virtual:fulgurjs-remote-schema") return bareClean;
1963
+ if (bareClean === "virtual:fulgurjs-api") return bareClean;
1569
1964
  if (bareClean === "virtual:fulgurjs-provides") return RESOLVED.provides;
1570
1965
  if (bareClean === "virtual:fulgurjs-remote-entry") return RESOLVED.remoteEntry;
1571
1966
  if (bareClean.startsWith(SHARED_NS_FACADE_PREFIX)) {
@@ -1592,6 +1987,9 @@ export { default } from ${JSON.stringify(url)};
1592
1987
  if (clean === "virtual:fulgurjs-provides" && state.normalized) {
1593
1988
  return genDevProvides(state.normalized);
1594
1989
  }
1990
+ if (clean === "virtual:fulgurjs-api") {
1991
+ return genApiFacade();
1992
+ }
1595
1993
  if (clean === "virtual:fulgurjs-remote-schema" && state.normalized) {
1596
1994
  if (state.command === "build") return genEmptyRemoteSchemaModule();
1597
1995
  remoteSchemaPromise ??= probeRemotesAndBuildSchema(state.normalized).then(
@@ -1659,6 +2057,7 @@ ${code}`, map: null };
1659
2057
  if (/\.vue(\?|$)/.test(id)) {
1660
2058
  if (state.command === "build" && /type=script/.test(id)) {
1661
2059
  return transformModule(code, id, {
2060
+ onRewrite: () => recordRewritten(id),
1662
2061
  options: state.normalized,
1663
2062
  rewriteShared: true,
1664
2063
  allowNodeModules,
@@ -1670,6 +2069,10 @@ ${code}`, map: null };
1670
2069
  }
1671
2070
  if (!isTransformableId(id, allowNodeModules)) return null;
1672
2071
  return transformModule(code, id, {
2072
+ onRewrite: () => {
2073
+ debugLog("transform", { stage: "pre", mode: state.command, module: redactModulePath(id, state.normalized.root) });
2074
+ recordRewritten(id);
2075
+ },
1673
2076
  options: state.normalized,
1674
2077
  // build:全量改写;dev:默认仅纯 remote 改写 shared(被宿主消费的组件需协商到宿主实例),
1675
2078
  // 双角色宿主可显式 devSharedSelf: true 参与协商
@@ -1692,7 +2095,7 @@ ${code}`, map: null };
1692
2095
  for (const tag of html.match(moduleScriptRe) ?? []) {
1693
2096
  const src = srcRe.exec(tag)?.[1];
1694
2097
  if (!src || src.startsWith("http") || src.startsWith("//")) continue;
1695
- const abs = import_node_path5.default.resolve(state.normalized.root, src.startsWith("/") ? src.slice(1) : src);
2098
+ const abs = import_node_path6.default.resolve(state.normalized.root, src.startsWith("/") ? src.slice(1) : src);
1696
2099
  state.entryAbsPaths.add(abs);
1697
2100
  }
1698
2101
  return html;
@@ -1704,7 +2107,7 @@ ${code}`, map: null };
1704
2107
  if (state.manualChunkSpecsPending) {
1705
2108
  for (const [group, specifier] of state.manualChunkSpecsPending) {
1706
2109
  try {
1707
- const r = await this.resolve(specifier, import_node_path5.default.join(n.root, "index.html"));
2110
+ const r = await this.resolve(specifier, import_node_path6.default.join(n.root, "index.html"));
1708
2111
  if (r?.id) {
1709
2112
  state.manualChunkGroups.set(r.id, group);
1710
2113
  state.manualChunkGroups.set(r.id.split("?")[0], group);
@@ -1734,7 +2137,7 @@ ${code}`, map: null };
1734
2137
  };
1735
2138
  for (const item of n.shared) {
1736
2139
  if (item.import === false) continue;
1737
- const selfFile = await this.resolve(item.import, import_node_path5.default.join(n.root, "index.html")).then(
2140
+ const selfFile = await this.resolve(item.import, import_node_path6.default.join(n.root, "index.html")).then(
1738
2141
  (r) => r?.id?.split("?")[0] ?? null
1739
2142
  ).catch(() => null);
1740
2143
  for (const alias of item.aliases) {
@@ -1749,7 +2152,7 @@ ${code}`, map: null };
1749
2152
  }
1750
2153
  }
1751
2154
  if (!file) {
1752
- file = await this.resolve(alias, import_node_path5.default.join(n.root, "index.html")).then(
2155
+ file = await this.resolve(alias, import_node_path6.default.join(n.root, "index.html")).then(
1753
2156
  (r) => r?.id?.split("?")[0] ?? null
1754
2157
  ).catch(() => null);
1755
2158
  }
@@ -1762,10 +2165,17 @@ ${code}`, map: null };
1762
2165
  }
1763
2166
  }
1764
2167
  state.sharedClosureRoots = [...rootKeys.entries()].map(([root, keys]) => ({ root, keys }));
2168
+ if (state.sharedClosureRoots.length > 0) {
2169
+ debugLog("facade", {
2170
+ stage: "buildStart",
2171
+ sharedClosureRoots: state.sharedClosureRoots.length,
2172
+ keys: [...new Set(state.sharedClosureRoots.flatMap((r) => [...r.keys]))]
2173
+ });
2174
+ }
1765
2175
  }
1766
2176
  if (n.exposes.length > 0) {
1767
2177
  for (const e of n.exposes) {
1768
- const resolved = await this.resolve(e.import, import_node_path5.default.join(n.root, "index.html"));
2178
+ const resolved = await this.resolve(e.import, import_node_path6.default.join(n.root, "index.html"));
1769
2179
  if (resolved) {
1770
2180
  state.exposeAbsPaths[e.import] = resolved.id.split("?")[0];
1771
2181
  } else {
@@ -1818,6 +2228,11 @@ ${code}`, map: null };
1818
2228
  }
1819
2229
  const entryChunkName = Object.keys(bundle).find((k) => bundle[k].type === "chunk" && k === n.filename);
1820
2230
  const manifest = genProdManifest(n, state.exposeFiles, entryChunkName ?? n.filename);
2231
+ debugLog("manifest", {
2232
+ stage: "generateBundle",
2233
+ exposes: Object.keys(state.exposeFiles).length,
2234
+ exposesWithCss: Object.values(state.exposeFiles).filter((e) => e.css.length > 0).length
2235
+ });
1821
2236
  this.emitFile({
1822
2237
  type: "asset",
1823
2238
  fileName: "fulgurjs-manifest.json",
@@ -1845,7 +2260,10 @@ ${code}`, map: null };
1845
2260
  const raw = (req.url ?? "").split("?")[0];
1846
2261
  const stripped = raw.startsWith(baseNorm) ? `/${raw.slice(baseNorm.length)}` : raw;
1847
2262
  if (stripped === "/@fulgurjs-entry.js" || stripped === "/@fulgurjs-manifest.json") {
1848
- res.setHeader("Access-Control-Allow-Origin", "*");
2263
+ const origin = Array.isArray(req.headers.origin) ? req.headers.origin[0] : req.headers.origin;
2264
+ for (const [k, v] of Object.entries(corsHeadersFor(origin, n.devCorsOrigins))) {
2265
+ res.setHeader(k, v);
2266
+ }
1849
2267
  res.setHeader("Access-Control-Allow-Methods", "GET,OPTIONS");
1850
2268
  res.setHeader("Access-Control-Allow-Headers", "*");
1851
2269
  if (req.method === "OPTIONS") {
@@ -1918,20 +2336,11 @@ ${code}`, map: null };
1918
2336
  if (state.command === "serve" && clean.includes("node_modules") && !id.includes(".vite/deps") && !devRewriteAll) {
1919
2337
  return null;
1920
2338
  }
1921
- if (state.command === "build" && !/\.vue(\?|$)/.test(id)) {
1922
- const quickCheck = /require\s*\(\s*["']|(?:from|import)\s*["']/.test(code);
1923
- if (!quickCheck) return null;
1924
- const allowNodeModules = isPureRemoteBuild;
1925
- return transformModule(code, id, {
1926
- options: state.normalized,
1927
- rewriteShared: true,
1928
- allowNodeModules,
1929
- sharedClosureRoots: state.sharedClosureRoots
1930
- });
2339
+ if (state.command === "build") {
2340
+ return buildFallbackTransform(code, id);
1931
2341
  }
1932
- const rewriteShared = state.command === "build" || state.normalized.devSharedSelf;
2342
+ const rewriteShared = state.normalized.devSharedSelf;
1933
2343
  const remapSpecifier = (spec) => {
1934
- if (state.normalized.shared.some((s) => s.aliases.includes(spec))) return spec;
1935
2344
  const depMatch = spec.match(/\/node_modules\/\.vite\/deps\/([^/?]+)\.js/);
1936
2345
  if (depMatch) {
1937
2346
  const depName = depMatch[1];
@@ -1942,14 +2351,13 @@ ${code}`, map: null };
1942
2351
  if (!cleanPath.startsWith("/")) return null;
1943
2352
  return state.resolvedSharedPaths.get(cleanPath) ?? null;
1944
2353
  };
1945
- const __r = await transformModule(code, id, {
2354
+ return transformModule(code, id, {
2355
+ onRewrite: () => recordRewritten(id),
1946
2356
  options: state.normalized,
1947
2357
  remapSpecifier,
1948
2358
  rewriteShared,
1949
- allowNodeModules: state.command === "build" ? isPureRemoteBuild || state.normalized.devSharedSelf : void 0,
1950
2359
  sharedClosureRoots: state.sharedClosureRoots
1951
2360
  });
1952
- return __r;
1953
2361
  }
1954
2362
  };
1955
2363
  function warmResolvedSharedPaths(server) {
@@ -1957,12 +2365,32 @@ ${code}`, map: null };
1957
2365
  if (!n) return;
1958
2366
  for (const s of n.shared) {
1959
2367
  if (s.import === false) continue;
1960
- void server.pluginContainer.resolveId(s.import, import_node_path5.default.join(n.root, "index.html")).then((r) => {
2368
+ void server.pluginContainer.resolveId(s.import, import_node_path6.default.join(n.root, "index.html")).then((r) => {
1961
2369
  if (r?.id) state.resolvedSharedPaths.set(r.id.split("?")[0], s.configKey);
1962
2370
  }).catch(() => {
1963
2371
  });
1964
2372
  }
1965
2373
  }
2374
+ async function buildFallbackTransform(code, id) {
2375
+ if (/type=(style|template)/.test(id)) return null;
2376
+ const clean = id.split("?")[0];
2377
+ const isJsLike = /\.(m|c)?[jt]sx?$/.test(clean) || clean.endsWith(".vue");
2378
+ if (!isJsLike) return null;
2379
+ const quickCheck = /require\s*\(\s*["']|(?:from|import)\s*["']/.test(code);
2380
+ if (!quickCheck) return null;
2381
+ const n = state.normalized;
2382
+ const isPureRemoteBuild = n.exposes.length > 0 && n.remotes.length === 0;
2383
+ return transformModule(code, id, {
2384
+ onRewrite: () => {
2385
+ debugLog("transform", { stage: "post-fallback", mode: "build", module: redactModulePath(id, n.root) });
2386
+ recordRewritten(id);
2387
+ },
2388
+ options: n,
2389
+ rewriteShared: true,
2390
+ allowNodeModules: isPureRemoteBuild || n.devSharedSelf,
2391
+ sharedClosureRoots: state.sharedClosureRoots
2392
+ });
2393
+ }
1966
2394
  return [pre, post];
1967
2395
  }
1968
2396
  var index_default = federation;