@micro-zoe/micro-app 1.0.0-alpha.3 → 1.0.0-alpha.4

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.d.ts CHANGED
@@ -41,6 +41,7 @@ declare module '@micro-zoe/micro-app/micro_app' {
41
41
  'disable-scopecss'?: boolean;
42
42
  'disable-sandbox'?: boolean;
43
43
  'disable-memory-router'?: boolean;
44
+ 'disable-patch-request'?: boolean;
44
45
  'keep-router-state'?: boolean;
45
46
  'hidden-router'?: boolean;
46
47
  esmodule?: boolean;
package/lib/index.esm.js CHANGED
@@ -1,4 +1,4 @@
1
- const version = '1.0.0-alpha.3';
1
+ const version = '1.0.0-alpha.4';
2
2
  // do not use isUndefined
3
3
  const isBrowser = typeof window !== 'undefined';
4
4
  // do not use isUndefined
@@ -502,6 +502,66 @@ function fetchSource(url, appName = null, options = {}) {
502
502
  });
503
503
  }
504
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
+
505
565
  // common reg
506
566
  const rootSelectorREG = /(^|\s+)(html|:root)(?=[\s>~[.#:]+|$)/;
507
567
  const bodySelectorREG = /(^|\s+)((html[\s>~]+body)|body)(?=[\s>~[.#:]+|$)/;
@@ -1143,12 +1203,12 @@ function handleNewNode(parent, child, app) {
1143
1203
  return child;
1144
1204
  }
1145
1205
  else if (child instanceof HTMLLinkElement) {
1146
- if (child.hasAttribute('exclude')) {
1206
+ if (child.hasAttribute('exclude') || checkExcludeUrl(child.getAttribute('href'), app.name)) {
1147
1207
  const linkReplaceComment = document.createComment('link element with exclude attribute ignored by micro-app');
1148
1208
  dynamicElementInMicroAppMap.set(child, linkReplaceComment);
1149
1209
  return linkReplaceComment;
1150
1210
  }
1151
- else if (child.hasAttribute('ignore')) {
1211
+ else if (child.hasAttribute('ignore') || checkIgnoreUrl(child.getAttribute('href'), app.name)) {
1152
1212
  return child;
1153
1213
  }
1154
1214
  const { url, info, replaceComment } = extractLinkFromHtml(child, parent, app, true);
@@ -1657,11 +1717,14 @@ const globalScripts = new Map();
1657
1717
  function extractScriptElement(script, parent, app, isDynamic = false) {
1658
1718
  let replaceComment = null;
1659
1719
  let src = script.getAttribute('src');
1660
- if (script.hasAttribute('exclude')) {
1720
+ if (src) {
1721
+ src = CompletionPath(src, app.url);
1722
+ }
1723
+ if (script.hasAttribute('exclude') || checkExcludeUrl(src, app.name)) {
1661
1724
  replaceComment = document.createComment('script element with exclude attribute removed by micro-app');
1662
1725
  }
1663
- else if ((script.type && !['text/javascript', 'text/ecmascript', 'application/javascript', 'application/ecmascript', 'module'].includes(script.type)) ||
1664
- 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)) {
1665
1728
  return null;
1666
1729
  }
1667
1730
  else if ((globalEnv.supportModuleScript && script.noModule) ||
@@ -1669,7 +1732,6 @@ function extractScriptElement(script, parent, app, isDynamic = false) {
1669
1732
  replaceComment = document.createComment(`${script.noModule ? 'noModule' : 'module'} script ignored by micro-app`);
1670
1733
  }
1671
1734
  else if (src) { // remote script
1672
- src = CompletionPath(src, app.url);
1673
1735
  const info = {
1674
1736
  code: '',
1675
1737
  isExternal: true,
@@ -1719,6 +1781,46 @@ function extractScriptElement(script, parent, app, isDynamic = false) {
1719
1781
  return parent.replaceChild(replaceComment, script);
1720
1782
  }
1721
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
+ }
1722
1824
  /**
1723
1825
  * Get remote resources of script
1724
1826
  * @param wrapElement htmlDom
@@ -1898,7 +2000,7 @@ function runDynamicRemoteScript(url, info, app, originScript) {
1898
2000
  catch (e) {
1899
2001
  console.error(`[micro-app from runDynamicScript] app ${app.name}: `, e, url);
1900
2002
  }
1901
- !info.module && dispatchOnLoadEvent(originScript);
2003
+ !info.module && dispatchScriptOnLoadEvent();
1902
2004
  }).catch((err) => {
1903
2005
  logError(err, app.name);
1904
2006
  dispatchOnErrorEvent(originScript);
@@ -1946,6 +2048,7 @@ function runCode2Function(code, info) {
1946
2048
  * @param info source script info
1947
2049
  */
1948
2050
  function bindScope(url, app, code, info) {
2051
+ // TODO: 增加缓存机制
1949
2052
  if (isPlainObject(microApp.plugins)) {
1950
2053
  code = usePlugins(url, code, app.name, microApp.plugins, info);
1951
2054
  }
@@ -2002,10 +2105,10 @@ function flatChildren(parent, app, microAppHead) {
2002
2105
  });
2003
2106
  for (const dom of children) {
2004
2107
  if (dom instanceof HTMLLinkElement) {
2005
- if (dom.hasAttribute('exclude')) {
2108
+ if (dom.hasAttribute('exclude') || checkExcludeUrl(dom.getAttribute('href'), app.name)) {
2006
2109
  parent.replaceChild(document.createComment('link element with exclude attribute ignored by micro-app'), dom);
2007
2110
  }
2008
- else if (!dom.hasAttribute('ignore')) {
2111
+ else if (!(dom.hasAttribute('ignore') || checkIgnoreUrl(dom.getAttribute('href'), app.name))) {
2009
2112
  extractLinkFromHtml(dom, parent, app);
2010
2113
  }
2011
2114
  else if (dom.hasAttribute('href')) {
@@ -2059,34 +2162,6 @@ function extractSourceDom(htmlStr, app) {
2059
2162
  app.onLoad(wrapElement);
2060
2163
  }
2061
2164
  }
2062
- /**
2063
- * Get and format html
2064
- * @param app app
2065
- */
2066
- function extractHtml(app) {
2067
- fetchSource(app.ssrUrl || app.url, app.name, { cache: 'no-cache' }).then((htmlStr) => {
2068
- if (!htmlStr) {
2069
- const msg = 'html is empty, please check in detail';
2070
- app.onerror(new Error(msg));
2071
- return logError(msg, app.name);
2072
- }
2073
- htmlStr = htmlStr
2074
- .replace(/<head[^>]*>[\s\S]*?<\/head>/i, (match) => {
2075
- return match
2076
- .replace(/<head/i, '<micro-app-head')
2077
- .replace(/<\/head>/i, '</micro-app-head>');
2078
- })
2079
- .replace(/<body[^>]*>[\s\S]*?<\/body>/i, (match) => {
2080
- return match
2081
- .replace(/<body/i, '<micro-app-body')
2082
- .replace(/<\/body>/i, '</micro-app-body>');
2083
- });
2084
- extractSourceDom(htmlStr, app);
2085
- }).catch((e) => {
2086
- logError(`Failed to fetch data from ${app.url}, micro-app stop rendering`, app.name, e);
2087
- app.onLoadError(e);
2088
- });
2089
- }
2090
2165
 
2091
2166
  class EventCenter {
2092
2167
  constructor() {
@@ -2369,12 +2444,39 @@ function rebuildDataCenterSnapshot(microAppEventCenter) {
2369
2444
  }
2370
2445
  }
2371
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
+
2372
2473
  function unmountNestedApp() {
2373
- appInstanceMap.forEach(app => {
2474
+ releaseUnmountOfNestedApp();
2475
+ AppManager.getInstance().getAll().forEach(app => {
2374
2476
  // @ts-ignore
2375
2477
  app.container && getRootContainer(app.container).disconnectedCallback();
2376
2478
  });
2377
- !window.__MICRO_APP_UMD_MODE__ && appInstanceMap.clear();
2479
+ !window.__MICRO_APP_UMD_MODE__ && AppManager.getInstance().clear();
2378
2480
  }
2379
2481
  // release listener
2380
2482
  function releaseUnmountOfNestedApp() {
@@ -2586,6 +2688,13 @@ function effect(appName, microAppWindow) {
2586
2688
  let umdIntervalIdMap = new Map();
2587
2689
  let umdTimeoutIdMap = new Map();
2588
2690
  let umdOnClickHandler;
2691
+ const clearUmdSnapshotData = () => {
2692
+ umdWindowListenerMap.clear();
2693
+ umdIntervalIdMap.clear();
2694
+ umdTimeoutIdMap.clear();
2695
+ umdDocumentListenerMap.clear();
2696
+ umdOnClickHandler = null;
2697
+ };
2589
2698
  // record event and timer before exec umdMountHook
2590
2699
  const recordUmdEffect = () => {
2591
2700
  // record window event
@@ -2631,13 +2740,12 @@ function effect(appName, microAppWindow) {
2631
2740
  // rebuild onclick event
2632
2741
  umdOnClickHandler && documentClickListMap.set(appName, umdOnClickHandler);
2633
2742
  // rebuild document event
2634
- setCurrentAppName(appName);
2635
2743
  umdDocumentListenerMap.forEach((listenerList, type) => {
2636
2744
  for (const listener of listenerList) {
2637
2745
  document.addEventListener(type, listener, listener === null || listener === void 0 ? void 0 : listener.__MICRO_APP_MARK_OPTIONS__);
2638
2746
  }
2639
2747
  });
2640
- setCurrentAppName(null);
2748
+ clearUmdSnapshotData();
2641
2749
  };
2642
2750
  // release all event listener & interval & timeout when unmount app
2643
2751
  const releaseEffect = () => {
@@ -2974,6 +3082,15 @@ function createMicroHistory(appName, microLocation) {
2974
3082
  }
2975
3083
  const rawValue = Reflect.get(target, key);
2976
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;
2977
3094
  }
2978
3095
  });
2979
3096
  }
@@ -3145,7 +3262,7 @@ function createRouterApi() {
3145
3262
  * NOTE:
3146
3263
  * 1. Modify browser url first, and then run guards,
3147
3264
  * consistent with the browser forward & back button
3148
- * 2. Note the element binding
3265
+ * 2. Prevent the element binding
3149
3266
  * @param appName app name
3150
3267
  * @param to target location
3151
3268
  * @param from old location
@@ -3212,12 +3329,14 @@ function createRouterApi() {
3212
3329
  const defaultPageRecord = useMapRecord();
3213
3330
  /**
3214
3331
  * defaultPage only effect when mount, and has lower priority than query on browser url
3215
- * @param appName app name
3216
- * @param path page path
3332
+ * SetDefaultPageOptions {
3333
+ * @param name app name
3334
+ * @param path page path
3335
+ * }
3217
3336
  */
3218
- function setDefaultPage(appName, path) {
3219
- appName = formatAppName(appName);
3220
- if (!appName || !path) {
3337
+ function setDefaultPage(options) {
3338
+ const appName = formatAppName(options.name);
3339
+ if (!appName || !options.path) {
3221
3340
  if (process.env.NODE_ENV !== 'production') {
3222
3341
  if (!appName) {
3223
3342
  logWarn(`setDefaultPage: invalid appName "${appName}"`);
@@ -3228,7 +3347,7 @@ function createRouterApi() {
3228
3347
  }
3229
3348
  return noopFalse;
3230
3349
  }
3231
- return defaultPageRecord.add(appName, path);
3350
+ return defaultPageRecord.add(appName, options.path);
3232
3351
  }
3233
3352
  function removeDefaultPage(appName) {
3234
3353
  appName = formatAppName(appName);
@@ -3254,6 +3373,10 @@ function createRouterApi() {
3254
3373
  removeDomScope();
3255
3374
  const rawValue = Reflect.get(target, key);
3256
3375
  return isFunction(rawValue) ? bindFunctionToRawObject(target, rawValue, 'BASEROUTER') : rawValue;
3376
+ },
3377
+ set(target, key, value) {
3378
+ Reflect.set(target, key, value);
3379
+ return true;
3257
3380
  }
3258
3381
  });
3259
3382
  }
@@ -3655,6 +3778,8 @@ class SandBox {
3655
3778
  this.injectedKeys = new Set();
3656
3779
  // Properties escape to rawWindow, cleared when unmount
3657
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>
3658
3783
  // sandbox state
3659
3784
  this.active = false;
3660
3785
  this.microAppWindow = {}; // Proxy target
@@ -3668,7 +3793,8 @@ class SandBox {
3668
3793
  // inject global properties
3669
3794
  this.initStaticGlobalKeys(this.microAppWindow, appName, url, useMemoryRouter);
3670
3795
  }
3671
- start(baseRoute, useMemoryRouter = true, defaultPage = '') {
3796
+ // TODO: 重构
3797
+ start(umdMode = false, baseRoute = '', useMemoryRouter = true, defaultPage = '', disablePatchRequest = false) {
3672
3798
  if (!this.active) {
3673
3799
  this.active = true;
3674
3800
  if (useMemoryRouter) {
@@ -3679,8 +3805,13 @@ class SandBox {
3679
3805
  else {
3680
3806
  this.microAppWindow.__MICRO_APP_BASE_ROUTE__ = this.microAppWindow.__MICRO_APP_BASE_URL__ = baseRoute;
3681
3807
  }
3682
- // prevent the key deleted during sandBox.stop after rewrite
3683
- 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
+ }
3684
3815
  if (++SandBox.activeCount === 1) {
3685
3816
  effectDocumentEvent();
3686
3817
  patchElementPrototypeMethods();
@@ -3690,7 +3821,7 @@ class SandBox {
3690
3821
  fixBabelPolyfill6();
3691
3822
  }
3692
3823
  }
3693
- stop(keepRouteState, clearEventSource) {
3824
+ stop(umdMode, keepRouteState, clearEventSource) {
3694
3825
  if (this.active) {
3695
3826
  this.releaseEffect();
3696
3827
  this.microAppWindow.microApp.clearDataListener();
@@ -3707,15 +3838,18 @@ class SandBox {
3707
3838
  * NOTE:
3708
3839
  * 1. injectedKeys and escapeKeys must be placed at the back
3709
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
3710
3842
  */
3711
- this.injectedKeys.forEach((key) => {
3712
- Reflect.deleteProperty(this.microAppWindow, key);
3713
- });
3714
- this.injectedKeys.clear();
3715
- this.escapeKeys.forEach((key) => {
3716
- Reflect.deleteProperty(globalEnv.rawWindow, key);
3717
- });
3718
- 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
+ }
3719
3853
  if (--SandBox.activeCount === 0) {
3720
3854
  releaseEffectDocumentEvent();
3721
3855
  releasePatches();
@@ -3726,19 +3860,19 @@ class SandBox {
3726
3860
  }
3727
3861
  // record umd snapshot before the first execution of umdHookMount
3728
3862
  recordUmdSnapshot() {
3729
- this.microAppWindow.__MICRO_APP_UMD_MODE__ = true;
3863
+ // this.microAppWindow.__MICRO_APP_UMD_MODE__ = true
3730
3864
  this.recordUmdEffect();
3731
3865
  recordDataCenterSnapshot(this.microAppWindow.microApp);
3732
- this.recordUmdInjectedValues = new Map();
3733
- this.injectedKeys.forEach((key) => {
3734
- this.recordUmdInjectedValues.set(key, Reflect.get(this.microAppWindow, key));
3735
- });
3866
+ // this.recordUmdInjectedValues = new Map<PropertyKey, unknown>()
3867
+ // this.injectedKeys.forEach((key: PropertyKey) => {
3868
+ // this.recordUmdInjectedValues!.set(key, Reflect.get(this.microAppWindow, key))
3869
+ // })
3736
3870
  }
3737
3871
  // rebuild umd snapshot before remount umd app
3738
3872
  rebuildUmdSnapshot() {
3739
- this.recordUmdInjectedValues.forEach((value, key) => {
3740
- Reflect.set(this.proxyWindow, key, value);
3741
- });
3873
+ // this.recordUmdInjectedValues!.forEach((value: unknown, key: PropertyKey) => {
3874
+ // Reflect.set(this.proxyWindow, key, value)
3875
+ // })
3742
3876
  this.rebuildUmdEffect();
3743
3877
  rebuildDataCenterSnapshot(this.microAppWindow.microApp);
3744
3878
  }
@@ -3942,11 +4076,13 @@ class SandBox {
3942
4076
  * @param microAppWindow micro window
3943
4077
  * @param appName app name
3944
4078
  * @param url app url
4079
+ * @param disablePatchRequest prevent rewrite request method of child app
3945
4080
  */
3946
- initGlobalKeysWhenStart(microAppWindow, appName, url) {
4081
+ initGlobalKeysWhenStart(microAppWindow, appName, url, disablePatchRequest) {
3947
4082
  microAppWindow.hasOwnProperty = (key) => rawHasOwnProperty.call(microAppWindow, key) || rawHasOwnProperty.call(globalEnv.rawWindow, key);
3948
4083
  this.setHijackProperty(microAppWindow, appName);
3949
- this.patchRequestApi(microAppWindow, appName, url);
4084
+ if (!disablePatchRequest)
4085
+ this.patchRequestApi(microAppWindow, appName, url);
3950
4086
  }
3951
4087
  // set hijack Properties to microAppWindow
3952
4088
  setHijackProperty(microAppWindow, appName) {
@@ -4071,6 +4207,14 @@ class SandBox {
4071
4207
  const rawValue = Reflect.get(target, key);
4072
4208
  return isFunction(rawValue) ? bindFunctionToRawObject(rawDocument, rawValue, 'DOCUMENT') : rawValue;
4073
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
+ }
4074
4218
  });
4075
4219
  class MicroDocument {
4076
4220
  static [Symbol.hasInstance](target) {
@@ -4094,11 +4238,16 @@ class SandBox {
4094
4238
  * B.prototype.__proto__ === A.prototype // true
4095
4239
  */
4096
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
4097
4242
  Object.setPrototypeOf(MicroDocument.prototype, new Proxy(rawRootDocument.prototype, {
4098
4243
  get(target, key) {
4099
4244
  throttleDeferForSetAppName(appName);
4100
4245
  const rawValue = Reflect.get(target, key);
4101
4246
  return isFunction(rawValue) ? bindFunctionToRawObject(rawDocument, rawValue, 'DOCUMENT') : rawValue;
4247
+ },
4248
+ set(target, key, value) {
4249
+ Reflect.set(target, key, value);
4250
+ return true;
4102
4251
  }
4103
4252
  }));
4104
4253
  return {
@@ -4173,7 +4322,7 @@ function dispatchCustomEventToMicroApp(eventName, appName, detail = {}) {
4173
4322
  // micro app instances
4174
4323
  const appInstanceMap = new Map();
4175
4324
  class CreateApp {
4176
- constructor({ name, url, ssrUrl, container, inline, scopecss, useSandbox, useMemoryRouter, baseroute, keepRouteState, hiddenRouter, defaultPage, }) {
4325
+ constructor({ name, url, ssrUrl, container, inline, scopecss, useSandbox, useMemoryRouter, baseroute, keepRouteState, hiddenRouter, defaultPage, disablePatchRequest, }) {
4177
4326
  this.state = appStates.CREATED;
4178
4327
  this.keepAliveState = null;
4179
4328
  this.keepAliveContainer = null;
@@ -4199,6 +4348,7 @@ class CreateApp {
4199
4348
  this.keepRouteState = keepRouteState !== null && keepRouteState !== void 0 ? keepRouteState : false;
4200
4349
  this.hiddenRouter = hiddenRouter !== null && hiddenRouter !== void 0 ? hiddenRouter : false;
4201
4350
  this.defaultPage = defaultPage !== null && defaultPage !== void 0 ? defaultPage : '';
4351
+ this.disablePatchRequest = disablePatchRequest !== null && disablePatchRequest !== void 0 ? disablePatchRequest : false;
4202
4352
  this.source = {
4203
4353
  links: new Map(),
4204
4354
  scripts: new Map(),
@@ -4209,7 +4359,7 @@ class CreateApp {
4209
4359
  // Load resources
4210
4360
  loadSourceCode() {
4211
4361
  this.state = appStates.LOADING;
4212
- extractHtml(this);
4362
+ HTMLLoader.getInstance().run(this, extractSourceDom);
4213
4363
  }
4214
4364
  /**
4215
4365
  * When resource is loaded, mount app if it is not prefetch or unmount
@@ -4249,8 +4399,9 @@ class CreateApp {
4249
4399
  * @param inline js runs in inline mode
4250
4400
  * @param baseroute route prefix, default is ''
4251
4401
  * @param keepRouteState keep route state when unmount, default is false
4402
+ * @param disablePatchRequest prevent rewrite request method of child app
4252
4403
  */
4253
- mount(container, inline, baseroute, keepRouteState, defaultPage, hiddenRouter) {
4404
+ mount(container, inline, baseroute, keepRouteState, defaultPage, hiddenRouter, disablePatchRequest) {
4254
4405
  var _a, _b, _c;
4255
4406
  this.inline = inline !== null && inline !== void 0 ? inline : this.inline;
4256
4407
  this.keepRouteState = keepRouteState !== null && keepRouteState !== void 0 ? keepRouteState : this.keepRouteState;
@@ -4258,6 +4409,7 @@ class CreateApp {
4258
4409
  this.baseroute = baseroute !== null && baseroute !== void 0 ? baseroute : this.baseroute;
4259
4410
  this.defaultPage = defaultPage !== null && defaultPage !== void 0 ? defaultPage : this.defaultPage;
4260
4411
  this.hiddenRouter = hiddenRouter !== null && hiddenRouter !== void 0 ? hiddenRouter : this.hiddenRouter;
4412
+ this.disablePatchRequest = disablePatchRequest !== null && disablePatchRequest !== void 0 ? disablePatchRequest : this.disablePatchRequest;
4261
4413
  if (this.loadSourceLevel !== 2) {
4262
4414
  this.state = appStates.LOADING;
4263
4415
  return;
@@ -4265,13 +4417,12 @@ class CreateApp {
4265
4417
  dispatchLifecyclesEvent(this.container, this.name, lifeCycles.BEFOREMOUNT);
4266
4418
  this.state = appStates.MOUNTING;
4267
4419
  cloneContainer(this.source.html, this.container, !this.umdMode);
4268
- (_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);
4269
4421
  let umdHookMountResult; // result of mount function
4270
4422
  if (!this.umdMode) {
4271
4423
  let hasDispatchMountedEvent = false;
4272
4424
  // if all js are executed, param isFinished will be true
4273
4425
  execScripts(this.source.scripts, this, (isFinished) => {
4274
- var _a;
4275
4426
  if (!this.umdMode) {
4276
4427
  const { mount, unmount } = this.getUmdLibraryHooks();
4277
4428
  // if mount & unmount is function, the sub app is umd mode
@@ -4279,7 +4430,9 @@ class CreateApp {
4279
4430
  this.umdHookMount = mount;
4280
4431
  this.umdHookUnmount = unmount;
4281
4432
  this.umdMode = true;
4282
- (_a = this.sandBox) === null || _a === void 0 ? void 0 : _a.recordUmdSnapshot();
4433
+ if (this.sandBox)
4434
+ this.sandBox.proxyWindow.__MICRO_APP_UMD_MODE__ = true;
4435
+ // this.sandBox?.recordUmdSnapshot()
4283
4436
  try {
4284
4437
  umdHookMountResult = this.umdHookMount();
4285
4438
  }
@@ -4381,20 +4534,23 @@ class CreateApp {
4381
4534
  * @param unmountcb callback of unmount
4382
4535
  */
4383
4536
  actionsForUnmount(destroy, unmountcb) {
4384
- var _a;
4537
+ var _a, _b;
4385
4538
  if (destroy) {
4386
4539
  this.actionsForCompletelyDestroy();
4387
4540
  }
4388
4541
  else if (this.umdMode && this.container.childElementCount) {
4389
4542
  cloneContainer(this.container, this.source.html, false);
4390
4543
  }
4544
+ if (this.umdMode) {
4545
+ (_a = this.sandBox) === null || _a === void 0 ? void 0 : _a.recordUmdSnapshot();
4546
+ }
4391
4547
  /**
4392
4548
  * this.container maybe contains micro-app element, stop sandbox should exec after cloneContainer
4393
4549
  * NOTE:
4394
4550
  * 1. if destroy is true, clear route state
4395
4551
  * 2. umd mode and keep-alive will not clear EventSource
4396
4552
  */
4397
- (_a = this.sandBox) === null || _a === void 0 ? void 0 : _a.stop(this.keepRouteState && !destroy, !this.umdMode || destroy);
4553
+ (_b = this.sandBox) === null || _b === void 0 ? void 0 : _b.stop(this.umdMode, this.keepRouteState && !destroy, !this.umdMode || destroy);
4398
4554
  if (!getActiveApps().length) {
4399
4555
  releasePatchSetAttribute();
4400
4556
  }
@@ -4709,7 +4865,7 @@ function defineElement(tagName) {
4709
4865
  app.isPrefetch = false;
4710
4866
  defer(() => {
4711
4867
  var _a;
4712
- 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'));
4868
+ 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'));
4713
4869
  });
4714
4870
  }
4715
4871
  // create app instance
@@ -4735,6 +4891,7 @@ function defineElement(tagName) {
4735
4891
  keepRouteState: this.getDisposeResult('keep-router-state'),
4736
4892
  defaultPage: this.getDefaultPageValue(),
4737
4893
  hiddenRouter: this.getDisposeResult('hidden-router'),
4894
+ disablePatchRequest: this.getDisposeResult('disable-patch-request'),
4738
4895
  });
4739
4896
  appInstanceMap.set(this.appName, instance);
4740
4897
  }
@@ -5084,6 +5241,7 @@ class MicroApp extends EventCenterForBaseApp {
5084
5241
  this['disable-scopecss'] = (_a = options['disable-scopecss']) !== null && _a !== void 0 ? _a : options.disableScopecss;
5085
5242
  this['disable-sandbox'] = (_b = options['disable-sandbox']) !== null && _b !== void 0 ? _b : options.disableSandbox;
5086
5243
  this['disable-memory-router'] = options['disable-memory-router'];
5244
+ this['disable-patch-request'] = options['disable-patch-request'];
5087
5245
  this['keep-router-state'] = options['keep-router-state'];
5088
5246
  this['hidden-router'] = options['hidden-router'];
5089
5247
  this.esmodule = options.esmodule;