Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Refactor] decouple settingsMachine from React #5142

Open
wants to merge 44 commits into
base: main
Choose a base branch
from

Conversation

franknoirot
Copy link
Collaborator

Continuing the work from #5108 and #5110, next up is the settings. After #5110 gets in I'll rebase and then consolidate the commits into a readable story.

This pivots from #5110's approach of using invoke for the actor children of appMachine, opting instead to spawnChild them on machine initialization. Spawning is nice because they are not tied to the appMachine's current state (when we eventually add a state chart to it).

Copy link

vercel bot commented Jan 23, 2025

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Updated (UTC)
modeling-app ✅ Ready (Inspect) Visit Preview Jan 23, 2025 8:20pm

Copy link

qa-wolf bot commented Jan 23, 2025

QA Wolf here! As you write new code it's important that your test coverage is keeping up.
Click here to request test coverage for this PR!

@franknoirot
Copy link
Collaborator Author

Oh hell yeah snapshots, great catch!

Copy link

codecov bot commented Jan 23, 2025

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 86.14%. Comparing base (20016b1) to head (a0cbc26).
Report is 2 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #5142   +/-   ##
=======================================
  Coverage   86.14%   86.14%           
=======================================
  Files          89       89           
  Lines       32489    32489           
=======================================
  Hits        27987    27987           
  Misses       4502     4502           
Flag Coverage Δ
wasm-lib 86.14% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

Copy link
Contributor

@lf94 lf94 left a comment

Choose a reason for hiding this comment

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

Really great job. This is a massive win and effort. I greatly appreciate it.

Comment on lines +8 to +12
/**
* A simple HOC that listens to the auth state of the app and navigates
* accordingly.
*/
export function AuthNavigationHandler({
Copy link
Contributor

Choose a reason for hiding this comment

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

The lack of any wrapping or nested components makes me believe this should instead be a hook? Why shouldn't it be a hook? Wondering if I'm missing something here.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

You're so right, great idea! For now it needs to live on in one of the components that is in the index route but it could absolutely be a hook there. In the future I think we should do something else to inject the ability to navigate into the appMachine but I need a team consultation on that. I'll switch it to a hook for now


return (
<Switch
checked={checked}
onChange={(newValue) => {
settings.send({
settingsActor.send({
Copy link
Contributor

Choose a reason for hiding this comment

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

So beautiful :')

Comment on lines +40 to +41
const s = setting as Setting
return (['project', 'user'] satisfies SettingsLevel[])
Copy link
Contributor

Choose a reason for hiding this comment

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

=_=

Copy link
Contributor

Choose a reason for hiding this comment

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

Ah, you didn't write this, all good

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I did write this, just not in this PR. I think you and @jtran found a way for Object.entries to pass through its types, do you remember what that was? Was it simply that we upgraded TS to a version that supports it? I'll try removing this as and see if that works now.

@@ -11,6 +11,9 @@ import { ToastUpdate } from 'components/ToastUpdate'
import { markOnce } from 'lib/performance'
import { AUTO_UPDATER_TOAST_ID } from 'lib/constants'
import { initializeWindowExceptionHandler } from 'lib/exceptions'
import { initPromise } from 'lang/wasm'
import { appActor } from 'machines/appMachine'
Copy link
Contributor

Choose a reason for hiding this comment

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

So it begins! Nice :)

Comment on lines +31 to +35
initPromise
.then(() => {
appActor.start()
})
.catch(reportRejection)
Copy link
Contributor

Choose a reason for hiding this comment

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

Is this a general pattern we'll use for other actors?

I believe this app actor should be the one responsible for starting the others.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yes 100%, I want to have you all design the appActor too, but my inclination is that it should instantiate everything else. I have to go back and wire commandBarActor into it

'value' in data &&
'level' in data
) {
const coercedData = data as unknown as SetEventTypes['data']
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm guessing the type system was too much to deal with here

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yeah it was not happy with the type gymnastics I was attempting. I can add a comment

} else {
send({ type })
console.error('Invalid data submitted to settings command')
Copy link
Contributor

Choose a reason for hiding this comment

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

Would be nice to have the data output? Makes debugging quick / could also show up in the coredump

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

On it

Comment on lines +322 to +324
if (settingValue[level] !== undefined) {
settingValue[level] = undefined
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Why not just settingValue[level] = undefined ? The code basically says "if it's set, unset it". Computationally you're spending more cycles on 1. doing equality computation and 2. doing the conditional check, vs just 1. assignment.

Simply setting to undefined will be faster and clearer I'd think.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Oh duh, thank you

Comment on lines +26 to +31
spawnChild(AUTH, { id: AUTH, systemId: AUTH }),
spawnChild(SETTINGS, {
id: SETTINGS,
systemId: SETTINGS,
input: createSettings(),
}),
Copy link
Contributor

Choose a reason for hiding this comment

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

Beauty

Comment on lines +36 to +38
export const authActor = appActor.system.get(AUTH) as ActorRefFrom<
typeof authMachine
>
Copy link
Contributor

Choose a reason for hiding this comment

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

XState wasnt able to infer on its own? (just curious)

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

No! This honestly is so frustrating to me. I figure it's just this one POS line for now but I do not want to have to do this for every actor in the system. I want to find a better way but I was just getting any back from system.get(). Maybe there's a type parameter I should add?

Copy link
Contributor

Choose a reason for hiding this comment

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

Not a clue. We'll have to look together more closely but isn't a blocker for me.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants