🐛 fix the counter issue while multiple apps mounting concurrently (#2250)
This commit is contained in:
parent
59da80eb9c
commit
a5a0273a11
|
|
@ -67,6 +67,32 @@ export function isStyledComponentsLike(element: HTMLStyleElement) {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const appsCounterMap = new Map<string, { bootstrappingPatchCount: number; mountingPatchCount: number }>();
|
||||||
|
export function calcAppCount(
|
||||||
|
appName: string,
|
||||||
|
calcType: 'increase' | 'decrease',
|
||||||
|
status: 'bootstrapping' | 'mounting',
|
||||||
|
): void {
|
||||||
|
const appCount = appsCounterMap.get(appName) || { bootstrappingPatchCount: 0, mountingPatchCount: 0 };
|
||||||
|
switch (calcType) {
|
||||||
|
case 'increase':
|
||||||
|
appCount[`${status}PatchCount`] += 1;
|
||||||
|
break;
|
||||||
|
case 'decrease':
|
||||||
|
// bootstrap patch just called once but its freer will be called multiple times
|
||||||
|
if (appCount[`${status}PatchCount`] > 0) {
|
||||||
|
appCount[`${status}PatchCount`] -= 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
appsCounterMap.set(appName, appCount);
|
||||||
|
}
|
||||||
|
export function isAllAppsUnmounted(): boolean {
|
||||||
|
return Array.from(appsCounterMap.entries()).every(
|
||||||
|
([, { bootstrappingPatchCount: bpc, mountingPatchCount: mpc }]) => bpc === 0 && mpc === 0,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
function patchCustomEvent(
|
function patchCustomEvent(
|
||||||
e: CustomEvent,
|
e: CustomEvent,
|
||||||
elementGetter: () => HTMLScriptElement | HTMLLinkElement | null,
|
elementGetter: () => HTMLScriptElement | HTMLLinkElement | null,
|
||||||
|
|
|
||||||
|
|
@ -5,10 +5,13 @@
|
||||||
|
|
||||||
import { checkActivityFunctions } from 'single-spa';
|
import { checkActivityFunctions } from 'single-spa';
|
||||||
import type { Freer } from '../../../interfaces';
|
import type { Freer } from '../../../interfaces';
|
||||||
import { patchHTMLDynamicAppendPrototypeFunctions, rebuildCSSRules, recordStyledComponentsCSSRules } from './common';
|
import {
|
||||||
|
calcAppCount,
|
||||||
let bootstrappingPatchCount = 0;
|
isAllAppsUnmounted,
|
||||||
let mountingPatchCount = 0;
|
patchHTMLDynamicAppendPrototypeFunctions,
|
||||||
|
rebuildCSSRules,
|
||||||
|
recordStyledComponentsCSSRules,
|
||||||
|
} from './common';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Just hijack dynamic head append, that could avoid accidentally hijacking the insertion of elements except in head.
|
* Just hijack dynamic head append, that could avoid accidentally hijacking the insertion of elements except in head.
|
||||||
|
|
@ -52,17 +55,15 @@ export function patchLooseSandbox(
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!mounting) bootstrappingPatchCount++;
|
if (!mounting) calcAppCount(appName, 'increase', 'bootstrapping');
|
||||||
if (mounting) mountingPatchCount++;
|
if (mounting) calcAppCount(appName, 'increase', 'mounting');
|
||||||
|
|
||||||
return function free() {
|
return function free() {
|
||||||
// bootstrap patch just called once but its freer will be called multiple times
|
if (!mounting) calcAppCount(appName, 'decrease', 'bootstrapping');
|
||||||
if (!mounting && bootstrappingPatchCount !== 0) bootstrappingPatchCount--;
|
if (mounting) calcAppCount(appName, 'decrease', 'mounting');
|
||||||
if (mounting) mountingPatchCount--;
|
|
||||||
|
|
||||||
const allMicroAppUnmounted = mountingPatchCount === 0 && bootstrappingPatchCount === 0;
|
|
||||||
// release the overwrite prototype after all the micro apps unmounted
|
// release the overwrite prototype after all the micro apps unmounted
|
||||||
if (allMicroAppUnmounted) unpatchDynamicAppendPrototypeFunctions();
|
if (isAllAppsUnmounted()) unpatchDynamicAppendPrototypeFunctions();
|
||||||
|
|
||||||
recordStyledComponentsCSSRules(dynamicStyleSheetElements);
|
recordStyledComponentsCSSRules(dynamicStyleSheetElements);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,9 @@ import { nativeGlobal } from '../../../utils';
|
||||||
import { getCurrentRunningApp } from '../../common';
|
import { getCurrentRunningApp } from '../../common';
|
||||||
import type { ContainerConfig } from './common';
|
import type { ContainerConfig } from './common';
|
||||||
import {
|
import {
|
||||||
|
calcAppCount,
|
||||||
getAppWrapperHeadElement,
|
getAppWrapperHeadElement,
|
||||||
|
isAllAppsUnmounted,
|
||||||
isHijackingTag,
|
isHijackingTag,
|
||||||
patchHTMLDynamicAppendPrototypeFunctions,
|
patchHTMLDynamicAppendPrototypeFunctions,
|
||||||
rawHeadAppendChild,
|
rawHeadAppendChild,
|
||||||
|
|
@ -74,9 +76,6 @@ function patchDocumentCreateElement() {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
let bootstrappingPatchCount = 0;
|
|
||||||
let mountingPatchCount = 0;
|
|
||||||
|
|
||||||
export function patchStrictSandbox(
|
export function patchStrictSandbox(
|
||||||
appName: string,
|
appName: string,
|
||||||
appWrapperGetter: () => HTMLElement | ShadowRoot,
|
appWrapperGetter: () => HTMLElement | ShadowRoot,
|
||||||
|
|
@ -108,17 +107,15 @@ export function patchStrictSandbox(
|
||||||
(element) => elementAttachContainerConfigMap.get(element)!,
|
(element) => elementAttachContainerConfigMap.get(element)!,
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!mounting) bootstrappingPatchCount++;
|
if (!mounting) calcAppCount(appName, 'increase', 'bootstrapping');
|
||||||
if (mounting) mountingPatchCount++;
|
if (mounting) calcAppCount(appName, 'increase', 'mounting');
|
||||||
|
|
||||||
return function free() {
|
return function free() {
|
||||||
// bootstrap patch just called once but its freer will be called multiple times
|
if (!mounting) calcAppCount(appName, 'decrease', 'bootstrapping');
|
||||||
if (!mounting && bootstrappingPatchCount !== 0) bootstrappingPatchCount--;
|
if (mounting) calcAppCount(appName, 'decrease', 'mounting');
|
||||||
if (mounting) mountingPatchCount--;
|
|
||||||
|
|
||||||
const allMicroAppUnmounted = mountingPatchCount === 0 && bootstrappingPatchCount === 0;
|
|
||||||
// release the overwritten prototype after all the micro apps unmounted
|
// release the overwritten prototype after all the micro apps unmounted
|
||||||
if (allMicroAppUnmounted) {
|
if (isAllAppsUnmounted()) {
|
||||||
unpatchDynamicAppendPrototypeFunctions();
|
unpatchDynamicAppendPrototypeFunctions();
|
||||||
unpatchDocumentCreate();
|
unpatchDocumentCreate();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user