Skip to content

Conversation

@internettrans
Copy link
Member

No description provided.

obj.currentTarget &&
obj.currentTarget.href &&
obj.preventDefault
(obj as MouseEvent).currentTarget &&
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm open to a better typescript solution that avoids repeated typecasting inside of this if statement. VS Code type checking didn't infer that obj was a MouseEvent after the two previous if statements. Type casting seemed to be the simplest approach that avoided runtime changes

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

depending on the level of "not wanting to change the runtime" you want, you could consider using the in operator for this, which for reasons unknown to me* make TS way happier:

https://www.typescriptlang.org/play?#code/GYVwdgxgLglg9mABFApgWwA4Ao4CMBWAXIgM5QBOMYA5ogD6IASAKgLIAyAgpABZzkBRADboUYKPUSs4IEigEA3MVACUiAN4AoRDsQxgWKAE8MKOMER58iALx3EAcjKUaDtVt2fLBbV50B6f0QAPQB+Xx0AX0QUITk9AytEADJkxwgQcnJlZgBDcmoUKAc9JCTUxwxspXEAERRgXJAhYtLvfHcIrysuz0CQ8M9IzUigA


* I suspect it's due to the difference between

const car = {sold: false, fancy: undefined}

// doesn't enter if statement
if(car.sold)...
if(car.fancy)...

// does enter if statement
if('sold' in car)...
if('fancy' in car)...

but am not actually sure on whether that's the real reason or not.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 I pushed a commit with this change

window.location.hash = destination.hash;
} else if (current.host !== destination.host && destination.host) {
if (process.env.BABEL_ENV === "test") {
// @ts-ignore
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In some of the single-spa tests, the function signature for navigateToUrl changes to have an object as the return type. Since that is never the case in the dev or prod builds of single-spa, I opted not to include that possibility in the return type for navigateToUrl. This resulted in the need for a ts-ignore here. I'm open to other options - a test-only return type is unusual and I thought a ts-ignore was warranted.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I kind of like using @ts-expect-error [text here] so that if the implementation ever changes and it starts working again, TS will be helpful and tell you to remove this comment. Not a big deal though, just a personal preference.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 updated

function urlReroute() {
reroute([], arguments);
function urlReroute(evt: HashChangeEvent | PopStateEvent) {
reroute([], [evt]);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a runtime change that I hope doesn't cause any changes to behavior for single-spa users. I made the change so that type checks were stricter.

The urlReroute function is added as an event listener to the window hashchange and popstate events. According to MDN docs, there is only one argument passed to hashchange and popstate events, so I don't think this change is safe.

try {
evt = new PopStateEvent("popstate", { state });
} catch (err) {
// IE 11 compatibility https://github.com/single-spa/single-spa/issues/299
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I removed this IE-specific workaround

const current = parseUri(window.location.href);
const destination = parseUri(url);
const current = new URL(window.location.href);
const destination = new URL(url, window.location.href);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IE10 and/or 11 didn't support new URL() to correctly parse all strings. Since single-spa@7 doesn't support IE, I've removed the parseUri function in favor of new URL.

I am not totally sure that the behavior is the same for the two implementations, but I think it should be. The main edge cases to consider are relative urls - I believe using window.location.href as the base url will be equivalent to creating an anchor element with a relative url for the href

}

const unloadPromises = appsToUnload.map(toUnloadPromise);
const unloadPromises: Promise<InternalApplication>[] =
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Once the lifecycles folder is migrated to typescript, the unloadPromises variable should have automatically-inferred types. Since that hasn't happened yet, though, I've put the types manually

}
);
)
.then(finishUpAndReturn);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this might be a fix for a bug that was accidentally introduced in single-spa@6 with the profiler code. The finishUpAndReturn sets the resolved value of the promise chain, so it should be at the end.

const mountPromises = appsToMount
.filter((appToMount) => appsToLoad.indexOf(appToMount) < 0)
const mountPromises: Promise<InternalApplication>[] = appsToMount
.filter((appToMount) => !appsToLoad.includes(appToMount))
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another small change to remove IE support - using Array.prototype.includes rather than Array.prototype.indexOf


if (extraProperties) {
assign(result.detail, extraProperties);
Object.assign(result.detail, extraProperties);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Native assign rather than IE workaround

"emitDeclarationOnly": true,
"declaration": true,
"lib": ["dom", "es5", "es2015"]
"lib": ["dom", "es5", "es2020"]
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Needed for Promise.prototype.finally

Copy link
Member

@frehner frehner left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Really only looked at a small portion of this PR, but generally seems like you have a good handle on this.

obj.currentTarget &&
obj.currentTarget.href &&
obj.preventDefault
(obj as MouseEvent).currentTarget &&
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

depending on the level of "not wanting to change the runtime" you want, you could consider using the in operator for this, which for reasons unknown to me* make TS way happier:

https://www.typescriptlang.org/play?#code/GYVwdgxgLglg9mABFApgWwA4Ao4CMBWAXIgM5QBOMYA5ogD6IASAKgLIAyAgpABZzkBRADboUYKPUSs4IEigEA3MVACUiAN4AoRDsQxgWKAE8MKOMER58iALx3EAcjKUaDtVt2fLBbV50B6f0QAPQB+Xx0AX0QUITk9AytEADJkxwgQcnJlZgBDcmoUKAc9JCTUxwxspXEAERRgXJAhYtLvfHcIrysuz0CQ8M9IzUigA


* I suspect it's due to the difference between

const car = {sold: false, fancy: undefined}

// doesn't enter if statement
if(car.sold)...
if(car.fancy)...

// does enter if statement
if('sold' in car)...
if('fancy' in car)...

but am not actually sure on whether that's the real reason or not.

window.location.hash = destination.hash;
} else if (current.host !== destination.host && destination.host) {
if (process.env.BABEL_ENV === "test") {
// @ts-ignore
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I kind of like using @ts-expect-error [text here] so that if the implementation ever changes and it starts working again, TS will be helpful and tell you to remove this comment. Not a big deal though, just a personal preference.

@internettrans internettrans merged commit a00b0df into 7.0 Mar 7, 2024
@internettrans internettrans deleted the ts-5 branch March 7, 2024 20:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants