🐛 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(
|
||||
e: CustomEvent,
|
||||
elementGetter: () => HTMLScriptElement | HTMLLinkElement | null,
|
||||
|
|
|
|||
|
|
@ -5,10 +5,13 @@
|
|||
|
||||
import { checkActivityFunctions } from 'single-spa';
|
||||
import type { Freer } from '../../../interfaces';
|
||||
import { patchHTMLDynamicAppendPrototypeFunctions, rebuildCSSRules, recordStyledComponentsCSSRules } from './common';
|
||||
|
||||
let bootstrappingPatchCount = 0;
|
||||
let mountingPatchCount = 0;
|
||||
import {
|
||||
calcAppCount,
|
||||
isAllAppsUnmounted,
|
||||
patchHTMLDynamicAppendPrototypeFunctions,
|
||||
rebuildCSSRules,
|
||||
recordStyledComponentsCSSRules,
|
||||
} from './common';
|
||||
|
||||
/**
|
||||
* 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) mountingPatchCount++;
|
||||
if (!mounting) calcAppCount(appName, 'increase', 'bootstrapping');
|
||||
if (mounting) calcAppCount(appName, 'increase', 'mounting');
|
||||
|
||||
return function free() {
|
||||
// bootstrap patch just called once but its freer will be called multiple times
|
||||
if (!mounting && bootstrappingPatchCount !== 0) bootstrappingPatchCount--;
|
||||
if (mounting) mountingPatchCount--;
|
||||
if (!mounting) calcAppCount(appName, 'decrease', 'bootstrapping');
|
||||
if (mounting) calcAppCount(appName, 'decrease', 'mounting');
|
||||
|
||||
const allMicroAppUnmounted = mountingPatchCount === 0 && bootstrappingPatchCount === 0;
|
||||
// release the overwrite prototype after all the micro apps unmounted
|
||||
if (allMicroAppUnmounted) unpatchDynamicAppendPrototypeFunctions();
|
||||
if (isAllAppsUnmounted()) unpatchDynamicAppendPrototypeFunctions();
|
||||
|
||||
recordStyledComponentsCSSRules(dynamicStyleSheetElements);
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,9 @@ import { nativeGlobal } from '../../../utils';
|
|||
import { getCurrentRunningApp } from '../../common';
|
||||
import type { ContainerConfig } from './common';
|
||||
import {
|
||||
calcAppCount,
|
||||
getAppWrapperHeadElement,
|
||||
isAllAppsUnmounted,
|
||||
isHijackingTag,
|
||||
patchHTMLDynamicAppendPrototypeFunctions,
|
||||
rawHeadAppendChild,
|
||||
|
|
@ -74,9 +76,6 @@ function patchDocumentCreateElement() {
|
|||
};
|
||||
}
|
||||
|
||||
let bootstrappingPatchCount = 0;
|
||||
let mountingPatchCount = 0;
|
||||
|
||||
export function patchStrictSandbox(
|
||||
appName: string,
|
||||
appWrapperGetter: () => HTMLElement | ShadowRoot,
|
||||
|
|
@ -108,17 +107,15 @@ export function patchStrictSandbox(
|
|||
(element) => elementAttachContainerConfigMap.get(element)!,
|
||||
);
|
||||
|
||||
if (!mounting) bootstrappingPatchCount++;
|
||||
if (mounting) mountingPatchCount++;
|
||||
if (!mounting) calcAppCount(appName, 'increase', 'bootstrapping');
|
||||
if (mounting) calcAppCount(appName, 'increase', 'mounting');
|
||||
|
||||
return function free() {
|
||||
// bootstrap patch just called once but its freer will be called multiple times
|
||||
if (!mounting && bootstrappingPatchCount !== 0) bootstrappingPatchCount--;
|
||||
if (mounting) mountingPatchCount--;
|
||||
if (!mounting) calcAppCount(appName, 'decrease', 'bootstrapping');
|
||||
if (mounting) calcAppCount(appName, 'decrease', 'mounting');
|
||||
|
||||
const allMicroAppUnmounted = mountingPatchCount === 0 && bootstrappingPatchCount === 0;
|
||||
// release the overwritten prototype after all the micro apps unmounted
|
||||
if (allMicroAppUnmounted) {
|
||||
if (isAllAppsUnmounted()) {
|
||||
unpatchDynamicAppendPrototypeFunctions();
|
||||
unpatchDocumentCreate();
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user