vanilla-native-federation
Version:
A lightweight **runtime micro frontend orchestrator** that loads micro frontends built with native federation into any web page. It can cache dependencies across page reloads, making it perfect for traditional server-rendered hosts (PHP, Java, Rails, etc.
2,540 lines • 90.1 kB
JavaScript
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __commonJS = (cb, mod) => function __require() {
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
// If the importer is in node compatibility mode or this is not an ESM
// file that has been converted to a CommonJS file using a Babel-
// compatible transform (i.e. "__esModule" has not been set), then set
// "default" to the CommonJS "module.exports" for node compatibility.
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
mod
));
// node_modules/.pnpm/semver@7.7.3/node_modules/semver/internal/debug.js
var require_debug = __commonJS({
"node_modules/.pnpm/semver@7.7.3/node_modules/semver/internal/debug.js"(exports, module) {
"use strict";
var debug = typeof process === "object" && process.env && process.env.NODE_DEBUG && /\bsemver\b/i.test(process.env.NODE_DEBUG) ? (...args) => console.error("SEMVER", ...args) : () => {
};
module.exports = debug;
}
});
// node_modules/.pnpm/semver@7.7.3/node_modules/semver/internal/constants.js
var require_constants = __commonJS({
"node_modules/.pnpm/semver@7.7.3/node_modules/semver/internal/constants.js"(exports, module) {
"use strict";
var SEMVER_SPEC_VERSION = "2.0.0";
var MAX_LENGTH = 256;
var MAX_SAFE_INTEGER = Number.MAX_SAFE_INTEGER || /* istanbul ignore next */
9007199254740991;
var MAX_SAFE_COMPONENT_LENGTH = 16;
var MAX_SAFE_BUILD_LENGTH = MAX_LENGTH - 6;
var RELEASE_TYPES = [
"major",
"premajor",
"minor",
"preminor",
"patch",
"prepatch",
"prerelease"
];
module.exports = {
MAX_LENGTH,
MAX_SAFE_COMPONENT_LENGTH,
MAX_SAFE_BUILD_LENGTH,
MAX_SAFE_INTEGER,
RELEASE_TYPES,
SEMVER_SPEC_VERSION,
FLAG_INCLUDE_PRERELEASE: 1,
FLAG_LOOSE: 2
};
}
});
// node_modules/.pnpm/semver@7.7.3/node_modules/semver/internal/re.js
var require_re = __commonJS({
"node_modules/.pnpm/semver@7.7.3/node_modules/semver/internal/re.js"(exports, module) {
"use strict";
var {
MAX_SAFE_COMPONENT_LENGTH,
MAX_SAFE_BUILD_LENGTH,
MAX_LENGTH
} = require_constants();
var debug = require_debug();
exports = module.exports = {};
var re = exports.re = [];
var safeRe = exports.safeRe = [];
var src = exports.src = [];
var safeSrc = exports.safeSrc = [];
var t = exports.t = {};
var R = 0;
var LETTERDASHNUMBER = "[a-zA-Z0-9-]";
var safeRegexReplacements = [
["\\s", 1],
["\\d", MAX_LENGTH],
[LETTERDASHNUMBER, MAX_SAFE_BUILD_LENGTH]
];
var makeSafeRegex = (value) => {
for (const [token, max] of safeRegexReplacements) {
value = value.split(`${token}*`).join(`${token}{0,${max}}`).split(`${token}+`).join(`${token}{1,${max}}`);
}
return value;
};
var createToken = (name, value, isGlobal) => {
const safe = makeSafeRegex(value);
const index = R++;
debug(name, index, value);
t[name] = index;
src[index] = value;
safeSrc[index] = safe;
re[index] = new RegExp(value, isGlobal ? "g" : void 0);
safeRe[index] = new RegExp(safe, isGlobal ? "g" : void 0);
};
createToken("NUMERICIDENTIFIER", "0|[1-9]\\d*");
createToken("NUMERICIDENTIFIERLOOSE", "\\d+");
createToken("NONNUMERICIDENTIFIER", `\\d*[a-zA-Z-]${LETTERDASHNUMBER}*`);
createToken("MAINVERSION", `(${src[t.NUMERICIDENTIFIER]})\\.(${src[t.NUMERICIDENTIFIER]})\\.(${src[t.NUMERICIDENTIFIER]})`);
createToken("MAINVERSIONLOOSE", `(${src[t.NUMERICIDENTIFIERLOOSE]})\\.(${src[t.NUMERICIDENTIFIERLOOSE]})\\.(${src[t.NUMERICIDENTIFIERLOOSE]})`);
createToken("PRERELEASEIDENTIFIER", `(?:${src[t.NONNUMERICIDENTIFIER]}|${src[t.NUMERICIDENTIFIER]})`);
createToken("PRERELEASEIDENTIFIERLOOSE", `(?:${src[t.NONNUMERICIDENTIFIER]}|${src[t.NUMERICIDENTIFIERLOOSE]})`);
createToken("PRERELEASE", `(?:-(${src[t.PRERELEASEIDENTIFIER]}(?:\\.${src[t.PRERELEASEIDENTIFIER]})*))`);
createToken("PRERELEASELOOSE", `(?:-?(${src[t.PRERELEASEIDENTIFIERLOOSE]}(?:\\.${src[t.PRERELEASEIDENTIFIERLOOSE]})*))`);
createToken("BUILDIDENTIFIER", `${LETTERDASHNUMBER}+`);
createToken("BUILD", `(?:\\+(${src[t.BUILDIDENTIFIER]}(?:\\.${src[t.BUILDIDENTIFIER]})*))`);
createToken("FULLPLAIN", `v?${src[t.MAINVERSION]}${src[t.PRERELEASE]}?${src[t.BUILD]}?`);
createToken("FULL", `^${src[t.FULLPLAIN]}$`);
createToken("LOOSEPLAIN", `[v=\\s]*${src[t.MAINVERSIONLOOSE]}${src[t.PRERELEASELOOSE]}?${src[t.BUILD]}?`);
createToken("LOOSE", `^${src[t.LOOSEPLAIN]}$`);
createToken("GTLT", "((?:<|>)?=?)");
createToken("XRANGEIDENTIFIERLOOSE", `${src[t.NUMERICIDENTIFIERLOOSE]}|x|X|\\*`);
createToken("XRANGEIDENTIFIER", `${src[t.NUMERICIDENTIFIER]}|x|X|\\*`);
createToken("XRANGEPLAIN", `[v=\\s]*(${src[t.XRANGEIDENTIFIER]})(?:\\.(${src[t.XRANGEIDENTIFIER]})(?:\\.(${src[t.XRANGEIDENTIFIER]})(?:${src[t.PRERELEASE]})?${src[t.BUILD]}?)?)?`);
createToken("XRANGEPLAINLOOSE", `[v=\\s]*(${src[t.XRANGEIDENTIFIERLOOSE]})(?:\\.(${src[t.XRANGEIDENTIFIERLOOSE]})(?:\\.(${src[t.XRANGEIDENTIFIERLOOSE]})(?:${src[t.PRERELEASELOOSE]})?${src[t.BUILD]}?)?)?`);
createToken("XRANGE", `^${src[t.GTLT]}\\s*${src[t.XRANGEPLAIN]}$`);
createToken("XRANGELOOSE", `^${src[t.GTLT]}\\s*${src[t.XRANGEPLAINLOOSE]}$`);
createToken("COERCEPLAIN", `${"(^|[^\\d])(\\d{1,"}${MAX_SAFE_COMPONENT_LENGTH}})(?:\\.(\\d{1,${MAX_SAFE_COMPONENT_LENGTH}}))?(?:\\.(\\d{1,${MAX_SAFE_COMPONENT_LENGTH}}))?`);
createToken("COERCE", `${src[t.COERCEPLAIN]}(?:$|[^\\d])`);
createToken("COERCEFULL", src[t.COERCEPLAIN] + `(?:${src[t.PRERELEASE]})?(?:${src[t.BUILD]})?(?:$|[^\\d])`);
createToken("COERCERTL", src[t.COERCE], true);
createToken("COERCERTLFULL", src[t.COERCEFULL], true);
createToken("LONETILDE", "(?:~>?)");
createToken("TILDETRIM", `(\\s*)${src[t.LONETILDE]}\\s+`, true);
exports.tildeTrimReplace = "$1~";
createToken("TILDE", `^${src[t.LONETILDE]}${src[t.XRANGEPLAIN]}$`);
createToken("TILDELOOSE", `^${src[t.LONETILDE]}${src[t.XRANGEPLAINLOOSE]}$`);
createToken("LONECARET", "(?:\\^)");
createToken("CARETTRIM", `(\\s*)${src[t.LONECARET]}\\s+`, true);
exports.caretTrimReplace = "$1^";
createToken("CARET", `^${src[t.LONECARET]}${src[t.XRANGEPLAIN]}$`);
createToken("CARETLOOSE", `^${src[t.LONECARET]}${src[t.XRANGEPLAINLOOSE]}$`);
createToken("COMPARATORLOOSE", `^${src[t.GTLT]}\\s*(${src[t.LOOSEPLAIN]})$|^$`);
createToken("COMPARATOR", `^${src[t.GTLT]}\\s*(${src[t.FULLPLAIN]})$|^$`);
createToken("COMPARATORTRIM", `(\\s*)${src[t.GTLT]}\\s*(${src[t.LOOSEPLAIN]}|${src[t.XRANGEPLAIN]})`, true);
exports.comparatorTrimReplace = "$1$2$3";
createToken("HYPHENRANGE", `^\\s*(${src[t.XRANGEPLAIN]})\\s+-\\s+(${src[t.XRANGEPLAIN]})\\s*$`);
createToken("HYPHENRANGELOOSE", `^\\s*(${src[t.XRANGEPLAINLOOSE]})\\s+-\\s+(${src[t.XRANGEPLAINLOOSE]})\\s*$`);
createToken("STAR", "(<|>)?=?\\s*\\*");
createToken("GTE0", "^\\s*>=\\s*0\\.0\\.0\\s*$");
createToken("GTE0PRE", "^\\s*>=\\s*0\\.0\\.0-0\\s*$");
}
});
// node_modules/.pnpm/semver@7.7.3/node_modules/semver/internal/parse-options.js
var require_parse_options = __commonJS({
"node_modules/.pnpm/semver@7.7.3/node_modules/semver/internal/parse-options.js"(exports, module) {
"use strict";
var looseOption = Object.freeze({ loose: true });
var emptyOpts = Object.freeze({});
var parseOptions = (options) => {
if (!options) {
return emptyOpts;
}
if (typeof options !== "object") {
return looseOption;
}
return options;
};
module.exports = parseOptions;
}
});
// node_modules/.pnpm/semver@7.7.3/node_modules/semver/internal/identifiers.js
var require_identifiers = __commonJS({
"node_modules/.pnpm/semver@7.7.3/node_modules/semver/internal/identifiers.js"(exports, module) {
"use strict";
var numeric = /^[0-9]+$/;
var compareIdentifiers = (a, b) => {
if (typeof a === "number" && typeof b === "number") {
return a === b ? 0 : a < b ? -1 : 1;
}
const anum = numeric.test(a);
const bnum = numeric.test(b);
if (anum && bnum) {
a = +a;
b = +b;
}
return a === b ? 0 : anum && !bnum ? -1 : bnum && !anum ? 1 : a < b ? -1 : 1;
};
var rcompareIdentifiers = (a, b) => compareIdentifiers(b, a);
module.exports = {
compareIdentifiers,
rcompareIdentifiers
};
}
});
// node_modules/.pnpm/semver@7.7.3/node_modules/semver/classes/semver.js
var require_semver = __commonJS({
"node_modules/.pnpm/semver@7.7.3/node_modules/semver/classes/semver.js"(exports, module) {
"use strict";
var debug = require_debug();
var { MAX_LENGTH, MAX_SAFE_INTEGER } = require_constants();
var { safeRe: re, t } = require_re();
var parseOptions = require_parse_options();
var { compareIdentifiers } = require_identifiers();
var SemVer = class _SemVer {
constructor(version, options) {
options = parseOptions(options);
if (version instanceof _SemVer) {
if (version.loose === !!options.loose && version.includePrerelease === !!options.includePrerelease) {
return version;
} else {
version = version.version;
}
} else if (typeof version !== "string") {
throw new TypeError(`Invalid version. Must be a string. Got type "${typeof version}".`);
}
if (version.length > MAX_LENGTH) {
throw new TypeError(
`version is longer than ${MAX_LENGTH} characters`
);
}
debug("SemVer", version, options);
this.options = options;
this.loose = !!options.loose;
this.includePrerelease = !!options.includePrerelease;
const m = version.trim().match(options.loose ? re[t.LOOSE] : re[t.FULL]);
if (!m) {
throw new TypeError(`Invalid Version: ${version}`);
}
this.raw = version;
this.major = +m[1];
this.minor = +m[2];
this.patch = +m[3];
if (this.major > MAX_SAFE_INTEGER || this.major < 0) {
throw new TypeError("Invalid major version");
}
if (this.minor > MAX_SAFE_INTEGER || this.minor < 0) {
throw new TypeError("Invalid minor version");
}
if (this.patch > MAX_SAFE_INTEGER || this.patch < 0) {
throw new TypeError("Invalid patch version");
}
if (!m[4]) {
this.prerelease = [];
} else {
this.prerelease = m[4].split(".").map((id) => {
if (/^[0-9]+$/.test(id)) {
const num = +id;
if (num >= 0 && num < MAX_SAFE_INTEGER) {
return num;
}
}
return id;
});
}
this.build = m[5] ? m[5].split(".") : [];
this.format();
}
format() {
this.version = `${this.major}.${this.minor}.${this.patch}`;
if (this.prerelease.length) {
this.version += `-${this.prerelease.join(".")}`;
}
return this.version;
}
toString() {
return this.version;
}
compare(other) {
debug("SemVer.compare", this.version, this.options, other);
if (!(other instanceof _SemVer)) {
if (typeof other === "string" && other === this.version) {
return 0;
}
other = new _SemVer(other, this.options);
}
if (other.version === this.version) {
return 0;
}
return this.compareMain(other) || this.comparePre(other);
}
compareMain(other) {
if (!(other instanceof _SemVer)) {
other = new _SemVer(other, this.options);
}
if (this.major < other.major) {
return -1;
}
if (this.major > other.major) {
return 1;
}
if (this.minor < other.minor) {
return -1;
}
if (this.minor > other.minor) {
return 1;
}
if (this.patch < other.patch) {
return -1;
}
if (this.patch > other.patch) {
return 1;
}
return 0;
}
comparePre(other) {
if (!(other instanceof _SemVer)) {
other = new _SemVer(other, this.options);
}
if (this.prerelease.length && !other.prerelease.length) {
return -1;
} else if (!this.prerelease.length && other.prerelease.length) {
return 1;
} else if (!this.prerelease.length && !other.prerelease.length) {
return 0;
}
let i = 0;
do {
const a = this.prerelease[i];
const b = other.prerelease[i];
debug("prerelease compare", i, a, b);
if (a === void 0 && b === void 0) {
return 0;
} else if (b === void 0) {
return 1;
} else if (a === void 0) {
return -1;
} else if (a === b) {
continue;
} else {
return compareIdentifiers(a, b);
}
} while (++i);
}
compareBuild(other) {
if (!(other instanceof _SemVer)) {
other = new _SemVer(other, this.options);
}
let i = 0;
do {
const a = this.build[i];
const b = other.build[i];
debug("build compare", i, a, b);
if (a === void 0 && b === void 0) {
return 0;
} else if (b === void 0) {
return 1;
} else if (a === void 0) {
return -1;
} else if (a === b) {
continue;
} else {
return compareIdentifiers(a, b);
}
} while (++i);
}
// preminor will bump the version up to the next minor release, and immediately
// down to pre-release. premajor and prepatch work the same way.
inc(release, identifier, identifierBase) {
if (release.startsWith("pre")) {
if (!identifier && identifierBase === false) {
throw new Error("invalid increment argument: identifier is empty");
}
if (identifier) {
const match = `-${identifier}`.match(this.options.loose ? re[t.PRERELEASELOOSE] : re[t.PRERELEASE]);
if (!match || match[1] !== identifier) {
throw new Error(`invalid identifier: ${identifier}`);
}
}
}
switch (release) {
case "premajor":
this.prerelease.length = 0;
this.patch = 0;
this.minor = 0;
this.major++;
this.inc("pre", identifier, identifierBase);
break;
case "preminor":
this.prerelease.length = 0;
this.patch = 0;
this.minor++;
this.inc("pre", identifier, identifierBase);
break;
case "prepatch":
this.prerelease.length = 0;
this.inc("patch", identifier, identifierBase);
this.inc("pre", identifier, identifierBase);
break;
// If the input is a non-prerelease version, this acts the same as
// prepatch.
case "prerelease":
if (this.prerelease.length === 0) {
this.inc("patch", identifier, identifierBase);
}
this.inc("pre", identifier, identifierBase);
break;
case "release":
if (this.prerelease.length === 0) {
throw new Error(`version ${this.raw} is not a prerelease`);
}
this.prerelease.length = 0;
break;
case "major":
if (this.minor !== 0 || this.patch !== 0 || this.prerelease.length === 0) {
this.major++;
}
this.minor = 0;
this.patch = 0;
this.prerelease = [];
break;
case "minor":
if (this.patch !== 0 || this.prerelease.length === 0) {
this.minor++;
}
this.patch = 0;
this.prerelease = [];
break;
case "patch":
if (this.prerelease.length === 0) {
this.patch++;
}
this.prerelease = [];
break;
// This probably shouldn't be used publicly.
// 1.0.0 'pre' would become 1.0.0-0 which is the wrong direction.
case "pre": {
const base = Number(identifierBase) ? 1 : 0;
if (this.prerelease.length === 0) {
this.prerelease = [base];
} else {
let i = this.prerelease.length;
while (--i >= 0) {
if (typeof this.prerelease[i] === "number") {
this.prerelease[i]++;
i = -2;
}
}
if (i === -1) {
if (identifier === this.prerelease.join(".") && identifierBase === false) {
throw new Error("invalid increment argument: identifier already exists");
}
this.prerelease.push(base);
}
}
if (identifier) {
let prerelease = [identifier, base];
if (identifierBase === false) {
prerelease = [identifier];
}
if (compareIdentifiers(this.prerelease[0], identifier) === 0) {
if (isNaN(this.prerelease[1])) {
this.prerelease = prerelease;
}
} else {
this.prerelease = prerelease;
}
}
break;
}
default:
throw new Error(`invalid increment argument: ${release}`);
}
this.raw = this.format();
if (this.build.length) {
this.raw += `+${this.build.join(".")}`;
}
return this;
}
};
module.exports = SemVer;
}
});
// node_modules/.pnpm/semver@7.7.3/node_modules/semver/functions/parse.js
var require_parse = __commonJS({
"node_modules/.pnpm/semver@7.7.3/node_modules/semver/functions/parse.js"(exports, module) {
"use strict";
var SemVer = require_semver();
var parse = (version, options, throwErrors = false) => {
if (version instanceof SemVer) {
return version;
}
try {
return new SemVer(version, options);
} catch (er) {
if (!throwErrors) {
return null;
}
throw er;
}
};
module.exports = parse;
}
});
// node_modules/.pnpm/semver@7.7.3/node_modules/semver/functions/valid.js
var require_valid = __commonJS({
"node_modules/.pnpm/semver@7.7.3/node_modules/semver/functions/valid.js"(exports, module) {
"use strict";
var parse = require_parse();
var valid = (version, options) => {
const v = parse(version, options);
return v ? v.version : null;
};
module.exports = valid;
}
});
// node_modules/.pnpm/semver@7.7.3/node_modules/semver/internal/lrucache.js
var require_lrucache = __commonJS({
"node_modules/.pnpm/semver@7.7.3/node_modules/semver/internal/lrucache.js"(exports, module) {
"use strict";
var LRUCache = class {
constructor() {
this.max = 1e3;
this.map = /* @__PURE__ */ new Map();
}
get(key) {
const value = this.map.get(key);
if (value === void 0) {
return void 0;
} else {
this.map.delete(key);
this.map.set(key, value);
return value;
}
}
delete(key) {
return this.map.delete(key);
}
set(key, value) {
const deleted = this.delete(key);
if (!deleted && value !== void 0) {
if (this.map.size >= this.max) {
const firstKey = this.map.keys().next().value;
this.delete(firstKey);
}
this.map.set(key, value);
}
return this;
}
};
module.exports = LRUCache;
}
});
// node_modules/.pnpm/semver@7.7.3/node_modules/semver/functions/compare.js
var require_compare = __commonJS({
"node_modules/.pnpm/semver@7.7.3/node_modules/semver/functions/compare.js"(exports, module) {
"use strict";
var SemVer = require_semver();
var compare = (a, b, loose) => new SemVer(a, loose).compare(new SemVer(b, loose));
module.exports = compare;
}
});
// node_modules/.pnpm/semver@7.7.3/node_modules/semver/functions/eq.js
var require_eq = __commonJS({
"node_modules/.pnpm/semver@7.7.3/node_modules/semver/functions/eq.js"(exports, module) {
"use strict";
var compare = require_compare();
var eq = (a, b, loose) => compare(a, b, loose) === 0;
module.exports = eq;
}
});
// node_modules/.pnpm/semver@7.7.3/node_modules/semver/functions/neq.js
var require_neq = __commonJS({
"node_modules/.pnpm/semver@7.7.3/node_modules/semver/functions/neq.js"(exports, module) {
"use strict";
var compare = require_compare();
var neq = (a, b, loose) => compare(a, b, loose) !== 0;
module.exports = neq;
}
});
// node_modules/.pnpm/semver@7.7.3/node_modules/semver/functions/gt.js
var require_gt = __commonJS({
"node_modules/.pnpm/semver@7.7.3/node_modules/semver/functions/gt.js"(exports, module) {
"use strict";
var compare = require_compare();
var gt = (a, b, loose) => compare(a, b, loose) > 0;
module.exports = gt;
}
});
// node_modules/.pnpm/semver@7.7.3/node_modules/semver/functions/gte.js
var require_gte = __commonJS({
"node_modules/.pnpm/semver@7.7.3/node_modules/semver/functions/gte.js"(exports, module) {
"use strict";
var compare = require_compare();
var gte = (a, b, loose) => compare(a, b, loose) >= 0;
module.exports = gte;
}
});
// node_modules/.pnpm/semver@7.7.3/node_modules/semver/functions/lt.js
var require_lt = __commonJS({
"node_modules/.pnpm/semver@7.7.3/node_modules/semver/functions/lt.js"(exports, module) {
"use strict";
var compare = require_compare();
var lt = (a, b, loose) => compare(a, b, loose) < 0;
module.exports = lt;
}
});
// node_modules/.pnpm/semver@7.7.3/node_modules/semver/functions/lte.js
var require_lte = __commonJS({
"node_modules/.pnpm/semver@7.7.3/node_modules/semver/functions/lte.js"(exports, module) {
"use strict";
var compare = require_compare();
var lte = (a, b, loose) => compare(a, b, loose) <= 0;
module.exports = lte;
}
});
// node_modules/.pnpm/semver@7.7.3/node_modules/semver/functions/cmp.js
var require_cmp = __commonJS({
"node_modules/.pnpm/semver@7.7.3/node_modules/semver/functions/cmp.js"(exports, module) {
"use strict";
var eq = require_eq();
var neq = require_neq();
var gt = require_gt();
var gte = require_gte();
var lt = require_lt();
var lte = require_lte();
var cmp = (a, op, b, loose) => {
switch (op) {
case "===":
if (typeof a === "object") {
a = a.version;
}
if (typeof b === "object") {
b = b.version;
}
return a === b;
case "!==":
if (typeof a === "object") {
a = a.version;
}
if (typeof b === "object") {
b = b.version;
}
return a !== b;
case "":
case "=":
case "==":
return eq(a, b, loose);
case "!=":
return neq(a, b, loose);
case ">":
return gt(a, b, loose);
case ">=":
return gte(a, b, loose);
case "<":
return lt(a, b, loose);
case "<=":
return lte(a, b, loose);
default:
throw new TypeError(`Invalid operator: ${op}`);
}
};
module.exports = cmp;
}
});
// node_modules/.pnpm/semver@7.7.3/node_modules/semver/classes/comparator.js
var require_comparator = __commonJS({
"node_modules/.pnpm/semver@7.7.3/node_modules/semver/classes/comparator.js"(exports, module) {
"use strict";
var ANY = /* @__PURE__ */ Symbol("SemVer ANY");
var Comparator = class _Comparator {
static get ANY() {
return ANY;
}
constructor(comp, options) {
options = parseOptions(options);
if (comp instanceof _Comparator) {
if (comp.loose === !!options.loose) {
return comp;
} else {
comp = comp.value;
}
}
comp = comp.trim().split(/\s+/).join(" ");
debug("comparator", comp, options);
this.options = options;
this.loose = !!options.loose;
this.parse(comp);
if (this.semver === ANY) {
this.value = "";
} else {
this.value = this.operator + this.semver.version;
}
debug("comp", this);
}
parse(comp) {
const r = this.options.loose ? re[t.COMPARATORLOOSE] : re[t.COMPARATOR];
const m = comp.match(r);
if (!m) {
throw new TypeError(`Invalid comparator: ${comp}`);
}
this.operator = m[1] !== void 0 ? m[1] : "";
if (this.operator === "=") {
this.operator = "";
}
if (!m[2]) {
this.semver = ANY;
} else {
this.semver = new SemVer(m[2], this.options.loose);
}
}
toString() {
return this.value;
}
test(version) {
debug("Comparator.test", version, this.options.loose);
if (this.semver === ANY || version === ANY) {
return true;
}
if (typeof version === "string") {
try {
version = new SemVer(version, this.options);
} catch (er) {
return false;
}
}
return cmp(version, this.operator, this.semver, this.options);
}
intersects(comp, options) {
if (!(comp instanceof _Comparator)) {
throw new TypeError("a Comparator is required");
}
if (this.operator === "") {
if (this.value === "") {
return true;
}
return new Range(comp.value, options).test(this.value);
} else if (comp.operator === "") {
if (comp.value === "") {
return true;
}
return new Range(this.value, options).test(comp.semver);
}
options = parseOptions(options);
if (options.includePrerelease && (this.value === "<0.0.0-0" || comp.value === "<0.0.0-0")) {
return false;
}
if (!options.includePrerelease && (this.value.startsWith("<0.0.0") || comp.value.startsWith("<0.0.0"))) {
return false;
}
if (this.operator.startsWith(">") && comp.operator.startsWith(">")) {
return true;
}
if (this.operator.startsWith("<") && comp.operator.startsWith("<")) {
return true;
}
if (this.semver.version === comp.semver.version && this.operator.includes("=") && comp.operator.includes("=")) {
return true;
}
if (cmp(this.semver, "<", comp.semver, options) && this.operator.startsWith(">") && comp.operator.startsWith("<")) {
return true;
}
if (cmp(this.semver, ">", comp.semver, options) && this.operator.startsWith("<") && comp.operator.startsWith(">")) {
return true;
}
return false;
}
};
module.exports = Comparator;
var parseOptions = require_parse_options();
var { safeRe: re, t } = require_re();
var cmp = require_cmp();
var debug = require_debug();
var SemVer = require_semver();
var Range = require_range();
}
});
// node_modules/.pnpm/semver@7.7.3/node_modules/semver/classes/range.js
var require_range = __commonJS({
"node_modules/.pnpm/semver@7.7.3/node_modules/semver/classes/range.js"(exports, module) {
"use strict";
var SPACE_CHARACTERS = /\s+/g;
var Range = class _Range {
constructor(range, options) {
options = parseOptions(options);
if (range instanceof _Range) {
if (range.loose === !!options.loose && range.includePrerelease === !!options.includePrerelease) {
return range;
} else {
return new _Range(range.raw, options);
}
}
if (range instanceof Comparator) {
this.raw = range.value;
this.set = [[range]];
this.formatted = void 0;
return this;
}
this.options = options;
this.loose = !!options.loose;
this.includePrerelease = !!options.includePrerelease;
this.raw = range.trim().replace(SPACE_CHARACTERS, " ");
this.set = this.raw.split("||").map((r) => this.parseRange(r.trim())).filter((c) => c.length);
if (!this.set.length) {
throw new TypeError(`Invalid SemVer Range: ${this.raw}`);
}
if (this.set.length > 1) {
const first = this.set[0];
this.set = this.set.filter((c) => !isNullSet(c[0]));
if (this.set.length === 0) {
this.set = [first];
} else if (this.set.length > 1) {
for (const c of this.set) {
if (c.length === 1 && isAny(c[0])) {
this.set = [c];
break;
}
}
}
}
this.formatted = void 0;
}
get range() {
if (this.formatted === void 0) {
this.formatted = "";
for (let i = 0; i < this.set.length; i++) {
if (i > 0) {
this.formatted += "||";
}
const comps = this.set[i];
for (let k = 0; k < comps.length; k++) {
if (k > 0) {
this.formatted += " ";
}
this.formatted += comps[k].toString().trim();
}
}
}
return this.formatted;
}
format() {
return this.range;
}
toString() {
return this.range;
}
parseRange(range) {
const memoOpts = (this.options.includePrerelease && FLAG_INCLUDE_PRERELEASE) | (this.options.loose && FLAG_LOOSE);
const memoKey = memoOpts + ":" + range;
const cached = cache.get(memoKey);
if (cached) {
return cached;
}
const loose = this.options.loose;
const hr = loose ? re[t.HYPHENRANGELOOSE] : re[t.HYPHENRANGE];
range = range.replace(hr, hyphenReplace(this.options.includePrerelease));
debug("hyphen replace", range);
range = range.replace(re[t.COMPARATORTRIM], comparatorTrimReplace);
debug("comparator trim", range);
range = range.replace(re[t.TILDETRIM], tildeTrimReplace);
debug("tilde trim", range);
range = range.replace(re[t.CARETTRIM], caretTrimReplace);
debug("caret trim", range);
let rangeList = range.split(" ").map((comp) => parseComparator(comp, this.options)).join(" ").split(/\s+/).map((comp) => replaceGTE0(comp, this.options));
if (loose) {
rangeList = rangeList.filter((comp) => {
debug("loose invalid filter", comp, this.options);
return !!comp.match(re[t.COMPARATORLOOSE]);
});
}
debug("range list", rangeList);
const rangeMap = /* @__PURE__ */ new Map();
const comparators = rangeList.map((comp) => new Comparator(comp, this.options));
for (const comp of comparators) {
if (isNullSet(comp)) {
return [comp];
}
rangeMap.set(comp.value, comp);
}
if (rangeMap.size > 1 && rangeMap.has("")) {
rangeMap.delete("");
}
const result = [...rangeMap.values()];
cache.set(memoKey, result);
return result;
}
intersects(range, options) {
if (!(range instanceof _Range)) {
throw new TypeError("a Range is required");
}
return this.set.some((thisComparators) => {
return isSatisfiable(thisComparators, options) && range.set.some((rangeComparators) => {
return isSatisfiable(rangeComparators, options) && thisComparators.every((thisComparator) => {
return rangeComparators.every((rangeComparator) => {
return thisComparator.intersects(rangeComparator, options);
});
});
});
});
}
// if ANY of the sets match ALL of its comparators, then pass
test(version) {
if (!version) {
return false;
}
if (typeof version === "string") {
try {
version = new SemVer(version, this.options);
} catch (er) {
return false;
}
}
for (let i = 0; i < this.set.length; i++) {
if (testSet(this.set[i], version, this.options)) {
return true;
}
}
return false;
}
};
module.exports = Range;
var LRU = require_lrucache();
var cache = new LRU();
var parseOptions = require_parse_options();
var Comparator = require_comparator();
var debug = require_debug();
var SemVer = require_semver();
var {
safeRe: re,
t,
comparatorTrimReplace,
tildeTrimReplace,
caretTrimReplace
} = require_re();
var { FLAG_INCLUDE_PRERELEASE, FLAG_LOOSE } = require_constants();
var isNullSet = (c) => c.value === "<0.0.0-0";
var isAny = (c) => c.value === "";
var isSatisfiable = (comparators, options) => {
let result = true;
const remainingComparators = comparators.slice();
let testComparator = remainingComparators.pop();
while (result && remainingComparators.length) {
result = remainingComparators.every((otherComparator) => {
return testComparator.intersects(otherComparator, options);
});
testComparator = remainingComparators.pop();
}
return result;
};
var parseComparator = (comp, options) => {
comp = comp.replace(re[t.BUILD], "");
debug("comp", comp, options);
comp = replaceCarets(comp, options);
debug("caret", comp);
comp = replaceTildes(comp, options);
debug("tildes", comp);
comp = replaceXRanges(comp, options);
debug("xrange", comp);
comp = replaceStars(comp, options);
debug("stars", comp);
return comp;
};
var isX = (id) => !id || id.toLowerCase() === "x" || id === "*";
var replaceTildes = (comp, options) => {
return comp.trim().split(/\s+/).map((c) => replaceTilde(c, options)).join(" ");
};
var replaceTilde = (comp, options) => {
const r = options.loose ? re[t.TILDELOOSE] : re[t.TILDE];
return comp.replace(r, (_, M, m, p, pr) => {
debug("tilde", comp, _, M, m, p, pr);
let ret;
if (isX(M)) {
ret = "";
} else if (isX(m)) {
ret = `>=${M}.0.0 <${+M + 1}.0.0-0`;
} else if (isX(p)) {
ret = `>=${M}.${m}.0 <${M}.${+m + 1}.0-0`;
} else if (pr) {
debug("replaceTilde pr", pr);
ret = `>=${M}.${m}.${p}-${pr} <${M}.${+m + 1}.0-0`;
} else {
ret = `>=${M}.${m}.${p} <${M}.${+m + 1}.0-0`;
}
debug("tilde return", ret);
return ret;
});
};
var replaceCarets = (comp, options) => {
return comp.trim().split(/\s+/).map((c) => replaceCaret(c, options)).join(" ");
};
var replaceCaret = (comp, options) => {
debug("caret", comp, options);
const r = options.loose ? re[t.CARETLOOSE] : re[t.CARET];
const z = options.includePrerelease ? "-0" : "";
return comp.replace(r, (_, M, m, p, pr) => {
debug("caret", comp, _, M, m, p, pr);
let ret;
if (isX(M)) {
ret = "";
} else if (isX(m)) {
ret = `>=${M}.0.0${z} <${+M + 1}.0.0-0`;
} else if (isX(p)) {
if (M === "0") {
ret = `>=${M}.${m}.0${z} <${M}.${+m + 1}.0-0`;
} else {
ret = `>=${M}.${m}.0${z} <${+M + 1}.0.0-0`;
}
} else if (pr) {
debug("replaceCaret pr", pr);
if (M === "0") {
if (m === "0") {
ret = `>=${M}.${m}.${p}-${pr} <${M}.${m}.${+p + 1}-0`;
} else {
ret = `>=${M}.${m}.${p}-${pr} <${M}.${+m + 1}.0-0`;
}
} else {
ret = `>=${M}.${m}.${p}-${pr} <${+M + 1}.0.0-0`;
}
} else {
debug("no pr");
if (M === "0") {
if (m === "0") {
ret = `>=${M}.${m}.${p}${z} <${M}.${m}.${+p + 1}-0`;
} else {
ret = `>=${M}.${m}.${p}${z} <${M}.${+m + 1}.0-0`;
}
} else {
ret = `>=${M}.${m}.${p} <${+M + 1}.0.0-0`;
}
}
debug("caret return", ret);
return ret;
});
};
var replaceXRanges = (comp, options) => {
debug("replaceXRanges", comp, options);
return comp.split(/\s+/).map((c) => replaceXRange(c, options)).join(" ");
};
var replaceXRange = (comp, options) => {
comp = comp.trim();
const r = options.loose ? re[t.XRANGELOOSE] : re[t.XRANGE];
return comp.replace(r, (ret, gtlt, M, m, p, pr) => {
debug("xRange", comp, ret, gtlt, M, m, p, pr);
const xM = isX(M);
const xm = xM || isX(m);
const xp = xm || isX(p);
const anyX = xp;
if (gtlt === "=" && anyX) {
gtlt = "";
}
pr = options.includePrerelease ? "-0" : "";
if (xM) {
if (gtlt === ">" || gtlt === "<") {
ret = "<0.0.0-0";
} else {
ret = "*";
}
} else if (gtlt && anyX) {
if (xm) {
m = 0;
}
p = 0;
if (gtlt === ">") {
gtlt = ">=";
if (xm) {
M = +M + 1;
m = 0;
p = 0;
} else {
m = +m + 1;
p = 0;
}
} else if (gtlt === "<=") {
gtlt = "<";
if (xm) {
M = +M + 1;
} else {
m = +m + 1;
}
}
if (gtlt === "<") {
pr = "-0";
}
ret = `${gtlt + M}.${m}.${p}${pr}`;
} else if (xm) {
ret = `>=${M}.0.0${pr} <${+M + 1}.0.0-0`;
} else if (xp) {
ret = `>=${M}.${m}.0${pr} <${M}.${+m + 1}.0-0`;
}
debug("xRange return", ret);
return ret;
});
};
var replaceStars = (comp, options) => {
debug("replaceStars", comp, options);
return comp.trim().replace(re[t.STAR], "");
};
var replaceGTE0 = (comp, options) => {
debug("replaceGTE0", comp, options);
return comp.trim().replace(re[options.includePrerelease ? t.GTE0PRE : t.GTE0], "");
};
var hyphenReplace = (incPr) => ($0, from, fM, fm, fp, fpr, fb, to, tM, tm, tp, tpr) => {
if (isX(fM)) {
from = "";
} else if (isX(fm)) {
from = `>=${fM}.0.0${incPr ? "-0" : ""}`;
} else if (isX(fp)) {
from = `>=${fM}.${fm}.0${incPr ? "-0" : ""}`;
} else if (fpr) {
from = `>=${from}`;
} else {
from = `>=${from}${incPr ? "-0" : ""}`;
}
if (isX(tM)) {
to = "";
} else if (isX(tm)) {
to = `<${+tM + 1}.0.0-0`;
} else if (isX(tp)) {
to = `<${tM}.${+tm + 1}.0-0`;
} else if (tpr) {
to = `<=${tM}.${tm}.${tp}-${tpr}`;
} else if (incPr) {
to = `<${tM}.${tm}.${+tp + 1}-0`;
} else {
to = `<=${to}`;
}
return `${from} ${to}`.trim();
};
var testSet = (set, version, options) => {
for (let i = 0; i < set.length; i++) {
if (!set[i].test(version)) {
return false;
}
}
if (version.prerelease.length && !options.includePrerelease) {
for (let i = 0; i < set.length; i++) {
debug(set[i].semver);
if (set[i].semver === Comparator.ANY) {
continue;
}
if (set[i].semver.prerelease.length > 0) {
const allowed = set[i].semver;
if (allowed.major === version.major && allowed.minor === version.minor && allowed.patch === version.patch) {
return true;
}
}
}
return false;
}
return true;
};
}
});
// node_modules/.pnpm/semver@7.7.3/node_modules/semver/functions/satisfies.js
var require_satisfies = __commonJS({
"node_modules/.pnpm/semver@7.7.3/node_modules/semver/functions/satisfies.js"(exports, module) {
"use strict";
var Range = require_range();
var satisfies = (version, range, options) => {
try {
range = new Range(range, options);
} catch (er) {
return false;
}
return range.test(version);
};
module.exports = satisfies;
}
});
// node_modules/.pnpm/semver@7.7.3/node_modules/semver/ranges/min-version.js
var require_min_version = __commonJS({
"node_modules/.pnpm/semver@7.7.3/node_modules/semver/ranges/min-version.js"(exports, module) {
"use strict";
var SemVer = require_semver();
var Range = require_range();
var gt = require_gt();
var minVersion = (range, loose) => {
range = new Range(range, loose);
let minver = new SemVer("0.0.0");
if (range.test(minver)) {
return minver;
}
minver = new SemVer("0.0.0-0");
if (range.test(minver)) {
return minver;
}
minver = null;
for (let i = 0; i < range.set.length; ++i) {
const comparators = range.set[i];
let setMin = null;
comparators.forEach((comparator) => {
const compver = new SemVer(comparator.semver.version);
switch (comparator.operator) {
case ">":
if (compver.prerelease.length === 0) {
compver.patch++;
} else {
compver.prerelease.push(0);
}
compver.raw = compver.format();
/* fallthrough */
case "":
case ">=":
if (!setMin || gt(compver, setMin)) {
setMin = compver;
}
break;
case "<":
case "<=":
break;
/* istanbul ignore next */
default:
throw new Error(`Unexpected operation: ${comparator.operator}`);
}
});
if (setMin && (!minver || gt(minver, setMin))) {
minver = setMin;
}
}
if (minver && range.test(minver)) {
return minver;
}
return null;
};
module.exports = minVersion;
}
});
// node_modules/.pnpm/semver@7.7.3/node_modules/semver/ranges/valid.js
var require_valid2 = __commonJS({
"node_modules/.pnpm/semver@7.7.3/node_modules/semver/ranges/valid.js"(exports, module) {
"use strict";
var Range = require_range();
var validRange = (range, options) => {
try {
return new Range(range, options).range || "*";
} catch (er) {
return null;
}
};
module.exports = validRange;
}
});
// src/lib/native-federation.error.ts
var NFError = class extends Error {
constructor(message, cause) {
super(message, cause);
this.name = "NFError";
}
};
// src/lib/utils/path.ts
function join(pathA, pathB) {
pathA = pathA.endsWith("/") ? pathA.slice(0, -1) : pathA;
pathB = pathB.startsWith("/") ? pathB.slice(1) : pathB;
return `${pathA}/${pathB}`;
}
function getScope(path) {
if (!path) return "";
const parts = path.split("/");
if (parts[parts.length - 1] === "" || parts[parts.length - 1].includes(".")) {
parts.pop();
}
if (parts.length < 1) return "";
return `${parts.join("/")}/`;
}
// src/lib/2.app/flows/init/get-remote-entries.ts
function createGetRemoteEntries(config, ports) {
return (remotesOrManifestUrl = {}) => ports.manifestProvider.provide(remotesOrManifestUrl).catch((e) => {
config.log.error(1, "Could not fetch manifest.", e);
return Promise.reject(new NFError("Failed to fetch manifest"));
}).then(addHostRemoteEntry).then(fetchRemoteEntries).then(removeSkippedRemotes);
function addHostRemoteEntry(manifest) {
if (!config.hostRemoteEntry) return manifest;
const { name, url, cacheTag } = config.hostRemoteEntry;
const urlWithCache = cacheTag ? `${url}?cacheTag=${cacheTag}` : url;
return {
...manifest,
[name]: urlWithCache
};
}
async function fetchRemoteEntries(manifest) {
const fetchPromises = Object.entries(manifest).map(
([remoteName, remoteEntryUrl]) => fetchRemoteEntry(remoteName, remoteEntryUrl)
);
return Promise.all(fetchPromises);
}
async function fetchRemoteEntry(remoteName, remoteEntryUrl) {
let isOverride = false;
let skip = false;
ports.remoteInfoRepo.tryGet(remoteName).ifPresent((cachedRemoteInfo) => {
if (config.profile.overrideCachedRemotes !== "never" && (remoteEntryUrl !== join(cachedRemoteInfo.scopeUrl, "remoteEntry.json") || config.profile.overrideCachedRemotesIfURLMatches)) {
config.log.debug(1, `Overriding existing remote '${remoteName}' with '${remoteEntryUrl}'.`);
isOverride = true;
} else {
config.log.debug(1, `Found remote '${remoteName}' in storage, omitting fetch.`);
skip = true;
}
});
if (skip) return false;
try {
const remoteEntry = await ports.remoteEntryProvider.provide(remoteEntryUrl);
config.log.debug(
1,
`Fetched '${remoteEntry.name}' from '${remoteEntry.url}', exposing: ${JSON.stringify(remoteEntry.exposes)}`
);
return prepareRemoteEntry(remoteEntry, remoteName, isOverride);
} catch (error) {
if (config.strict.strictRemoteEntry) {
config.log.error(1, `Could not fetch remote '${remoteName}'.`, error);
return Promise.reject(new NFError(`Could not fetch remote '${remoteName}'`));
}
config.log.warn(1, `Could not fetch remote '${remoteName}'. skipping init.`, error);
return Promise.resolve(false);
}
}
function prepareRemoteEntry(remoteEntry, expectedRemoteName, isOverride) {
if (isOverride) remoteEntry.override = isOverride;
if (!!config.hostRemoteEntry && expectedRemoteName === config.hostRemoteEntry.name) {
remoteEntry.host = true;
remoteEntry.name = config.hostRemoteEntry.name;
}
if (remoteEntry.name !== expectedRemoteName) {
const errorDetails = `Fetched remote '${remoteEntry.name}' does not match requested '${expectedRemoteName}'.`;
if (config.strict.strictRemoteEntry) {
throw new NFError(errorDetails);
}
config.log.warn(1, `${errorDetails} Omitting expected name.`);
}
return remoteEntry;
}
function removeSkippedRemotes(remoteEntries) {
return remoteEntries.filter((entry) => entry !== false);
}
}
// src/lib/2.app/flows/init/process-remote-entries.ts
function createProcessRemoteEntries(config, ports) {
return (remoteEntries) => {
try {
remoteEntries.forEach((remoteEntry) => {
if (remoteEntry?.override) removeCachedRemoteEntry(remoteEntry);
addRemoteInfoToStorage(remoteEntry);
addExternalsToStorage(remoteEntry);
});
return Promise.resolve(remoteEntries);
} catch (e) {
return Promise.reject(e);
}
};
function removeCachedRemoteEntry(remoteEntry) {
ports.remoteInfoRepo.remove(remoteEntry.name);
ports.scopedExternalsRepo.remove(remoteEntry.name);
ports.sharedExternalsRepo.removeFromAllScopes(remoteEntry.name);
}
function addRemoteInfoToStorage({ name, url, exposes }) {
ports.remoteInfoRepo.addOrUpdate(name, {
scopeUrl: getScope(url),
exposes: Object.values(exposes ?? []).map((m) => ({
moduleName: m.key,
file: m.outFileName
}))
});
}
function addExternalsToStorage(remoteEntry) {
remoteEntry.shared.forEach((external) => {
if (!external.version || !ports.versionCheck.isValidSemver(external.version)) {
const errorMsg = `[${remoteEntry.name}][${external.packageName}] Version '${external.version}' is not a valid version.`;
if (config.strict.strictExternalVersion) {
config.log.error(2, errorMsg);
throw new NFError(`Could not process remote '${remoteEntry.name}'`);
}
config.log.warn(2, errorMsg);
}
if (external.singleton) {
addSharedExternal(remoteEntry.name, external, remoteEntry);
} else {
addScopedExternal(remoteEntry.name, external);
}
});
}
function addSharedExternal(remoteName, sharedInfo, remoteEntry) {
let action = "skip";
const tag = sharedInfo.version ?? ports.versionCheck.smallestVersion(sharedInfo.requiredVersion);
const remote = {
file: sharedInfo.outFileName,
name: remoteName,
strictVersion: sharedInfo.strictVersion,
cached: false,
requiredVersion: sharedInfo.requiredVersion || tag
};
const scopeType = ports.sharedExternalsRepo.scopeType(sharedInfo.shareScope);
if (scopeType === "strict") {
action = "share";
remote.requiredVersion = tag;
}
const cached = ports.sharedExternalsRepo.tryGet(sharedInfo.packageName, sharedInfo.shareScope).orElse({ dirty: false, versions: [] });
const matchingVersion = cached.versions.find((version) => version.tag === sharedInfo.version);
let dirty = cached.dirty;
if (!!matchingVersion) {
if (remote.strictVersion && matchingVersion.remotes[0].requiredVersion !== remote.requiredVersion) {
const errorMsg = `[${remoteName}][${sharedInfo.packageName}@${sharedInfo.version}] Required version-range '${remote.requiredVersion}' does not match cached version-range '${matchingVersion.remotes[0].requiredVersion}'`;
if (config.strict.strictExternalCompatibility) {
config.log.error(2, errorMsg);
throw new NFError(`Could not process remote '${remoteEntry.name}'`);
}
config.log.warn(2, errorMsg);
}
if (!matchingVersion.host && !!remoteEntry?.host) {
matchingVersion.host = true;
matchingVersion.remotes.unshift(remote);
} else matchingVersion.remotes.push(remote);
} else {
if (scopeType !== "strict") dirty = true;
cached.versions.push({ tag, action, host: !!remoteEntry?.host, remotes: [remote] });
}
ports.sharedExternalsRepo.addOrUpdate(
sharedInfo.packageName,
{
dirty,
versions: cached.versions.sort((a, b) => ports.versionCheck.compare(b.tag, a.tag))
},
sharedInfo.shareScope
);
}
function addScopedExternal(scope, sharedInfo) {
ports.scopedExternalsRepo.addExternal(scope, sharedInfo.packageName, {
tag: sharedInfo.version ?? ports.versionCheck.smallestVersion(sharedInfo.requiredVersion),
file: sharedInfo.outFileName
});
}
}
// src/lib/1.domain/externals/external.contract.ts
var GLOBAL_SCOPE = "__GLOBAL__";
var STRICT_SCOPE = "strict";
// src/lib/2.app/flows/init/determine-shared-externals.ts
function createDetermineSharedExternals(config, ports) {
return () => {
for (const shareScope of ports.sharedExternalsRepo.getScopes()) {
const sharedExternals = ports.sharedExternalsRepo.getFromScope(shareScope);
try {
Object.entries(sharedExternals).filter(([_, e]) => e.dirty).forEach(
([name, external]) => ports.sharedExternalsRepo.addOrUpdate(
name,
setVersionActions(name, external),
shareScope
)
);
} catch (error) {
config.log.error(
3,
`[${shareScope ?? GLOBAL_SCOPE}] failed to determine shared externals.`,
{
sharedExternals,
error
}
);
return Promise.reject(
new NFError(
`Could not determine shared externals in scope ${shareScope}.`,
error
)
);
}
}
return Promise.resolve();
};
function setVersionActions(externalName, external) {
if (external.versions.length === 1) {
external.versions[0].action = "share";
external.dirty = false;
return external;
}
let sharedVersion = external.versions.find((v) => v.host);
if (!sharedVersion && config.profile.latestSharedExternal) {
sharedVersion = external.versions[0];
}
if (!sharedVersion) {
let leastExtraDownloads = Number.MAX_VALUE;
external.versions.forEach((vA) => {
const extraDownloads = external.versions.filter(
(vB) => !vB.remotes[0].cached && vB.remotes[0].strictVersion && !ports.versionCheck.isCompatible(vA.tag, vB.remotes[0].requiredVersion)
).length;
if (extraDownloads < leastExtraDownloads) {
leastExtraDownloads = extraDownloads;
sharedVersion = vA;
}
});
}
if (!sharedVersion) {
throw new NFError(`[${externalName}] Could not determine shared version!`);
}
external.versions.forEach((v) => {
if (ports.versionCheck.isCompatible(sharedVersion.tag, v.remotes[0].requiredVersion)) {
v.action = "skip";
return;
}
if (config.strict.strictExternalCompatibility && v.remotes[0].strictVersion) {
config.log.error(
3,
`[${v.remotes[0].name}][${externalName}@${v.tag}] Is not compatible with requiredRange '${sharedVersion.remotes[0]?.requiredVersion}' from remote '${sharedVersion.remotes[0].name}'.`
);
throw new NFError(`External ${externalName}@${v.tag} could not be shared.`);
}
v.action = v.remotes[0].strictVersion ? "scope" : "skip";
});
sharedVersion.action = "share";
external.dirty = false;
return external;
}
}
// src/lib/2.app/flows/init/generate-import-map.ts
function createGenerateImportMap(config, ports) {
return () => {
const importMap = { imports: {} };
try {
addScopedExternals(importMap);
addshareScopeExternals(importMap);
addGlobalSharedExternals(importMap);
addRemoteInfos(importMap);
return Promise.resolve(importMap);
} catch (e) {
return Promise.reject(e);
}
};
function addScopedExternals(importMap) {
const scopedExternals = ports.scopedExternalsRepo.getAll();
for (const [remoteName, externals] of Object.entries(scopedExternals)) {
const remote = ports.remoteInfoRepo.tryGet(remoteName).orThrow(() => {
config.log.error(4, `[scoped][${remoteName}] Remote name not found in cache.`);
return new NFError("Could not create ImportMap.");
});
addToScope(importMap, remote.scopeUrl, createScopeModules(externals, remote.scopeUrl));
}
return importMap;
}
function createScopeModules(externals, scope) {
const modules = {};
for (const [external, version] of Object.entries(externals)) {
modules[external] = join(scope, version.file);
}
return modules;
}
function addshareScopeExternals(importMap) {
const shareScopes = ports.sharedExternalsRepo.getScopes({ includeGlobal: false });
for (const shareScope of shareScopes) {
processshareScope(importMap, shareScope);
}
return importMap;
}
function processshareScope(importMap, shareScope) {
const sharedExternals = ports.sharedExternalsRepo.getFromScope(shareScope);
for (const [externalName, external] of Object.entries(sharedExternals)) {
let override = void 0;
let overrideScope = void 0;
for (const version of external.versions) {
if (version.action === "scope") {
for (const remote of version.remotes) {
const remoteScope = getScope2(externalName, shareScope, remote.name);
addToScope(importMap, remoteScope, {
[externalName]: join(remoteScope, remote.file)
});
remote.cached = true;
}
continue;
}
const scope = getScope2(externalName, shareScope, version.remotes[0].name);
let targetFileUrl = join(scope, version.remotes[0].file);
version.remotes[0].cached = true;
if (version.action === "skip") {
if (!override) {
override = findOverride(external, shareScope, externalName) ?? "NOT_AVAILABLE";
}
if (override !== "NOT_AVAILABLE") {
if (!overrideScope)
overrideScope = getScope2(externalName, shareScope, override.remotes[0].name);
targetFileUrl = join(overrideScope, override.remotes[0].file);
override.remotes[0].cached = true;
version.remotes[0].cached = false;
}
}
version.remotes.forEach((r) => {
const scope2 = getScope2(externalName, shareScope, r.name);
addToScope(importMap, scope2, { [externalName]: targetFileUrl });
});
}
ports.sharedExternalsRepo.addOrUpdate(externalName, external, shareScope);
}
}
function findOverride(external, shareScope, externalName) {
const sharedVersions = external.versions.filter((v) => v.action === "share");
const scopedExternalName = `${shareScope}.${externalName}`;
if (sharedVersions.length > 1) {
handleMultipleSharedVersions(scopedExternalName);
}
if (sharedVersions.length < 1) {
if (config.strict.strictImportMap) {
config.log.error(4, `[${shareScope}][${externalName}] shareScope has no override version.`);
throw new NFError("Could not create ImportMap.");
}
config.log.debug(
4,
`[${shareScope}][${externalName}] shareScope has no override version, scoping override versions.`
);
}
return sharedVersions[0];
}
function handleMultipleSharedVersions(scopedExternalName) {
if (config.strict.strictImportMap) {
config.log.error(
4,
`[${scopedExternalName}] ShareScope external has multiple shared versions.`
);
throw new NFError("Could not create ImportMap.");
}
config.log.warn(4, `ShareScope external ${scopedExternalName} has multiple shared versions.`);
}
function addGlobalSharedExternals(importMap) {
const sharedExternals = ports.sharedExternalsRepo.getFromScope();
for (const [externalName, external] of Object.entries(sharedExternals)) {
for (const version of external.versions) {
if (version.action === "skip") continue;
if (version.action === "scope") {
for (const remote of version.remotes) {
const remoteScope = getScope2(externalName, GLOBAL_SCOPE, remote.name);
addToScope(importMap, remoteScope, {
[externalName]: join(remoteScope, remote.file)
});
remote.cached = true;
}
continue;
}
if (importMap.imports[externalName]) {
handleDuplicateGlobalExternal(externalName);
continue;
}
const scope = getScope2(externalName, GLOBAL_SCOPE, version.remotes[0].name);
addToGlobal(importMap, { [externalName]: join(scope, version.remotes[0].file) });
version.remotes[0].cached = true;
}
ports.sharedExternalsRepo.addOrUpdate(externalName, external);
}
return importMap;
}
function handleDuplicateGlobalExternal(externalName) {
if (config.strict.strictImportMap) {
config.log.error(4, `[${externalName}] Shared external has multiple shared versions.`);
throw new NFError("Could not create ImportMap.");
}
config.log.warn(4, `Singleton external ${externalName} has multiple shared versions.`);
}
function addToScope(importMap, scope, imports) {
if (!importMap.scopes) importMap.scopes = {};
if (!importMap.scopes[scope]) importMap.scopes[scope] = {};
importMap.scopes[scope] = Object.assign(importMap.scopes[scope], imports);
}
function addToGlobal(importMap, imports) {
importMap.imports = Object.assign(importMap.imports, imports);
}
function addRemoteInfos(importMap) {
const remotes = ports.remoteInfoRepo.getAll();
for (const [remoteName, remote] of Object.entries(remotes)) {
addRemoteExposedModules(importMap, remoteName, remote);
}
}
function addRemoteExposedModules(importMap, remoteName, remote) {
for (const exposed of remote.exposes) {
const moduleName = join(remoteName, exposed.moduleName);
const moduleUrl = join(remote.scopeUrl, exposed.file);
importMap.imports[moduleName] = moduleUrl;
}
}
function getScope2(externalName, shareScope, remoteName) {
return ports.remoteInfoRepo.tryGet(remoteName).map((remote) => remote.scopeUrl).orThrow(() => {
config.log.error(
4,
`[${shareScope}][${externalName}][${remoteName}] Remote name not found in cache.`
);
return new NFError("Could not create ImportMap.");
});
}
}
// src/lib/2.app/flows/init/commit-changes.ts
function createCommitChanges(config, ports) {
return (importMap) => Promise.resolve(importMap).then(addToBrowser).then(persistRepositoryChanges);
function addToBrowser(importMap) {
ports.browser.setImportMapFn(importMap);
config.log.debug(5, "Added import map to browser.", importMap);
return importMap;
}
function persistRepositoryChanges() {
ports.remoteInfoRepo.commit();
ports.scopedExternalsRepo.commit();
ports.sharedExternalsRepo.commit();
return;
}
}
// src/lib/2.app/flows/init/expose-module-loader.ts
function createExposeModuleLoader(config, ports) {
return () => Promise.resolve(loadRemoteModule);
function loadRemoteModule(remoteName, exposedModule) {
try {
if (!ports.remoteInfoRepo.contains(remoteName)) {
throw new NFError(`Remote '${remoteName}' is not initialized.`);
}
const remoteModuleUrl = ports.remoteInfoRepo.tryGetModule(remoteName, exposedModule).orThrow(
new NFError(
`Exposed module '${exposedModule}' from remote '${remoteName}' not found in storage.`
)
);
config.log.debug(6, `Loading initialized module '${remoteModuleUrl}'`);
return ports.browser.importModule(remoteModuleUrl);
} catch (error) {
config.log.error(6, `Failed to load module ${join(remoteName, exposedModule)}: `, {
error
});
return Promise.reject(
new NFError(`Failed to load module ${join(remoteName, exposedModule)}`)
);
}
}
}
// src/lib/5.di/flows/init.factory.ts
var createInitDrivers = ({
config,
adapters
}) => ({
getRemoteEntries: createGetRemoteEntries(config, adapters),
processRemoteEntries: createProcessRemoteEntries(config, adapters),
determineSharedExternals: createDetermineSharedExternals(config, adapters),
generateImportMap: createGenerateImportMap(config, adapters),
commitChanges: createCommitChanges(config, adapters),
exposeModuleLoader: createExposeModuleLoader(config, adapters)
});
var INIT_FLOW_FACTORY = ({
config,
adapters
}) => {
const flow = createInitDrivers({ config, adapters });
return {
flow,
adapters,
config
};
};
var createInitFlow = ({
flow,
adapters,
config
}) => {
return (remotesOrManifestUrl) => flow.getRemoteEntries(remotesOrManifestUrl).then(flow.processRemoteEntries).then(flow.determineSharedExternals).then(flow.generateImportMap).then(flow.commitChanges).then(flow.exposeModuleLoader).then((loadRemoteModule) => ({
config,
adapters,
loadRemoteModule
}));
};
// src/lib/3.adapters/browser/browser.ts
var createBrowser = (config) => {
return {
setImportMapFn: config.setImportMapFn,
importModule: config.loadModuleFn
};
};
// src/lib/3.adapters/checks/version.check.ts
var import_valid = __toESM(require_valid());
var import_satisfies = __toESM(require_satisfies());
var import_compare = __toESM(require_compare());
var import_min_version = __toESM(require_min_version());
var import_valid2 = __toESM(require_valid2());
var createVersionCheck = () => {
return {
isValidSemver: function(version) {
return (0, import_valid.default)(version) !== null;
},
isCompatible: function(version, range) {
return (0, import_satisfies.default)(version, range);
},
compare: function(versionA, versionB) {
return (0, import_compare.default)(versionA, versionB, true);
},
smallestVersion: function(versionRange) {
if (!(0, import_valid2.default)(versionRange)) return "0.0.0";
const minVersion = (0, import_min_version.default)(versionRange);
return minVersion?.raw ?? "0.0.0";
}
};
};
// src/lib/3.adapters/http/manifest-provider.ts
var createManifestProvider = () => {
const mapToJson = (response) => {
if (!response.ok)
return Promise.reject(new NFError(`${response.status} - ${response.statusText}`));
return response.json();
};
const formatError = (remoteEntryUrl) => (err) => {
const msg = err instanceof Error ? err.message : String(err);
throw new NFError(`Fetch of '${remoteEntryUrl}' returned ${msg}`);
};
return {
provide: async function(remotesOrManifestUrl) {
if (typeof remotesOrManifestUrl !== "string") return Promise.resolve(remotesOrManifestUrl);
return fetch(remotesOrManifestUrl).then(mapToJson).catch(formatError(remotesOrManifestUrl));
}
};
};
// src/lib/3.adapters/http/remote-entry-provider.ts
var createRemoteEntryProvider = () => {
const mapToJson = (response) => {
if (!response.ok)
return Promise.reject(new Error(`${response.status} - ${response.statusText}`));
return response.json();
};
const fillEmptyFields = (remoteEntryUrl) => (remoteEntry) => {
if (!remoteEntry.exposes) remoteEntry.exposes = [];
if (!remoteEntry.shared) remoteEntry.shared = [];
if (!remoteEntry.url) remoteEntry.url = remoteEntryUrl;
return remoteEntry;
};
const formatError = (remoteEntryUrl) => (err) => {
const msg = err instanceof Error ? err.message : String(err);
throw new NFError(`Fetch of '${remoteEntryUrl}' returned ${msg}`);
};
return {
provide: async function(remoteEntryUrl) {
return fetch(remoteEntryUrl).then(mapToJson).then(fillEmptyFields(remoteEntryUrl)).catch(formatError(remoteEntryUrl));
}
};
};
// src/lib/utils/optional.ts
var Optional = class _Optional {
constructor(item) {
this.item = item;
}
static of(item) {
return new _Optional(item);
}
static empty() {
return _Optional.of(void 0);
}
isPresent() {
return typeof this.item !== "undefined" && this.item !== null;
}
set(other) {
return _Optional.of(other);
}
ifPresent(callback) {
if (this.isPresent()) callback(this.item);
}
map(callback) {
if (!this.isPresent()) return _Optional.empty();
const result = callback(this.item);
return result instanceof _Optional ? result : _Optional.of(result);
}
orElse(other) {
return this.isPresent() ? this.item : other;
}
orThrow(error) {
if (this.isPresent()) return this.item;
if (typeof error === "function") throw error();
throw typeof error === "string" ? new Error(error) : error;
}
get() {
return this.item;
}
};
// src/lib/3.adapters/storage/remote-info.repository.ts
var createRemoteInfoRepository = (config) => {
const STORAGE = config.storage("remotes", {});
if (config.clearStorage) STORAGE.clear();
const _cache = STORAGE.get() ?? {};
return {
contains: function(remoteName) {
return !!_cache[remoteName];
},
remove: function(remoteName) {
delete _cache[remoteName];
return this;
},
addOrUpdate: function(remoteName, remote) {
_cache[remoteName] = remote;
return this;
},
tryGet: function(remoteName) {
return Optional.of(_cache[remoteName]);
},
tryGetModule: function(remoteName, exposedModule) {
return Optional.of(_cache[remoteName]?.exposes.find((m) => m.moduleName === exposedModule)).map(
(m) => join(_cache[remoteName].scopeUrl, m.file)
);
},
getAll: function() {
return _cache;
},
commit: function() {
STORAGE.set(_cache);
return this;
}
};
};
// src/lib/3.adapters/storage/scoped-externals.repository.ts
var createScopedExternalsRepository = (config) => {
const STORAGE = config.storage("scoped-externals", {});
if (config.clearStorage) STORAGE.clear();
const _cache = STORAGE.get() ?? {};
return {
addExternal: function(remoteName, external, version) {
if (!_cache[remoteName]) _cache[remoteName] = {};
_cache[remoteName][external] = version;
return this;
},
remove: function(remoteName) {
delete _cache[remoteName];
return this;
},
getAll: function() {
return _cache;
},
tryGet: function(remoteName) {
return Optional.of(_cache[remoteName]);
},
commit: function() {
STORAGE.set(_cache);
return this;
}
};
};
// src/lib/3.adapters/storage/shared-externals.repository.ts
var createSharedExternalsRepository = (config) => {
const STORAGE = config.storage(
"shared-externals",
{ [GLOBAL_SCOPE]: {} }
);
if (config.clearStorage) STORAGE.clear();
const _cache = STORAGE.get();
return {
getFromScope: function(shareScope) {
return { ..._cache[shareScope ?? GLOBAL_SCOPE] };
},
addOrUpdate: function(externalName, external, shareScope) {
if (!_cache[shareScope ?? GLOBAL_SCOPE]) _cache[shareScope ?? GLOBAL_SCOPE] = {};
_cache[shareScope ?? GLOBAL_SCOPE][externalName] = external;
return this;
},
getScopes: function(o = { includeGlobal: true }) {
if (o.includeGlobal) return Object.keys(_cache);
return Object.keys(_cache).filter((s) => s !== GLOBAL_SCOPE);
},
removeFromAllScopes: function(remoteName) {
Object.values(_cache).forEach((scope) => {
const removeExternals = [];
Object.entries(scope).forEach(([name, external]) => {
const removeVersionIdx = [];
external.versions.forEach((version, i) => {
const versionRemoteIDX = version.remotes.findIndex((r) => r.name === remoteName);
if (~versionRemoteIDX) {
version.remotes.splice(versionRemoteIDX, 1);
}
if (version.remotes.length === 0) removeVersionIdx.push(i);
});
if (removeVersionIdx.length > 0) {
for (let i = removeVersionIdx.length - 1; i >= 0; i--) {
external.versions.splice(removeVersionIdx[i], 1);
}
external.dirty = true;
if (external.versions.length === 0) removeExternals.push(name);
}
});
removeExternals.forEach((name) => delete scope[name]);
});
},
scopeType: function(shareScope) {
switch (shareScope) {
case GLOBAL_SCOPE:
case null:
case void 0:
return "global";
case STRICT_SCOPE:
return "strict";
default:
return "shareScope";
}
},
tryGet: function(external, shareScope) {
return Optional.of(_cache[shareScope ?? GLOBAL_SCOPE]?.[external]);
},
commit: function() {
STORAGE.set(_cache);
return this;
}
};
};
// src/lib/5.di/driving.factory.ts
var createDriving = (config) => {
const adapters = {
versionCheck: createVersionCheck(),
manifestProvider: createManifestProvider(),
remoteEntryProvider: createRemoteEntryProvider(),
remoteInfoRepo: createRemoteInfoRepository(config),
scopedExternalsRepo: createScopedExternalsRepository(config),
sharedExternalsRepo: createSharedExternalsRepository(config),
browser: createBrowser(config)
};
return { adapters, config };
};
// src/lib/4.config/import-map/replace-in-dom.ts
var replaceInDOM = (mapType) => (importMap, opts = {}) => {
if (opts?.override) {
document.head.querySelectorAll(`script[type="${mapType}"]`).forEach((importMap2) => importMap2.remove());
}
document.head.appendChild(
Object.assign(document.createElement("script"), {
type: mapType,
innerHTML: JSON.stringify(importMap)
})
);
return Promise.resolve(importMap);
};
// src/lib/4.config/import-map/use-default.ts
var useDefaultImportMap = () => ({
loadModuleFn: (url) => import(
/* @vite-ignore */
url
),
setImportMapFn: replaceInDOM("importmap")
});
// src/lib/4.config/import-map/import-map.config.ts
var createImportMapConfig = (o) => {
const fallback = useDefaultImportMap();
return {
setImportMapFn: o.setImportMapFn ?? fallback.setImportMapFn,
loadModuleFn: o.loadModuleFn ?? fallback.loadModuleFn
};
};
// src/lib/4.config/host/host.config.ts
var createHostConfig = (override) => {
if (!override?.hostRemoteEntry) {
return { hostRemoteEntry: false };
}
if (typeof override.hostRemoteEntry === "string") {
return {
hostRemoteEntry: {
name: "__NF-HOST__",
url: override.hostRemoteEntry
}
};
}
return {
hostRemoteEntry: {
name: "__NF-HOST__",
...override.hostRemoteEntry
}
};
};
// src/lib/4.config/logging/noop.logger.ts
var noopLogger = {
debug: () => {
},
error: () => {
},
warn: () => {
}
};
// src/lib/2.app/config/log.contract.ts
var LogLevel = {
debug: 0,
warn: 1,
error: 2
};
// src/lib/4.config/logging/log.handler.ts
var createLogHandler = (logger, logLevel) => {
const logTypes = Object.keys(LogLevel).filter((key) => isNaN(Number(key)));
return logTypes.reduce(
(acc, logMessageType) => {
return {
...acc,
[logMessageType]: (step, message, details) => {
if (LogLevel[logMessageType] >= LogLevel[logLevel]) {
logger[logMessageType](step, message, details);
}
}
};
},
{ level: logLevel }
);
};
// src/lib/4.config/logging/log.config.ts
var createLogConfig = ({ logger, logLevel }) => ({
log: createLogHandler(logger ?? noopLogger, logLevel ?? "error")
});
// src/lib/utils/clone-entry.ts
var cloneEntry = (name, raw) => {
try {
if (typeof structuredClone === "function") {
return structuredClone(raw);
}
} catch {
}
try {
return JSON.parse(JSON.stringify(raw));
} catch {
}
throw new NFError(`Could not parse storage entry '${String(name)}'`);
};
// src/lib/4.config/storage/global-this.storage.ts
var globalThisStorageEntry = (namespace) => (key, initialValue) => {
if (!globalThis[namespace]) {
globalThis[namespace] = {};
}
const storage = globalThis[namespace];
if (!storage[key]) storage[key] = initialValue;
const entry = {
get() {
return cloneEntry(key, storage[key]);
},
set(value) {
storage[key] = cloneEntry(key, value);
return entry;
},
clear() {
storage[key] = cloneEntry(key, initialValue);
return this;
}
};
return entry;
};
// src/lib/4.config/storage/storage.config.ts
var createStorageConfig = (override) => ({
storage: override.storage ? override.storage(override.storageNamespace ?? "__NATIVE_FEDERATION__") : globalThisStorageEntry(override.storageNamespace ?? "__NATIVE_FEDERATION__"),
clearStorage: override.clearStorage ?? false
});
// src/lib/4.config/mode/default.profile.ts
var defaultProfile = {
latestSharedExternal: false,
overrideCachedRemotes: "init-only",
overrideCachedRemotesIfURLMatches: false
};
// src/lib/4.config/mode/mode.config.ts
var createModeConfig = (override) => {
const strictnessConfig = typeof override.strict === "boolean" ? {
strictRemoteEntry: override.strict,
strictExternalCompatibility: override.strict,
strictExternalVersion: override.strict,
strictImportMap: override.strict
} : {
strictRemoteEntry: override.strict?.strictRemoteEntry ?? false,
strictExternalCompatibility: override.strict?.strictExternalCompatibility ?? false,
strictExternalVersion: override.strict?.strictExternalVersion ?? false,
strictImportMap: override.strict?.strictImportMap ?? false
};
return {
strict: strictnessConfig,
profile: { ...defaultProfile, ...override.profile ?? {} }
};
};
// src/lib/5.di/config.factory.ts
var createConfigHandlers = (overrides) => ({
...createImportMapConfig(overrides),
...createHostConfig(overrides),
...createLogConfig(overrides),
...createStorageConfig(overrides),
...createModeConfig(overrides)
});
// src/lib/2.app/flows/dynamic-init/convert-to-import-map.ts
function createConvertToImportMap({ log }) {
return ({ entry, actions }) => {
const importMap = { imports: {} };
addExternals(entry, actions, importMap);
addRemoteInfos(entry, importMap);
log.debug(9, `[${entry.name}] Processed actions:`, actions);
return Promise.resolve(importMap);
};
function addExternals(remoteEntry, actions, importMap) {
if (!remoteEntry.shared) {
return;
}
const remoteEntryScope = getScope(remoteEntry.url);
remoteEntry.shared.forEach((external) => {
if (!external.singleton) {
addToScopes(
remoteEntryScope,
external.packageName,
join(remoteEntryScope, external.outFileName),
importMap
);
return;
}
if (!actions[external.packageName]) {
log.warn(
9,
`[${remoteEntry.name}] No action defined for shared external '${external.packageName}', skipping.`
);
return;
}
if (actions[external.packageName].action === "skip") {
if (!external.shareScope) return;
if (actions[external.packageName].override) {
addToScopes(
remoteEntryScope,
external.packageName,
actions[external.packageName].override,
importMap
);
return;
}
}
if (actions[external.packageName].action === "scope") {
addToScopes(
remoteEntryScope,
external.packageName,
join(remoteEntryScope, external.outFileName),
importMap
);
return;
}
if (external.shareScope) {
addToScopes(
remoteEntryScope,
external.packageName,
join(remoteEntryScope, external.outFileName),
importMap
);
return;
}
importMap.imports[external.packageName] = join(remoteEntryScope, external.outFileName);
});
}
function addToScopes(scope, packageName, url, importMap) {
if (!importMap.scopes) importMap.scopes = {};
if (!importMap.scopes[scope]) importMap.scopes[scope] = {};
importMap.scopes[scope][packageName] = url;
}
function addRemoteInfos(remoteEntry, importMap) {
if (!remoteEntry.exposes) return;
const scope = getScope(remoteEntry.url);
remoteEntry.exposes.forEach((exposed) => {
const moduleName = join(remoteEntry.name, exposed.key);
const moduleUrl = join(scope, exposed.outFileName);
importMap.imports[moduleName] = moduleUrl;
});
}
}
// src/lib/2.app/flows/dynamic-init/get-remote-entry.ts
function createGetRemoteEntry(config, ports) {
return async (remoteEntryUrl, remoteName) => {
if (!!remoteName && shouldSkipCachedRemote(remoteEntryUrl, remoteName)) {
config.log.debug(7, `Found remote '${remoteName}' in storage, omitting fetch.`);
return Optional.empty();
}
try {
const remoteEntry = await ports.remoteEntryProvider.provide(remoteEntryUrl);
config.log.debug(
7,
`[${remoteEntry.name}] Fetched from '${remoteEntry.url}', exposing: ${JSON.stringify(remoteEntry.exposes)}`
);
if (!!remoteName && remoteEntry.name !== remoteName) {
const errorMsg = `Fetched remote '${remoteEntry.name}' does not match requested '${remoteName}'.`;
if (config.strict.strictRemoteEntry) {
config.log.error(7, errorMsg);
throw new NFError("Could not fetch remote entry");
}
config.log.warn(7, errorMsg + " Omitting expected name.");
}
if (ports.remoteInfoRepo.contains(remoteEntry.name)) {
remoteEntry.override = true;
config.log.debug(7, `Overriding existing remote '${remoteName}' with '${remoteEntryUrl}'.`);
}
return Optional.of(remoteEntry);
} catch (error) {
config.log.error(
7,
`[${remoteName ?? "unknown"}] Could not fetch remoteEntry from ${remoteEntryUrl}.`,
error
);
return Promise.reject(
new NFError(`[${remoteName ?? remoteEntryUrl}] Could not fetch remoteEntry.`)
);
}
};
function shouldSkipCachedRemote(remoteEntryUrl, remoteName) {
return ports.remoteInfoRepo.tryGet(remoteName).map(
(cachedRemoteInfo) => config.profile.overrideCachedRemotes !== "always" || !config.profile.overrideCachedRemotesIfURLMatches && remoteEntryUrl === join(cachedRemoteInfo.scopeUrl, "remoteEntry.json")
).orElse(false);
}
}
// src/lib/2.app/flows/dynamic-init/update-cache.ts
function createUpdateCache(config, ports) {
return (remoteEntry) => {
try {
if (remoteEntry?.override) removeCachedRemoteEntry(remoteEntry);
addRemoteInfoToStorage(remoteEntry);
const actions = mergeExternalsIntoStorage(remoteEntry);
return Promise.resolve({ entry: remoteEntry, actions });
} catch (error) {
return Promise.reject(error);
}
};
function removeCachedRemoteEntry(remoteEntry) {
ports.remoteInfoRepo.remove(remoteEntry.name);
ports.scopedExternalsRepo.remove(remoteEntry.name);
ports.sharedExternalsRepo.removeFromAllScopes(remoteEntry.name);
}
function addRemoteInfoToStorage({ name, url, exposes }) {
ports.remoteInfoRepo.addOrUpdate(name, {
scopeUrl: getScope(url),
exposes: Object.values(exposes ?? []).map((m) => ({
moduleName: m.key,
file: m.outFileName
}))
});
}
function mergeExternalsIntoStorage(remoteEntry) {
const actions = {};
remoteEntry.shared.forEach((external) => {
if (!external.version || !ports.versionCheck.isValidSemver(external.version)) {
const errorMsg = `[${remoteEntry.name}][${external.packageName}] Version '${external.version}' is not a valid version.`;
if (config.strict.strictExternalVersion) {
config.log.error(8, errorMsg);
throw new NFError(`Could not process remote '${remoteEntry.name}'`);
}
config.log.warn(8, errorMsg);
}
if (external.singleton) {
const { action, sharedVersion } = addSharedExternal(remoteEntry.name, external);
actions[external.packageName] = { action };
if (action === "skip" && external.shareScope && sharedVersion?.remotes[0]?.file) {
actions[external.packageName].override = ports.remoteInfoRepo.tryGet(sharedVersion.remotes[0].name).map((remote) => join(remote.scopeUrl, sharedVersion.remotes[0].file)).orThrow(() => {
config.log.error(
8,
`[${external.shareScope ?? GLOBAL_SCOPE}][${remoteEntry.name}][${external.packageName}@${external.version}][override] Remote name not found in cache.`
);
return new NFError(
`Could not find override url from remote ${sharedVersion.remotes[0].name}`
);
});
}
} else {
addScopedExternal(remoteEntry.name, external);
}
});
return actions;
}
function addSharedExternal(remoteName, sharedInfo) {
const cached = ports.sharedExternalsRepo.tryGet(sharedInfo.packageName, sharedInfo.shareScope).orElse({ dirty: false, versions: [] });
let action = "skip";
const tag = sharedInfo.version ?? ports.versionCheck.smallestVersion(sharedInfo.requiredVersion);
const remote = {
file: sharedInfo.outFileName,
strictVersion: sharedInfo.strictVersion,
requiredVersion: sharedInfo.requiredVersion || tag,
name: remoteName,
cached: false
};
const scopeType = ports.sharedExternalsRepo.scopeType(sharedInfo.shareScope);
if (scopeType === "strict") {
remote.requiredVersion = tag;
action = "share";
}
const sharedVersion = cached.versions.find((c) => c.action === "share");
const isCompatible = !sharedVersion || ports.versionCheck.isCompatible(sharedVersion.tag, remote.requiredVersion);
if (action === "skip" && !isCompatible && remote.strictVersion) {
action = "scope";
const errorMsg = `[${sharedInfo.shareScope ?? GLOBAL_SCOPE}][${remoteName}] ${sharedInfo.packageName}@${sharedInfo.version} Is not compatible with existing ${sharedInfo.packageName}@${sharedVersion.tag} requiredRange '${sharedVersion.remotes[0]?.requiredVersion}'`;
if (config.strict.strictExternalCompatibility) {
config.log.error(8, errorMsg);
throw new NFError(`Could not process remote '${remoteName}'`);
}
config.log.warn(8, errorMsg);
}
const matchingVersion = cached.versions.find((cached2) => cached2.tag === tag);
if (!!matchingVersion) {
if (remote.strictVersion && matchingVersion.remotes[0].requiredVersion !== remote.requiredVersion) {
const errorMsg = `[${remoteName}][${sharedInfo.packageName}@${sharedInfo.version}] Required version '${remote.requiredVersion}' does not match existing '${matchingVersion.remotes[0].requiredVersion}'`;
if (config.strict.strictExternalCompatibility) {
config.log.error(8, errorMsg);
throw new NFError(`Could not process remote '${remoteName}'`);
}
config.log.warn(8, errorMsg);
}
matchingVersion.remotes.push(remote);
} else {
if (!sharedVersion) action = "share";
remote.cached = action !== "skip";
cached.versions.push({ tag, action, host: false, remotes: [remote] });
}
ports.sharedExternalsRepo.addOrUpdate(
sharedInfo.packageName,
{
dirty: cached.dirty,
versions: cached.versions.sort((a, b) => ports.versionCheck.compare(b.tag, a.tag))
},
sharedInfo.shareScope
);
return { action, sharedVersion };
}
function addScopedExternal(remoteName, sharedInfo) {
ports.scopedExternalsRepo.addExternal(remoteName, sharedInfo.packageName, {
tag: sharedInfo.version ?? ports.versionCheck.smallestVersion(sharedInfo.requiredVersion),
file: sharedInfo.outFileName
});
}
}
// src/lib/5.di/flows/dynamic-init.factory.ts
var createDynamicInitDrivers = ({
config,
adapters
}) => ({
getRemoteEntry: createGetRemoteEntry(config, adapters),
updateCache: createUpdateCache(config, adapters),
convertToImportMap: createConvertToImportMap(config),
commitChanges: createCommitChanges(config, adapters)
});
var DYNAMIC_INIT_FLOW_FACTORY = ({
config,
adapters
}) => {
const flow = createDynamicInitDrivers({ config, adapters });
return {
flow,
adapters,
config
};
};
var createDynamicInitFlow = ({
flow,
adapters,
config
}) => {
const processDynamicRemoteEntry = async (remoteEntry) => {
return flow.updateCache(remoteEntry).then(flow.convertToImportMap).then(flow.commitChanges);
};
const initRemoteEntry = (remoteEntryUrl, remoteName) => flow.getRemoteEntry(remoteEntryUrl, remoteName).then((entry) => entry.map(processDynamicRemoteEntry).orElse(Promise.resolve())).then(() => ({
config,
adapters,
initRemoteEntry
}));
return initRemoteEntry;
};
// src/lib/init-federation.ts
var initFederation = (remotesOrManifestUrl, options = {}) => {
const { adapters, config } = createDriving(createConfigHandlers(options));
const stateDump = (msg) => config.log.debug(0, msg, {
remotes: { ...adapters.remoteInfoRepo.getAll() },
"shared-externals": adapters.sharedExternalsRepo.getScopes({ includeGlobal: true }).reduce(
(acc, scope) => ({ ...acc, [scope]: adapters.sharedExternalsRepo.getFromScope(scope) }),
{}
),
"scoped-externals": adapters.scopedExternalsRepo.getAll()
});
const initFlow = createInitFlow(INIT_FLOW_FACTORY({ adapters, config }));
const dynamicInitFlow = createDynamicInitFlow(DYNAMIC_INIT_FLOW_FACTORY({ config, adapters }));
return initFlow(remotesOrManifestUrl).then(({ loadRemoteModule }) => {
const output = {
config,
adapters,
loadRemoteModule,
as: () => ({
loadRemoteModule
}),
remote: (remoteName) => ({
loadModule: (exposedModule) => loadRemoteModule(remoteName, exposedModule)
})
};
const initRemoteEntry = async (remoteEntryUrl, remoteName) => dynamicInitFlow(remoteEntryUrl, remoteName).catch((e) => {
stateDump(`[dynamic-init][${remoteName ?? remoteEntryUrl}] STATE DUMP`);
if (config.strict.strictRemoteEntry) return Promise.reject(e);
else console.warn("Failed to initialize remote entry, continuing anyway.");
return Promise.resolve();
}).then(() => ({
...output,
initRemoteEntry
}));
return {
...output,
initRemoteEntry
};
}).catch((e) => {
stateDump(`[init] STATE DUMP`);
return Promise.reject(e);
});
};
export {
DYNAMIC_INIT_FLOW_FACTORY,
INIT_FLOW_FACTORY,
NFError,
createConfigHandlers,
createDriving,
createDynamicInitDrivers,
createDynamicInitFlow,
createInitDrivers,
createInitFlow,
initFederation
};
//# sourceMappingURL=vanilla-native-federation.mjs.map