Skip to content

Commit

Permalink
before-app-change and before-no-app change events. Resolves #545 (#547)
Browse files Browse the repository at this point in the history
* before-app-change and before-no-app change events. Resolves #545

* Self review

* Self review

* Anthony's feedback
  • Loading branch information
joeldenning committed May 12, 2020
1 parent cbfd48c commit d89173b
Show file tree
Hide file tree
Showing 2 changed files with 123 additions and 11 deletions.
85 changes: 85 additions & 0 deletions spec/apis/single-spa-events-api.spec.js
Expand Up @@ -441,4 +441,89 @@ describe(`events api :`, () => {
.catch(fail);
});
});

describe(`single-spa:before-app-change`, () => {
it(`is fired before apps will change, and not fired if no apps are changing`, (done) => {
window.location.hash = `#/russell`;

singleSpa
.triggerAppChange()
.then(() => {
expect(singleSpa.getAppStatus("boom")).toMatch(
/NOT_MOUNTED|NOT_LOADED/
);
expect(singleSpa.getAppStatus("russell")).toBe(singleSpa.MOUNTED);
window.addEventListener("single-spa:before-app-change", finishTest);
window.addEventListener(
"single-spa:before-no-app-change",
finishTest
);
boom = true;
window.location.hash = `#not-a-real-app`;

function finishTest(evt) {
window.removeEventListener(
"single-spa:before-app-change",
finishTest
);
window.removeEventListener(
"single-spa:before-no-app-change",
finishTest
);
expect(evt.type).toBe("single-spa:before-app-change");
expect(singleSpa.getAppStatus("boom")).toMatch(
/NOT_MOUNTED|NOT_LOADED/
);
expect(singleSpa.getAppStatus("russell")).toBe(singleSpa.MOUNTED);
expect(evt.detail.appsByNewStatus[singleSpa.MOUNTED]).toEqual([
"boom",
]);
expect(evt.detail.appsByNewStatus[singleSpa.NOT_MOUNTED]).toEqual([
"russell",
]);
done();
}
})
.catch(fail);
});
});

describe(`single-spa:before-no-app-change`, () => {
it(`is fired before apps will not change, and not fired if apps are changing`, (done) => {
window.location.hash = `#/russell`;

singleSpa
.triggerAppChange()
.then(() => {
expect(singleSpa.getAppStatus("boom")).toMatch(
/NOT_MOUNTED|NOT_LOADED/
);
expect(singleSpa.getAppStatus("russell")).toBe(singleSpa.MOUNTED);
window.addEventListener(
"single-spa:before-no-app-change",
finishTest
);
window.addEventListener("single-spa:before-app-change", finishTest);
singleSpa.triggerAppChange();

function finishTest(evt) {
window.removeEventListener(
"single-spa:before-no-app-change",
finishTest
);
window.removeEventListener(
"single-spa:before-app-change",
finishTest
);
expect(evt.type).toEqual("single-spa:before-no-app-change");
expect(evt.detail.appsByNewStatus[singleSpa.MOUNTED]).toEqual([]);
expect(evt.detail.appsByNewStatus[singleSpa.NOT_MOUNTED]).toEqual(
[]
);
done();
}
})
.catch(fail);
});
});
});
49 changes: 38 additions & 11 deletions src/navigation/reroute.js
Expand Up @@ -79,10 +79,20 @@ export function reroute(pendingPromises = [], eventArguments) {

function performAppChanges() {
return Promise.resolve().then(() => {
// https://github.com/single-spa/single-spa/issues/545
window.dispatchEvent(
new CustomEvent(
appsThatChanged.length === 0
? "single-spa:before-no-app-change"
: "single-spa:before-app-change",
getCustomEventDetail(true)
)
);

window.dispatchEvent(
new CustomEvent(
"single-spa:before-routing-event",
getCustomEventDetail()
getCustomEventDetail(true)
)
);
const unloadPromises = appsToUnload.map(toUnloadPromise);
Expand All @@ -99,7 +109,7 @@ export function reroute(pendingPromises = [], eventArguments) {
window.dispatchEvent(
new CustomEvent(
"single-spa:before-mount-routing-event",
getCustomEventDetail()
getCustomEventDetail(true)
)
);
});
Expand Down Expand Up @@ -202,7 +212,7 @@ export function reroute(pendingPromises = [], eventArguments) {
callCapturedEventListeners(eventArguments);
}

function getCustomEventDetail() {
function getCustomEventDetail(isBeforeChanges = false) {
const newAppStatuses = {};
const appsByNewStatus = {
// for apps that were mounted
Expand All @@ -214,14 +224,22 @@ export function reroute(pendingPromises = [], eventArguments) {
// apps that attempted to do something but are broken now
[SKIP_BECAUSE_BROKEN]: [],
};
appsThatChanged.forEach((app) => {
const appName = toName(app);
const status = getAppStatus(appName);
newAppStatuses[appName] = status;
const statusArr = (appsByNewStatus[status] =
appsByNewStatus[status] || []);
statusArr.push(appName);
});

if (isBeforeChanges) {
appsToLoad.concat(appsToMount).forEach((app, index) => {
addApp(app, MOUNTED);
});
appsToUnload.forEach((app) => {
addApp(app, NOT_LOADED);
});
appsToUnmount.forEach((app) => {
addApp(app, NOT_MOUNTED);
});
} else {
appsThatChanged.forEach((app) => {
addApp(app);
});
}

return {
detail: {
Expand All @@ -231,6 +249,15 @@ export function reroute(pendingPromises = [], eventArguments) {
originalEvent: eventArguments?.[0],
},
};

function addApp(app, status) {
const appName = toName(app);
status = status || getAppStatus(appName);
newAppStatuses[appName] = status;
const statusArr = (appsByNewStatus[status] =
appsByNewStatus[status] || []);
statusArr.push(appName);
}
}
}

Expand Down

0 comments on commit d89173b

Please sign in to comment.