@micro-zoe/micro-app 0.5.2 → 0.6.2

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 = '0.5.2';
1
+ const version = '0.6.2';
2
2
  // do not use isUndefined
3
3
  const isBrowser = typeof window !== 'undefined';
4
4
  // do not use isUndefined
@@ -297,16 +297,16 @@ var ObservedAttrName;
297
297
  ObservedAttrName["URL"] = "url";
298
298
  })(ObservedAttrName || (ObservedAttrName = {}));
299
299
  // app status
300
- var appStatus;
301
- (function (appStatus) {
302
- appStatus["NOT_LOADED"] = "NOT_LOADED";
303
- appStatus["LOADING_SOURCE_CODE"] = "LOADING_SOURCE_CODE";
304
- appStatus["LOAD_SOURCE_FINISHED"] = "LOAD_SOURCE_FINISHED";
305
- appStatus["LOAD_SOURCE_ERROR"] = "LOAD_SOURCE_ERROR";
306
- appStatus["MOUNTING"] = "MOUNTING";
307
- appStatus["MOUNTED"] = "MOUNTED";
308
- appStatus["UNMOUNT"] = "UNMOUNT";
309
- })(appStatus || (appStatus = {}));
300
+ var appStates;
301
+ (function (appStates) {
302
+ appStates["NOT_LOADED"] = "NOT_LOADED";
303
+ appStates["LOADING_SOURCE_CODE"] = "LOADING_SOURCE_CODE";
304
+ appStates["LOAD_SOURCE_FINISHED"] = "LOAD_SOURCE_FINISHED";
305
+ appStates["LOAD_SOURCE_ERROR"] = "LOAD_SOURCE_ERROR";
306
+ appStates["MOUNTING"] = "MOUNTING";
307
+ appStates["MOUNTED"] = "MOUNTED";
308
+ appStates["UNMOUNT"] = "UNMOUNT";
309
+ })(appStates || (appStates = {}));
310
310
  // lifecycles
311
311
  var lifeCycles;
312
312
  (function (lifeCycles) {
@@ -315,7 +315,17 @@ var lifeCycles;
315
315
  lifeCycles["MOUNTED"] = "mounted";
316
316
  lifeCycles["UNMOUNT"] = "unmount";
317
317
  lifeCycles["ERROR"] = "error";
318
+ // 👇 keep-alive only
319
+ lifeCycles["BEFORESHOW"] = "beforeshow";
320
+ lifeCycles["AFTERSHOW"] = "aftershow";
321
+ lifeCycles["AFTERHIDDEN"] = "afterhidden";
318
322
  })(lifeCycles || (lifeCycles = {}));
323
+ // keep-alive status
324
+ var keepAliveStates;
325
+ (function (keepAliveStates) {
326
+ keepAliveStates["KEEP_ALIVE_SHOW"] = "KEEP_ALIVE_SHOW";
327
+ keepAliveStates["KEEP_ALIVE_HIDDEN"] = "KEEP_ALIVE_HIDDEN";
328
+ })(keepAliveStates || (keepAliveStates = {}));
319
329
 
320
330
  /**
321
331
  * fetch source of html, js, css
@@ -340,12 +350,13 @@ function initGlobalEnv() {
340
350
  * pay attention to this binding
341
351
  */
342
352
  const rawSetAttribute = Element.prototype.setAttribute;
343
- const rawAppendChild = Node.prototype.appendChild;
344
- const rawInsertBefore = Node.prototype.insertBefore;
345
- const rawReplaceChild = Node.prototype.replaceChild;
346
- const rawRemoveChild = Node.prototype.removeChild;
353
+ const rawAppendChild = Element.prototype.appendChild;
354
+ const rawInsertBefore = Element.prototype.insertBefore;
355
+ const rawReplaceChild = Element.prototype.replaceChild;
356
+ const rawRemoveChild = Element.prototype.removeChild;
347
357
  const rawAppend = Element.prototype.append;
348
358
  const rawPrepend = Element.prototype.prepend;
359
+ const rawCloneNode = Element.prototype.cloneNode;
349
360
  const rawCreateElement = Document.prototype.createElement;
350
361
  const rawCreateElementNS = Document.prototype.createElementNS;
351
362
  const rawCreateDocumentFragment = Document.prototype.createDocumentFragment;
@@ -355,6 +366,13 @@ function initGlobalEnv() {
355
366
  const rawGetElementsByClassName = Document.prototype.getElementsByClassName;
356
367
  const rawGetElementsByTagName = Document.prototype.getElementsByTagName;
357
368
  const rawGetElementsByName = Document.prototype.getElementsByName;
369
+ const ImageProxy = new Proxy(Image, {
370
+ construct(Target, args) {
371
+ const elementImage = new Target(...args);
372
+ elementImage.__MICRO_APP_NAME__ = getCurrentAppName();
373
+ return elementImage;
374
+ },
375
+ });
358
376
  const rawWindow = Function('return window')();
359
377
  const rawDocument = Function('return document')();
360
378
  const supportModuleScript = isSupportModuleScript();
@@ -382,6 +400,7 @@ function initGlobalEnv() {
382
400
  rawRemoveChild,
383
401
  rawAppend,
384
402
  rawPrepend,
403
+ rawCloneNode,
385
404
  rawCreateElement,
386
405
  rawCreateElementNS,
387
406
  rawCreateDocumentFragment,
@@ -391,6 +410,7 @@ function initGlobalEnv() {
391
410
  rawGetElementsByClassName,
392
411
  rawGetElementsByTagName,
393
412
  rawGetElementsByName,
413
+ ImageProxy,
394
414
  // common global vars
395
415
  rawWindow,
396
416
  rawDocument,
@@ -1180,305 +1200,6 @@ function extractHtml(app) {
1180
1200
  });
1181
1201
  }
1182
1202
 
1183
- const boundedMap = new WeakMap();
1184
- function isBoundedFunction(value) {
1185
- if (boundedMap.has(value)) {
1186
- return boundedMap.get(value);
1187
- }
1188
- // bind function
1189
- const boundFunction = isBoundFunction(value);
1190
- boundedMap.set(value, boundFunction);
1191
- return boundFunction;
1192
- }
1193
- const constructorMap = new WeakMap();
1194
- function isConstructor(value) {
1195
- if (constructorMap.has(value)) {
1196
- return constructorMap.get(value);
1197
- }
1198
- const valueStr = value.toString();
1199
- const result = (value.prototype &&
1200
- value.prototype.constructor === value &&
1201
- Object.getOwnPropertyNames(value.prototype).length > 1) ||
1202
- /^function\s+[A-Z]/.test(valueStr) ||
1203
- /^class\s+/.test(valueStr);
1204
- constructorMap.set(value, result);
1205
- return result;
1206
- }
1207
- const rawWindowMethodMap = new WeakMap();
1208
- // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
1209
- function bindFunctionToRawWidow(rawWindow, value) {
1210
- if (rawWindowMethodMap.has(value)) {
1211
- return rawWindowMethodMap.get(value);
1212
- }
1213
- if (isFunction(value) && !isConstructor(value) && !isBoundedFunction(value)) {
1214
- const bindRawWindowValue = value.bind(rawWindow);
1215
- for (const key in value) {
1216
- bindRawWindowValue[key] = value[key];
1217
- }
1218
- if (value.hasOwnProperty('prototype') && !bindRawWindowValue.hasOwnProperty('prototype')) {
1219
- bindRawWindowValue.prototype = value.prototype;
1220
- }
1221
- rawWindowMethodMap.set(value, bindRawWindowValue);
1222
- return bindRawWindowValue;
1223
- }
1224
- return value;
1225
- }
1226
-
1227
- // document.onclick binding list, the binding function of each application is unique
1228
- const documentClickListMap = new Map();
1229
- let hasRewriteDocumentOnClick = false;
1230
- /**
1231
- * Rewrite document.onclick and execute it only once
1232
- */
1233
- function overwriteDocumentOnClick() {
1234
- hasRewriteDocumentOnClick = true;
1235
- if (Object.getOwnPropertyDescriptor(document, 'onclick')) {
1236
- return logWarn('Cannot redefine document property onclick');
1237
- }
1238
- const rawOnClick = document.onclick;
1239
- document.onclick = null;
1240
- let hasDocumentClickInited = false;
1241
- function onClickHandler(e) {
1242
- documentClickListMap.forEach((f) => {
1243
- isFunction(f) && f.call(document, e);
1244
- });
1245
- }
1246
- Object.defineProperty(document, 'onclick', {
1247
- configurable: true,
1248
- enumerable: true,
1249
- get() {
1250
- const appName = getCurrentAppName();
1251
- return appName ? documentClickListMap.get(appName) : documentClickListMap.get('base');
1252
- },
1253
- set(f) {
1254
- const appName = getCurrentAppName();
1255
- if (appName) {
1256
- documentClickListMap.set(appName, f);
1257
- }
1258
- else {
1259
- documentClickListMap.set('base', f);
1260
- }
1261
- if (!hasDocumentClickInited && isFunction(f)) {
1262
- hasDocumentClickInited = true;
1263
- globalEnv.rawDocumentAddEventListener.call(globalEnv.rawDocument, 'click', onClickHandler, false);
1264
- }
1265
- }
1266
- });
1267
- rawOnClick && (document.onclick = rawOnClick);
1268
- }
1269
- /**
1270
- * The document event is globally, we need to clear these event bindings when micro application unmounted
1271
- */
1272
- const documentEventListenerMap = new Map();
1273
- function effectDocumentEvent() {
1274
- const { rawDocument, rawDocumentAddEventListener, rawDocumentRemoveEventListener, } = globalEnv;
1275
- !hasRewriteDocumentOnClick && overwriteDocumentOnClick();
1276
- document.addEventListener = function (type, listener, options) {
1277
- var _a;
1278
- const appName = getCurrentAppName();
1279
- /**
1280
- * ignore bound function of document event in umd mode, used to solve problem of react global events
1281
- */
1282
- if (appName && !(((_a = appInstanceMap.get(appName)) === null || _a === void 0 ? void 0 : _a.umdMode) && isBoundFunction(listener))) {
1283
- const appListenersMap = documentEventListenerMap.get(appName);
1284
- if (appListenersMap) {
1285
- const appListenerList = appListenersMap.get(type);
1286
- if (appListenerList) {
1287
- appListenerList.add(listener);
1288
- }
1289
- else {
1290
- appListenersMap.set(type, new Set([listener]));
1291
- }
1292
- }
1293
- else {
1294
- documentEventListenerMap.set(appName, new Map([[type, new Set([listener])]]));
1295
- }
1296
- listener && (listener.__MICRO_MARK_OPTIONS__ = options);
1297
- }
1298
- rawDocumentAddEventListener.call(rawDocument, type, listener, options);
1299
- };
1300
- document.removeEventListener = function (type, listener, options) {
1301
- var _a;
1302
- const appName = getCurrentAppName();
1303
- if (appName && !(((_a = appInstanceMap.get(appName)) === null || _a === void 0 ? void 0 : _a.umdMode) && isBoundFunction(listener))) {
1304
- const appListenersMap = documentEventListenerMap.get(appName);
1305
- if (appListenersMap) {
1306
- const appListenerList = appListenersMap.get(type);
1307
- if ((appListenerList === null || appListenerList === void 0 ? void 0 : appListenerList.size) && appListenerList.has(listener)) {
1308
- appListenerList.delete(listener);
1309
- }
1310
- }
1311
- }
1312
- rawDocumentRemoveEventListener.call(rawDocument, type, listener, options);
1313
- };
1314
- }
1315
- // Clear the document event agent
1316
- function releaseEffectDocumentEvent() {
1317
- document.addEventListener = globalEnv.rawDocumentAddEventListener;
1318
- document.removeEventListener = globalEnv.rawDocumentRemoveEventListener;
1319
- }
1320
- /**
1321
- * Format event name
1322
- * @param type event name
1323
- * @param microWindow micro window
1324
- */
1325
- function formatEventType(type, microWindow) {
1326
- if (type === 'unmount') {
1327
- return `unmount-${microWindow.__MICRO_APP_NAME__}`;
1328
- }
1329
- return type;
1330
- }
1331
- /**
1332
- * Rewrite side-effect events
1333
- * @param microWindow micro window
1334
- */
1335
- function effect(microWindow) {
1336
- const appName = microWindow.__MICRO_APP_NAME__;
1337
- const eventListenerMap = new Map();
1338
- const intervalIdMap = new Map();
1339
- const timeoutIdMap = new Map();
1340
- const { rawWindow, rawDocument, rawWindowAddEventListener, rawWindowRemoveEventListener, rawSetInterval, rawSetTimeout, rawClearInterval, rawClearTimeout, rawDocumentRemoveEventListener, } = globalEnv;
1341
- // listener may be null, e.g test-passive
1342
- microWindow.addEventListener = function (type, listener, options) {
1343
- type = formatEventType(type, microWindow);
1344
- const listenerList = eventListenerMap.get(type);
1345
- if (listenerList) {
1346
- listenerList.add(listener);
1347
- }
1348
- else {
1349
- eventListenerMap.set(type, new Set([listener]));
1350
- }
1351
- listener && (listener.__MICRO_MARK_OPTIONS__ = options);
1352
- rawWindowAddEventListener.call(rawWindow, type, listener, options);
1353
- };
1354
- microWindow.removeEventListener = function (type, listener, options) {
1355
- type = formatEventType(type, microWindow);
1356
- const listenerList = eventListenerMap.get(type);
1357
- if ((listenerList === null || listenerList === void 0 ? void 0 : listenerList.size) && listenerList.has(listener)) {
1358
- listenerList.delete(listener);
1359
- }
1360
- rawWindowRemoveEventListener.call(rawWindow, type, listener, options);
1361
- };
1362
- microWindow.setInterval = function (handler, timeout, ...args) {
1363
- const intervalId = rawSetInterval.call(rawWindow, handler, timeout, ...args);
1364
- intervalIdMap.set(intervalId, { handler, timeout, args });
1365
- return intervalId;
1366
- };
1367
- microWindow.setTimeout = function (handler, timeout, ...args) {
1368
- const timeoutId = rawSetTimeout.call(rawWindow, handler, timeout, ...args);
1369
- timeoutIdMap.set(timeoutId, { handler, timeout, args });
1370
- return timeoutId;
1371
- };
1372
- microWindow.clearInterval = function (intervalId) {
1373
- intervalIdMap.delete(intervalId);
1374
- rawClearInterval.call(rawWindow, intervalId);
1375
- };
1376
- microWindow.clearTimeout = function (timeoutId) {
1377
- timeoutIdMap.delete(timeoutId);
1378
- rawClearTimeout.call(rawWindow, timeoutId);
1379
- };
1380
- const umdWindowListenerMap = new Map();
1381
- const umdDocumentListenerMap = new Map();
1382
- let umdIntervalIdMap = new Map();
1383
- let umdTimeoutIdMap = new Map();
1384
- let umdOnClickHandler;
1385
- // record event and timer before exec umdMountHook
1386
- const recordUmdEffect = () => {
1387
- // record window event
1388
- eventListenerMap.forEach((listenerList, type) => {
1389
- if (listenerList.size) {
1390
- umdWindowListenerMap.set(type, new Set(listenerList));
1391
- }
1392
- });
1393
- // record timers
1394
- if (intervalIdMap.size) {
1395
- umdIntervalIdMap = new Map(intervalIdMap);
1396
- }
1397
- if (timeoutIdMap.size) {
1398
- umdTimeoutIdMap = new Map(timeoutIdMap);
1399
- }
1400
- // record onclick handler
1401
- umdOnClickHandler = documentClickListMap.get(appName);
1402
- // record document event
1403
- const documentAppListenersMap = documentEventListenerMap.get(appName);
1404
- if (documentAppListenersMap) {
1405
- documentAppListenersMap.forEach((listenerList, type) => {
1406
- if (listenerList.size) {
1407
- umdDocumentListenerMap.set(type, new Set(listenerList));
1408
- }
1409
- });
1410
- }
1411
- };
1412
- // rebuild event and timer before remount umd app
1413
- const rebuildUmdEffect = () => {
1414
- // rebuild window event
1415
- umdWindowListenerMap.forEach((listenerList, type) => {
1416
- for (const listener of listenerList) {
1417
- microWindow.addEventListener(type, listener, listener === null || listener === void 0 ? void 0 : listener.__MICRO_MARK_OPTIONS__);
1418
- }
1419
- });
1420
- // rebuild timer
1421
- umdIntervalIdMap.forEach((info) => {
1422
- microWindow.setInterval(info.handler, info.timeout, ...info.args);
1423
- });
1424
- umdTimeoutIdMap.forEach((info) => {
1425
- microWindow.setTimeout(info.handler, info.timeout, ...info.args);
1426
- });
1427
- // rebuild onclick event
1428
- umdOnClickHandler && documentClickListMap.set(appName, umdOnClickHandler);
1429
- // rebuild document event
1430
- setCurrentAppName(appName);
1431
- umdDocumentListenerMap.forEach((listenerList, type) => {
1432
- for (const listener of listenerList) {
1433
- document.addEventListener(type, listener, listener === null || listener === void 0 ? void 0 : listener.__MICRO_MARK_OPTIONS__);
1434
- }
1435
- });
1436
- setCurrentAppName(null);
1437
- };
1438
- // release all event listener & interval & timeout when unmount app
1439
- const releaseEffect = () => {
1440
- // Clear window binding events
1441
- if (eventListenerMap.size) {
1442
- eventListenerMap.forEach((listenerList, type) => {
1443
- for (const listener of listenerList) {
1444
- rawWindowRemoveEventListener.call(rawWindow, type, listener);
1445
- }
1446
- });
1447
- eventListenerMap.clear();
1448
- }
1449
- // Clear timers
1450
- if (intervalIdMap.size) {
1451
- intervalIdMap.forEach((_, intervalId) => {
1452
- rawClearInterval.call(rawWindow, intervalId);
1453
- });
1454
- intervalIdMap.clear();
1455
- }
1456
- if (timeoutIdMap.size) {
1457
- timeoutIdMap.forEach((_, timeoutId) => {
1458
- rawClearTimeout.call(rawWindow, timeoutId);
1459
- });
1460
- timeoutIdMap.clear();
1461
- }
1462
- // Clear the function bound by micro application through document.onclick
1463
- documentClickListMap.delete(appName);
1464
- // Clear document binding event
1465
- const documentAppListenersMap = documentEventListenerMap.get(appName);
1466
- if (documentAppListenersMap) {
1467
- documentAppListenersMap.forEach((listenerList, type) => {
1468
- for (const listener of listenerList) {
1469
- rawDocumentRemoveEventListener.call(rawDocument, type, listener);
1470
- }
1471
- });
1472
- documentAppListenersMap.clear();
1473
- }
1474
- };
1475
- return {
1476
- recordUmdEffect,
1477
- rebuildUmdEffect,
1478
- releaseEffect,
1479
- };
1480
- }
1481
-
1482
1203
  class EventCenter {
1483
1204
  constructor() {
1484
1205
  this.eventList = new Map();
@@ -1717,47 +1438,348 @@ class EventCenterForMicroApp extends EventCenterForGlobal {
1717
1438
  data,
1718
1439
  }
1719
1440
  });
1720
- getRootContainer(app.container).dispatchEvent(event);
1441
+ getRootContainer(app.container).dispatchEvent(event);
1442
+ }
1443
+ }
1444
+ /**
1445
+ * clear all listeners
1446
+ */
1447
+ clearDataListener() {
1448
+ eventCenter.off(formatEventName(this.appName, true));
1449
+ }
1450
+ }
1451
+ /**
1452
+ * Record UMD function before exec umdHookMount
1453
+ * @param microAppEventCneter
1454
+ */
1455
+ function recordDataCenterSnapshot(microAppEventCneter) {
1456
+ const appName = microAppEventCneter.appName;
1457
+ microAppEventCneter.umdDataListeners = { global: new Set(), normal: new Set() };
1458
+ const globalEventInfo = eventCenter.eventList.get('global');
1459
+ if (globalEventInfo) {
1460
+ for (const cb of globalEventInfo.callbacks) {
1461
+ if (appName === cb.__APP_NAME__) {
1462
+ microAppEventCneter.umdDataListeners.global.add(cb);
1463
+ }
1464
+ }
1465
+ }
1466
+ const subAppEventInfo = eventCenter.eventList.get(formatEventName(appName, true));
1467
+ if (subAppEventInfo) {
1468
+ microAppEventCneter.umdDataListeners.normal = new Set(subAppEventInfo.callbacks);
1469
+ }
1470
+ }
1471
+ /**
1472
+ * Rebind the UMD function of the record before remount
1473
+ * @param microAppEventCneter instance of EventCenterForMicroApp
1474
+ */
1475
+ function rebuildDataCenterSnapshot(microAppEventCneter) {
1476
+ for (const cb of microAppEventCneter.umdDataListeners.global) {
1477
+ microAppEventCneter.addGlobalDataListener(cb, cb.__AUTO_TRIGGER__);
1478
+ }
1479
+ for (const cb of microAppEventCneter.umdDataListeners.normal) {
1480
+ microAppEventCneter.addDataListener(cb, cb.__AUTO_TRIGGER__);
1481
+ }
1482
+ }
1483
+
1484
+ const boundedMap = new WeakMap();
1485
+ function isBoundedFunction(value) {
1486
+ if (boundedMap.has(value)) {
1487
+ return boundedMap.get(value);
1488
+ }
1489
+ // bind function
1490
+ const boundFunction = isBoundFunction(value);
1491
+ boundedMap.set(value, boundFunction);
1492
+ return boundFunction;
1493
+ }
1494
+ const constructorMap = new WeakMap();
1495
+ function isConstructor(value) {
1496
+ if (constructorMap.has(value)) {
1497
+ return constructorMap.get(value);
1498
+ }
1499
+ const valueStr = value.toString();
1500
+ const result = (value.prototype &&
1501
+ value.prototype.constructor === value &&
1502
+ Object.getOwnPropertyNames(value.prototype).length > 1) ||
1503
+ /^function\s+[A-Z]/.test(valueStr) ||
1504
+ /^class\s+/.test(valueStr);
1505
+ constructorMap.set(value, result);
1506
+ return result;
1507
+ }
1508
+ const rawWindowMethodMap = new WeakMap();
1509
+ // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
1510
+ function bindFunctionToRawWidow(rawWindow, value) {
1511
+ if (rawWindowMethodMap.has(value)) {
1512
+ return rawWindowMethodMap.get(value);
1513
+ }
1514
+ if (isFunction(value) && !isConstructor(value) && !isBoundedFunction(value)) {
1515
+ const bindRawWindowValue = value.bind(rawWindow);
1516
+ for (const key in value) {
1517
+ bindRawWindowValue[key] = value[key];
1518
+ }
1519
+ if (value.hasOwnProperty('prototype') && !bindRawWindowValue.hasOwnProperty('prototype')) {
1520
+ bindRawWindowValue.prototype = value.prototype;
1521
+ }
1522
+ rawWindowMethodMap.set(value, bindRawWindowValue);
1523
+ return bindRawWindowValue;
1524
+ }
1525
+ return value;
1526
+ }
1527
+
1528
+ // document.onclick binding list, the binding function of each application is unique
1529
+ const documentClickListMap = new Map();
1530
+ let hasRewriteDocumentOnClick = false;
1531
+ /**
1532
+ * Rewrite document.onclick and execute it only once
1533
+ */
1534
+ function overwriteDocumentOnClick() {
1535
+ hasRewriteDocumentOnClick = true;
1536
+ if (Object.getOwnPropertyDescriptor(document, 'onclick')) {
1537
+ return logWarn('Cannot redefine document property onclick');
1538
+ }
1539
+ const rawOnClick = document.onclick;
1540
+ document.onclick = null;
1541
+ let hasDocumentClickInited = false;
1542
+ function onClickHandler(e) {
1543
+ documentClickListMap.forEach((f) => {
1544
+ isFunction(f) && f.call(document, e);
1545
+ });
1546
+ }
1547
+ Object.defineProperty(document, 'onclick', {
1548
+ configurable: true,
1549
+ enumerable: true,
1550
+ get() {
1551
+ const appName = getCurrentAppName();
1552
+ return appName ? documentClickListMap.get(appName) : documentClickListMap.get('base');
1553
+ },
1554
+ set(f) {
1555
+ const appName = getCurrentAppName();
1556
+ if (appName) {
1557
+ documentClickListMap.set(appName, f);
1558
+ }
1559
+ else {
1560
+ documentClickListMap.set('base', f);
1561
+ }
1562
+ if (!hasDocumentClickInited && isFunction(f)) {
1563
+ hasDocumentClickInited = true;
1564
+ globalEnv.rawDocumentAddEventListener.call(globalEnv.rawDocument, 'click', onClickHandler, false);
1565
+ }
1566
+ }
1567
+ });
1568
+ rawOnClick && (document.onclick = rawOnClick);
1569
+ }
1570
+ /**
1571
+ * The document event is globally, we need to clear these event bindings when micro application unmounted
1572
+ */
1573
+ const documentEventListenerMap = new Map();
1574
+ function effectDocumentEvent() {
1575
+ const { rawDocument, rawDocumentAddEventListener, rawDocumentRemoveEventListener, } = globalEnv;
1576
+ !hasRewriteDocumentOnClick && overwriteDocumentOnClick();
1577
+ document.addEventListener = function (type, listener, options) {
1578
+ var _a;
1579
+ const appName = getCurrentAppName();
1580
+ /**
1581
+ * ignore bound function of document event in umd mode, used to solve problem of react global events
1582
+ */
1583
+ if (appName && !(((_a = appInstanceMap.get(appName)) === null || _a === void 0 ? void 0 : _a.umdMode) && isBoundFunction(listener))) {
1584
+ const appListenersMap = documentEventListenerMap.get(appName);
1585
+ if (appListenersMap) {
1586
+ const appListenerList = appListenersMap.get(type);
1587
+ if (appListenerList) {
1588
+ appListenerList.add(listener);
1589
+ }
1590
+ else {
1591
+ appListenersMap.set(type, new Set([listener]));
1592
+ }
1593
+ }
1594
+ else {
1595
+ documentEventListenerMap.set(appName, new Map([[type, new Set([listener])]]));
1596
+ }
1597
+ listener && (listener.__MICRO_MARK_OPTIONS__ = options);
1598
+ }
1599
+ rawDocumentAddEventListener.call(rawDocument, type, listener, options);
1600
+ };
1601
+ document.removeEventListener = function (type, listener, options) {
1602
+ var _a;
1603
+ const appName = getCurrentAppName();
1604
+ if (appName && !(((_a = appInstanceMap.get(appName)) === null || _a === void 0 ? void 0 : _a.umdMode) && isBoundFunction(listener))) {
1605
+ const appListenersMap = documentEventListenerMap.get(appName);
1606
+ if (appListenersMap) {
1607
+ const appListenerList = appListenersMap.get(type);
1608
+ if ((appListenerList === null || appListenerList === void 0 ? void 0 : appListenerList.size) && appListenerList.has(listener)) {
1609
+ appListenerList.delete(listener);
1610
+ }
1611
+ }
1612
+ }
1613
+ rawDocumentRemoveEventListener.call(rawDocument, type, listener, options);
1614
+ };
1615
+ }
1616
+ // Clear the document event agent
1617
+ function releaseEffectDocumentEvent() {
1618
+ document.addEventListener = globalEnv.rawDocumentAddEventListener;
1619
+ document.removeEventListener = globalEnv.rawDocumentRemoveEventListener;
1620
+ }
1621
+ // this events should be sent to the specified app
1622
+ const formatEventList = ['unmount', 'appstate-change'];
1623
+ /**
1624
+ * Format event name
1625
+ * @param type event name
1626
+ * @param microWindow micro window
1627
+ */
1628
+ function formatEventType(type, microWindow) {
1629
+ if (formatEventList.includes(type)) {
1630
+ return `${type}-${microWindow.__MICRO_APP_NAME__}`;
1631
+ }
1632
+ return type;
1633
+ }
1634
+ /**
1635
+ * Rewrite side-effect events
1636
+ * @param microWindow micro window
1637
+ */
1638
+ function effect(microWindow) {
1639
+ const appName = microWindow.__MICRO_APP_NAME__;
1640
+ const eventListenerMap = new Map();
1641
+ const intervalIdMap = new Map();
1642
+ const timeoutIdMap = new Map();
1643
+ const { rawWindow, rawDocument, rawWindowAddEventListener, rawWindowRemoveEventListener, rawSetInterval, rawSetTimeout, rawClearInterval, rawClearTimeout, rawDocumentRemoveEventListener, } = globalEnv;
1644
+ // listener may be null, e.g test-passive
1645
+ microWindow.addEventListener = function (type, listener, options) {
1646
+ type = formatEventType(type, microWindow);
1647
+ const listenerList = eventListenerMap.get(type);
1648
+ if (listenerList) {
1649
+ listenerList.add(listener);
1650
+ }
1651
+ else {
1652
+ eventListenerMap.set(type, new Set([listener]));
1653
+ }
1654
+ listener && (listener.__MICRO_MARK_OPTIONS__ = options);
1655
+ rawWindowAddEventListener.call(rawWindow, type, listener, options);
1656
+ };
1657
+ microWindow.removeEventListener = function (type, listener, options) {
1658
+ type = formatEventType(type, microWindow);
1659
+ const listenerList = eventListenerMap.get(type);
1660
+ if ((listenerList === null || listenerList === void 0 ? void 0 : listenerList.size) && listenerList.has(listener)) {
1661
+ listenerList.delete(listener);
1662
+ }
1663
+ rawWindowRemoveEventListener.call(rawWindow, type, listener, options);
1664
+ };
1665
+ microWindow.setInterval = function (handler, timeout, ...args) {
1666
+ const intervalId = rawSetInterval.call(rawWindow, handler, timeout, ...args);
1667
+ intervalIdMap.set(intervalId, { handler, timeout, args });
1668
+ return intervalId;
1669
+ };
1670
+ microWindow.setTimeout = function (handler, timeout, ...args) {
1671
+ const timeoutId = rawSetTimeout.call(rawWindow, handler, timeout, ...args);
1672
+ timeoutIdMap.set(timeoutId, { handler, timeout, args });
1673
+ return timeoutId;
1674
+ };
1675
+ microWindow.clearInterval = function (intervalId) {
1676
+ intervalIdMap.delete(intervalId);
1677
+ rawClearInterval.call(rawWindow, intervalId);
1678
+ };
1679
+ microWindow.clearTimeout = function (timeoutId) {
1680
+ timeoutIdMap.delete(timeoutId);
1681
+ rawClearTimeout.call(rawWindow, timeoutId);
1682
+ };
1683
+ const umdWindowListenerMap = new Map();
1684
+ const umdDocumentListenerMap = new Map();
1685
+ let umdIntervalIdMap = new Map();
1686
+ let umdTimeoutIdMap = new Map();
1687
+ let umdOnClickHandler;
1688
+ // record event and timer before exec umdMountHook
1689
+ const recordUmdEffect = () => {
1690
+ // record window event
1691
+ eventListenerMap.forEach((listenerList, type) => {
1692
+ if (listenerList.size) {
1693
+ umdWindowListenerMap.set(type, new Set(listenerList));
1694
+ }
1695
+ });
1696
+ // record timers
1697
+ if (intervalIdMap.size) {
1698
+ umdIntervalIdMap = new Map(intervalIdMap);
1699
+ }
1700
+ if (timeoutIdMap.size) {
1701
+ umdTimeoutIdMap = new Map(timeoutIdMap);
1702
+ }
1703
+ // record onclick handler
1704
+ umdOnClickHandler = documentClickListMap.get(appName);
1705
+ // record document event
1706
+ const documentAppListenersMap = documentEventListenerMap.get(appName);
1707
+ if (documentAppListenersMap) {
1708
+ documentAppListenersMap.forEach((listenerList, type) => {
1709
+ if (listenerList.size) {
1710
+ umdDocumentListenerMap.set(type, new Set(listenerList));
1711
+ }
1712
+ });
1721
1713
  }
1722
- }
1723
- /**
1724
- * clear all listeners
1725
- */
1726
- clearDataListener() {
1727
- eventCenter.off(formatEventName(this.appName, true));
1728
- }
1729
- }
1730
- /**
1731
- * Record UMD function before exec umdHookMount
1732
- * @param microAppEventCneter
1733
- */
1734
- function recordDataCenterSnapshot(microAppEventCneter) {
1735
- const appName = microAppEventCneter.appName;
1736
- microAppEventCneter.umdDataListeners = { global: new Set(), normal: new Set() };
1737
- const globalEventInfo = eventCenter.eventList.get('global');
1738
- if (globalEventInfo) {
1739
- for (const cb of globalEventInfo.callbacks) {
1740
- if (appName === cb.__APP_NAME__) {
1741
- microAppEventCneter.umdDataListeners.global.add(cb);
1714
+ };
1715
+ // rebuild event and timer before remount umd app
1716
+ const rebuildUmdEffect = () => {
1717
+ // rebuild window event
1718
+ umdWindowListenerMap.forEach((listenerList, type) => {
1719
+ for (const listener of listenerList) {
1720
+ microWindow.addEventListener(type, listener, listener === null || listener === void 0 ? void 0 : listener.__MICRO_MARK_OPTIONS__);
1721
+ }
1722
+ });
1723
+ // rebuild timer
1724
+ umdIntervalIdMap.forEach((info) => {
1725
+ microWindow.setInterval(info.handler, info.timeout, ...info.args);
1726
+ });
1727
+ umdTimeoutIdMap.forEach((info) => {
1728
+ microWindow.setTimeout(info.handler, info.timeout, ...info.args);
1729
+ });
1730
+ // rebuild onclick event
1731
+ umdOnClickHandler && documentClickListMap.set(appName, umdOnClickHandler);
1732
+ // rebuild document event
1733
+ setCurrentAppName(appName);
1734
+ umdDocumentListenerMap.forEach((listenerList, type) => {
1735
+ for (const listener of listenerList) {
1736
+ document.addEventListener(type, listener, listener === null || listener === void 0 ? void 0 : listener.__MICRO_MARK_OPTIONS__);
1742
1737
  }
1738
+ });
1739
+ setCurrentAppName(null);
1740
+ };
1741
+ // release all event listener & interval & timeout when unmount app
1742
+ const releaseEffect = () => {
1743
+ // Clear window binding events
1744
+ if (eventListenerMap.size) {
1745
+ eventListenerMap.forEach((listenerList, type) => {
1746
+ for (const listener of listenerList) {
1747
+ rawWindowRemoveEventListener.call(rawWindow, type, listener);
1748
+ }
1749
+ });
1750
+ eventListenerMap.clear();
1743
1751
  }
1744
- }
1745
- const subAppEventInfo = eventCenter.eventList.get(formatEventName(appName, true));
1746
- if (subAppEventInfo) {
1747
- microAppEventCneter.umdDataListeners.normal = new Set(subAppEventInfo.callbacks);
1748
- }
1749
- }
1750
- /**
1751
- * Rebind the UMD function of the record before remount
1752
- * @param microAppEventCneter instance of EventCenterForMicroApp
1753
- */
1754
- function rebuildDataCenterSnapshot(microAppEventCneter) {
1755
- for (const cb of microAppEventCneter.umdDataListeners.global) {
1756
- microAppEventCneter.addGlobalDataListener(cb, cb.__AUTO_TRIGGER__);
1757
- }
1758
- for (const cb of microAppEventCneter.umdDataListeners.normal) {
1759
- microAppEventCneter.addDataListener(cb, cb.__AUTO_TRIGGER__);
1760
- }
1752
+ // Clear timers
1753
+ if (intervalIdMap.size) {
1754
+ intervalIdMap.forEach((_, intervalId) => {
1755
+ rawClearInterval.call(rawWindow, intervalId);
1756
+ });
1757
+ intervalIdMap.clear();
1758
+ }
1759
+ if (timeoutIdMap.size) {
1760
+ timeoutIdMap.forEach((_, timeoutId) => {
1761
+ rawClearTimeout.call(rawWindow, timeoutId);
1762
+ });
1763
+ timeoutIdMap.clear();
1764
+ }
1765
+ // Clear the function bound by micro application through document.onclick
1766
+ documentClickListMap.delete(appName);
1767
+ // Clear document binding event
1768
+ const documentAppListenersMap = documentEventListenerMap.get(appName);
1769
+ if (documentAppListenersMap) {
1770
+ documentAppListenersMap.forEach((listenerList, type) => {
1771
+ for (const listener of listenerList) {
1772
+ rawDocumentRemoveEventListener.call(rawDocument, type, listener);
1773
+ }
1774
+ });
1775
+ documentAppListenersMap.clear();
1776
+ }
1777
+ };
1778
+ return {
1779
+ recordUmdEffect,
1780
+ rebuildUmdEffect,
1781
+ releaseEffect,
1782
+ };
1761
1783
  }
1762
1784
 
1763
1785
  // Variables that can escape to rawWindow
@@ -1828,7 +1850,7 @@ class SandBox {
1828
1850
  }
1829
1851
  if (key === 'hasOwnProperty')
1830
1852
  return hasOwnProperty;
1831
- if (key === 'document' || key === 'eval') {
1853
+ if (key === 'document' || key === 'eval' || key === 'Image') {
1832
1854
  if (this.active) {
1833
1855
  setCurrentAppName(appName);
1834
1856
  (macro ? macroTask : defer)(() => setCurrentAppName(null));
@@ -1838,6 +1860,8 @@ class SandBox {
1838
1860
  return rawDocument;
1839
1861
  case 'eval':
1840
1862
  return eval;
1863
+ case 'Image':
1864
+ return globalEnv.ImageProxy;
1841
1865
  }
1842
1866
  }
1843
1867
  if (Reflect.has(target, key)) {
@@ -1888,12 +1912,15 @@ class SandBox {
1888
1912
  return key in target;
1889
1913
  return key in unscopables || key in target || key in rawWindow;
1890
1914
  },
1915
+ // Object.getOwnPropertyDescriptor(window, key)
1916
+ // TODO: use set
1891
1917
  getOwnPropertyDescriptor: (target, key) => {
1892
1918
  if (target.hasOwnProperty(key)) {
1893
1919
  descriptorTargetMap.set(key, 'target');
1894
1920
  return Object.getOwnPropertyDescriptor(target, key);
1895
1921
  }
1896
1922
  if (rawWindow.hasOwnProperty(key)) {
1923
+ // like console, alert ...
1897
1924
  descriptorTargetMap.set(key, 'rawWindow');
1898
1925
  const descriptor = Object.getOwnPropertyDescriptor(rawWindow, key);
1899
1926
  if (descriptor && !descriptor.configurable) {
@@ -1903,6 +1930,7 @@ class SandBox {
1903
1930
  }
1904
1931
  return undefined;
1905
1932
  },
1933
+ // Object.defineProperty(window, key, Descriptor)
1906
1934
  defineProperty: (target, key, value) => {
1907
1935
  const from = descriptorTargetMap.get(key);
1908
1936
  if (from === 'rawWindow') {
@@ -1910,11 +1938,13 @@ class SandBox {
1910
1938
  }
1911
1939
  return Reflect.defineProperty(target, key, value);
1912
1940
  },
1941
+ // Object.getOwnPropertyNames(window)
1913
1942
  ownKeys: (target) => {
1914
1943
  return unique(Reflect.ownKeys(rawWindow).concat(Reflect.ownKeys(target)));
1915
1944
  },
1916
1945
  deleteProperty: (target, key) => {
1917
1946
  if (target.hasOwnProperty(key)) {
1947
+ this.injectedKeys.has(key) && this.injectedKeys.delete(key);
1918
1948
  this.escapeKeys.has(key) && Reflect.deleteProperty(rawWindow, key);
1919
1949
  return Reflect.deleteProperty(target, key);
1920
1950
  }
@@ -2021,7 +2051,7 @@ class SandBox {
2021
2051
  }
2022
2052
  SandBox.activeCount = 0; // number of active sandbox
2023
2053
 
2024
- function eventHandler$1(event, element) {
2054
+ function formatEventInfo(event, element) {
2025
2055
  Object.defineProperties(event, {
2026
2056
  currentTarget: {
2027
2057
  get() {
@@ -2060,7 +2090,7 @@ function dispatchLifecyclesEvent(element, appName, lifecycleName, error) {
2060
2090
  const event = new CustomEvent(lifecycleName, {
2061
2091
  detail,
2062
2092
  });
2063
- eventHandler$1(event, element);
2093
+ formatEventInfo(event, element);
2064
2094
  // global hooks
2065
2095
  // @ts-ignore
2066
2096
  if (isFunction((_a = microApp.lifeCycles) === null || _a === void 0 ? void 0 : _a[lifecycleName])) {
@@ -2070,11 +2100,15 @@ function dispatchLifecyclesEvent(element, appName, lifecycleName, error) {
2070
2100
  element.dispatchEvent(event);
2071
2101
  }
2072
2102
  /**
2073
- * Dispatch unmount event to micro app
2074
- * @param appName app.name
2103
+ * Dispatch custom event to micro app
2104
+ * @param eventName event name
2105
+ * @param appName app name
2106
+ * @param detail event detail
2075
2107
  */
2076
- function dispatchUnmountToMicroApp(appName) {
2077
- const event = new CustomEvent(`unmount-${appName}`);
2108
+ function dispatchCustomEventToMicroApp(eventName, appName, detail = {}) {
2109
+ const event = new CustomEvent(`${eventName}-${appName}`, {
2110
+ detail,
2111
+ });
2078
2112
  window.dispatchEvent(event);
2079
2113
  }
2080
2114
 
@@ -2082,7 +2116,9 @@ function dispatchUnmountToMicroApp(appName) {
2082
2116
  const appInstanceMap = new Map();
2083
2117
  class CreateApp {
2084
2118
  constructor({ name, url, ssrUrl, container, inline, scopecss, useSandbox, macro, baseroute, }) {
2085
- this.status = appStatus.NOT_LOADED;
2119
+ this.state = appStates.NOT_LOADED;
2120
+ this.keepAliveState = null;
2121
+ this.keepAliveContainer = null;
2086
2122
  this.loadSourceLevel = 0;
2087
2123
  this.umdHookMount = null;
2088
2124
  this.umdHookUnmount = null;
@@ -2112,7 +2148,7 @@ class CreateApp {
2112
2148
  }
2113
2149
  // Load resources
2114
2150
  loadSourceCode() {
2115
- this.status = appStatus.LOADING_SOURCE_CODE;
2151
+ this.state = appStates.LOADING_SOURCE_CODE;
2116
2152
  extractHtml(this);
2117
2153
  }
2118
2154
  /**
@@ -2121,9 +2157,9 @@ class CreateApp {
2121
2157
  onLoad(html) {
2122
2158
  if (++this.loadSourceLevel === 2) {
2123
2159
  this.source.html = html;
2124
- if (this.isPrefetch || appStatus.UNMOUNT === this.status)
2160
+ if (this.isPrefetch || appStates.UNMOUNT === this.state)
2125
2161
  return;
2126
- this.status = appStatus.LOAD_SOURCE_FINISHED;
2162
+ this.state = appStates.LOAD_SOURCE_FINISHED;
2127
2163
  this.mount();
2128
2164
  }
2129
2165
  }
@@ -2133,9 +2169,9 @@ class CreateApp {
2133
2169
  */
2134
2170
  onLoadError(e) {
2135
2171
  this.loadSourceLevel = -1;
2136
- if (appStatus.UNMOUNT !== this.status) {
2172
+ if (appStates.UNMOUNT !== this.state) {
2137
2173
  this.onerror(e);
2138
- this.status = appStatus.LOAD_SOURCE_ERROR;
2174
+ this.state = appStates.LOAD_SOURCE_ERROR;
2139
2175
  }
2140
2176
  }
2141
2177
  /**
@@ -2152,11 +2188,11 @@ class CreateApp {
2152
2188
  this.container = (_a = this.container) !== null && _a !== void 0 ? _a : container;
2153
2189
  this.baseroute = baseroute !== null && baseroute !== void 0 ? baseroute : this.baseroute;
2154
2190
  if (this.loadSourceLevel !== 2) {
2155
- this.status = appStatus.LOADING_SOURCE_CODE;
2191
+ this.state = appStates.LOADING_SOURCE_CODE;
2156
2192
  return;
2157
2193
  }
2158
2194
  dispatchLifecyclesEvent(this.container, this.name, lifeCycles.BEFOREMOUNT);
2159
- this.status = appStatus.MOUNTING;
2195
+ this.state = appStates.MOUNTING;
2160
2196
  cloneContainer(this.source.html, this.container, !this.umdMode);
2161
2197
  (_b = this.sandBox) === null || _b === void 0 ? void 0 : _b.start(this.baseroute);
2162
2198
  let umdHookMountResult; // result of mount function
@@ -2216,20 +2252,23 @@ class CreateApp {
2216
2252
  * dispatch mounted event when app run finished
2217
2253
  */
2218
2254
  dispatchMountedEvent() {
2219
- if (appStatus.UNMOUNT !== this.status) {
2220
- this.status = appStatus.MOUNTED;
2255
+ if (appStates.UNMOUNT !== this.state) {
2256
+ this.state = appStates.MOUNTED;
2221
2257
  dispatchLifecyclesEvent(this.container, this.name, lifeCycles.MOUNTED);
2222
2258
  }
2223
2259
  }
2224
2260
  /**
2225
2261
  * unmount app
2226
2262
  * @param destroy completely destroy, delete cache resources
2263
+ * @param unmountcb callback of unmount
2227
2264
  */
2228
- unmount(destroy) {
2229
- if (this.status === appStatus.LOAD_SOURCE_ERROR) {
2265
+ unmount(destroy, unmountcb) {
2266
+ if (this.state === appStates.LOAD_SOURCE_ERROR) {
2230
2267
  destroy = true;
2231
2268
  }
2232
- this.status = appStatus.UNMOUNT;
2269
+ this.state = appStates.UNMOUNT;
2270
+ this.keepAliveState = null;
2271
+ this.keepAliveContainer = null;
2233
2272
  // result of unmount function
2234
2273
  let umdHookUnmountResult;
2235
2274
  /**
@@ -2245,42 +2284,44 @@ class CreateApp {
2245
2284
  }
2246
2285
  }
2247
2286
  // dispatch unmount event to micro app
2248
- dispatchUnmountToMicroApp(this.name);
2249
- this.handleUnmounted(destroy, umdHookUnmountResult);
2287
+ dispatchCustomEventToMicroApp('unmount', this.name);
2288
+ this.handleUnmounted(destroy, umdHookUnmountResult, unmountcb);
2250
2289
  }
2251
2290
  /**
2252
2291
  * handle for promise umdHookUnmount
2292
+ * @param destroy completely destroy, delete cache resources
2253
2293
  * @param umdHookUnmountResult result of umdHookUnmount
2294
+ * @param unmountcb callback of unmount
2254
2295
  */
2255
- handleUnmounted(destroy, umdHookUnmountResult) {
2296
+ handleUnmounted(destroy, umdHookUnmountResult, unmountcb) {
2256
2297
  if (isPromise(umdHookUnmountResult)) {
2257
2298
  umdHookUnmountResult
2258
- .then(() => this.actionsForUnmount(destroy))
2259
- .catch(() => this.actionsForUnmount(destroy));
2299
+ .then(() => this.actionsForUnmount(destroy, unmountcb))
2300
+ .catch(() => this.actionsForUnmount(destroy, unmountcb));
2260
2301
  }
2261
2302
  else {
2262
- this.actionsForUnmount(destroy);
2303
+ this.actionsForUnmount(destroy, unmountcb);
2263
2304
  }
2264
2305
  }
2265
2306
  /**
2266
2307
  * actions for unmount app
2267
2308
  * @param destroy completely destroy, delete cache resources
2309
+ * @param unmountcb callback of unmount
2268
2310
  */
2269
- actionsForUnmount(destroy) {
2311
+ actionsForUnmount(destroy, unmountcb) {
2270
2312
  var _a;
2271
- // dispatch unmount event to base app
2272
- dispatchLifecyclesEvent(this.container, this.name, lifeCycles.UNMOUNT);
2273
2313
  (_a = this.sandBox) === null || _a === void 0 ? void 0 : _a.stop();
2274
2314
  if (destroy) {
2275
2315
  this.actionsForCompletelyDestory();
2276
2316
  }
2277
2317
  else if (this.umdMode && this.container.childElementCount) {
2278
- /**
2279
- * In umd mode, ui frameworks will no longer create style elements to head in lazy load page when render again, so we should save container to keep these elements
2280
- */
2281
2318
  cloneContainer(this.container, this.source.html, false);
2282
2319
  }
2320
+ // dispatch unmount event to base app
2321
+ dispatchLifecyclesEvent(this.container, this.name, lifeCycles.UNMOUNT);
2322
+ this.container.innerHTML = '';
2283
2323
  this.container = null;
2324
+ unmountcb && unmountcb();
2284
2325
  }
2285
2326
  // actions for completely destroy
2286
2327
  actionsForCompletelyDestory() {
@@ -2289,6 +2330,38 @@ class CreateApp {
2289
2330
  }
2290
2331
  appInstanceMap.delete(this.name);
2291
2332
  }
2333
+ // hidden app when disconnectedCallback called with keep-alive
2334
+ hiddenKeepAliveApp() {
2335
+ const oldContainer = this.container;
2336
+ cloneContainer(this.container, this.keepAliveContainer ? this.keepAliveContainer : (this.keepAliveContainer = document.createElement('div')), false);
2337
+ this.container = this.keepAliveContainer;
2338
+ this.keepAliveState = keepAliveStates.KEEP_ALIVE_HIDDEN;
2339
+ // event should dispatch before clone node
2340
+ // dispatch afterhidden event to micro-app
2341
+ dispatchCustomEventToMicroApp('appstate-change', this.name, {
2342
+ appState: 'afterhidden',
2343
+ });
2344
+ // dispatch afterhidden event to base app
2345
+ dispatchLifecyclesEvent(oldContainer, this.name, lifeCycles.AFTERHIDDEN);
2346
+ }
2347
+ // show app when connectedCallback called with keep-alive
2348
+ showKeepAliveApp(container) {
2349
+ // dispatch beforeshow event to micro-app
2350
+ dispatchCustomEventToMicroApp('appstate-change', this.name, {
2351
+ appState: 'beforeshow',
2352
+ });
2353
+ // dispatch beforeshow event to base app
2354
+ dispatchLifecyclesEvent(container, this.name, lifeCycles.BEFORESHOW);
2355
+ cloneContainer(this.container, container, false);
2356
+ this.container = container;
2357
+ this.keepAliveState = keepAliveStates.KEEP_ALIVE_SHOW;
2358
+ // dispatch aftershow event to micro-app
2359
+ dispatchCustomEventToMicroApp('appstate-change', this.name, {
2360
+ appState: 'aftershow',
2361
+ });
2362
+ // dispatch aftershow event to base app
2363
+ dispatchLifecyclesEvent(this.container, this.name, lifeCycles.AFTERSHOW);
2364
+ }
2292
2365
  /**
2293
2366
  * app rendering error
2294
2367
  * @param e Error
@@ -2296,15 +2369,19 @@ class CreateApp {
2296
2369
  onerror(e) {
2297
2370
  dispatchLifecyclesEvent(this.container, this.name, lifeCycles.ERROR, e);
2298
2371
  }
2299
- // get app status
2300
- getAppStatus() {
2301
- return this.status;
2372
+ // get app state
2373
+ getAppState() {
2374
+ return this.state;
2375
+ }
2376
+ // get keep-alive state
2377
+ getKeepAliveState() {
2378
+ return this.keepAliveState;
2302
2379
  }
2303
2380
  // get umd library, if it not exist, return empty object
2304
2381
  getUmdLibraryHooks() {
2305
2382
  var _a, _b;
2306
2383
  // after execScripts, the app maybe unmounted
2307
- if (appStatus.UNMOUNT !== this.status) {
2384
+ if (appStates.UNMOUNT !== this.state) {
2308
2385
  const global = ((_b = (_a = this.sandBox) === null || _a === void 0 ? void 0 : _a.proxyWindow) !== null && _b !== void 0 ? _b : globalEnv.rawWindow);
2309
2386
  this.libraryName = getRootContainer(this.container).getAttribute('library') || `micro-app-${this.name}`;
2310
2387
  // do not use isObject
@@ -2317,7 +2394,7 @@ class CreateApp {
2317
2394
  function getActiveApps() {
2318
2395
  const activeApps = [];
2319
2396
  appInstanceMap.forEach((app, appName) => {
2320
- if (appStatus.UNMOUNT !== app.getAppStatus() && !app.isPrefetch) {
2397
+ if (appStates.UNMOUNT !== app.getAppState() && !app.isPrefetch) {
2321
2398
  activeApps.push(appName);
2322
2399
  }
2323
2400
  });
@@ -2327,6 +2404,78 @@ function getActiveApps() {
2327
2404
  function getAllApps() {
2328
2405
  return Array.from(appInstanceMap.keys());
2329
2406
  }
2407
+ /**
2408
+ * unmount app by appname
2409
+ * @param appName
2410
+ * @param options unmountAppParams
2411
+ * @returns Promise<void>
2412
+ */
2413
+ function unmountApp(appName, options) {
2414
+ const app = appInstanceMap.get(formatAppName(appName));
2415
+ return new Promise((reslove) => {
2416
+ if (app) {
2417
+ if (app.getAppState() === appStates.UNMOUNT || app.isPrefetch) {
2418
+ if (options === null || options === void 0 ? void 0 : options.destroy) {
2419
+ app.actionsForCompletelyDestory();
2420
+ }
2421
+ reslove();
2422
+ }
2423
+ else if (app.getKeepAliveState() === keepAliveStates.KEEP_ALIVE_HIDDEN) {
2424
+ if (options === null || options === void 0 ? void 0 : options.destroy) {
2425
+ app.unmount(true, reslove);
2426
+ }
2427
+ else if (options === null || options === void 0 ? void 0 : options.clearAliveState) {
2428
+ app.unmount(false, reslove);
2429
+ }
2430
+ else {
2431
+ reslove();
2432
+ }
2433
+ }
2434
+ else {
2435
+ const container = getRootContainer(app.container);
2436
+ const unmountHandler = () => {
2437
+ container.removeEventListener('unmount', unmountHandler);
2438
+ container.removeEventListener('afterhidden', afterhiddenHandler);
2439
+ reslove();
2440
+ };
2441
+ const afterhiddenHandler = () => {
2442
+ container.removeEventListener('unmount', unmountHandler);
2443
+ container.removeEventListener('afterhidden', afterhiddenHandler);
2444
+ reslove();
2445
+ };
2446
+ container.addEventListener('unmount', unmountHandler);
2447
+ container.addEventListener('afterhidden', afterhiddenHandler);
2448
+ if (options === null || options === void 0 ? void 0 : options.destroy) {
2449
+ let destroyAttrValue, destoryAttrValue;
2450
+ container.hasAttribute('destroy') && (destroyAttrValue = container.getAttribute('destroy'));
2451
+ container.hasAttribute('destory') && (destoryAttrValue = container.getAttribute('destory'));
2452
+ container.setAttribute('destroy', 'true');
2453
+ container.parentNode.removeChild(container);
2454
+ container.removeAttribute('destroy');
2455
+ typeof destroyAttrValue === 'string' && container.setAttribute('destroy', destroyAttrValue);
2456
+ typeof destoryAttrValue === 'string' && container.setAttribute('destory', destoryAttrValue);
2457
+ }
2458
+ else if ((options === null || options === void 0 ? void 0 : options.clearAliveState) && container.hasAttribute('keep-alive')) {
2459
+ const keepAliveAttrValue = container.getAttribute('keep-alive');
2460
+ container.removeAttribute('keep-alive');
2461
+ container.parentNode.removeChild(container);
2462
+ container.setAttribute('keep-alive', keepAliveAttrValue);
2463
+ }
2464
+ else {
2465
+ container.parentNode.removeChild(container);
2466
+ }
2467
+ }
2468
+ }
2469
+ else {
2470
+ logWarn(`app ${appName} does not exist`);
2471
+ reslove();
2472
+ }
2473
+ });
2474
+ }
2475
+ // unmount all apps in turn
2476
+ function unmountAllApps(options) {
2477
+ return Array.from(appInstanceMap.keys()).reduce((pre, next) => pre.then(() => unmountApp(next, options)), Promise.resolve());
2478
+ }
2330
2479
 
2331
2480
  // Record element and map element
2332
2481
  const dynamicElementInMicroAppMap = new WeakMap();
@@ -2521,13 +2670,13 @@ function patchElementPrototypeMethods() {
2521
2670
  }
2522
2671
  };
2523
2672
  // prototype methods of add element👇
2524
- Node.prototype.appendChild = function appendChild(newChild) {
2673
+ Element.prototype.appendChild = function appendChild(newChild) {
2525
2674
  return commonElementHander(this, newChild, null, globalEnv.rawAppendChild);
2526
2675
  };
2527
- Node.prototype.insertBefore = function insertBefore(newChild, refChild) {
2676
+ Element.prototype.insertBefore = function insertBefore(newChild, refChild) {
2528
2677
  return commonElementHander(this, newChild, refChild, globalEnv.rawInsertBefore);
2529
2678
  };
2530
- Node.prototype.replaceChild = function replaceChild(newChild, oldChild) {
2679
+ Element.prototype.replaceChild = function replaceChild(newChild, oldChild) {
2531
2680
  return commonElementHander(this, newChild, oldChild, globalEnv.rawReplaceChild);
2532
2681
  };
2533
2682
  Element.prototype.append = function append(...nodes) {
@@ -2546,7 +2695,7 @@ function patchElementPrototypeMethods() {
2546
2695
  }
2547
2696
  };
2548
2697
  // prototype methods of delete element👇
2549
- Node.prototype.removeChild = function removeChild(oldChild) {
2698
+ Element.prototype.removeChild = function removeChild(oldChild) {
2550
2699
  if (oldChild === null || oldChild === void 0 ? void 0 : oldChild.__MICRO_APP_NAME__) {
2551
2700
  const app = appInstanceMap.get(oldChild.__MICRO_APP_NAME__);
2552
2701
  if (app === null || app === void 0 ? void 0 : app.container) {
@@ -2556,6 +2705,12 @@ function patchElementPrototypeMethods() {
2556
2705
  }
2557
2706
  return globalEnv.rawRemoveChild.call(this, oldChild);
2558
2707
  };
2708
+ // patch cloneNode
2709
+ Element.prototype.cloneNode = function cloneNode(deep) {
2710
+ const clonedNode = globalEnv.rawCloneNode.call(this, deep);
2711
+ this.__MICRO_APP_NAME__ && (clonedNode.__MICRO_APP_NAME__ = this.__MICRO_APP_NAME__);
2712
+ return clonedNode;
2713
+ };
2559
2714
  }
2560
2715
  /**
2561
2716
  * Mark the newly created element in the micro application
@@ -2674,12 +2829,13 @@ function releasePatches() {
2674
2829
  setCurrentAppName(null);
2675
2830
  releasePatchDocument();
2676
2831
  Element.prototype.setAttribute = globalEnv.rawSetAttribute;
2677
- Node.prototype.appendChild = globalEnv.rawAppendChild;
2678
- Node.prototype.insertBefore = globalEnv.rawInsertBefore;
2679
- Node.prototype.replaceChild = globalEnv.rawReplaceChild;
2680
- Node.prototype.removeChild = globalEnv.rawRemoveChild;
2832
+ Element.prototype.appendChild = globalEnv.rawAppendChild;
2833
+ Element.prototype.insertBefore = globalEnv.rawInsertBefore;
2834
+ Element.prototype.replaceChild = globalEnv.rawReplaceChild;
2835
+ Element.prototype.removeChild = globalEnv.rawRemoveChild;
2681
2836
  Element.prototype.append = globalEnv.rawAppend;
2682
2837
  Element.prototype.prepend = globalEnv.rawPrepend;
2838
+ Element.prototype.cloneNode = globalEnv.rawCloneNode;
2683
2839
  }
2684
2840
  // Set the style of micro-app-head and micro-app-body
2685
2841
  let hasRejectMicroAppStyle = false;
@@ -2694,7 +2850,7 @@ function rejectMicroAppStyle() {
2694
2850
  }
2695
2851
 
2696
2852
  function unmountNestedApp() {
2697
- replaseUnmountOfNestedApp();
2853
+ releaseUnmountOfNestedApp();
2698
2854
  appInstanceMap.forEach(app => {
2699
2855
  // @ts-ignore
2700
2856
  app.container && getRootContainer(app.container).disconnectedCallback();
@@ -2712,7 +2868,7 @@ function listenUmountOfNestedApp() {
2712
2868
  }
2713
2869
  }
2714
2870
  // release listener
2715
- function replaseUnmountOfNestedApp() {
2871
+ function releaseUnmountOfNestedApp() {
2716
2872
  if (window.__MICRO_APP_ENVIRONMENT__) {
2717
2873
  window.removeEventListener('unmount', unmountNestedApp, false);
2718
2874
  }
@@ -2739,7 +2895,6 @@ function defineElement(tagName) {
2739
2895
  * handle for change of name an url after element inited
2740
2896
  */
2741
2897
  this.handleAttributeUpdate = () => {
2742
- var _a;
2743
2898
  this.isWating = false;
2744
2899
  const formatAttrName = formatAppName(this.getAttribute('name'));
2745
2900
  const formatAttrUrl = formatAppURL(this.getAttribute('url'), this.appName);
@@ -2747,44 +2902,27 @@ function defineElement(tagName) {
2747
2902
  const existApp = appInstanceMap.get(formatAttrName);
2748
2903
  if (formatAttrName !== this.appName && existApp) {
2749
2904
  // handling of cached and non-prefetch apps
2750
- if (appStatus.UNMOUNT !== existApp.getAppStatus() && !existApp.isPrefetch) {
2905
+ if (appStates.UNMOUNT !== existApp.getAppState() &&
2906
+ keepAliveStates.KEEP_ALIVE_HIDDEN !== existApp.getKeepAliveState() &&
2907
+ !existApp.isPrefetch) {
2751
2908
  this.setAttribute('name', this.appName);
2752
- return logError(`an app named ${formatAttrName} already exists`, this.appName);
2909
+ return logError(`app name conflict, an app named ${formatAttrName} is running`, this.appName);
2753
2910
  }
2754
2911
  }
2755
2912
  if (formatAttrName !== this.appName || formatAttrUrl !== this.appUrl) {
2756
- this.handleUnmount(formatAttrName === this.appName);
2757
- /**
2758
- * change ssrUrl in ssr mode
2759
- * do not add judgment of formatAttrUrl === this.appUrl
2760
- */
2761
- if (this.getDisposeResult('ssr')) {
2762
- this.ssrUrl = CompletionPath(globalEnv.rawWindow.location.pathname, formatAttrUrl);
2763
- }
2764
- else if (this.ssrUrl) {
2765
- this.ssrUrl = '';
2766
- }
2767
- this.appName = formatAttrName;
2768
- this.appUrl = formatAttrUrl;
2769
- ((_a = this.shadowRoot) !== null && _a !== void 0 ? _a : this).innerHTML = '';
2770
- if (formatAttrName !== this.getAttribute('name')) {
2771
- this.setAttribute('name', this.appName);
2913
+ if (formatAttrName === this.appName) {
2914
+ this.handleUnmount(true, () => {
2915
+ this.actionsForAttributeChange(formatAttrName, formatAttrUrl, existApp);
2916
+ });
2772
2917
  }
2773
- /**
2774
- * when existApp not null:
2775
- * scene1: if formatAttrName and this.appName are equal: exitApp is the current app, the url must be different, existApp has been unmounted
2776
- * scene2: if formatAttrName and this.appName are different: existApp must be prefetch or unmounted, if url is equal, then just mount, if url is different, then create new app to replace existApp
2777
- * scene3: url is different but ssrUrl is equal
2778
- * scene4: url is equal but ssrUrl is different, if url is equal, name must different
2779
- */
2780
- if (existApp &&
2781
- existApp.url === this.appUrl &&
2782
- existApp.ssrUrl === this.ssrUrl) {
2783
- // mount app
2784
- this.handleAppMount(existApp);
2918
+ else if (this.getKeepAliveModeResult()) {
2919
+ this.handleHiddenKeepAliveApp();
2920
+ this.actionsForAttributeChange(formatAttrName, formatAttrUrl, existApp);
2785
2921
  }
2786
2922
  else {
2787
- this.handleCreateApp();
2923
+ this.handleUnmount(this.getDestroyCompatibleResult(), () => {
2924
+ this.actionsForAttributeChange(formatAttrName, formatAttrUrl, existApp);
2925
+ });
2788
2926
  }
2789
2927
  }
2790
2928
  }
@@ -2810,6 +2948,7 @@ function defineElement(tagName) {
2810
2948
  // disableSandbox: whether disable sandbox, default is false
2811
2949
  // macro: used to solve the async render problem of vue3, default is false
2812
2950
  // baseRoute: route prefix, default is ''
2951
+ // keep-alive: open keep-alive mode
2813
2952
  connectedCallback() {
2814
2953
  this.hasConnected = true;
2815
2954
  if (!elementInstanceMap.has(this)) {
@@ -2820,10 +2959,17 @@ function defineElement(tagName) {
2820
2959
  }
2821
2960
  disconnectedCallback() {
2822
2961
  this.hasConnected = false;
2823
- elementInstanceMap.delete(this);
2824
- this.handleUnmount(this.getDisposeResult('destroy') || this.getDisposeResult('destory'));
2825
- if (elementInstanceMap.size === 0) {
2826
- releasePatches();
2962
+ // keep-alive
2963
+ if (this.getKeepAliveModeResult()) {
2964
+ this.handleHiddenKeepAliveApp();
2965
+ }
2966
+ else {
2967
+ elementInstanceMap.delete(this);
2968
+ this.handleUnmount(this.getDestroyCompatibleResult(), () => {
2969
+ if (elementInstanceMap.size === 0) {
2970
+ releasePatches();
2971
+ }
2972
+ });
2827
2973
  }
2828
2974
  }
2829
2975
  attributeChangedCallback(attr, _oldVal, newVal) {
@@ -2867,7 +3013,7 @@ function defineElement(tagName) {
2867
3013
  if (elementInstanceMap.set(this, true).size === 1) {
2868
3014
  patchElementPrototypeMethods();
2869
3015
  rejectMicroAppStyle();
2870
- replaseUnmountOfNestedApp();
3016
+ releaseUnmountOfNestedApp();
2871
3017
  listenUmountOfNestedApp();
2872
3018
  }
2873
3019
  }
@@ -2886,15 +3032,21 @@ function defineElement(tagName) {
2886
3032
  else if (this.ssrUrl) {
2887
3033
  this.ssrUrl = '';
2888
3034
  }
2889
- const app = appInstanceMap.get(this.appName);
2890
- if (app) {
3035
+ if (appInstanceMap.has(this.appName)) {
3036
+ const app = appInstanceMap.get(this.appName);
2891
3037
  const existAppUrl = app.ssrUrl || app.url;
2892
3038
  const activeAppUrl = this.ssrUrl || this.appUrl;
2893
- if (existAppUrl === activeAppUrl && (app.isPrefetch ||
2894
- app.getAppStatus() === appStatus.UNMOUNT)) {
3039
+ // keep-alive don't care about ssrUrl
3040
+ // Even if the keep-alive app is pushed into the background, it is still active and cannot be replaced. Otherwise, it is difficult for developers to troubleshoot in case of conflict and will leave developers at a loss
3041
+ if (app.getKeepAliveState() === keepAliveStates.KEEP_ALIVE_HIDDEN &&
3042
+ app.url === this.appUrl) {
3043
+ this.handleShowKeepAliveApp(app);
3044
+ }
3045
+ else if (existAppUrl === activeAppUrl && (app.isPrefetch ||
3046
+ app.getAppState() === appStates.UNMOUNT)) {
2895
3047
  this.handleAppMount(app);
2896
3048
  }
2897
- else if (app.isPrefetch || app.getAppStatus() === appStatus.UNMOUNT) {
3049
+ else if (app.isPrefetch || app.getAppState() === appStates.UNMOUNT) {
2898
3050
  /**
2899
3051
  * url is different & old app is unmounted or prefetch, create new app to replace old one
2900
3052
  */
@@ -2902,7 +3054,56 @@ function defineElement(tagName) {
2902
3054
  this.handleCreateApp();
2903
3055
  }
2904
3056
  else {
2905
- logError(`an app named ${this.appName} already exists`, this.appName);
3057
+ logError(`app name conflict, an app named ${this.appName} is running`, this.appName);
3058
+ }
3059
+ }
3060
+ else {
3061
+ this.handleCreateApp();
3062
+ }
3063
+ }
3064
+ // remount app or create app if attribute url or name change
3065
+ actionsForAttributeChange(formatAttrName, formatAttrUrl, existApp) {
3066
+ var _a;
3067
+ /**
3068
+ * change ssrUrl in ssr mode
3069
+ * do not add judgment of formatAttrUrl === this.appUrl
3070
+ */
3071
+ if (this.getDisposeResult('ssr')) {
3072
+ this.ssrUrl = CompletionPath(globalEnv.rawWindow.location.pathname, formatAttrUrl);
3073
+ }
3074
+ else if (this.ssrUrl) {
3075
+ this.ssrUrl = '';
3076
+ }
3077
+ this.appName = formatAttrName;
3078
+ this.appUrl = formatAttrUrl;
3079
+ ((_a = this.shadowRoot) !== null && _a !== void 0 ? _a : this).innerHTML = '';
3080
+ if (formatAttrName !== this.getAttribute('name')) {
3081
+ this.setAttribute('name', this.appName);
3082
+ }
3083
+ /**
3084
+ * when existApp not null: this.appName === existApp.name
3085
+ * scene1: if formatAttrName and this.appName are equal: exitApp is the current app, the url must be different, existApp has been unmounted
3086
+ * scene2: if formatAttrName and this.appName are different: existApp must be prefetch or unmounted, if url is equal, then just mount, if url is different, then create new app to replace existApp
3087
+ * scene3: url is different but ssrUrl is equal
3088
+ * scene4: url is equal but ssrUrl is different, if url is equal, name must different
3089
+ * scene5: if existApp is KEEP_ALIVE_HIDDEN, name must different
3090
+ */
3091
+ if (existApp) {
3092
+ if (existApp.getKeepAliveState() === keepAliveStates.KEEP_ALIVE_HIDDEN) {
3093
+ if (existApp.url === this.appUrl) {
3094
+ this.handleShowKeepAliveApp(existApp);
3095
+ }
3096
+ else {
3097
+ // the hidden keep-alive app is still active
3098
+ logError(`app name conflict, an app named ${this.appName} is running`, this.appName);
3099
+ }
3100
+ }
3101
+ else if (existApp.url === this.appUrl && existApp.ssrUrl === this.ssrUrl) {
3102
+ // mount app
3103
+ this.handleAppMount(existApp);
3104
+ }
3105
+ else {
3106
+ this.handleCreateApp();
2906
3107
  }
2907
3108
  }
2908
3109
  else {
@@ -2962,10 +3163,24 @@ function defineElement(tagName) {
2962
3163
  * unmount app
2963
3164
  * @param destroy delete cache resources when unmount
2964
3165
  */
2965
- handleUnmount(destroy) {
3166
+ handleUnmount(destroy, unmountcb) {
3167
+ const app = appInstanceMap.get(this.appName);
3168
+ if (app &&
3169
+ app.getAppState() !== appStates.UNMOUNT)
3170
+ app.unmount(destroy, unmountcb);
3171
+ }
3172
+ // hidden app when disconnectedCallback called with keep-alive
3173
+ handleHiddenKeepAliveApp() {
2966
3174
  const app = appInstanceMap.get(this.appName);
2967
- if (app && appStatus.UNMOUNT !== app.getAppStatus())
2968
- app.unmount(destroy);
3175
+ if (app &&
3176
+ app.getAppState() !== appStates.UNMOUNT &&
3177
+ app.getKeepAliveState() !== keepAliveStates.KEEP_ALIVE_HIDDEN)
3178
+ app.hiddenKeepAliveApp();
3179
+ }
3180
+ // show app when connectedCallback called with keep-alive
3181
+ handleShowKeepAliveApp(app) {
3182
+ // must be asnyc
3183
+ defer(() => { var _a; return app.showKeepAliveApp((_a = this.shadowRoot) !== null && _a !== void 0 ? _a : this); });
2969
3184
  }
2970
3185
  /**
2971
3186
  * Get configuration
@@ -2974,7 +3189,27 @@ function defineElement(tagName) {
2974
3189
  */
2975
3190
  getDisposeResult(name) {
2976
3191
  // @ts-ignore
2977
- return (this.hasAttribute(name) || microApp[name]) && this.getAttribute(name) !== 'false';
3192
+ return (this.compatibleSpecialProperties(name) || microApp[name]) && this.compatibleDisablSpecialProperties(name);
3193
+ }
3194
+ // compatible of disableScopecss & disableSandbox
3195
+ compatibleSpecialProperties(name) {
3196
+ if (name === 'disableScopecss') {
3197
+ return this.hasAttribute('disableScopecss') || this.hasAttribute('disable-scopecss');
3198
+ }
3199
+ else if (name === 'disableSandbox') {
3200
+ return this.hasAttribute('disableSandbox') || this.hasAttribute('disable-sandbox');
3201
+ }
3202
+ return this.hasAttribute(name);
3203
+ }
3204
+ // compatible of disableScopecss & disableSandbox
3205
+ compatibleDisablSpecialProperties(name) {
3206
+ if (name === 'disableScopecss') {
3207
+ return this.getAttribute('disableScopecss') !== 'false' && this.getAttribute('disable-scopecss') !== 'false';
3208
+ }
3209
+ else if (name === 'disableSandbox') {
3210
+ return this.getAttribute('disableSandbox') !== 'false' && this.getAttribute('disable-sandbox') !== 'false';
3211
+ }
3212
+ return this.getAttribute(name) !== 'false';
2978
3213
  }
2979
3214
  /**
2980
3215
  * 2021-09-08
@@ -2985,6 +3220,16 @@ function defineElement(tagName) {
2985
3220
  var _a, _b;
2986
3221
  return (_b = (_a = this.getAttribute('baseroute')) !== null && _a !== void 0 ? _a : this.getAttribute('baseurl')) !== null && _b !== void 0 ? _b : '';
2987
3222
  }
3223
+ // compatible of destroy
3224
+ getDestroyCompatibleResult() {
3225
+ return this.getDisposeResult('destroy') || this.getDisposeResult('destory');
3226
+ }
3227
+ /**
3228
+ * destroy has priority over destroy keep-alive
3229
+ */
3230
+ getKeepAliveModeResult() {
3231
+ return this.getDisposeResult('keep-alive') && !this.getDestroyCompatibleResult();
3232
+ }
2988
3233
  /**
2989
3234
  * Data from the base application
2990
3235
  */
@@ -3141,6 +3386,7 @@ class MicroApp extends EventCenterForBaseApp {
3141
3386
  this.disableScopecss = options.disableScopecss;
3142
3387
  this.disableSandbox = options.disableSandbox;
3143
3388
  this.macro = options.macro;
3389
+ this.ssr = options.ssr;
3144
3390
  isFunction(options.fetch) && (this.fetch = options.fetch);
3145
3391
  isPlainObject(options.lifeCycles) && (this.lifeCycles = options.lifeCycles);
3146
3392
  // load app assets when browser is idle
@@ -3168,5 +3414,5 @@ class MicroApp extends EventCenterForBaseApp {
3168
3414
  var microApp = new MicroApp();
3169
3415
 
3170
3416
  export default microApp;
3171
- export { EventCenterForMicroApp, getActiveApps, getAllApps, preFetch, pureCreateElement, removeDomScope, version };
3417
+ export { EventCenterForMicroApp, getActiveApps, getAllApps, preFetch, pureCreateElement, removeDomScope, unmountAllApps, unmountApp, version };
3172
3418
  //# sourceMappingURL=index.esm.js.map