@micro-zoe/micro-app 1.0.0-alpha.2 → 1.0.0-alpha.5

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/lib/index.esm.js CHANGED
@@ -1,4 +1,4 @@
1
- const version = '1.0.0-alpha.2';
1
+ const version = '1.0.0-alpha.5';
2
2
  // do not use isUndefined
3
3
  const isBrowser = typeof window !== 'undefined';
4
4
  // do not use isUndefined
@@ -72,6 +72,10 @@ function isShadowRoot(target) {
72
72
  function isURL(target) {
73
73
  return target instanceof URL;
74
74
  }
75
+ // is ProxyDocument
76
+ function isProxyDocument(target) {
77
+ return toString.call(target) === '[object ProxyDocument]';
78
+ }
75
79
  /**
76
80
  * format error log
77
81
  * @param msg message
@@ -498,6 +502,66 @@ function fetchSource(url, appName = null, options = {}) {
498
502
  });
499
503
  }
500
504
 
505
+ class HTMLLoader {
506
+ static getInstance() {
507
+ if (!this.instance) {
508
+ this.instance = new HTMLLoader();
509
+ }
510
+ return this.instance;
511
+ }
512
+ /**
513
+ * run logic of load and format html
514
+ * @param successCb success callback
515
+ * @param errorCb error callback, type: (err: Error, meetFetchErr: boolean) => void
516
+ */
517
+ run(app, successCb) {
518
+ const appName = app.name;
519
+ const htmlUrl = app.ssrUrl || app.url;
520
+ fetchSource(htmlUrl, appName, { cache: 'no-cache' }).then((htmlStr) => {
521
+ if (!htmlStr) {
522
+ const msg = 'html is empty, please check in detail';
523
+ app.onerror(new Error(msg));
524
+ return logError(msg, appName);
525
+ }
526
+ htmlStr = this.formatHTML(htmlUrl, htmlStr, appName);
527
+ successCb(htmlStr, app);
528
+ }).catch((e) => {
529
+ logError(`Failed to fetch data from ${app.url}, micro-app stop rendering`, appName, e);
530
+ app.onLoadError(e);
531
+ });
532
+ }
533
+ formatHTML(htmlUrl, htmlStr, appName) {
534
+ return this.processHtml(htmlUrl, htmlStr, appName, microApp.plugins)
535
+ .replace(/<head[^>]*>[\s\S]*?<\/head>/i, (match) => {
536
+ return match
537
+ .replace(/<head/i, '<micro-app-head')
538
+ .replace(/<\/head>/i, '</micro-app-head>');
539
+ })
540
+ .replace(/<body[^>]*>[\s\S]*?<\/body>/i, (match) => {
541
+ return match
542
+ .replace(/<body/i, '<micro-app-body')
543
+ .replace(/<\/body>/i, '</micro-app-body>');
544
+ });
545
+ }
546
+ processHtml(url, code, appName, plugins) {
547
+ var _a;
548
+ if (!plugins)
549
+ return code;
550
+ const mergedPlugins = [];
551
+ plugins.global && mergedPlugins.push(...plugins.global);
552
+ ((_a = plugins.modules) === null || _a === void 0 ? void 0 : _a[appName]) && mergedPlugins.push(...plugins.modules[appName]);
553
+ if (mergedPlugins.length > 0) {
554
+ return mergedPlugins.reduce((preCode, plugin) => {
555
+ if (isPlainObject(plugin) && isFunction(plugin.processHtml)) {
556
+ return plugin.processHtml(preCode, url, plugin.options);
557
+ }
558
+ return preCode;
559
+ }, code);
560
+ }
561
+ return code;
562
+ }
563
+ }
564
+
501
565
  // common reg
502
566
  const rootSelectorREG = /(^|\s+)(html|:root)(?=[\s>~[.#:]+|$)/;
503
567
  const bodySelectorREG = /(^|\s+)((html[\s>~]+body)|body)(?=[\s>~[.#:]+|$)/;
@@ -1139,12 +1203,12 @@ function handleNewNode(parent, child, app) {
1139
1203
  return child;
1140
1204
  }
1141
1205
  else if (child instanceof HTMLLinkElement) {
1142
- if (child.hasAttribute('exclude')) {
1206
+ if (child.hasAttribute('exclude') || checkExcludeUrl(child.getAttribute('href'), app.name)) {
1143
1207
  const linkReplaceComment = document.createComment('link element with exclude attribute ignored by micro-app');
1144
1208
  dynamicElementInMicroAppMap.set(child, linkReplaceComment);
1145
1209
  return linkReplaceComment;
1146
1210
  }
1147
- else if (child.hasAttribute('ignore')) {
1211
+ else if (child.hasAttribute('ignore') || checkIgnoreUrl(child.getAttribute('href'), app.name)) {
1148
1212
  return child;
1149
1213
  }
1150
1214
  const { url, info, replaceComment } = extractLinkFromHtml(child, parent, app, true);
@@ -1363,101 +1427,112 @@ function markElement(element) {
1363
1427
  // methods of document
1364
1428
  function patchDocument() {
1365
1429
  const rawDocument = globalEnv.rawDocument;
1430
+ const rawRootDocument = globalEnv.rawRootDocument;
1431
+ function getBindTarget(target) {
1432
+ return isProxyDocument(target) ? rawDocument : target;
1433
+ }
1366
1434
  // create element 👇
1367
- Document.prototype.createElement = function createElement(tagName, options) {
1368
- const element = globalEnv.rawCreateElement.call(this, tagName, options);
1435
+ rawRootDocument.prototype.createElement = function createElement(tagName, options) {
1436
+ const element = globalEnv.rawCreateElement.call(getBindTarget(this), tagName, options);
1369
1437
  return markElement(element);
1370
1438
  };
1371
- Document.prototype.createElementNS = function createElementNS(namespaceURI, name, options) {
1372
- const element = globalEnv.rawCreateElementNS.call(this, namespaceURI, name, options);
1439
+ rawRootDocument.prototype.createElementNS = function createElementNS(namespaceURI, name, options) {
1440
+ const element = globalEnv.rawCreateElementNS.call(getBindTarget(this), namespaceURI, name, options);
1373
1441
  return markElement(element);
1374
1442
  };
1375
- Document.prototype.createDocumentFragment = function createDocumentFragment() {
1376
- const element = globalEnv.rawCreateDocumentFragment.call(this);
1443
+ rawRootDocument.prototype.createDocumentFragment = function createDocumentFragment() {
1444
+ const element = globalEnv.rawCreateDocumentFragment.call(getBindTarget(this));
1377
1445
  return markElement(element);
1378
1446
  };
1379
1447
  // query element👇
1380
1448
  function querySelector(selectors) {
1381
1449
  var _a, _b, _c, _d;
1450
+ const _this = getBindTarget(this);
1382
1451
  const currentAppName = getCurrentAppName();
1383
1452
  if (!currentAppName ||
1384
1453
  !((_a = appInstanceMap.get(currentAppName)) === null || _a === void 0 ? void 0 : _a.container) ||
1385
1454
  !selectors ||
1386
1455
  isUniqueElement(selectors) ||
1387
1456
  // see https://github.com/micro-zoe/micro-app/issues/56
1388
- rawDocument !== this) {
1389
- return globalEnv.rawQuerySelector.call(this, selectors);
1457
+ rawDocument !== _this) {
1458
+ return globalEnv.rawQuerySelector.call(_this, selectors);
1390
1459
  }
1391
1460
  return (_d = (_c = (_b = appInstanceMap.get(currentAppName)) === null || _b === void 0 ? void 0 : _b.container) === null || _c === void 0 ? void 0 : _c.querySelector(selectors)) !== null && _d !== void 0 ? _d : null;
1392
1461
  }
1393
1462
  function querySelectorAll(selectors) {
1394
1463
  var _a, _b, _c, _d;
1464
+ const _this = getBindTarget(this);
1395
1465
  const currentAppName = getCurrentAppName();
1396
1466
  if (!currentAppName ||
1397
1467
  !((_a = appInstanceMap.get(currentAppName)) === null || _a === void 0 ? void 0 : _a.container) ||
1398
1468
  !selectors ||
1399
1469
  isUniqueElement(selectors) ||
1400
- rawDocument !== this) {
1401
- return globalEnv.rawQuerySelectorAll.call(this, selectors);
1470
+ rawDocument !== _this) {
1471
+ return globalEnv.rawQuerySelectorAll.call(_this, selectors);
1402
1472
  }
1403
1473
  return (_d = (_c = (_b = appInstanceMap.get(currentAppName)) === null || _b === void 0 ? void 0 : _b.container) === null || _c === void 0 ? void 0 : _c.querySelectorAll(selectors)) !== null && _d !== void 0 ? _d : [];
1404
1474
  }
1405
- Document.prototype.querySelector = querySelector;
1406
- Document.prototype.querySelectorAll = querySelectorAll;
1407
- Document.prototype.getElementById = function getElementById(key) {
1475
+ rawRootDocument.prototype.querySelector = querySelector;
1476
+ rawRootDocument.prototype.querySelectorAll = querySelectorAll;
1477
+ rawRootDocument.prototype.getElementById = function getElementById(key) {
1478
+ const _this = getBindTarget(this);
1408
1479
  if (!getCurrentAppName() || isInvalidQuerySelectorKey(key)) {
1409
- return globalEnv.rawGetElementById.call(this, key);
1480
+ return globalEnv.rawGetElementById.call(_this, key);
1410
1481
  }
1411
1482
  try {
1412
- return querySelector.call(this, `#${key}`);
1483
+ return querySelector.call(_this, `#${key}`);
1413
1484
  }
1414
1485
  catch (_a) {
1415
- return globalEnv.rawGetElementById.call(this, key);
1486
+ return globalEnv.rawGetElementById.call(_this, key);
1416
1487
  }
1417
1488
  };
1418
- Document.prototype.getElementsByClassName = function getElementsByClassName(key) {
1489
+ rawRootDocument.prototype.getElementsByClassName = function getElementsByClassName(key) {
1490
+ const _this = getBindTarget(this);
1419
1491
  if (!getCurrentAppName() || isInvalidQuerySelectorKey(key)) {
1420
- return globalEnv.rawGetElementsByClassName.call(this, key);
1492
+ return globalEnv.rawGetElementsByClassName.call(_this, key);
1421
1493
  }
1422
1494
  try {
1423
- return querySelectorAll.call(this, `.${key}`);
1495
+ return querySelectorAll.call(_this, `.${key}`);
1424
1496
  }
1425
1497
  catch (_a) {
1426
- return globalEnv.rawGetElementsByClassName.call(this, key);
1498
+ return globalEnv.rawGetElementsByClassName.call(_this, key);
1427
1499
  }
1428
1500
  };
1429
- Document.prototype.getElementsByTagName = function getElementsByTagName(key) {
1501
+ rawRootDocument.prototype.getElementsByTagName = function getElementsByTagName(key) {
1430
1502
  var _a;
1503
+ const _this = getBindTarget(this);
1431
1504
  const currentAppName = getCurrentAppName();
1432
1505
  if (!currentAppName ||
1433
1506
  isUniqueElement(key) ||
1434
1507
  isInvalidQuerySelectorKey(key) ||
1435
1508
  (!((_a = appInstanceMap.get(currentAppName)) === null || _a === void 0 ? void 0 : _a.inline) && /^script$/i.test(key))) {
1436
- return globalEnv.rawGetElementsByTagName.call(this, key);
1509
+ return globalEnv.rawGetElementsByTagName.call(_this, key);
1437
1510
  }
1438
1511
  try {
1439
- return querySelectorAll.call(this, key);
1512
+ return querySelectorAll.call(_this, key);
1440
1513
  }
1441
1514
  catch (_b) {
1442
- return globalEnv.rawGetElementsByTagName.call(this, key);
1515
+ return globalEnv.rawGetElementsByTagName.call(_this, key);
1443
1516
  }
1444
1517
  };
1445
- Document.prototype.getElementsByName = function getElementsByName(key) {
1518
+ rawRootDocument.prototype.getElementsByName = function getElementsByName(key) {
1519
+ const _this = getBindTarget(this);
1446
1520
  if (!getCurrentAppName() || isInvalidQuerySelectorKey(key)) {
1447
- return globalEnv.rawGetElementsByName.call(this, key);
1521
+ return globalEnv.rawGetElementsByName.call(_this, key);
1448
1522
  }
1449
1523
  try {
1450
- return querySelectorAll.call(this, `[name=${key}]`);
1524
+ return querySelectorAll.call(_this, `[name=${key}]`);
1451
1525
  }
1452
1526
  catch (_a) {
1453
- return globalEnv.rawGetElementsByName.call(this, key);
1527
+ return globalEnv.rawGetElementsByName.call(_this, key);
1454
1528
  }
1455
1529
  };
1456
1530
  }
1457
1531
  /**
1458
1532
  * patchSetAttribute is different from other patch
1459
- * it not dependent on sandbox
1460
- * it should exec when micro-app first created & release when all app unmounted
1533
+ * NOTE:
1534
+ * 1. it not dependent on sandbox
1535
+ * 2. it should exec when first micro-app-element created & release when all app unmounted
1461
1536
  */
1462
1537
  let hasRewriteSetAttribute = false;
1463
1538
  function patchSetAttribute() {
@@ -1492,24 +1567,21 @@ function patchSetAttribute() {
1492
1567
  }
1493
1568
  };
1494
1569
  }
1495
- function releasePatchSetAttribute() {
1496
- hasRewriteSetAttribute = false;
1497
- Element.prototype.setAttribute = globalEnv.rawSetAttribute;
1498
- }
1499
1570
  function releasePatchDocument() {
1500
- Document.prototype.createElement = globalEnv.rawCreateElement;
1501
- Document.prototype.createElementNS = globalEnv.rawCreateElementNS;
1502
- Document.prototype.createDocumentFragment = globalEnv.rawCreateDocumentFragment;
1503
- Document.prototype.querySelector = globalEnv.rawQuerySelector;
1504
- Document.prototype.querySelectorAll = globalEnv.rawQuerySelectorAll;
1505
- Document.prototype.getElementById = globalEnv.rawGetElementById;
1506
- Document.prototype.getElementsByClassName = globalEnv.rawGetElementsByClassName;
1507
- Document.prototype.getElementsByTagName = globalEnv.rawGetElementsByTagName;
1508
- Document.prototype.getElementsByName = globalEnv.rawGetElementsByName;
1571
+ const rawRootDocument = globalEnv.rawRootDocument;
1572
+ rawRootDocument.prototype.createElement = globalEnv.rawCreateElement;
1573
+ rawRootDocument.prototype.createElementNS = globalEnv.rawCreateElementNS;
1574
+ rawRootDocument.prototype.createDocumentFragment = globalEnv.rawCreateDocumentFragment;
1575
+ rawRootDocument.prototype.querySelector = globalEnv.rawQuerySelector;
1576
+ rawRootDocument.prototype.querySelectorAll = globalEnv.rawQuerySelectorAll;
1577
+ rawRootDocument.prototype.getElementById = globalEnv.rawGetElementById;
1578
+ rawRootDocument.prototype.getElementsByClassName = globalEnv.rawGetElementsByClassName;
1579
+ rawRootDocument.prototype.getElementsByTagName = globalEnv.rawGetElementsByTagName;
1580
+ rawRootDocument.prototype.getElementsByName = globalEnv.rawGetElementsByName;
1509
1581
  }
1510
1582
  // release patch
1511
1583
  function releasePatches() {
1512
- setCurrentAppName(null);
1584
+ removeDomScope();
1513
1585
  releasePatchDocument();
1514
1586
  Element.prototype.appendChild = globalEnv.rawAppendChild;
1515
1587
  Element.prototype.insertBefore = globalEnv.rawInsertBefore;
@@ -1519,6 +1591,11 @@ function releasePatches() {
1519
1591
  Element.prototype.prepend = globalEnv.rawPrepend;
1520
1592
  Element.prototype.cloneNode = globalEnv.rawCloneNode;
1521
1593
  }
1594
+ // exec when last child unmount
1595
+ function releasePatchSetAttribute() {
1596
+ hasRewriteSetAttribute = false;
1597
+ Element.prototype.setAttribute = globalEnv.rawSetAttribute;
1598
+ }
1522
1599
  // Set the style of micro-app-head and micro-app-body
1523
1600
  let hasRejectMicroAppStyle = false;
1524
1601
  function rejectMicroAppStyle() {
@@ -1538,6 +1615,10 @@ const globalEnv = {};
1538
1615
  */
1539
1616
  function initGlobalEnv() {
1540
1617
  if (isBrowser) {
1618
+ const rawWindow = Function('return window')();
1619
+ const rawDocument = Function('return document')();
1620
+ const rawRootDocument = Function('return Document')();
1621
+ const supportModuleScript = isSupportModuleScript();
1541
1622
  /**
1542
1623
  * save patch raw methods
1543
1624
  * pay attention to this binding
@@ -1550,15 +1631,15 @@ function initGlobalEnv() {
1550
1631
  const rawAppend = Element.prototype.append;
1551
1632
  const rawPrepend = Element.prototype.prepend;
1552
1633
  const rawCloneNode = Element.prototype.cloneNode;
1553
- const rawCreateElement = Document.prototype.createElement;
1554
- const rawCreateElementNS = Document.prototype.createElementNS;
1555
- const rawCreateDocumentFragment = Document.prototype.createDocumentFragment;
1556
- const rawQuerySelector = Document.prototype.querySelector;
1557
- const rawQuerySelectorAll = Document.prototype.querySelectorAll;
1558
- const rawGetElementById = Document.prototype.getElementById;
1559
- const rawGetElementsByClassName = Document.prototype.getElementsByClassName;
1560
- const rawGetElementsByTagName = Document.prototype.getElementsByTagName;
1561
- const rawGetElementsByName = Document.prototype.getElementsByName;
1634
+ const rawCreateElement = rawRootDocument.prototype.createElement;
1635
+ const rawCreateElementNS = rawRootDocument.prototype.createElementNS;
1636
+ const rawCreateDocumentFragment = rawRootDocument.prototype.createDocumentFragment;
1637
+ const rawQuerySelector = rawRootDocument.prototype.querySelector;
1638
+ const rawQuerySelectorAll = rawRootDocument.prototype.querySelectorAll;
1639
+ const rawGetElementById = rawRootDocument.prototype.getElementById;
1640
+ const rawGetElementsByClassName = rawRootDocument.prototype.getElementsByClassName;
1641
+ const rawGetElementsByTagName = rawRootDocument.prototype.getElementsByTagName;
1642
+ const rawGetElementsByName = rawRootDocument.prototype.getElementsByName;
1562
1643
  const ImageProxy = new Proxy(Image, {
1563
1644
  construct(Target, args) {
1564
1645
  const elementImage = new Target(...args);
@@ -1566,9 +1647,6 @@ function initGlobalEnv() {
1566
1647
  return elementImage;
1567
1648
  },
1568
1649
  });
1569
- const rawWindow = Function('return window')();
1570
- const rawDocument = Function('return document')();
1571
- const supportModuleScript = isSupportModuleScript();
1572
1650
  /**
1573
1651
  * save effect raw methods
1574
1652
  * pay attention to this binding, especially setInterval, setTimeout, clearInterval, clearTimeout
@@ -1579,11 +1657,18 @@ function initGlobalEnv() {
1579
1657
  const rawSetTimeout = rawWindow.setTimeout;
1580
1658
  const rawClearInterval = rawWindow.clearInterval;
1581
1659
  const rawClearTimeout = rawWindow.clearTimeout;
1660
+ const rawPushState = rawWindow.history.pushState;
1661
+ const rawReplaceState = rawWindow.history.replaceState;
1582
1662
  const rawDocumentAddEventListener = rawDocument.addEventListener;
1583
1663
  const rawDocumentRemoveEventListener = rawDocument.removeEventListener;
1584
1664
  // mark current application as base application
1585
1665
  window.__MICRO_APP_BASE_APPLICATION__ = true;
1586
1666
  assign(globalEnv, {
1667
+ // common global vars
1668
+ rawWindow,
1669
+ rawDocument,
1670
+ rawRootDocument,
1671
+ supportModuleScript,
1587
1672
  // source/patch
1588
1673
  rawSetAttribute,
1589
1674
  rawAppendChild,
@@ -1603,10 +1688,6 @@ function initGlobalEnv() {
1603
1688
  rawGetElementsByTagName,
1604
1689
  rawGetElementsByName,
1605
1690
  ImageProxy,
1606
- // common global vars
1607
- rawWindow,
1608
- rawDocument,
1609
- supportModuleScript,
1610
1691
  // sandbox/effect
1611
1692
  rawWindowAddEventListener,
1612
1693
  rawWindowRemoveEventListener,
@@ -1616,6 +1697,8 @@ function initGlobalEnv() {
1616
1697
  rawClearTimeout,
1617
1698
  rawDocumentAddEventListener,
1618
1699
  rawDocumentRemoveEventListener,
1700
+ rawPushState,
1701
+ rawReplaceState,
1619
1702
  });
1620
1703
  // global effect
1621
1704
  rejectMicroAppStyle();
@@ -1634,11 +1717,14 @@ const globalScripts = new Map();
1634
1717
  function extractScriptElement(script, parent, app, isDynamic = false) {
1635
1718
  let replaceComment = null;
1636
1719
  let src = script.getAttribute('src');
1637
- if (script.hasAttribute('exclude')) {
1720
+ if (src) {
1721
+ src = CompletionPath(src, app.url);
1722
+ }
1723
+ if (script.hasAttribute('exclude') || checkExcludeUrl(src, app.name)) {
1638
1724
  replaceComment = document.createComment('script element with exclude attribute removed by micro-app');
1639
1725
  }
1640
- else if ((script.type && !['text/javascript', 'text/ecmascript', 'application/javascript', 'application/ecmascript', 'module'].includes(script.type)) ||
1641
- script.hasAttribute('ignore')) {
1726
+ else if ((script.type && !['text/javascript', 'text/ecmascript', 'application/javascript', 'application/ecmascript', 'module', 'systemjs-module', 'systemjs-importmap'].includes(script.type)) ||
1727
+ script.hasAttribute('ignore') || checkIgnoreUrl(src, app.name)) {
1642
1728
  return null;
1643
1729
  }
1644
1730
  else if ((globalEnv.supportModuleScript && script.noModule) ||
@@ -1646,7 +1732,6 @@ function extractScriptElement(script, parent, app, isDynamic = false) {
1646
1732
  replaceComment = document.createComment(`${script.noModule ? 'noModule' : 'module'} script ignored by micro-app`);
1647
1733
  }
1648
1734
  else if (src) { // remote script
1649
- src = CompletionPath(src, app.url);
1650
1735
  const info = {
1651
1736
  code: '',
1652
1737
  isExternal: true,
@@ -1696,6 +1781,46 @@ function extractScriptElement(script, parent, app, isDynamic = false) {
1696
1781
  return parent.replaceChild(replaceComment, script);
1697
1782
  }
1698
1783
  }
1784
+ /**
1785
+ * get assets plugins
1786
+ * @param appName app name
1787
+ */
1788
+ function getAssetsPlugins(appName) {
1789
+ var _a, _b, _c;
1790
+ const globalPlugins = ((_a = microApp.plugins) === null || _a === void 0 ? void 0 : _a.global) || [];
1791
+ const modulePlugins = ((_c = (_b = microApp.plugins) === null || _b === void 0 ? void 0 : _b.modules) === null || _c === void 0 ? void 0 : _c[appName]) || [];
1792
+ return [...globalPlugins, ...modulePlugins];
1793
+ }
1794
+ /**
1795
+ * whether the url needs to be excluded
1796
+ * @param url css or js link
1797
+ * @param plugins microApp plugins
1798
+ */
1799
+ function checkExcludeUrl(url, appName) {
1800
+ if (!url)
1801
+ return false;
1802
+ const plugins = getAssetsPlugins(appName) || [];
1803
+ return plugins.some(plugin => {
1804
+ if (!plugin.excludeChecker)
1805
+ return false;
1806
+ return plugin.excludeChecker(url);
1807
+ });
1808
+ }
1809
+ /**
1810
+ * whether the url needs to be ignore
1811
+ * @param url css or js link
1812
+ * @param plugins microApp plugins
1813
+ */
1814
+ function checkIgnoreUrl(url, appName) {
1815
+ if (!url)
1816
+ return false;
1817
+ const plugins = getAssetsPlugins(appName) || [];
1818
+ return plugins.some(plugin => {
1819
+ if (!plugin.ignoreChecker)
1820
+ return false;
1821
+ return plugin.ignoreChecker(url);
1822
+ });
1823
+ }
1699
1824
  /**
1700
1825
  * Get remote resources of script
1701
1826
  * @param wrapElement htmlDom
@@ -1836,6 +1961,13 @@ function runDynamicRemoteScript(url, info, app, originScript) {
1836
1961
  if (app.source.scripts.has(url)) {
1837
1962
  const existInfo = app.source.scripts.get(url);
1838
1963
  !existInfo.module && defer(dispatchScriptOnLoadEvent);
1964
+ /**
1965
+ * TODO: 这里要改,当script初始化时动态创建远程script时,初次渲染和二次渲染的顺序不一致,会导致错误
1966
+ * 1、url不存在缓存,初始化的时候肯定是要异步请求,那么执行顺序就会靠后,至少落后于html自带的script
1967
+ * 2、url存在缓存,那么二次渲染的时候这里会同步执行,就会先于html自带的script执行
1968
+ * 3、测试一下,初次渲染和二次渲染时,onload的执行时机,是在js执行完成,还是执行之前
1969
+ * 4、将上述问题做成注释,方便后续阅读和理解
1970
+ */
1839
1971
  return runScript(url, app, existInfo, true, dispatchScriptOnLoadEvent);
1840
1972
  }
1841
1973
  if (globalScripts.has(url)) {
@@ -1868,7 +2000,7 @@ function runDynamicRemoteScript(url, info, app, originScript) {
1868
2000
  catch (e) {
1869
2001
  console.error(`[micro-app from runDynamicScript] app ${app.name}: `, e, url);
1870
2002
  }
1871
- !info.module && dispatchOnLoadEvent(originScript);
2003
+ !info.module && dispatchScriptOnLoadEvent();
1872
2004
  }).catch((err) => {
1873
2005
  logError(err, app.name);
1874
2006
  dispatchOnErrorEvent(originScript);
@@ -1916,6 +2048,7 @@ function runCode2Function(code, info) {
1916
2048
  * @param info source script info
1917
2049
  */
1918
2050
  function bindScope(url, app, code, info) {
2051
+ // TODO: 增加缓存机制
1919
2052
  if (isPlainObject(microApp.plugins)) {
1920
2053
  code = usePlugins(url, code, app.name, microApp.plugins, info);
1921
2054
  }
@@ -1972,10 +2105,10 @@ function flatChildren(parent, app, microAppHead) {
1972
2105
  });
1973
2106
  for (const dom of children) {
1974
2107
  if (dom instanceof HTMLLinkElement) {
1975
- if (dom.hasAttribute('exclude')) {
2108
+ if (dom.hasAttribute('exclude') || checkExcludeUrl(dom.getAttribute('href'), app.name)) {
1976
2109
  parent.replaceChild(document.createComment('link element with exclude attribute ignored by micro-app'), dom);
1977
2110
  }
1978
- else if (!dom.hasAttribute('ignore')) {
2111
+ else if (!(dom.hasAttribute('ignore') || checkIgnoreUrl(dom.getAttribute('href'), app.name))) {
1979
2112
  extractLinkFromHtml(dom, parent, app);
1980
2113
  }
1981
2114
  else if (dom.hasAttribute('href')) {
@@ -2029,34 +2162,6 @@ function extractSourceDom(htmlStr, app) {
2029
2162
  app.onLoad(wrapElement);
2030
2163
  }
2031
2164
  }
2032
- /**
2033
- * Get and format html
2034
- * @param app app
2035
- */
2036
- function extractHtml(app) {
2037
- fetchSource(app.ssrUrl || app.url, app.name, { cache: 'no-cache' }).then((htmlStr) => {
2038
- if (!htmlStr) {
2039
- const msg = 'html is empty, please check in detail';
2040
- app.onerror(new Error(msg));
2041
- return logError(msg, app.name);
2042
- }
2043
- htmlStr = htmlStr
2044
- .replace(/<head[^>]*>[\s\S]*?<\/head>/i, (match) => {
2045
- return match
2046
- .replace(/<head/i, '<micro-app-head')
2047
- .replace(/<\/head>/i, '</micro-app-head>');
2048
- })
2049
- .replace(/<body[^>]*>[\s\S]*?<\/body>/i, (match) => {
2050
- return match
2051
- .replace(/<body/i, '<micro-app-body')
2052
- .replace(/<\/body>/i, '</micro-app-body>');
2053
- });
2054
- extractSourceDom(htmlStr, app);
2055
- }).catch((e) => {
2056
- logError(`Failed to fetch data from ${app.url}, micro-app stop rendering`, app.name, e);
2057
- app.onLoadError(e);
2058
- });
2059
- }
2060
2165
 
2061
2166
  class EventCenter {
2062
2167
  constructor() {
@@ -2339,12 +2444,39 @@ function rebuildDataCenterSnapshot(microAppEventCenter) {
2339
2444
  }
2340
2445
  }
2341
2446
 
2447
+ // 管理 app 的单例
2448
+ class AppManager {
2449
+ constructor() {
2450
+ // Todo: appInstanceMap 由 AppManager 来创建,不再由 create_app 管理
2451
+ this.appInstanceMap = appInstanceMap;
2452
+ }
2453
+ static getInstance() {
2454
+ if (!this.instance) {
2455
+ this.instance = new AppManager();
2456
+ }
2457
+ return this.instance;
2458
+ }
2459
+ get(appName) {
2460
+ return this.appInstanceMap.get(appName);
2461
+ }
2462
+ set(appName, app) {
2463
+ this.appInstanceMap.set(appName, app);
2464
+ }
2465
+ getAll() {
2466
+ return Array.from(this.appInstanceMap.values());
2467
+ }
2468
+ clear() {
2469
+ this.appInstanceMap.clear();
2470
+ }
2471
+ }
2472
+
2342
2473
  function unmountNestedApp() {
2343
- appInstanceMap.forEach(app => {
2474
+ releaseUnmountOfNestedApp();
2475
+ AppManager.getInstance().getAll().forEach(app => {
2344
2476
  // @ts-ignore
2345
2477
  app.container && getRootContainer(app.container).disconnectedCallback();
2346
2478
  });
2347
- !window.__MICRO_APP_UMD_MODE__ && appInstanceMap.clear();
2479
+ !window.__MICRO_APP_UMD_MODE__ && AppManager.getInstance().clear();
2348
2480
  }
2349
2481
  // release listener
2350
2482
  function releaseUnmountOfNestedApp() {
@@ -2556,6 +2688,13 @@ function effect(appName, microAppWindow) {
2556
2688
  let umdIntervalIdMap = new Map();
2557
2689
  let umdTimeoutIdMap = new Map();
2558
2690
  let umdOnClickHandler;
2691
+ const clearUmdSnapshotData = () => {
2692
+ umdWindowListenerMap.clear();
2693
+ umdIntervalIdMap.clear();
2694
+ umdTimeoutIdMap.clear();
2695
+ umdDocumentListenerMap.clear();
2696
+ umdOnClickHandler = null;
2697
+ };
2559
2698
  // record event and timer before exec umdMountHook
2560
2699
  const recordUmdEffect = () => {
2561
2700
  // record window event
@@ -2601,13 +2740,12 @@ function effect(appName, microAppWindow) {
2601
2740
  // rebuild onclick event
2602
2741
  umdOnClickHandler && documentClickListMap.set(appName, umdOnClickHandler);
2603
2742
  // rebuild document event
2604
- setCurrentAppName(appName);
2605
2743
  umdDocumentListenerMap.forEach((listenerList, type) => {
2606
2744
  for (const listener of listenerList) {
2607
2745
  document.addEventListener(type, listener, listener === null || listener === void 0 ? void 0 : listener.__MICRO_APP_MARK_OPTIONS__);
2608
2746
  }
2609
2747
  });
2610
- setCurrentAppName(null);
2748
+ clearUmdSnapshotData();
2611
2749
  };
2612
2750
  // release all event listener & interval & timeout when unmount app
2613
2751
  const releaseEffect = () => {
@@ -2654,7 +2792,8 @@ function effect(appName, microAppWindow) {
2654
2792
  }
2655
2793
 
2656
2794
  // set micro app state to origin state
2657
- function setMicroState(appName, rawState, microState) {
2795
+ function setMicroState(appName, microState) {
2796
+ const rawState = globalEnv.rawWindow.history.state;
2658
2797
  const additionalState = {
2659
2798
  microAppState: assign({}, rawState === null || rawState === void 0 ? void 0 : rawState.microAppState, {
2660
2799
  [appName]: microState
@@ -2677,9 +2816,9 @@ function removeMicroState(appName, rawState) {
2677
2816
  return assign({}, rawState);
2678
2817
  }
2679
2818
  // get micro app state form origin state
2680
- function getMicroState(appName, state) {
2681
- var _a;
2682
- return ((_a = state === null || state === void 0 ? void 0 : state.microAppState) === null || _a === void 0 ? void 0 : _a[appName]) || null;
2819
+ function getMicroState(appName) {
2820
+ var _a, _b;
2821
+ return ((_b = (_a = globalEnv.rawWindow.history.state) === null || _a === void 0 ? void 0 : _a.microAppState) === null || _b === void 0 ? void 0 : _b[appName]) || null;
2683
2822
  }
2684
2823
  const ENC_AD_RE = /&/g; // %M1
2685
2824
  const ENC_EQ_RE = /=/g; // %M2
@@ -2704,7 +2843,8 @@ function commonDecode(path) {
2704
2843
  }
2705
2844
  // 格式化query参数key,防止与原有参数的冲突
2706
2845
  function formatQueryAppName(appName) {
2707
- return `app-${appName}`;
2846
+ // return `app-${appName}`
2847
+ return appName;
2708
2848
  }
2709
2849
  // 根据浏览器url参数,获取当前子应用的path
2710
2850
  function getMicroPathFromURL(appName) {
@@ -2827,7 +2967,7 @@ function addHistoryListener(appName) {
2827
2967
  isHashChange = proxyWindow.location.hash !== oldHash;
2828
2968
  }
2829
2969
  // dispatch formatted popStateEvent to child
2830
- dispatchPopStateEventToMicroApp(appName, proxyWindow, rawWindow.history.state);
2970
+ dispatchPopStateEventToMicroApp(appName, proxyWindow);
2831
2971
  // dispatch formatted hashChangeEvent to child when hash change
2832
2972
  if (isHashChange)
2833
2973
  dispatchHashChangeEventToMicroApp(appName, proxyWindow, oldHref);
@@ -2846,9 +2986,9 @@ function addHistoryListener(appName) {
2846
2986
  * @param proxyWindow sandbox window
2847
2987
  * @param eventState history.state
2848
2988
  */
2849
- function dispatchPopStateEventToMicroApp(appName, proxyWindow, eventState) {
2989
+ function dispatchPopStateEventToMicroApp(appName, proxyWindow) {
2850
2990
  // create PopStateEvent named popstate-appName with sub app state
2851
- const newPopStateEvent = new PopStateEvent(formatEventName$1('popstate', appName), { state: getMicroState(appName, eventState) });
2991
+ const newPopStateEvent = new PopStateEvent(formatEventName$1('popstate', appName), { state: getMicroState(appName) });
2852
2992
  globalEnv.rawWindow.dispatchEvent(newPopStateEvent);
2853
2993
  // call function window.onpopstate if it exists
2854
2994
  typeof proxyWindow.onpopstate === 'function' && proxyWindow.onpopstate(newPopStateEvent);
@@ -2916,19 +3056,15 @@ function createMicroHistory(appName, microLocation) {
2916
3056
  if (isString(rests[2]) || isURL(rests[2])) {
2917
3057
  const targetLocation = createURL(rests[2], microLocation.href);
2918
3058
  if (targetLocation.origin === microLocation.origin) {
2919
- navigateWithNativeEvent(methodName, setMicroPathToURL(appName, targetLocation), true, setMicroState(appName, rawHistory.state, rests[0]), rests[1]);
3059
+ navigateWithNativeEvent(methodName, setMicroPathToURL(appName, targetLocation), true, setMicroState(appName, rests[0]), rests[1]);
2920
3060
  const targetFullPath = targetLocation.pathname + targetLocation.search + targetLocation.hash;
2921
3061
  if (targetFullPath !== microLocation.fullPath) {
2922
3062
  updateMicroLocation(appName, targetFullPath, microLocation);
2923
3063
  }
3064
+ return void 0;
2924
3065
  }
2925
- else {
2926
- rawHistory[methodName].apply(rawHistory, rests);
2927
- }
2928
- }
2929
- else {
2930
- rawHistory[methodName].apply(rawHistory, rests);
2931
3066
  }
3067
+ nativeHistoryNavigate(methodName, rests[2], rests[0], rests[1]);
2932
3068
  };
2933
3069
  }
2934
3070
  const pushState = getMicroHistoryMethod('pushState');
@@ -2936,7 +3072,7 @@ function createMicroHistory(appName, microLocation) {
2936
3072
  return new Proxy(rawHistory, {
2937
3073
  get(target, key) {
2938
3074
  if (key === 'state') {
2939
- return getMicroState(appName, rawHistory.state);
3075
+ return getMicroState(appName);
2940
3076
  }
2941
3077
  else if (key === 'pushState') {
2942
3078
  return pushState;
@@ -2946,6 +3082,15 @@ function createMicroHistory(appName, microLocation) {
2946
3082
  }
2947
3083
  const rawValue = Reflect.get(target, key);
2948
3084
  return isFunction(rawValue) ? bindFunctionToRawObject(target, rawValue, 'HISTORY') : rawValue;
3085
+ },
3086
+ set(target, key, value) {
3087
+ Reflect.set(target, key, value);
3088
+ /**
3089
+ * If the set() method returns false, and the assignment happened in strict-mode code, a TypeError will be thrown.
3090
+ * e.g. history.state = {}
3091
+ * TypeError: 'set' on proxy: trap returned falsish for property 'state'
3092
+ */
3093
+ return true;
2949
3094
  }
2950
3095
  });
2951
3096
  }
@@ -2957,7 +3102,8 @@ function createMicroHistory(appName, microLocation) {
2957
3102
  * @param title history.title, default is ''
2958
3103
  */
2959
3104
  function nativeHistoryNavigate(methodName, fullPath, state = null, title = '') {
2960
- globalEnv.rawWindow.history[methodName](state, title, fullPath);
3105
+ const method = methodName === 'pushState' ? globalEnv.rawPushState : globalEnv.rawReplaceState;
3106
+ method.call(globalEnv.rawWindow.history, state, title, fullPath);
2961
3107
  }
2962
3108
  /**
2963
3109
  * Navigate to new path, and dispatch native popStateEvent/hashChangeEvent to browser
@@ -2992,10 +3138,10 @@ function attachRouteToBrowserURL(result, state) {
2992
3138
  }
2993
3139
  /**
2994
3140
  * When path is same, keep the microAppState in history.state
2995
- * Fix bug of missing microAppState in next.js & angular
3141
+ * Fix bug of missing microAppState when base app is next.js or angular
2996
3142
  * @param method history.pushState/replaceState
2997
3143
  */
2998
- function patchHistoryState(method) {
3144
+ function reWriteHistoryMethod(method) {
2999
3145
  const rawWindow = globalEnv.rawWindow;
3000
3146
  return function (...rests) {
3001
3147
  var _a;
@@ -3011,22 +3157,38 @@ function patchHistoryState(method) {
3011
3157
  }
3012
3158
  }
3013
3159
  method.apply(rawWindow.history, rests);
3160
+ /**
3161
+ * Attach child router info to browser url when base app navigate with pushState/replaceState
3162
+ * NOTE:
3163
+ * 1. Exec after apply pushState/replaceState
3164
+ * 2. Unable to catch when base app navigate with location
3165
+ * 3. When in nest app, rawPushState/rawReplaceState has been modified by parent
3166
+ * 4.
3167
+ */
3168
+ getActiveApps(true).forEach(appName => {
3169
+ const app = appInstanceMap.get(appName);
3170
+ if (app.sandBox && app.useMemoryRouter && !getMicroPathFromURL(appName)) {
3171
+ attachRouteToBrowserURL(setMicroPathToURL(appName, app.sandBox.proxyWindow.location), setMicroState(appName, getMicroState(appName)));
3172
+ }
3173
+ });
3174
+ // fix bug for nest app
3175
+ removeDomScope();
3014
3176
  };
3015
3177
  }
3016
- let isReWriteHistoryState = false;
3017
3178
  /**
3018
3179
  * rewrite history.pushState/replaceState
3019
3180
  * used to fix the problem that the microAppState maybe missing when mainApp navigate to same path
3020
3181
  * e.g: when nextjs, angular receive popstate event, they will use history.replaceState to update browser url with a new state object
3021
3182
  */
3022
- function rewriteHistoryState() {
3023
- // filter nest app
3024
- if (!isReWriteHistoryState && !window.__MICRO_APP_ENVIRONMENT__) {
3025
- isReWriteHistoryState = true;
3026
- const rawWindow = globalEnv.rawWindow;
3027
- rawWindow.history.pushState = patchHistoryState(rawWindow.history.pushState);
3028
- rawWindow.history.replaceState = patchHistoryState(rawWindow.history.replaceState);
3029
- }
3183
+ function patchHistory() {
3184
+ const rawWindow = globalEnv.rawWindow;
3185
+ rawWindow.history.pushState = reWriteHistoryMethod(globalEnv.rawPushState);
3186
+ rawWindow.history.replaceState = reWriteHistoryMethod(globalEnv.rawReplaceState);
3187
+ }
3188
+ function releasePatchHistory() {
3189
+ const rawWindow = globalEnv.rawWindow;
3190
+ rawWindow.history.pushState = globalEnv.rawPushState;
3191
+ rawWindow.history.replaceState = globalEnv.rawReplaceState;
3030
3192
  }
3031
3193
 
3032
3194
  function createRouterApi() {
@@ -3038,7 +3200,7 @@ function createRouterApi() {
3038
3200
  * @param state to.state
3039
3201
  */
3040
3202
  function navigateWithRawHistory(appName, methodName, targetLocation, state) {
3041
- navigateWithNativeEvent(methodName, setMicroPathToURL(appName, targetLocation), false, setMicroState(appName, globalEnv.rawWindow.history.state, state !== null && state !== void 0 ? state : null));
3203
+ navigateWithNativeEvent(methodName, setMicroPathToURL(appName, targetLocation), false, setMicroState(appName, state !== null && state !== void 0 ? state : null));
3042
3204
  // clear element scope after navigate
3043
3205
  removeDomScope();
3044
3206
  }
@@ -3100,7 +3262,7 @@ function createRouterApi() {
3100
3262
  * NOTE:
3101
3263
  * 1. Modify browser url first, and then run guards,
3102
3264
  * consistent with the browser forward & back button
3103
- * 2. Note the element binding
3265
+ * 2. Prevent the element binding
3104
3266
  * @param appName app name
3105
3267
  * @param to target location
3106
3268
  * @param from old location
@@ -3142,7 +3304,7 @@ function createRouterApi() {
3142
3304
  function commonHandlerForAttachToURL(appName) {
3143
3305
  const app = appInstanceMap.get(appName);
3144
3306
  if (app.sandBox && app.useMemoryRouter) {
3145
- attachRouteToBrowserURL(setMicroPathToURL(appName, app.sandBox.proxyWindow.location), setMicroState(appName, globalEnv.rawWindow.history.state, null));
3307
+ attachRouteToBrowserURL(setMicroPathToURL(appName, app.sandBox.proxyWindow.location), setMicroState(appName, getMicroState(appName)));
3146
3308
  }
3147
3309
  }
3148
3310
  /**
@@ -3157,21 +3319,24 @@ function createRouterApi() {
3157
3319
  }
3158
3320
  /**
3159
3321
  * Attach all active app router info to browser url
3322
+ * exclude hidden keep-alive app
3160
3323
  */
3161
- function attachAllToURL() {
3162
- getActiveApps().forEach(appName => commonHandlerForAttachToURL(appName));
3324
+ function attachAllToURL(includeHiddenApp = false) {
3325
+ getActiveApps(!includeHiddenApp).forEach(appName => commonHandlerForAttachToURL(appName));
3163
3326
  }
3164
3327
  function createDefaultPageApi() {
3165
3328
  // defaultPage data
3166
3329
  const defaultPageRecord = useMapRecord();
3167
3330
  /**
3168
3331
  * defaultPage only effect when mount, and has lower priority than query on browser url
3169
- * @param appName app name
3170
- * @param path page path
3332
+ * SetDefaultPageOptions {
3333
+ * @param name app name
3334
+ * @param path page path
3335
+ * }
3171
3336
  */
3172
- function setDefaultPage(appName, path) {
3173
- appName = formatAppName(appName);
3174
- if (!appName || !path) {
3337
+ function setDefaultPage(options) {
3338
+ const appName = formatAppName(options.name);
3339
+ if (!appName || !options.path) {
3175
3340
  if (process.env.NODE_ENV !== 'production') {
3176
3341
  if (!appName) {
3177
3342
  logWarn(`setDefaultPage: invalid appName "${appName}"`);
@@ -3182,7 +3347,7 @@ function createRouterApi() {
3182
3347
  }
3183
3348
  return noopFalse;
3184
3349
  }
3185
- return defaultPageRecord.add(appName, path);
3350
+ return defaultPageRecord.add(appName, options.path);
3186
3351
  }
3187
3352
  function removeDefaultPage(appName) {
3188
3353
  appName = formatAppName(appName);
@@ -3208,6 +3373,10 @@ function createRouterApi() {
3208
3373
  removeDomScope();
3209
3374
  const rawValue = Reflect.get(target, key);
3210
3375
  return isFunction(rawValue) ? bindFunctionToRawObject(target, rawValue, 'BASEROUTER') : rawValue;
3376
+ },
3377
+ set(target, key, value) {
3378
+ Reflect.set(target, key, value);
3379
+ return true;
3211
3380
  }
3212
3381
  });
3213
3382
  }
@@ -3439,7 +3608,6 @@ function updateMicroLocation(appName, path, microLocation, type) {
3439
3608
  * @returns MicroRouter
3440
3609
  */
3441
3610
  function createMicroRouter(appName, url) {
3442
- rewriteHistoryState();
3443
3611
  const microLocation = createMicroLocation(appName, url);
3444
3612
  return {
3445
3613
  microLocation,
@@ -3465,7 +3633,7 @@ function updateBrowserURLWithLocation(appName, microLocation, defaultPage) {
3465
3633
  if (defaultPage)
3466
3634
  updateMicroLocation(appName, defaultPage, microLocation, 'prevent');
3467
3635
  // attach microApp route info to browser URL
3468
- attachRouteToBrowserURL(setMicroPathToURL(appName, microLocation), setMicroState(appName, globalEnv.rawWindow.history.state, null));
3636
+ attachRouteToBrowserURL(setMicroPathToURL(appName, microLocation), setMicroState(appName, null));
3469
3637
  // trigger guards after change browser URL
3470
3638
  autoTriggerNavigationGuard(appName, microLocation);
3471
3639
  }
@@ -3610,6 +3778,8 @@ class SandBox {
3610
3778
  this.injectedKeys = new Set();
3611
3779
  // Properties escape to rawWindow, cleared when unmount
3612
3780
  this.escapeKeys = new Set();
3781
+ // record injected values before the first execution of umdHookMount and rebuild before remount umd app
3782
+ // private recordUmdInjectedValues?: Map<PropertyKey, unknown>
3613
3783
  // sandbox state
3614
3784
  this.active = false;
3615
3785
  this.microAppWindow = {}; // Proxy target
@@ -3623,7 +3793,8 @@ class SandBox {
3623
3793
  // inject global properties
3624
3794
  this.initStaticGlobalKeys(this.microAppWindow, appName, url, useMemoryRouter);
3625
3795
  }
3626
- start(baseRoute, useMemoryRouter = true, defaultPage = '') {
3796
+ // TODO: 重构
3797
+ start(umdMode = false, baseRoute = '', useMemoryRouter = true, defaultPage = '', disablePatchRequest = false) {
3627
3798
  if (!this.active) {
3628
3799
  this.active = true;
3629
3800
  if (useMemoryRouter) {
@@ -3634,17 +3805,23 @@ class SandBox {
3634
3805
  else {
3635
3806
  this.microAppWindow.__MICRO_APP_BASE_ROUTE__ = this.microAppWindow.__MICRO_APP_BASE_URL__ = baseRoute;
3636
3807
  }
3637
- // prevent the key deleted during sandBox.stop after rewrite
3638
- this.initGlobalKeysWhenStart(this.microAppWindow, this.proxyWindow.__MICRO_APP_NAME__, this.proxyWindow.__MICRO_APP_URL__);
3808
+ /**
3809
+ * 1. prevent the key deleted during sandBox.stop after rewrite
3810
+ * 2. umd mode will not delete any keys during sandBox.stop
3811
+ */
3812
+ if (!umdMode) {
3813
+ this.initGlobalKeysWhenStart(this.microAppWindow, this.proxyWindow.__MICRO_APP_NAME__, this.proxyWindow.__MICRO_APP_URL__, disablePatchRequest);
3814
+ }
3639
3815
  if (++SandBox.activeCount === 1) {
3640
3816
  effectDocumentEvent();
3641
3817
  patchElementPrototypeMethods();
3642
3818
  initEnvOfNestedApp();
3819
+ patchHistory();
3643
3820
  }
3644
3821
  fixBabelPolyfill6();
3645
3822
  }
3646
3823
  }
3647
- stop(keepRouteState, clearEventSource) {
3824
+ stop(umdMode, keepRouteState, clearEventSource) {
3648
3825
  if (this.active) {
3649
3826
  this.releaseEffect();
3650
3827
  this.microAppWindow.microApp.clearDataListener();
@@ -3661,37 +3838,41 @@ class SandBox {
3661
3838
  * NOTE:
3662
3839
  * 1. injectedKeys and escapeKeys must be placed at the back
3663
3840
  * 2. if key in initial microAppWindow, and then rewrite, this key will be delete from microAppWindow when stop, and lost when restart
3841
+ * 3. umd mode will not delete global keys
3664
3842
  */
3665
- this.injectedKeys.forEach((key) => {
3666
- Reflect.deleteProperty(this.microAppWindow, key);
3667
- });
3668
- this.injectedKeys.clear();
3669
- this.escapeKeys.forEach((key) => {
3670
- Reflect.deleteProperty(globalEnv.rawWindow, key);
3671
- });
3672
- this.escapeKeys.clear();
3843
+ if (!umdMode) {
3844
+ this.injectedKeys.forEach((key) => {
3845
+ Reflect.deleteProperty(this.microAppWindow, key);
3846
+ });
3847
+ this.injectedKeys.clear();
3848
+ this.escapeKeys.forEach((key) => {
3849
+ Reflect.deleteProperty(globalEnv.rawWindow, key);
3850
+ });
3851
+ this.escapeKeys.clear();
3852
+ }
3673
3853
  if (--SandBox.activeCount === 0) {
3674
3854
  releaseEffectDocumentEvent();
3675
3855
  releasePatches();
3856
+ releasePatchHistory();
3676
3857
  }
3677
3858
  this.active = false;
3678
3859
  }
3679
3860
  }
3680
3861
  // record umd snapshot before the first execution of umdHookMount
3681
3862
  recordUmdSnapshot() {
3682
- this.microAppWindow.__MICRO_APP_UMD_MODE__ = true;
3863
+ // this.microAppWindow.__MICRO_APP_UMD_MODE__ = true
3683
3864
  this.recordUmdEffect();
3684
3865
  recordDataCenterSnapshot(this.microAppWindow.microApp);
3685
- this.recordUmdInjectedValues = new Map();
3686
- this.injectedKeys.forEach((key) => {
3687
- this.recordUmdInjectedValues.set(key, Reflect.get(this.microAppWindow, key));
3688
- });
3866
+ // this.recordUmdInjectedValues = new Map<PropertyKey, unknown>()
3867
+ // this.injectedKeys.forEach((key: PropertyKey) => {
3868
+ // this.recordUmdInjectedValues!.set(key, Reflect.get(this.microAppWindow, key))
3869
+ // })
3689
3870
  }
3690
3871
  // rebuild umd snapshot before remount umd app
3691
3872
  rebuildUmdSnapshot() {
3692
- this.recordUmdInjectedValues.forEach((value, key) => {
3693
- Reflect.set(this.proxyWindow, key, value);
3694
- });
3873
+ // this.recordUmdInjectedValues!.forEach((value: unknown, key: PropertyKey) => {
3874
+ // Reflect.set(this.proxyWindow, key, value)
3875
+ // })
3695
3876
  this.rebuildUmdEffect();
3696
3877
  rebuildDataCenterSnapshot(this.microAppWindow.microApp);
3697
3878
  }
@@ -3841,15 +4022,26 @@ class SandBox {
3841
4022
  this.setMicroAppRouter(microAppWindow, appName, url);
3842
4023
  }
3843
4024
  setProxyDocument(microAppWindow, appName) {
3844
- const proxyDocument = this.createProxyDocument(appName);
3845
- rawDefineProperty(microAppWindow, 'document', {
3846
- configurable: false,
3847
- enumerable: true,
3848
- get() {
3849
- throttleDeferForSetAppName(appName);
3850
- // return globalEnv.rawDocument
3851
- return proxyDocument;
4025
+ const { proxyDocument, MicroDocument } = this.createProxyDocument(appName);
4026
+ rawDefineProperties(microAppWindow, {
4027
+ document: {
4028
+ configurable: false,
4029
+ enumerable: true,
4030
+ get() {
4031
+ throttleDeferForSetAppName(appName);
4032
+ // return globalEnv.rawDocument
4033
+ return proxyDocument;
4034
+ },
3852
4035
  },
4036
+ Document: {
4037
+ configurable: false,
4038
+ enumerable: false,
4039
+ get() {
4040
+ throttleDeferForSetAppName(appName);
4041
+ // return globalEnv.rawRootDocument
4042
+ return MicroDocument;
4043
+ },
4044
+ }
3853
4045
  });
3854
4046
  }
3855
4047
  // properties associated with the native window
@@ -3884,11 +4076,13 @@ class SandBox {
3884
4076
  * @param microAppWindow micro window
3885
4077
  * @param appName app name
3886
4078
  * @param url app url
4079
+ * @param disablePatchRequest prevent rewrite request method of child app
3887
4080
  */
3888
- initGlobalKeysWhenStart(microAppWindow, appName, url) {
4081
+ initGlobalKeysWhenStart(microAppWindow, appName, url, disablePatchRequest) {
3889
4082
  microAppWindow.hasOwnProperty = (key) => rawHasOwnProperty.call(microAppWindow, key) || rawHasOwnProperty.call(globalEnv.rawWindow, key);
3890
4083
  this.setHijackProperty(microAppWindow, appName);
3891
- this.patchRequestApi(microAppWindow, appName, url);
4084
+ if (!disablePatchRequest)
4085
+ this.patchRequestApi(microAppWindow, appName, url);
3892
4086
  }
3893
4087
  // set hijack Properties to microAppWindow
3894
4088
  setHijackProperty(microAppWindow, appName) {
@@ -3991,23 +4185,75 @@ class SandBox {
3991
4185
  removeRouteInfoForKeepAliveApp() {
3992
4186
  removeStateAndPathFromBrowser(this.proxyWindow.__MICRO_APP_NAME__);
3993
4187
  }
4188
+ /**
4189
+ * Create new document and Document
4190
+ */
3994
4191
  createProxyDocument(appName) {
4192
+ const rawDocument = globalEnv.rawDocument;
4193
+ const rawRootDocument = globalEnv.rawRootDocument;
3995
4194
  const createElement = function (tagName, options) {
3996
- const element = globalEnv.rawCreateElement.call(globalEnv.rawDocument, tagName, options);
4195
+ const element = globalEnv.rawCreateElement.call(rawDocument, tagName, options);
3997
4196
  element.__MICRO_APP_NAME__ = appName;
3998
4197
  return element;
3999
4198
  };
4000
- const proxyDocument = new Proxy(globalEnv.rawDocument, {
4199
+ const proxyDocument = new Proxy(rawDocument, {
4001
4200
  get(target, key) {
4002
4201
  throttleDeferForSetAppName(appName);
4003
4202
  throttleDeferForParentNode(proxyDocument);
4004
4203
  if (key === 'createElement')
4005
4204
  return createElement;
4205
+ if (key === Symbol.toStringTag)
4206
+ return 'ProxyDocument';
4006
4207
  const rawValue = Reflect.get(target, key);
4007
- return isFunction(rawValue) ? bindFunctionToRawObject(target, rawValue, 'DOCUMENT') : rawValue;
4208
+ return isFunction(rawValue) ? bindFunctionToRawObject(rawDocument, rawValue, 'DOCUMENT') : rawValue;
4008
4209
  },
4210
+ set(target, key, value) {
4211
+ // Fix TypeError: Illegal invocation when set document.title
4212
+ Reflect.set(target, key, value);
4213
+ /**
4214
+ * If the set method returns false, and the assignment happened in strict-mode code, a TypeError will be thrown.
4215
+ */
4216
+ return true;
4217
+ }
4009
4218
  });
4010
- return proxyDocument;
4219
+ class MicroDocument {
4220
+ static [Symbol.hasInstance](target) {
4221
+ let proto = target;
4222
+ while (proto = Object.getPrototypeOf(proto)) {
4223
+ if (proto === MicroDocument.prototype) {
4224
+ return true;
4225
+ }
4226
+ }
4227
+ return (target === proxyDocument ||
4228
+ target instanceof rawRootDocument);
4229
+ }
4230
+ }
4231
+ /**
4232
+ * TIP:
4233
+ * 1. child class __proto__, which represents the inherit of the constructor, always points to the parent class
4234
+ * 2. child class prototype.__proto__, which represents the inherit of methods, always points to parent class prototype
4235
+ * e.g.
4236
+ * class B extends A {}
4237
+ * B.__proto__ === A // true
4238
+ * B.prototype.__proto__ === A.prototype // true
4239
+ */
4240
+ Object.setPrototypeOf(MicroDocument, rawRootDocument);
4241
+ // Object.create(rawRootDocument.prototype) will cause MicroDocument and proxyDocument methods not same when exec Document.prototype.xxx = xxx in child app
4242
+ Object.setPrototypeOf(MicroDocument.prototype, new Proxy(rawRootDocument.prototype, {
4243
+ get(target, key) {
4244
+ throttleDeferForSetAppName(appName);
4245
+ const rawValue = Reflect.get(target, key);
4246
+ return isFunction(rawValue) ? bindFunctionToRawObject(rawDocument, rawValue, 'DOCUMENT') : rawValue;
4247
+ },
4248
+ set(target, key, value) {
4249
+ Reflect.set(target, key, value);
4250
+ return true;
4251
+ }
4252
+ }));
4253
+ return {
4254
+ proxyDocument,
4255
+ MicroDocument,
4256
+ };
4011
4257
  }
4012
4258
  }
4013
4259
  SandBox.activeCount = 0; // number of active sandbox
@@ -4076,7 +4322,7 @@ function dispatchCustomEventToMicroApp(eventName, appName, detail = {}) {
4076
4322
  // micro app instances
4077
4323
  const appInstanceMap = new Map();
4078
4324
  class CreateApp {
4079
- constructor({ name, url, ssrUrl, container, inline, scopecss, useSandbox, useMemoryRouter, baseroute, keepRouteState, defaultPage, }) {
4325
+ constructor({ name, url, ssrUrl, container, inline, scopecss, useSandbox, useMemoryRouter, baseroute, keepRouteState, hiddenRouter, defaultPage, disablePatchRequest, }) {
4080
4326
  this.state = appStates.CREATED;
4081
4327
  this.keepAliveState = null;
4082
4328
  this.keepAliveContainer = null;
@@ -4089,18 +4335,20 @@ class CreateApp {
4089
4335
  this.prefetchResolve = null;
4090
4336
  this.container = null;
4091
4337
  this.sandBox = null;
4092
- this.container = container !== null && container !== void 0 ? container : null;
4093
- this.inline = inline !== null && inline !== void 0 ? inline : false;
4094
- this.baseroute = baseroute !== null && baseroute !== void 0 ? baseroute : '';
4095
- this.keepRouteState = keepRouteState !== null && keepRouteState !== void 0 ? keepRouteState : false;
4096
- this.ssrUrl = ssrUrl !== null && ssrUrl !== void 0 ? ssrUrl : '';
4097
- // optional during init👆
4098
4338
  this.name = name;
4099
4339
  this.url = url;
4100
4340
  this.useSandbox = useSandbox;
4101
4341
  this.scopecss = this.useSandbox && scopecss;
4102
4342
  this.useMemoryRouter = this.useSandbox && useMemoryRouter;
4343
+ // optional during init base on prefetch 👇
4344
+ this.container = container !== null && container !== void 0 ? container : null;
4345
+ this.ssrUrl = ssrUrl !== null && ssrUrl !== void 0 ? ssrUrl : '';
4346
+ this.inline = inline !== null && inline !== void 0 ? inline : false;
4347
+ this.baseroute = baseroute !== null && baseroute !== void 0 ? baseroute : '';
4348
+ this.keepRouteState = keepRouteState !== null && keepRouteState !== void 0 ? keepRouteState : false;
4349
+ this.hiddenRouter = hiddenRouter !== null && hiddenRouter !== void 0 ? hiddenRouter : false;
4103
4350
  this.defaultPage = defaultPage !== null && defaultPage !== void 0 ? defaultPage : '';
4351
+ this.disablePatchRequest = disablePatchRequest !== null && disablePatchRequest !== void 0 ? disablePatchRequest : false;
4104
4352
  this.source = {
4105
4353
  links: new Map(),
4106
4354
  scripts: new Map(),
@@ -4111,7 +4359,7 @@ class CreateApp {
4111
4359
  // Load resources
4112
4360
  loadSourceCode() {
4113
4361
  this.state = appStates.LOADING;
4114
- extractHtml(this);
4362
+ HTMLLoader.getInstance().run(this, extractSourceDom);
4115
4363
  }
4116
4364
  /**
4117
4365
  * When resource is loaded, mount app if it is not prefetch or unmount
@@ -4151,17 +4399,17 @@ class CreateApp {
4151
4399
  * @param inline js runs in inline mode
4152
4400
  * @param baseroute route prefix, default is ''
4153
4401
  * @param keepRouteState keep route state when unmount, default is false
4402
+ * @param disablePatchRequest prevent rewrite request method of child app
4154
4403
  */
4155
- mount(container, inline, baseroute, keepRouteState, defaultPage) {
4404
+ mount(container, inline, baseroute, keepRouteState, defaultPage, hiddenRouter, disablePatchRequest) {
4156
4405
  var _a, _b, _c;
4157
- if (isBoolean(inline))
4158
- this.inline = inline;
4159
- // keepRouteState effective on unmount
4160
- if (isBoolean(keepRouteState))
4161
- this.keepRouteState = keepRouteState;
4406
+ this.inline = inline !== null && inline !== void 0 ? inline : this.inline;
4407
+ this.keepRouteState = keepRouteState !== null && keepRouteState !== void 0 ? keepRouteState : this.keepRouteState;
4162
4408
  this.container = (_a = this.container) !== null && _a !== void 0 ? _a : container;
4163
4409
  this.baseroute = baseroute !== null && baseroute !== void 0 ? baseroute : this.baseroute;
4164
4410
  this.defaultPage = defaultPage !== null && defaultPage !== void 0 ? defaultPage : this.defaultPage;
4411
+ this.hiddenRouter = hiddenRouter !== null && hiddenRouter !== void 0 ? hiddenRouter : this.hiddenRouter;
4412
+ this.disablePatchRequest = disablePatchRequest !== null && disablePatchRequest !== void 0 ? disablePatchRequest : this.disablePatchRequest;
4165
4413
  if (this.loadSourceLevel !== 2) {
4166
4414
  this.state = appStates.LOADING;
4167
4415
  return;
@@ -4169,21 +4417,26 @@ class CreateApp {
4169
4417
  dispatchLifecyclesEvent(this.container, this.name, lifeCycles.BEFOREMOUNT);
4170
4418
  this.state = appStates.MOUNTING;
4171
4419
  cloneContainer(this.source.html, this.container, !this.umdMode);
4172
- (_b = this.sandBox) === null || _b === void 0 ? void 0 : _b.start(this.baseroute, this.useMemoryRouter, this.defaultPage);
4420
+ (_b = this.sandBox) === null || _b === void 0 ? void 0 : _b.start(this.umdMode, this.baseroute, this.useMemoryRouter, this.defaultPage, this.disablePatchRequest);
4173
4421
  let umdHookMountResult; // result of mount function
4174
4422
  if (!this.umdMode) {
4175
4423
  let hasDispatchMountedEvent = false;
4176
4424
  // if all js are executed, param isFinished will be true
4177
4425
  execScripts(this.source.scripts, this, (isFinished) => {
4178
- var _a;
4179
4426
  if (!this.umdMode) {
4180
4427
  const { mount, unmount } = this.getUmdLibraryHooks();
4428
+ /**
4429
+ * umdHookUnmount can works in non UMD mode
4430
+ * register with window.unmount
4431
+ */
4432
+ this.umdHookUnmount = unmount;
4181
4433
  // if mount & unmount is function, the sub app is umd mode
4182
4434
  if (isFunction(mount) && isFunction(unmount)) {
4183
4435
  this.umdHookMount = mount;
4184
- this.umdHookUnmount = unmount;
4185
4436
  this.umdMode = true;
4186
- (_a = this.sandBox) === null || _a === void 0 ? void 0 : _a.recordUmdSnapshot();
4437
+ if (this.sandBox)
4438
+ this.sandBox.proxyWindow.__MICRO_APP_UMD_MODE__ = true;
4439
+ // this.sandBox?.recordUmdSnapshot()
4187
4440
  try {
4188
4441
  umdHookMountResult = this.umdHookMount();
4189
4442
  }
@@ -4251,7 +4504,7 @@ class CreateApp {
4251
4504
  * send an unmount event to the micro app or call umd unmount hook
4252
4505
  * before the sandbox is cleared
4253
4506
  */
4254
- if (this.umdHookUnmount) {
4507
+ if (isFunction(this.umdHookUnmount)) {
4255
4508
  try {
4256
4509
  umdHookUnmountResult = this.umdHookUnmount();
4257
4510
  }
@@ -4285,20 +4538,23 @@ class CreateApp {
4285
4538
  * @param unmountcb callback of unmount
4286
4539
  */
4287
4540
  actionsForUnmount(destroy, unmountcb) {
4288
- var _a;
4541
+ var _a, _b;
4289
4542
  if (destroy) {
4290
4543
  this.actionsForCompletelyDestroy();
4291
4544
  }
4292
4545
  else if (this.umdMode && this.container.childElementCount) {
4293
4546
  cloneContainer(this.container, this.source.html, false);
4294
4547
  }
4548
+ if (this.umdMode) {
4549
+ (_a = this.sandBox) === null || _a === void 0 ? void 0 : _a.recordUmdSnapshot();
4550
+ }
4295
4551
  /**
4296
4552
  * this.container maybe contains micro-app element, stop sandbox should exec after cloneContainer
4297
4553
  * NOTE:
4298
4554
  * 1. if destroy is true, clear route state
4299
4555
  * 2. umd mode and keep-alive will not clear EventSource
4300
4556
  */
4301
- (_a = this.sandBox) === null || _a === void 0 ? void 0 : _a.stop(this.keepRouteState && !destroy, !this.umdMode || destroy);
4557
+ (_b = this.sandBox) === null || _b === void 0 ? void 0 : _b.stop(this.umdMode, this.keepRouteState && !destroy, !this.umdMode || destroy);
4302
4558
  if (!getActiveApps().length) {
4303
4559
  releasePatchSetAttribute();
4304
4560
  }
@@ -4370,13 +4626,18 @@ class CreateApp {
4370
4626
  }
4371
4627
  // get umd library, if it not exist, return empty object
4372
4628
  getUmdLibraryHooks() {
4373
- var _a, _b;
4629
+ var _a, _b, _c, _d;
4374
4630
  // after execScripts, the app maybe unmounted
4375
4631
  if (appStates.UNMOUNT !== this.state) {
4376
4632
  const global = ((_b = (_a = this.sandBox) === null || _a === void 0 ? void 0 : _a.proxyWindow) !== null && _b !== void 0 ? _b : globalEnv.rawWindow);
4377
4633
  this.libraryName = getRootContainer(this.container).getAttribute('library') || `micro-app-${this.name}`;
4378
- // do not use isObject
4379
- return typeof global[this.libraryName] === 'object' ? global[this.libraryName] : {};
4634
+ if (isObject(global[this.libraryName])) {
4635
+ return global[this.libraryName];
4636
+ }
4637
+ return {
4638
+ mount: (_c = this.sandBox) === null || _c === void 0 ? void 0 : _c.proxyWindow.mount,
4639
+ unmount: (_d = this.sandBox) === null || _d === void 0 ? void 0 : _d.proxyWindow.unmount,
4640
+ };
4380
4641
  }
4381
4642
  return {};
4382
4643
  }
@@ -4436,6 +4697,7 @@ function defineElement(tagName) {
4436
4697
  this.setAttribute('name', this.appName);
4437
4698
  }
4438
4699
  };
4700
+ // patchSetAttribute hijiack data attribute, it needs exec first
4439
4701
  patchSetAttribute();
4440
4702
  }
4441
4703
  static get observedAttributes() {
@@ -4612,7 +4874,7 @@ function defineElement(tagName) {
4612
4874
  app.isPrefetch = false;
4613
4875
  defer(() => {
4614
4876
  var _a;
4615
- return app.mount((_a = this.shadowRoot) !== null && _a !== void 0 ? _a : this, this.getDisposeResult('inline'), this.getBaseRouteCompatible(), this.getDisposeResult('keep-router-state'), this.getDefaultPageValue());
4877
+ return app.mount((_a = this.shadowRoot) !== null && _a !== void 0 ? _a : this, this.getDisposeResult('inline'), this.getBaseRouteCompatible(), this.getDisposeResult('keep-router-state'), this.getDefaultPageValue(), this.getDisposeResult('hidden-router'), this.getDisposeResult('disable-patch-request'));
4616
4878
  });
4617
4879
  }
4618
4880
  // create app instance
@@ -4631,12 +4893,14 @@ function defineElement(tagName) {
4631
4893
  ssrUrl: this.ssrUrl,
4632
4894
  container: (_a = this.shadowRoot) !== null && _a !== void 0 ? _a : this,
4633
4895
  inline: this.getDisposeResult('inline'),
4634
- scopecss: !(this.getDisposeResult('disableScopecss') || this.getDisposeResult('shadowDOM')),
4635
- useSandbox: !this.getDisposeResult('disableSandbox'),
4896
+ scopecss: !(this.getDisposeResult('disable-scopecss') || this.getDisposeResult('shadowDOM')),
4897
+ useSandbox: !this.getDisposeResult('disable-sandbox'),
4636
4898
  useMemoryRouter: !this.getDisposeResult('disable-memory-router'),
4637
4899
  baseroute: this.getBaseRouteCompatible(),
4638
4900
  keepRouteState: this.getDisposeResult('keep-router-state'),
4639
4901
  defaultPage: this.getDefaultPageValue(),
4902
+ hiddenRouter: this.getDisposeResult('hidden-router'),
4903
+ disablePatchRequest: this.getDisposeResult('disable-patch-request'),
4640
4904
  });
4641
4905
  appInstanceMap.set(this.appName, instance);
4642
4906
  }
@@ -4671,25 +4935,25 @@ function defineElement(tagName) {
4671
4935
  */
4672
4936
  getDisposeResult(name) {
4673
4937
  // @ts-ignore
4674
- return (this.compatibleSpecialProperties(name) || microApp[name]) && this.compatibleDisableSpecialProperties(name);
4938
+ return (this.compatibleSpecialProperties(name) || !!microApp[name]) && this.compatibleDisableSpecialProperties(name);
4675
4939
  }
4676
4940
  // compatible of disableScopecss & disableSandbox
4677
4941
  compatibleSpecialProperties(name) {
4678
- if (name === 'disableScopecss') {
4679
- return this.hasAttribute('disableScopecss') || this.hasAttribute('disable-scopecss');
4942
+ if (name === 'disable-scopecss') {
4943
+ return this.hasAttribute('disable-scopecss') || this.hasAttribute('disableScopecss');
4680
4944
  }
4681
- else if (name === 'disableSandbox') {
4682
- return this.hasAttribute('disableSandbox') || this.hasAttribute('disable-sandbox');
4945
+ else if (name === 'disable-sandbox') {
4946
+ return this.hasAttribute('disable-sandbox') || this.hasAttribute('disableSandbox');
4683
4947
  }
4684
4948
  return this.hasAttribute(name);
4685
4949
  }
4686
4950
  // compatible of disableScopecss & disableSandbox
4687
4951
  compatibleDisableSpecialProperties(name) {
4688
- if (name === 'disableScopecss') {
4689
- return this.getAttribute('disableScopecss') !== 'false' && this.getAttribute('disable-scopecss') !== 'false';
4952
+ if (name === 'disable-scopecss') {
4953
+ return this.getAttribute('disable-scopecss') !== 'false' && this.getAttribute('disableScopecss') !== 'false';
4690
4954
  }
4691
- else if (name === 'disableSandbox') {
4692
- return this.getAttribute('disableSandbox') !== 'false' && this.getAttribute('disable-sandbox') !== 'false';
4955
+ else if (name === 'disable-sandbox') {
4956
+ return this.getAttribute('disable-sandbox') !== 'false' && this.getAttribute('disableSandbox') !== 'false';
4693
4957
  }
4694
4958
  return this.getAttribute(name) !== 'false';
4695
4959
  }
@@ -4801,7 +5065,7 @@ function preFetch(apps) {
4801
5065
  function preFetchInSerial(prefetchApp) {
4802
5066
  return new Promise((resolve) => {
4803
5067
  requestIdleCallback(() => {
4804
- var _a, _b, _c;
5068
+ var _a, _b, _c, _d, _e;
4805
5069
  if (isPlainObject(prefetchApp) && navigator.onLine) {
4806
5070
  prefetchApp.name = formatAppName(prefetchApp.name);
4807
5071
  prefetchApp.url = formatAppURL(prefetchApp.url, prefetchApp.name);
@@ -4809,9 +5073,9 @@ function preFetchInSerial(prefetchApp) {
4809
5073
  const app = new CreateApp({
4810
5074
  name: prefetchApp.name,
4811
5075
  url: prefetchApp.url,
4812
- scopecss: !((_a = prefetchApp.disableScopecss) !== null && _a !== void 0 ? _a : microApp.disableScopecss),
4813
- useSandbox: !((_b = prefetchApp.disableSandbox) !== null && _b !== void 0 ? _b : microApp.disableSandbox),
4814
- useMemoryRouter: !((_c = prefetchApp.disableMemoryRouter) !== null && _c !== void 0 ? _c : microApp.disableMemoryRouter),
5076
+ scopecss: !((_b = (_a = prefetchApp['disable-scopecss']) !== null && _a !== void 0 ? _a : prefetchApp.disableScopecss) !== null && _b !== void 0 ? _b : microApp['disable-scopecss']),
5077
+ useSandbox: !((_d = (_c = prefetchApp['disable-sandbox']) !== null && _c !== void 0 ? _c : prefetchApp.disableSandbox) !== null && _d !== void 0 ? _d : microApp['disable-sandbox']),
5078
+ useMemoryRouter: !((_e = prefetchApp['disable-memory-router']) !== null && _e !== void 0 ? _e : microApp['disable-memory-router']),
4815
5079
  });
4816
5080
  app.isPrefetch = true;
4817
5081
  app.prefetchResolve = resolve;
@@ -4861,7 +5125,7 @@ function fetchGlobalResources(resources, suffix, cache) {
4861
5125
  * @param excludeHiddenApp exclude hidden keep-alive app, default is false
4862
5126
  * @returns active apps
4863
5127
  */
4864
- function getActiveApps(excludeHiddenApp) {
5128
+ function getActiveApps(excludeHiddenApp = false) {
4865
5129
  const activeApps = [];
4866
5130
  appInstanceMap.forEach((app, appName) => {
4867
5131
  if (appStates.UNMOUNT !== app.getAppState() &&
@@ -4957,6 +5221,7 @@ class MicroApp extends EventCenterForBaseApp {
4957
5221
  this.router = router;
4958
5222
  }
4959
5223
  start(options) {
5224
+ var _a, _b;
4960
5225
  if (!isBrowser || !window.customElements) {
4961
5226
  return logError('micro-app is not supported in this environment');
4962
5227
  }
@@ -4982,9 +5247,13 @@ class MicroApp extends EventCenterForBaseApp {
4982
5247
  // @ts-ignore
4983
5248
  this.destory = options.destory;
4984
5249
  this.inline = options.inline;
4985
- this.disableScopecss = options.disableScopecss;
4986
- this.disableSandbox = options.disableSandbox;
4987
- this.disableMemoryRouter = options.disableMemoryRouter;
5250
+ this['disable-scopecss'] = (_a = options['disable-scopecss']) !== null && _a !== void 0 ? _a : options.disableScopecss;
5251
+ this['disable-sandbox'] = (_b = options['disable-sandbox']) !== null && _b !== void 0 ? _b : options.disableSandbox;
5252
+ this['disable-memory-router'] = options['disable-memory-router'];
5253
+ this['disable-patch-request'] = options['disable-patch-request'];
5254
+ this['keep-router-state'] = options['keep-router-state'];
5255
+ this['hidden-router'] = options['hidden-router'];
5256
+ this.esmodule = options.esmodule;
4988
5257
  this.ssr = options.ssr;
4989
5258
  isFunction(options.fetch) && (this.fetch = options.fetch);
4990
5259
  isPlainObject(options.lifeCycles) && (this.lifeCycles = options.lifeCycles);