@micro-zoe/micro-app 0.8.1 → 0.8.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/README.md CHANGED
@@ -152,7 +152,7 @@ For more commands, see [DEVELP](https://github.com/micro-zoe/micro-app/blob/mast
152
152
  </details>
153
153
 
154
154
  # Contributors
155
- <a href="https://github.com/micro-zoe/micro-app/graphs/contributors"><img src="./.github/contributors.svg" /></a>
155
+ <a href="https://github.com/micro-zoe/micro-app/graphs/contributors"><img src="https://micro-zoe.com/contributors.svg?height=55&people=11" /></a>
156
156
  <!-- opencollective is inaccurate -->
157
157
  <!-- <a href="https://github.com/micro-zoe/micro-app/graphs/contributors"><img src="https://opencollective.com/micro-app/contributors.svg?width=890&button=false" /></a> -->
158
158
 
package/README.zh-cn.md CHANGED
@@ -153,7 +153,7 @@ yarn start # 访问 http://localhost:3000
153
153
  </details>
154
154
 
155
155
  # 贡献者们
156
- <a href="https://github.com/micro-zoe/micro-app/graphs/contributors"><img src="./.github/contributors.svg" /></a>
156
+ <a href="https://github.com/micro-zoe/micro-app/graphs/contributors"><img src="https://micro-zoe.com/contributors.svg?height=55&people=11" /></a>
157
157
  <!-- opencollective is inaccurate -->
158
158
  <!-- <a href="https://github.com/micro-zoe/micro-app/graphs/contributors"><img src="https://opencollective.com/micro-app/contributors.svg?width=890&button=false" /></a> -->
159
159
 
package/lib/index.esm.js CHANGED
@@ -1,4 +1,4 @@
1
- const version = '0.8.1';
1
+ const version = '0.8.2';
2
2
  // do not use isUndefined
3
3
  const isBrowser = typeof window !== 'undefined';
4
4
  // do not use isUndefined
@@ -224,7 +224,7 @@ const requestIdleCallback = globalThis.requestIdleCallback ||
224
224
  return Math.max(0, 50 - (Date.now() - lastTime));
225
225
  },
226
226
  });
227
- }, 1);
227
+ }, 50);
228
228
  };
229
229
  /**
230
230
  * Record the currently running app.name
@@ -834,11 +834,9 @@ function extractLinkFromHtml(link, parent, app, isDynamic = false) {
834
834
  */
835
835
  function fetchLinksFromHtml(wrapElement, app, microAppHead) {
836
836
  const linkEntries = Array.from(app.source.links.entries());
837
- const fetchLinkPromise = [];
838
- for (const [url] of linkEntries) {
839
- const globalLinkCode = globalLinks.get(url);
840
- globalLinkCode ? fetchLinkPromise.push(globalLinkCode) : fetchLinkPromise.push(fetchSource(url, app.name));
841
- }
837
+ const fetchLinkPromise = linkEntries.map(([url]) => {
838
+ return globalLinks.has(url) ? globalLinks.get(url) : fetchSource(url, app.name);
839
+ });
842
840
  promiseStream(fetchLinkPromise, (res) => {
843
841
  fetchLinkSuccess(linkEntries[res.index][0], linkEntries[res.index][1], res.data, microAppHead, app);
844
842
  }, (err) => {
@@ -1115,6 +1113,27 @@ function patchElementPrototypeMethods() {
1115
1113
  this.__MICRO_APP_NAME__ && (clonedNode.__MICRO_APP_NAME__ = this.__MICRO_APP_NAME__);
1116
1114
  return clonedNode;
1117
1115
  };
1116
+ // patch getBoundingClientRect
1117
+ // TODO: scenes test
1118
+ // Element.prototype.getBoundingClientRect = function getBoundingClientRect () {
1119
+ // const rawRect: DOMRect = globalEnv.rawGetBoundingClientRect.call(this)
1120
+ // if (this.__MICRO_APP_NAME__) {
1121
+ // const app = appInstanceMap.get(this.__MICRO_APP_NAME__)
1122
+ // if (!app?.container) {
1123
+ // return rawRect
1124
+ // }
1125
+ // const appBody = app.container.querySelector('micro-app-body')
1126
+ // const appBodyRect: DOMRect = globalEnv.rawGetBoundingClientRect.call(appBody)
1127
+ // const computedRect: DOMRect = new DOMRect(
1128
+ // rawRect.x - appBodyRect.x,
1129
+ // rawRect.y - appBodyRect.y,
1130
+ // rawRect.width,
1131
+ // rawRect.height,
1132
+ // )
1133
+ // return computedRect
1134
+ // }
1135
+ // return rawRect
1136
+ // }
1118
1137
  }
1119
1138
  /**
1120
1139
  * Mark the newly created element in the micro application
@@ -1281,6 +1300,7 @@ function releasePatches() {
1281
1300
  Element.prototype.append = globalEnv.rawAppend;
1282
1301
  Element.prototype.prepend = globalEnv.rawPrepend;
1283
1302
  Element.prototype.cloneNode = globalEnv.rawCloneNode;
1303
+ // Element.prototype.getBoundingClientRect = globalEnv.rawGetBoundingClientRect
1284
1304
  }
1285
1305
  // Set the style of micro-app-head and micro-app-body
1286
1306
  let hasRejectMicroAppStyle = false;
@@ -1289,7 +1309,7 @@ function rejectMicroAppStyle() {
1289
1309
  hasRejectMicroAppStyle = true;
1290
1310
  const style = pureCreateElement('style');
1291
1311
  globalEnv.rawSetAttribute.call(style, 'type', 'text/css');
1292
- style.textContent = `\n${microApp.tagName}, micro-app-body { display: block; } \nmicro-app-head { display: none; }`;
1312
+ style.textContent = `\n${microApp.tagName}, micro-app-body { display: block; position: relative; } \nmicro-app-head { display: none; }`;
1293
1313
  globalEnv.rawDocument.head.appendChild(style);
1294
1314
  }
1295
1315
  }
@@ -1334,6 +1354,7 @@ function initGlobalEnv() {
1334
1354
  const rawAppend = Element.prototype.append;
1335
1355
  const rawPrepend = Element.prototype.prepend;
1336
1356
  const rawCloneNode = Element.prototype.cloneNode;
1357
+ // const rawGetBoundingClientRect = Element.prototype.getBoundingClientRect
1337
1358
  const rawCreateElement = Document.prototype.createElement;
1338
1359
  const rawCreateElementNS = Document.prototype.createElementNS;
1339
1360
  const rawCreateDocumentFragment = Document.prototype.createDocumentFragment;
@@ -1377,6 +1398,7 @@ function initGlobalEnv() {
1377
1398
  rawAppend,
1378
1399
  rawPrepend,
1379
1400
  rawCloneNode,
1401
+ // rawGetBoundingClientRect,
1380
1402
  rawCreateElement,
1381
1403
  rawCreateElementNS,
1382
1404
  rawCreateDocumentFragment,
@@ -1497,7 +1519,7 @@ function fetchScriptsFromHtml(wrapElement, app) {
1497
1519
  if (globalScriptText) {
1498
1520
  info.code = globalScriptText;
1499
1521
  }
1500
- else if (!info.defer && !info.async) {
1522
+ else if ((!info.defer && !info.async) || app.isPrefetch) {
1501
1523
  fetchScriptPromise.push(fetchSource(url, app.name));
1502
1524
  fetchScriptPromiseInfo.push([url, info]);
1503
1525
  }
@@ -2432,8 +2454,11 @@ const escapeSetterKeyList = [
2432
2454
  const globalPropertyList = ['window', 'self', 'globalThis'];
2433
2455
  class SandBox {
2434
2456
  constructor(appName, url) {
2435
- // Scoped global Properties(Properties that can only get and set in microAppWindow, will not escape to rawWindow)
2436
- this.scopeProperties = ['webpackJsonp'];
2457
+ /**
2458
+ * Scoped global Properties(Properties that can only get and set in microAppWindow, will not escape to rawWindow)
2459
+ * https://github.com/micro-zoe/micro-app/issues/234
2460
+ */
2461
+ this.scopeProperties = ['webpackJsonp', 'Vue'];
2437
2462
  // Properties that can be escape to rawWindow
2438
2463
  this.escapeProperties = [];
2439
2464
  // Properties newly added to microAppWindow
@@ -2631,10 +2656,12 @@ class SandBox {
2631
2656
  microAppWindow.__MICRO_APP_NAME__ = appName;
2632
2657
  microAppWindow.__MICRO_APP_PUBLIC_PATH__ = getEffectivePath(url);
2633
2658
  microAppWindow.__MICRO_APP_WINDOW__ = microAppWindow;
2634
- microAppWindow.microApp = new EventCenterForMicroApp(appName);
2659
+ microAppWindow.microApp = Object.assign(new EventCenterForMicroApp(appName), {
2660
+ removeDomScope,
2661
+ pureCreateElement,
2662
+ });
2635
2663
  microAppWindow.rawWindow = globalEnv.rawWindow;
2636
2664
  microAppWindow.rawDocument = globalEnv.rawDocument;
2637
- microAppWindow.removeDomScope = removeDomScope;
2638
2665
  microAppWindow.hasOwnProperty = (key) => rawHasOwnProperty.call(microAppWindow, key) || rawHasOwnProperty.call(globalEnv.rawWindow, key);
2639
2666
  this.setMappingPropertiesWithRawDescriptor(microAppWindow);
2640
2667
  this.setHijackProperties(microAppWindow, appName);
@@ -2779,6 +2806,7 @@ class CreateApp {
2779
2806
  this.libraryName = null;
2780
2807
  this.umdMode = false;
2781
2808
  this.isPrefetch = false;
2809
+ this.prefetchResolve = null;
2782
2810
  this.container = null;
2783
2811
  this.baseroute = '';
2784
2812
  this.sandBox = null;
@@ -2807,12 +2835,17 @@ class CreateApp {
2807
2835
  * When resource is loaded, mount app if it is not prefetch or unmount
2808
2836
  */
2809
2837
  onLoad(html) {
2838
+ var _a;
2810
2839
  if (++this.loadSourceLevel === 2) {
2811
2840
  this.source.html = html;
2812
- if (this.isPrefetch || appStates.UNMOUNT === this.state)
2813
- return;
2814
- this.state = appStates.LOAD_SOURCE_FINISHED;
2815
- this.mount();
2841
+ if (this.isPrefetch) {
2842
+ (_a = this.prefetchResolve) === null || _a === void 0 ? void 0 : _a.call(this);
2843
+ this.prefetchResolve = null;
2844
+ }
2845
+ else if (appStates.UNMOUNT !== this.state) {
2846
+ this.state = appStates.LOAD_SOURCE_FINISHED;
2847
+ this.mount();
2848
+ }
2816
2849
  }
2817
2850
  }
2818
2851
  /**
@@ -2821,6 +2854,10 @@ class CreateApp {
2821
2854
  */
2822
2855
  onLoadError(e) {
2823
2856
  this.loadSourceLevel = -1;
2857
+ if (this.prefetchResolve) {
2858
+ this.prefetchResolve();
2859
+ this.prefetchResolve = null;
2860
+ }
2824
2861
  if (appStates.UNMOUNT !== this.state) {
2825
2862
  this.onerror(e);
2826
2863
  this.state = appStates.LOAD_SOURCE_ERROR;
@@ -3406,21 +3443,6 @@ function defineElement(tagName) {
3406
3443
  window.customElements.define(tagName, MicroAppElement);
3407
3444
  }
3408
3445
 
3409
- function filterPreFetchTarget(apps) {
3410
- const validApps = [];
3411
- if (isArray(apps)) {
3412
- apps.forEach((item) => {
3413
- if (isPlainObject(item)) {
3414
- item.name = formatAppName(item.name);
3415
- item.url = formatAppURL(item.url, item.name);
3416
- if (item.name && item.url && !appInstanceMap.has(item.name)) {
3417
- validApps.push(item);
3418
- }
3419
- }
3420
- });
3421
- }
3422
- return validApps;
3423
- }
3424
3446
  /**
3425
3447
  * preFetch([
3426
3448
  * {
@@ -3442,16 +3464,37 @@ function preFetch(apps) {
3442
3464
  }
3443
3465
  requestIdleCallback(() => {
3444
3466
  isFunction(apps) && (apps = apps());
3445
- filterPreFetchTarget(apps).forEach((item) => {
3467
+ if (isArray(apps)) {
3468
+ apps.reduce((pre, next) => pre.then(() => preFetchInSerial(next)), Promise.resolve());
3469
+ }
3470
+ });
3471
+ }
3472
+ // sequential preload app
3473
+ function preFetchInSerial(prefetchApp) {
3474
+ return new Promise((resolve) => {
3475
+ requestIdleCallback(() => {
3446
3476
  var _a, _b;
3447
- const app = new CreateApp({
3448
- name: item.name,
3449
- url: item.url,
3450
- scopecss: !((_a = item.disableScopecss) !== null && _a !== void 0 ? _a : microApp.disableScopecss),
3451
- useSandbox: !((_b = item.disableSandbox) !== null && _b !== void 0 ? _b : microApp.disableSandbox),
3452
- });
3453
- app.isPrefetch = true;
3454
- appInstanceMap.set(item.name, app);
3477
+ if (isPlainObject(prefetchApp) && navigator.onLine) {
3478
+ prefetchApp.name = formatAppName(prefetchApp.name);
3479
+ prefetchApp.url = formatAppURL(prefetchApp.url, prefetchApp.name);
3480
+ if (prefetchApp.name && prefetchApp.url && !appInstanceMap.has(prefetchApp.name)) {
3481
+ const app = new CreateApp({
3482
+ name: prefetchApp.name,
3483
+ url: prefetchApp.url,
3484
+ scopecss: !((_a = prefetchApp.disableScopecss) !== null && _a !== void 0 ? _a : microApp.disableScopecss),
3485
+ useSandbox: !((_b = prefetchApp.disableSandbox) !== null && _b !== void 0 ? _b : microApp.disableSandbox),
3486
+ });
3487
+ app.isPrefetch = true;
3488
+ app.prefetchResolve = resolve;
3489
+ appInstanceMap.set(prefetchApp.name, app);
3490
+ }
3491
+ else {
3492
+ resolve();
3493
+ }
3494
+ }
3495
+ else {
3496
+ resolve();
3497
+ }
3455
3498
  });
3456
3499
  });
3457
3500
  }
@@ -3462,38 +3505,23 @@ function preFetch(apps) {
3462
3505
  function getGlobalAssets(assets) {
3463
3506
  if (isPlainObject(assets)) {
3464
3507
  requestIdleCallback(() => {
3465
- if (isArray(assets.js)) {
3466
- const effectiveJs = assets.js.filter((path) => isString(path) && path.includes('.js') && !globalScripts.has(path));
3467
- const fetchJSPromise = [];
3468
- effectiveJs.forEach((path) => {
3469
- fetchJSPromise.push(fetchSource(path));
3470
- });
3471
- // fetch js with stream
3472
- promiseStream(fetchJSPromise, (res) => {
3473
- const path = effectiveJs[res.index];
3474
- if (!globalScripts.has(path)) {
3475
- globalScripts.set(path, res.data);
3476
- }
3477
- }, (err) => {
3478
- logError(err);
3479
- });
3480
- }
3481
- if (isArray(assets.css)) {
3482
- const effectiveCss = assets.css.filter((path) => isString(path) && path.includes('.css') && !globalLinks.has(path));
3483
- const fetchCssPromise = [];
3484
- effectiveCss.forEach((path) => {
3485
- fetchCssPromise.push(fetchSource(path));
3486
- });
3487
- // fetch css with stream
3488
- promiseStream(fetchCssPromise, (res) => {
3489
- const path = effectiveCss[res.index];
3490
- if (!globalLinks.has(path)) {
3491
- globalLinks.set(path, res.data);
3492
- }
3493
- }, (err) => {
3494
- logError(err);
3495
- });
3508
+ fetchGlobalResources(assets.js, 'js', globalScripts);
3509
+ fetchGlobalResources(assets.css, 'css', globalLinks);
3510
+ });
3511
+ }
3512
+ }
3513
+ function fetchGlobalResources(resources, suffix, cache) {
3514
+ if (isArray(resources)) {
3515
+ const effectiveResource = resources.filter((path) => isString(path) && path.includes(`.${suffix}`) && !cache.has(path));
3516
+ const fetchResourcePromise = effectiveResource.map((path) => fetchSource(path));
3517
+ // fetch resource with stream
3518
+ promiseStream(fetchResourcePromise, (res) => {
3519
+ const path = effectiveResource[res.index];
3520
+ if (!cache.has(path)) {
3521
+ cache.set(path, res.data);
3496
3522
  }
3523
+ }, (err) => {
3524
+ logError(err);
3497
3525
  });
3498
3526
  }
3499
3527
  }