@fulgurjs/federation 2.0.3 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +42 -0
- package/README.md +80 -25
- package/client.d.ts +49 -2
- package/dist/{chunk-RQPLFDDT.js → chunk-YBS2PO34.js} +1 -1
- package/dist/cli.js +148 -4
- package/dist/index.cjs +509 -61
- package/dist/index.d.cts +13 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.js +511 -61
- package/dist/runtime.js +3 -3
- package/dist/vue.cjs +98 -30
- package/dist/vue.js +99 -31
- package/package.json +19 -28
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
|
|
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 = "
|
|
46
|
+
var RUNTIME_VERSION = "3.0.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;
|
|
@@ -593,6 +812,9 @@ function genRuntimeProxyModule() {
|
|
|
593
812
|
` return await __fulgurjs_mod_p;`,
|
|
594
813
|
`};`,
|
|
595
814
|
...promiseApis.map((m) => `export const ${m} = (...a) => __fulgurjs_rt().then((m2) => m2.${m}(...a));`),
|
|
815
|
+
// shareScopeMap:本模块只会在应用代码 import 链里被求值——页面运行期单例必已由 init 建立
|
|
816
|
+
// (时序契约:宿主/远程 init 先于一切联邦模块),故求值期直读 globalThis 安全
|
|
817
|
+
`export const shareScopeMap = (globalThis).__FULGURJS_RUNTIME__?.shareScopeMap;`,
|
|
596
818
|
`export const getRuntime = () => (globalThis).__FULGURJS_RUNTIME__;`,
|
|
597
819
|
`export const unwrapDefault = (ns) =>`,
|
|
598
820
|
` ns && typeof ns === 'object' && 'default' in ns ? (ns.default !== undefined ? ns.default : ns) : ns;`,
|
|
@@ -696,17 +918,50 @@ function genBuildRemoteEntry(options, exposeAbsPaths) {
|
|
|
696
918
|
""
|
|
697
919
|
].join("\n");
|
|
698
920
|
}
|
|
921
|
+
function genApiFacade(mode) {
|
|
922
|
+
if (mode === "build") {
|
|
923
|
+
return [
|
|
924
|
+
"export {",
|
|
925
|
+
" initSharing, registerShare, registerRemotes, registerRemote, registerPlugins,",
|
|
926
|
+
" loadShare, loadRemote, getContainer, preloadRemote, parseSpec,",
|
|
927
|
+
" getRuntime, shareScopeMap, unwrapDefault, version,",
|
|
928
|
+
'} from "virtual:fulgurjs-runtime";',
|
|
929
|
+
"export { provideAppContext, getAppContext, requireAppContext } from '@fulgurjs/federation/internal/context.js';",
|
|
930
|
+
"export { definePages, validatePages } from '@fulgurjs/federation/internal/pages.js';",
|
|
931
|
+
"export { remoteComponent } from '@fulgurjs/federation/internal/vue.js';",
|
|
932
|
+
"export { default as remoteSchema } from 'virtual:fulgurjs-remote-schema';",
|
|
933
|
+
""
|
|
934
|
+
].join("\n");
|
|
935
|
+
}
|
|
936
|
+
return [
|
|
937
|
+
"export {",
|
|
938
|
+
" loadRemote, loadShare, preloadRemote, getContainer,",
|
|
939
|
+
" registerRemote, registerRemotes, registerShare, initSharing, registerPlugins,",
|
|
940
|
+
" parseSpec, getRuntime, shareScopeMap, unwrapDefault, version,",
|
|
941
|
+
'} from "virtual:fulgurjs-runtime-proxy";',
|
|
942
|
+
"export { provideAppContext, getAppContext, requireAppContext } from '@fulgurjs/federation/internal/context.js';",
|
|
943
|
+
"export { definePages, validatePages } from '@fulgurjs/federation/internal/pages.js';",
|
|
944
|
+
`let __fulgurjs_vue_p;`,
|
|
945
|
+
`export const remoteComponent = (...a) => (__fulgurjs_vue_p ??= import('@fulgurjs/federation/internal/vue.js')).then((m) => m.remoteComponent(...a));`,
|
|
946
|
+
"export { default as remoteSchema } from 'virtual:fulgurjs-remote-schema';",
|
|
947
|
+
""
|
|
948
|
+
].join("\n");
|
|
949
|
+
}
|
|
699
950
|
function genDevManifest(options, base) {
|
|
700
951
|
const b = base.endsWith("/") ? base : `${base}/`;
|
|
701
952
|
return {
|
|
953
|
+
schemaVersion: MANIFEST_SCHEMA_VERSION,
|
|
702
954
|
id: options.name,
|
|
703
955
|
name: options.name,
|
|
704
956
|
version: options.pkgDependencies?.["fulgurjs"] ?? "0.0.0",
|
|
705
957
|
devServer: true,
|
|
706
958
|
base: b,
|
|
707
959
|
entry: `${b}@fulgurjs-entry.js`,
|
|
708
|
-
/**
|
|
709
|
-
|
|
960
|
+
/**
|
|
961
|
+
* 本地联调时供宿主端 dts 类型直连(见 dts.ts);远程不在本机时宿主回退 any 桩。
|
|
962
|
+
* WP5:devFsRoot: false 时不写入(本机路径不外发);该字段永不进入 prod manifest。
|
|
963
|
+
*/
|
|
964
|
+
...options.devFsRoot === false ? {} : { fsRoot: options.root },
|
|
710
965
|
exposes: options.exposes.map((e) => ({
|
|
711
966
|
name: e.name,
|
|
712
967
|
src: e.import,
|
|
@@ -728,6 +983,7 @@ function genDevManifest(options, base) {
|
|
|
728
983
|
}
|
|
729
984
|
function genProdManifest(options, exposeFiles, entryFile) {
|
|
730
985
|
return {
|
|
986
|
+
schemaVersion: MANIFEST_SCHEMA_VERSION,
|
|
731
987
|
id: options.name,
|
|
732
988
|
name: options.name,
|
|
733
989
|
entry: entryFile,
|
|
@@ -909,6 +1165,7 @@ async function transformModule(code, id, ctx) {
|
|
|
909
1165
|
cjsEdited = true;
|
|
910
1166
|
}
|
|
911
1167
|
if (!cjsEdited) return null;
|
|
1168
|
+
ctx.onRewrite?.();
|
|
912
1169
|
return { code, map: null };
|
|
913
1170
|
}
|
|
914
1171
|
await ensureLexer();
|
|
@@ -1031,6 +1288,7 @@ export { ${nsAs[1]} };`);
|
|
|
1031
1288
|
}
|
|
1032
1289
|
}
|
|
1033
1290
|
if (!edited) return null;
|
|
1291
|
+
ctx.onRewrite?.();
|
|
1034
1292
|
if (usesRuntimeHelpers) {
|
|
1035
1293
|
const runtimeSpec = JSON.stringify(ctx.devUrls?.runtime ?? "virtual:fulgurjs-runtime");
|
|
1036
1294
|
s.prepend(
|
|
@@ -1056,7 +1314,22 @@ async function fetchManifest(devEntry, attempts = 30, delayMs = 2e3) {
|
|
|
1056
1314
|
for (let i = 0; i < attempts; i++) {
|
|
1057
1315
|
try {
|
|
1058
1316
|
const res = await fetch(manifestUrl, { signal: AbortSignal.timeout(3e3) });
|
|
1059
|
-
if (res.ok)
|
|
1317
|
+
if (res.ok) {
|
|
1318
|
+
const parsed = parseManifest(await res.json());
|
|
1319
|
+
if (parsed.unsupportedVersion) {
|
|
1320
|
+
console.warn(
|
|
1321
|
+
`[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`
|
|
1322
|
+
);
|
|
1323
|
+
return null;
|
|
1324
|
+
}
|
|
1325
|
+
if (parsed.issues.length > 0) {
|
|
1326
|
+
console.warn(
|
|
1327
|
+
`[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`
|
|
1328
|
+
);
|
|
1329
|
+
return null;
|
|
1330
|
+
}
|
|
1331
|
+
return parsed.manifest;
|
|
1332
|
+
}
|
|
1060
1333
|
} catch {
|
|
1061
1334
|
}
|
|
1062
1335
|
await new Promise((r) => setTimeout(r, delayMs));
|
|
@@ -1104,7 +1377,7 @@ function extractTsExportNames(text) {
|
|
|
1104
1377
|
}
|
|
1105
1378
|
function genRuntimeTypesShim() {
|
|
1106
1379
|
return [
|
|
1107
|
-
"// \u81EA\u52A8\u751F\u6210\uFF1Afulgurjs-federation \u8FD0\u884C\u65F6\u7C7B\u578B\uFF08virtual:fulgurjs-
|
|
1380
|
+
"// \u81EA\u52A8\u751F\u6210\uFF1Afulgurjs-federation \u8FD0\u884C\u65F6\u7C7B\u578B\uFF08virtual:fulgurjs-api\uFF09",
|
|
1108
1381
|
"import '@fulgurjs/federation/client'",
|
|
1109
1382
|
"export {}",
|
|
1110
1383
|
""
|
|
@@ -1119,7 +1392,7 @@ function resolveDtsMode(dtsOpt) {
|
|
|
1119
1392
|
return (typeof dtsOpt === "object" ? dtsOpt.mode : void 0) ?? "source";
|
|
1120
1393
|
}
|
|
1121
1394
|
function buildShimModule(abs, moduleSpecifier) {
|
|
1122
|
-
const lines = [`declare module
|
|
1395
|
+
const lines = [`declare module ${JSON.stringify(moduleSpecifier)} {`];
|
|
1123
1396
|
if (abs.endsWith(".vue")) {
|
|
1124
1397
|
lines.push(` import type { DefineComponent } from 'vue'`);
|
|
1125
1398
|
lines.push(` const component: DefineComponent<Record<string, unknown>, Record<string, unknown>, any>`);
|
|
@@ -1156,9 +1429,18 @@ async function generateDevTypes(options, _server) {
|
|
|
1156
1429
|
continue;
|
|
1157
1430
|
}
|
|
1158
1431
|
const remoteRoot = manifest.fsRoot;
|
|
1159
|
-
if (!remoteRoot
|
|
1432
|
+
if (!remoteRoot) {
|
|
1433
|
+
console.warn(
|
|
1434
|
+
`[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`
|
|
1435
|
+
);
|
|
1436
|
+
continue;
|
|
1437
|
+
}
|
|
1438
|
+
let realRoot;
|
|
1439
|
+
try {
|
|
1440
|
+
realRoot = import_node_fs2.default.realpathSync(remoteRoot);
|
|
1441
|
+
} catch {
|
|
1160
1442
|
console.warn(
|
|
1161
|
-
`[fulgurjs] dts: remote "${remote.key}" is not on this machine; type mapping skipped (module types fall back to any).`
|
|
1443
|
+
`[fulgurjs] dts: remote "${remote.key}" is not on this machine (fsRoot unreachable); type mapping skipped (module types fall back to any).`
|
|
1162
1444
|
);
|
|
1163
1445
|
continue;
|
|
1164
1446
|
}
|
|
@@ -1166,45 +1448,78 @@ async function generateDevTypes(options, _server) {
|
|
|
1166
1448
|
`// \u81EA\u52A8\u751F\u6210\uFF1Afulgurjs-federation dev \u7C7B\u578B\u76F4\u8FDE\uFF08remote: ${remote.name}\uFF0Cmode: ${mode}\uFF09`,
|
|
1167
1449
|
`// \u91CD\u65B0\u751F\u6210\uFF1A\u91CD\u542F host dev server`
|
|
1168
1450
|
];
|
|
1451
|
+
let accepted = 0;
|
|
1169
1452
|
for (const expose of manifest.exposes ?? []) {
|
|
1170
|
-
const
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1453
|
+
const skipped = (reason) => console.warn(`[fulgurjs] dts: remote "${remote.key}" expose ${JSON.stringify(expose.name)} \u8DF3\u8FC7\uFF1A${reason}`);
|
|
1454
|
+
const src = expose.src;
|
|
1455
|
+
if (!src || typeof src !== "string") {
|
|
1456
|
+
skipped("src \u7F3A\u5931");
|
|
1457
|
+
continue;
|
|
1458
|
+
}
|
|
1459
|
+
if (src.startsWith("/") || /^[a-z]+:/i.test(src)) {
|
|
1460
|
+
skipped(`src \u5FC5\u987B\u662F\u76F8\u5BF9\u8DEF\u5F84\uFF0Cgot ${JSON.stringify(src)}`);
|
|
1461
|
+
continue;
|
|
1462
|
+
}
|
|
1463
|
+
if (src.split("/").includes("..")) {
|
|
1464
|
+
skipped(`src \u4E0D\u5F97\u5305\u542B ..\uFF0Cgot ${JSON.stringify(src)}`);
|
|
1465
|
+
continue;
|
|
1466
|
+
}
|
|
1467
|
+
const abs = import_node_path3.default.join(realRoot, src);
|
|
1468
|
+
let realAbs;
|
|
1469
|
+
try {
|
|
1470
|
+
realAbs = import_node_fs2.default.realpathSync(abs);
|
|
1471
|
+
} catch {
|
|
1472
|
+
skipped(`\u6E90\u6587\u4EF6\u4E0D\u5B58\u5728\uFF08${src}\uFF09`);
|
|
1473
|
+
continue;
|
|
1474
|
+
}
|
|
1475
|
+
if (import_node_path3.default.relative(realRoot, realAbs).startsWith("..")) {
|
|
1476
|
+
skipped(`\u89E3\u6790\u7ED3\u679C\u8D8A\u51FA fsRoot\uFF08${src} \u2192 ${realAbs}\uFF09`);
|
|
1477
|
+
continue;
|
|
1478
|
+
}
|
|
1479
|
+
if (!import_node_fs2.default.existsSync(realAbs)) continue;
|
|
1480
|
+
const rel = import_node_path3.default.relative(outDir, realAbs).split(import_node_path3.default.sep).join("/");
|
|
1481
|
+
const importPath = realAbs.endsWith(".vue") ? sourceImportPath(rel) : stripTsExtension(sourceImportPath(rel));
|
|
1174
1482
|
const moduleSpecifier = `${remote.key}/${expose.name.replace(/^\.\//, "")}`;
|
|
1483
|
+
const moduleLiteral = JSON.stringify(moduleSpecifier);
|
|
1484
|
+
const importLiteral = JSON.stringify(importPath);
|
|
1175
1485
|
lines.push("");
|
|
1176
1486
|
if (mode === "shim") {
|
|
1177
|
-
lines.push(buildShimModule(
|
|
1487
|
+
lines.push(buildShimModule(realAbs, moduleSpecifier));
|
|
1488
|
+
accepted++;
|
|
1178
1489
|
continue;
|
|
1179
1490
|
}
|
|
1180
|
-
if (
|
|
1181
|
-
lines.push(`declare module
|
|
1491
|
+
if (realAbs.endsWith(".vue")) {
|
|
1492
|
+
lines.push(`declare module ${moduleLiteral} {`);
|
|
1182
1493
|
lines.push(` import type { DefineComponent } from 'vue'`);
|
|
1183
1494
|
lines.push(` const component: DefineComponent<Record<string, unknown>, Record<string, unknown>, unknown>`);
|
|
1184
1495
|
lines.push(` export default component`);
|
|
1185
|
-
lines.push(` export * from
|
|
1496
|
+
lines.push(` export * from ${importLiteral}`);
|
|
1186
1497
|
lines.push(`}`);
|
|
1187
1498
|
} else {
|
|
1188
|
-
lines.push(`declare module
|
|
1189
|
-
const names = extractTsExportNames(import_node_fs2.default.readFileSync(
|
|
1499
|
+
lines.push(`declare module ${moduleLiteral} {`);
|
|
1500
|
+
const names = extractTsExportNames(import_node_fs2.default.readFileSync(realAbs, "utf8"));
|
|
1190
1501
|
if (names.length > 0) {
|
|
1191
|
-
lines.push(` export { ${names.join(", ")} } from
|
|
1502
|
+
lines.push(` export { ${names.join(", ")} } from ${importLiteral}`);
|
|
1192
1503
|
} else {
|
|
1193
|
-
lines.push(` export * from
|
|
1504
|
+
lines.push(` export * from ${importLiteral}`);
|
|
1194
1505
|
}
|
|
1195
|
-
if (sourceHasDefaultExport(
|
|
1506
|
+
if (sourceHasDefaultExport(realAbs)) lines.push(` export { default } from ${importLiteral}`);
|
|
1196
1507
|
lines.push(`}`);
|
|
1197
1508
|
}
|
|
1509
|
+
accepted++;
|
|
1198
1510
|
}
|
|
1199
|
-
|
|
1511
|
+
if (accepted > 0) {
|
|
1512
|
+
import_node_fs2.default.writeFileSync(import_node_path3.default.join(outDir, `${remote.key}.d.ts`), `${lines.join("\n")}
|
|
1200
1513
|
`);
|
|
1514
|
+
}
|
|
1201
1515
|
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`
|
|
1516
|
+
`[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
1517
|
);
|
|
1204
1518
|
}
|
|
1205
1519
|
}
|
|
1206
1520
|
|
|
1207
1521
|
// src/diagnostics.ts
|
|
1522
|
+
var import_node_path4 = __toESM(require("path"), 1);
|
|
1208
1523
|
function formatFulgurjsDiagnostic(input) {
|
|
1209
1524
|
const ctx = input.details ? `
|
|
1210
1525
|
\u4E0A\u4E0B\u6587\uFF1A${JSON.stringify(input.details)}` : "";
|
|
@@ -1227,6 +1542,33 @@ async function isPortReachable(host, port, timeoutMs = 800) {
|
|
|
1227
1542
|
socket.connect(port, host);
|
|
1228
1543
|
});
|
|
1229
1544
|
}
|
|
1545
|
+
var __debugEnvCache = "";
|
|
1546
|
+
var __debugEnabledCache = {};
|
|
1547
|
+
function debugEnabled(category) {
|
|
1548
|
+
const spec = process.env.FULGURJS_DEBUG ?? process.env.DEBUG ?? "";
|
|
1549
|
+
if (spec !== __debugEnvCache) {
|
|
1550
|
+
__debugEnvCache = spec;
|
|
1551
|
+
__debugEnabledCache = {};
|
|
1552
|
+
}
|
|
1553
|
+
if (category in __debugEnabledCache) return __debugEnabledCache[category];
|
|
1554
|
+
const patterns = spec.split(",").map((x) => x.trim()).filter(Boolean);
|
|
1555
|
+
const enabled = patterns.some((p) => p === "fulgurjs" || p === "fulgurjs:*" || p === `fulgurjs:${category}`);
|
|
1556
|
+
__debugEnabledCache[category] = enabled;
|
|
1557
|
+
return enabled;
|
|
1558
|
+
}
|
|
1559
|
+
function debugLog(category, data) {
|
|
1560
|
+
if (!debugEnabled(category)) return;
|
|
1561
|
+
console.error(`[fulgurjs:debug:${category}] ${JSON.stringify(data)}`);
|
|
1562
|
+
}
|
|
1563
|
+
function redactModulePath(id, root) {
|
|
1564
|
+
const clean = id.split("?")[0];
|
|
1565
|
+
try {
|
|
1566
|
+
const rel = import_node_path4.default.relative(root, clean);
|
|
1567
|
+
if (rel && !rel.startsWith("..") && !import_node_path4.default.isAbsolute(rel)) return rel;
|
|
1568
|
+
} catch {
|
|
1569
|
+
}
|
|
1570
|
+
return clean.split("/").pop() ?? clean;
|
|
1571
|
+
}
|
|
1230
1572
|
|
|
1231
1573
|
// src/remote-schema.ts
|
|
1232
1574
|
function manifestUrlOf(devEntry) {
|
|
@@ -1253,8 +1595,35 @@ async function probeRemotesAndBuildSchema(options) {
|
|
|
1253
1595
|
try {
|
|
1254
1596
|
const res = await fetch(u, { signal: AbortSignal.timeout(3e3) });
|
|
1255
1597
|
if (!res.ok) throw new Error(`HTTP ${res.status}`);
|
|
1256
|
-
const
|
|
1257
|
-
|
|
1598
|
+
const parsed = parseManifest(await res.json());
|
|
1599
|
+
if (parsed.unsupportedVersion) {
|
|
1600
|
+
schema[remote.key] = { exposes: [], exists: false };
|
|
1601
|
+
console.warn(
|
|
1602
|
+
formatFulgurjsDiagnostic({
|
|
1603
|
+
code: "DEV-002",
|
|
1604
|
+
symptom: `remote "${remote.key}" \u7684 manifest schemaVersion=${parsed.unsupportedVersion} \u4E0D\u53D7\u652F\u6301\uFF08\u672C\u673A\u652F\u6301 1\uFF09`,
|
|
1605
|
+
cause: "\u5BBF\u4E3B\u4E0E\u8FDC\u7A0B\u7684 @fulgurjs/federation \u5927\u7248\u672C\u4E0D\u4E00\u81F4",
|
|
1606
|
+
fix: "\u5BF9\u9F50\u5BBF\u4E3B\u4E0E\u8FDC\u7A0B\u7684 @fulgurjs/federation \u7248\u672C\u540E\u91CD\u542F dev server",
|
|
1607
|
+
details: { remote: remote.key, url: u.href }
|
|
1608
|
+
})
|
|
1609
|
+
);
|
|
1610
|
+
continue;
|
|
1611
|
+
}
|
|
1612
|
+
if (parsed.issues.length > 0 || !parsed.manifest) {
|
|
1613
|
+
schema[remote.key] = { exposes: [], exists: false };
|
|
1614
|
+
console.warn(
|
|
1615
|
+
formatFulgurjsDiagnostic({
|
|
1616
|
+
code: "DEV-002",
|
|
1617
|
+
symptom: `remote "${remote.key}" \u7684 dev manifest \u5951\u7EA6\u6821\u9A8C\u5931\u8D25\uFF08${u.href}\uFF09`,
|
|
1618
|
+
cause: parsed.issues.map((x) => `${x.field}: ${x.message}`).join("\uFF1B"),
|
|
1619
|
+
fix: "\u6838\u5BF9 remote \u7684 federation \u914D\u7F6E exposes\uFF0C\u5E76\u786E\u8BA4 @fulgurjs/federation \u7248\u672C\u4E0E\u5BBF\u4E3B\u4E00\u81F4",
|
|
1620
|
+
details: { remote: remote.key, url: u.href, issues: parsed.issues.slice(0, 5) }
|
|
1621
|
+
})
|
|
1622
|
+
);
|
|
1623
|
+
continue;
|
|
1624
|
+
}
|
|
1625
|
+
const manifest = parsed.manifest;
|
|
1626
|
+
const exposes = [...normalizeExposes(manifest).keys()];
|
|
1258
1627
|
schema[remote.key] = { exposes, exists: true };
|
|
1259
1628
|
if (exposes.length === 0) {
|
|
1260
1629
|
console.warn(
|
|
@@ -1263,11 +1632,11 @@ async function probeRemotesAndBuildSchema(options) {
|
|
|
1263
1632
|
symptom: `remote "${remote.key}" \u7684 dev manifest \u53EF\u8FBE\u4F46 exposes \u4E3A\u7A7A\uFF08${u.href}\uFF09`,
|
|
1264
1633
|
cause: "remote \u4FA7 federation({ exposes }) \u4E3A\u7A7A\uFF0C\u6216\u5176\u63D2\u4EF6\u7248\u672C\u8FC7\u65E7\u5BFC\u81F4 manifest \u7F3A\u5B57\u6BB5",
|
|
1265
1634
|
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
|
|
1635
|
+
details: { remote: remote.key, url: u.href, pluginVersion: manifest.version }
|
|
1267
1636
|
})
|
|
1268
1637
|
);
|
|
1269
1638
|
}
|
|
1270
|
-
const remoteVersion = manifest
|
|
1639
|
+
const remoteVersion = manifest.version;
|
|
1271
1640
|
if (remoteVersion && remoteVersion !== options.pluginVersion) {
|
|
1272
1641
|
console.warn(
|
|
1273
1642
|
formatFulgurjsDiagnostic({
|
|
@@ -1303,17 +1672,17 @@ function genEmptyRemoteSchemaModule() {
|
|
|
1303
1672
|
|
|
1304
1673
|
// src/vite-cache.ts
|
|
1305
1674
|
var import_node_fs3 = __toESM(require("fs"), 1);
|
|
1306
|
-
var
|
|
1675
|
+
var import_node_path5 = __toESM(require("path"), 1);
|
|
1307
1676
|
function syncViteCacheMarker(root, pluginVersion, log) {
|
|
1308
|
-
const viteDir =
|
|
1309
|
-
const marker =
|
|
1677
|
+
const viteDir = import_node_path5.default.join(root, "node_modules", ".vite");
|
|
1678
|
+
const marker = import_node_path5.default.join(viteDir, "fulgurjs-version.txt");
|
|
1310
1679
|
try {
|
|
1311
1680
|
if (import_node_fs3.default.existsSync(viteDir)) {
|
|
1312
1681
|
const prev = import_node_fs3.default.existsSync(marker) ? import_node_fs3.default.readFileSync(marker, "utf8").trim() : "";
|
|
1313
1682
|
if (prev === pluginVersion) return;
|
|
1314
1683
|
import_node_fs3.default.rmSync(viteDir, { recursive: true, force: true });
|
|
1315
1684
|
log(
|
|
1316
|
-
`[fulgurjs] \u63D2\u4EF6\u7248\u672C\u53D8\u5316\uFF08${prev || "\u65E0\u8BB0\u5F55"} \u2192 ${pluginVersion}\uFF09\uFF0C\u5DF2\u81EA\u52A8\u6E05\u9664 ${
|
|
1685
|
+
`[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
1686
|
);
|
|
1318
1687
|
}
|
|
1319
1688
|
import_node_fs3.default.mkdirSync(viteDir, { recursive: true });
|
|
@@ -1326,7 +1695,7 @@ function syncViteCacheMarker(root, pluginVersion, log) {
|
|
|
1326
1695
|
}
|
|
1327
1696
|
|
|
1328
1697
|
// 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';
|
|
1698
|
+
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="3.0.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
1699
|
|
|
1331
1700
|
// src/index.ts
|
|
1332
1701
|
function readRuntimeCode() {
|
|
@@ -1343,7 +1712,7 @@ function enumerateCjsExports(packageName, appRoot) {
|
|
|
1343
1712
|
if (cached) return cached;
|
|
1344
1713
|
let names = [];
|
|
1345
1714
|
try {
|
|
1346
|
-
const appRequire = (0, import_node_module2.createRequire)(
|
|
1715
|
+
const appRequire = (0, import_node_module2.createRequire)(import_node_path6.default.join(appRoot, "package.json"));
|
|
1347
1716
|
const mod = appRequire(packageName);
|
|
1348
1717
|
names = Object.keys(mod);
|
|
1349
1718
|
} catch {
|
|
@@ -1403,14 +1772,19 @@ function federation(options) {
|
|
|
1403
1772
|
entryInitInjected: /* @__PURE__ */ new Set(),
|
|
1404
1773
|
manualChunkGroups: /* @__PURE__ */ new Map(),
|
|
1405
1774
|
sharedClosureRoots: [],
|
|
1406
|
-
facadeDynamic: false
|
|
1775
|
+
facadeDynamic: false,
|
|
1776
|
+
transformedModules: /* @__PURE__ */ new Set()
|
|
1777
|
+
};
|
|
1778
|
+
const recordRewritten = (id) => {
|
|
1779
|
+
state.transformedModules.add(id);
|
|
1780
|
+
state.transformedModules.add(id.split("?")[0]);
|
|
1407
1781
|
};
|
|
1408
1782
|
const pre = {
|
|
1409
1783
|
name: "fulgurjs:core",
|
|
1410
1784
|
enforce: "pre",
|
|
1411
1785
|
async config(userConfig, env) {
|
|
1412
1786
|
state.command = env.command;
|
|
1413
|
-
const root =
|
|
1787
|
+
const root = import_node_path6.default.resolve(userConfig.root ?? process.cwd());
|
|
1414
1788
|
const normalized = normalizeOptions(options, root, env.command);
|
|
1415
1789
|
state.normalized = normalized;
|
|
1416
1790
|
const extra = {};
|
|
@@ -1455,10 +1829,34 @@ export { default } from ${JSON.stringify(url)};
|
|
|
1455
1829
|
}
|
|
1456
1830
|
if (env.command === "serve") {
|
|
1457
1831
|
syncViteCacheMarker(root, normalized.pluginVersion, (msg) => console.warn(msg));
|
|
1832
|
+
const corsOption = normalized.devCorsOrigins && normalized.devCorsOrigins !== "*" ? { origin: normalized.devCorsOrigins } : true;
|
|
1458
1833
|
extra.server = {
|
|
1459
1834
|
...userConfig.server ?? {},
|
|
1460
|
-
cors: userConfig.server?.cors ??
|
|
1835
|
+
cors: userConfig.server?.cors ?? corsOption
|
|
1461
1836
|
};
|
|
1837
|
+
const host = userConfig.server?.host;
|
|
1838
|
+
if (isNonLoopbackHost(host)) {
|
|
1839
|
+
if (!normalized.devCorsOrigins || normalized.devCorsOrigins === "*") {
|
|
1840
|
+
console.warn(
|
|
1841
|
+
formatFulgurjsDiagnostic({
|
|
1842
|
+
code: "DEV-011",
|
|
1843
|
+
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`,
|
|
1844
|
+
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",
|
|
1845
|
+
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`
|
|
1846
|
+
})
|
|
1847
|
+
);
|
|
1848
|
+
}
|
|
1849
|
+
if (normalized.devFsRoot) {
|
|
1850
|
+
console.warn(
|
|
1851
|
+
formatFulgurjsDiagnostic({
|
|
1852
|
+
code: "DEV-012",
|
|
1853
|
+
symptom: `server.host=${String(host)} \u975E loopback \u4E14 dev manifest \u643A\u5E26 fsRoot\uFF08remote \u6839\u76EE\u5F55\u672C\u673A\u7EDD\u5BF9\u8DEF\u5F84\uFF09`,
|
|
1854
|
+
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",
|
|
1855
|
+
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`
|
|
1856
|
+
})
|
|
1857
|
+
);
|
|
1858
|
+
}
|
|
1859
|
+
}
|
|
1462
1860
|
} else {
|
|
1463
1861
|
const userTarget = userConfig.build?.target;
|
|
1464
1862
|
if (userTarget) {
|
|
@@ -1473,6 +1871,12 @@ export { default } from ${JSON.stringify(url)};
|
|
|
1473
1871
|
}
|
|
1474
1872
|
if (normalized.remotes.length > 0 && normalized.devSharedSelf) {
|
|
1475
1873
|
state.facadeDynamic = true;
|
|
1874
|
+
const userMc = userConfig.build?.rollupOptions?.output?.manualChunks;
|
|
1875
|
+
debugLog("facade", {
|
|
1876
|
+
stage: "config",
|
|
1877
|
+
facadeDynamic: true,
|
|
1878
|
+
manualChunks: Array.isArray(userConfig.build?.rollupOptions?.output) ? "array" : typeof userMc
|
|
1879
|
+
});
|
|
1476
1880
|
const userOutput = userConfig.build?.rollupOptions?.output;
|
|
1477
1881
|
if (Array.isArray(userOutput)) {
|
|
1478
1882
|
console.warn(
|
|
@@ -1540,7 +1944,7 @@ export { default } from ${JSON.stringify(url)};
|
|
|
1540
1944
|
}
|
|
1541
1945
|
}
|
|
1542
1946
|
},
|
|
1543
|
-
resolveId(source) {
|
|
1947
|
+
resolveId(source, importer) {
|
|
1544
1948
|
let s = source;
|
|
1545
1949
|
if (s.startsWith("/@id/")) s = s.slice(5);
|
|
1546
1950
|
if (s.startsWith("__x00__")) s = "\0" + s.slice(7);
|
|
@@ -1548,6 +1952,16 @@ export { default } from ${JSON.stringify(url)};
|
|
|
1548
1952
|
const bare = q === -1 ? s : s.slice(0, q);
|
|
1549
1953
|
const query = q === -1 ? "" : s.slice(q);
|
|
1550
1954
|
const bareClean = bare.startsWith("\0") ? bare.slice(1) : bare;
|
|
1955
|
+
if (state.normalized && importer) {
|
|
1956
|
+
const impClean = importer.split("?")[0];
|
|
1957
|
+
const isOurVirtual = impClean.startsWith("virtual:fulgurjs-") || impClean.startsWith("\0virtual:fulgurjs-");
|
|
1958
|
+
if (!isOurVirtual && !impClean.includes("/node_modules/.vite/") && !state.sharedClosureRoots.some((r) => impClean.startsWith(r.root)) && (state.transformedModules.has(importer) || state.transformedModules.has(impClean))) {
|
|
1959
|
+
const hit = state.normalized.shared.find((sh) => sh.aliases.includes(bareClean));
|
|
1960
|
+
if (hit) {
|
|
1961
|
+
return RESOLVED.sharedNsFacade(hit.shareKey) + query;
|
|
1962
|
+
}
|
|
1963
|
+
}
|
|
1964
|
+
}
|
|
1551
1965
|
const n = state.normalized;
|
|
1552
1966
|
if (n && !bare.startsWith("\0") && !bareClean.startsWith(".") && !bareClean.startsWith("/") && !bareClean.startsWith("virtual:")) {
|
|
1553
1967
|
const slash = bareClean.indexOf("/");
|
|
@@ -1566,6 +1980,7 @@ export { default } from ${JSON.stringify(url)};
|
|
|
1566
1980
|
if (bareClean === RUNTIME_PROXY_VIRTUAL_ID) return RESOLVED.runtimeProxy;
|
|
1567
1981
|
if (bareClean === INIT_VIRTUAL_ID) return RESOLVED.init;
|
|
1568
1982
|
if (bareClean === "virtual:fulgurjs-remote-schema") return bareClean;
|
|
1983
|
+
if (bareClean === "virtual:fulgurjs-api") return bareClean;
|
|
1569
1984
|
if (bareClean === "virtual:fulgurjs-provides") return RESOLVED.provides;
|
|
1570
1985
|
if (bareClean === "virtual:fulgurjs-remote-entry") return RESOLVED.remoteEntry;
|
|
1571
1986
|
if (bareClean.startsWith(SHARED_NS_FACADE_PREFIX)) {
|
|
@@ -1592,6 +2007,9 @@ export { default } from ${JSON.stringify(url)};
|
|
|
1592
2007
|
if (clean === "virtual:fulgurjs-provides" && state.normalized) {
|
|
1593
2008
|
return genDevProvides(state.normalized);
|
|
1594
2009
|
}
|
|
2010
|
+
if (clean === "virtual:fulgurjs-api") {
|
|
2011
|
+
return genApiFacade(state.command);
|
|
2012
|
+
}
|
|
1595
2013
|
if (clean === "virtual:fulgurjs-remote-schema" && state.normalized) {
|
|
1596
2014
|
if (state.command === "build") return genEmptyRemoteSchemaModule();
|
|
1597
2015
|
remoteSchemaPromise ??= probeRemotesAndBuildSchema(state.normalized).then(
|
|
@@ -1659,6 +2077,7 @@ ${code}`, map: null };
|
|
|
1659
2077
|
if (/\.vue(\?|$)/.test(id)) {
|
|
1660
2078
|
if (state.command === "build" && /type=script/.test(id)) {
|
|
1661
2079
|
return transformModule(code, id, {
|
|
2080
|
+
onRewrite: () => recordRewritten(id),
|
|
1662
2081
|
options: state.normalized,
|
|
1663
2082
|
rewriteShared: true,
|
|
1664
2083
|
allowNodeModules,
|
|
@@ -1670,6 +2089,10 @@ ${code}`, map: null };
|
|
|
1670
2089
|
}
|
|
1671
2090
|
if (!isTransformableId(id, allowNodeModules)) return null;
|
|
1672
2091
|
return transformModule(code, id, {
|
|
2092
|
+
onRewrite: () => {
|
|
2093
|
+
debugLog("transform", { stage: "pre", mode: state.command, module: redactModulePath(id, state.normalized.root) });
|
|
2094
|
+
recordRewritten(id);
|
|
2095
|
+
},
|
|
1673
2096
|
options: state.normalized,
|
|
1674
2097
|
// build:全量改写;dev:默认仅纯 remote 改写 shared(被宿主消费的组件需协商到宿主实例),
|
|
1675
2098
|
// 双角色宿主可显式 devSharedSelf: true 参与协商
|
|
@@ -1692,7 +2115,7 @@ ${code}`, map: null };
|
|
|
1692
2115
|
for (const tag of html.match(moduleScriptRe) ?? []) {
|
|
1693
2116
|
const src = srcRe.exec(tag)?.[1];
|
|
1694
2117
|
if (!src || src.startsWith("http") || src.startsWith("//")) continue;
|
|
1695
|
-
const abs =
|
|
2118
|
+
const abs = import_node_path6.default.resolve(state.normalized.root, src.startsWith("/") ? src.slice(1) : src);
|
|
1696
2119
|
state.entryAbsPaths.add(abs);
|
|
1697
2120
|
}
|
|
1698
2121
|
return html;
|
|
@@ -1704,7 +2127,7 @@ ${code}`, map: null };
|
|
|
1704
2127
|
if (state.manualChunkSpecsPending) {
|
|
1705
2128
|
for (const [group, specifier] of state.manualChunkSpecsPending) {
|
|
1706
2129
|
try {
|
|
1707
|
-
const r = await this.resolve(specifier,
|
|
2130
|
+
const r = await this.resolve(specifier, import_node_path6.default.join(n.root, "index.html"));
|
|
1708
2131
|
if (r?.id) {
|
|
1709
2132
|
state.manualChunkGroups.set(r.id, group);
|
|
1710
2133
|
state.manualChunkGroups.set(r.id.split("?")[0], group);
|
|
@@ -1734,7 +2157,7 @@ ${code}`, map: null };
|
|
|
1734
2157
|
};
|
|
1735
2158
|
for (const item of n.shared) {
|
|
1736
2159
|
if (item.import === false) continue;
|
|
1737
|
-
const selfFile = await this.resolve(item.import,
|
|
2160
|
+
const selfFile = await this.resolve(item.import, import_node_path6.default.join(n.root, "index.html")).then(
|
|
1738
2161
|
(r) => r?.id?.split("?")[0] ?? null
|
|
1739
2162
|
).catch(() => null);
|
|
1740
2163
|
for (const alias of item.aliases) {
|
|
@@ -1749,7 +2172,7 @@ ${code}`, map: null };
|
|
|
1749
2172
|
}
|
|
1750
2173
|
}
|
|
1751
2174
|
if (!file) {
|
|
1752
|
-
file = await this.resolve(alias,
|
|
2175
|
+
file = await this.resolve(alias, import_node_path6.default.join(n.root, "index.html")).then(
|
|
1753
2176
|
(r) => r?.id?.split("?")[0] ?? null
|
|
1754
2177
|
).catch(() => null);
|
|
1755
2178
|
}
|
|
@@ -1762,10 +2185,17 @@ ${code}`, map: null };
|
|
|
1762
2185
|
}
|
|
1763
2186
|
}
|
|
1764
2187
|
state.sharedClosureRoots = [...rootKeys.entries()].map(([root, keys]) => ({ root, keys }));
|
|
2188
|
+
if (state.sharedClosureRoots.length > 0) {
|
|
2189
|
+
debugLog("facade", {
|
|
2190
|
+
stage: "buildStart",
|
|
2191
|
+
sharedClosureRoots: state.sharedClosureRoots.length,
|
|
2192
|
+
keys: [...new Set(state.sharedClosureRoots.flatMap((r) => [...r.keys]))]
|
|
2193
|
+
});
|
|
2194
|
+
}
|
|
1765
2195
|
}
|
|
1766
2196
|
if (n.exposes.length > 0) {
|
|
1767
2197
|
for (const e of n.exposes) {
|
|
1768
|
-
const resolved = await this.resolve(e.import,
|
|
2198
|
+
const resolved = await this.resolve(e.import, import_node_path6.default.join(n.root, "index.html"));
|
|
1769
2199
|
if (resolved) {
|
|
1770
2200
|
state.exposeAbsPaths[e.import] = resolved.id.split("?")[0];
|
|
1771
2201
|
} else {
|
|
@@ -1818,6 +2248,11 @@ ${code}`, map: null };
|
|
|
1818
2248
|
}
|
|
1819
2249
|
const entryChunkName = Object.keys(bundle).find((k) => bundle[k].type === "chunk" && k === n.filename);
|
|
1820
2250
|
const manifest = genProdManifest(n, state.exposeFiles, entryChunkName ?? n.filename);
|
|
2251
|
+
debugLog("manifest", {
|
|
2252
|
+
stage: "generateBundle",
|
|
2253
|
+
exposes: Object.keys(state.exposeFiles).length,
|
|
2254
|
+
exposesWithCss: Object.values(state.exposeFiles).filter((e) => e.css.length > 0).length
|
|
2255
|
+
});
|
|
1821
2256
|
this.emitFile({
|
|
1822
2257
|
type: "asset",
|
|
1823
2258
|
fileName: "fulgurjs-manifest.json",
|
|
@@ -1845,7 +2280,10 @@ ${code}`, map: null };
|
|
|
1845
2280
|
const raw = (req.url ?? "").split("?")[0];
|
|
1846
2281
|
const stripped = raw.startsWith(baseNorm) ? `/${raw.slice(baseNorm.length)}` : raw;
|
|
1847
2282
|
if (stripped === "/@fulgurjs-entry.js" || stripped === "/@fulgurjs-manifest.json") {
|
|
1848
|
-
|
|
2283
|
+
const origin = Array.isArray(req.headers.origin) ? req.headers.origin[0] : req.headers.origin;
|
|
2284
|
+
for (const [k, v] of Object.entries(corsHeadersFor(origin, n.devCorsOrigins))) {
|
|
2285
|
+
res.setHeader(k, v);
|
|
2286
|
+
}
|
|
1849
2287
|
res.setHeader("Access-Control-Allow-Methods", "GET,OPTIONS");
|
|
1850
2288
|
res.setHeader("Access-Control-Allow-Headers", "*");
|
|
1851
2289
|
if (req.method === "OPTIONS") {
|
|
@@ -1918,20 +2356,11 @@ ${code}`, map: null };
|
|
|
1918
2356
|
if (state.command === "serve" && clean.includes("node_modules") && !id.includes(".vite/deps") && !devRewriteAll) {
|
|
1919
2357
|
return null;
|
|
1920
2358
|
}
|
|
1921
|
-
if (state.command === "build"
|
|
1922
|
-
|
|
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
|
-
});
|
|
2359
|
+
if (state.command === "build") {
|
|
2360
|
+
return buildFallbackTransform(code, id);
|
|
1931
2361
|
}
|
|
1932
|
-
const rewriteShared = state.
|
|
2362
|
+
const rewriteShared = state.normalized.devSharedSelf;
|
|
1933
2363
|
const remapSpecifier = (spec) => {
|
|
1934
|
-
if (state.normalized.shared.some((s) => s.aliases.includes(spec))) return spec;
|
|
1935
2364
|
const depMatch = spec.match(/\/node_modules\/\.vite\/deps\/([^/?]+)\.js/);
|
|
1936
2365
|
if (depMatch) {
|
|
1937
2366
|
const depName = depMatch[1];
|
|
@@ -1942,14 +2371,13 @@ ${code}`, map: null };
|
|
|
1942
2371
|
if (!cleanPath.startsWith("/")) return null;
|
|
1943
2372
|
return state.resolvedSharedPaths.get(cleanPath) ?? null;
|
|
1944
2373
|
};
|
|
1945
|
-
|
|
2374
|
+
return transformModule(code, id, {
|
|
2375
|
+
onRewrite: () => recordRewritten(id),
|
|
1946
2376
|
options: state.normalized,
|
|
1947
2377
|
remapSpecifier,
|
|
1948
2378
|
rewriteShared,
|
|
1949
|
-
allowNodeModules: state.command === "build" ? isPureRemoteBuild || state.normalized.devSharedSelf : void 0,
|
|
1950
2379
|
sharedClosureRoots: state.sharedClosureRoots
|
|
1951
2380
|
});
|
|
1952
|
-
return __r;
|
|
1953
2381
|
}
|
|
1954
2382
|
};
|
|
1955
2383
|
function warmResolvedSharedPaths(server) {
|
|
@@ -1957,12 +2385,32 @@ ${code}`, map: null };
|
|
|
1957
2385
|
if (!n) return;
|
|
1958
2386
|
for (const s of n.shared) {
|
|
1959
2387
|
if (s.import === false) continue;
|
|
1960
|
-
void server.pluginContainer.resolveId(s.import,
|
|
2388
|
+
void server.pluginContainer.resolveId(s.import, import_node_path6.default.join(n.root, "index.html")).then((r) => {
|
|
1961
2389
|
if (r?.id) state.resolvedSharedPaths.set(r.id.split("?")[0], s.configKey);
|
|
1962
2390
|
}).catch(() => {
|
|
1963
2391
|
});
|
|
1964
2392
|
}
|
|
1965
2393
|
}
|
|
2394
|
+
async function buildFallbackTransform(code, id) {
|
|
2395
|
+
if (/type=(style|template)/.test(id)) return null;
|
|
2396
|
+
const clean = id.split("?")[0];
|
|
2397
|
+
const isJsLike = /\.(m|c)?[jt]sx?$/.test(clean) || clean.endsWith(".vue");
|
|
2398
|
+
if (!isJsLike) return null;
|
|
2399
|
+
const quickCheck = /require\s*\(\s*["']|(?:from|import)\s*["']/.test(code);
|
|
2400
|
+
if (!quickCheck) return null;
|
|
2401
|
+
const n = state.normalized;
|
|
2402
|
+
const isPureRemoteBuild = n.exposes.length > 0 && n.remotes.length === 0;
|
|
2403
|
+
return transformModule(code, id, {
|
|
2404
|
+
onRewrite: () => {
|
|
2405
|
+
debugLog("transform", { stage: "post-fallback", mode: "build", module: redactModulePath(id, n.root) });
|
|
2406
|
+
recordRewritten(id);
|
|
2407
|
+
},
|
|
2408
|
+
options: n,
|
|
2409
|
+
rewriteShared: true,
|
|
2410
|
+
allowNodeModules: isPureRemoteBuild || n.devSharedSelf,
|
|
2411
|
+
sharedClosureRoots: state.sharedClosureRoots
|
|
2412
|
+
});
|
|
2413
|
+
}
|
|
1966
2414
|
return [pre, post];
|
|
1967
2415
|
}
|
|
1968
2416
|
var index_default = federation;
|