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: separate authMachine from React #5110

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

Conversation

franknoirot
Copy link
Collaborator

Continuation of the work to separate out XState actors from React wherever possible.

This PR also begins the use of an XState system, which subsequent PRs will continue to use.

Copy link

qa-wolf bot commented Jan 18, 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!

Copy link

vercel bot commented Jan 18, 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 27, 2025 3:56pm

Copy link

codecov bot commented Jan 18, 2025

Codecov Report

All modified and coverable lines are covered by tests ✅

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

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #5110   +/-   ##
=======================================
  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.

Base automatically changed from franknoirot/adhoc/cmd-bar-out-of-react to main January 23, 2025 15:25
@franknoirot franknoirot force-pushed the franknoirot/adhoc/project-file-out-of-react branch from 249e85e to 928b8ab Compare January 23, 2025 15:26
@franknoirot franknoirot requested review from lf94 and pierremtb January 23, 2025 17:13
@lf94
Copy link
Contributor

lf94 commented Jan 27, 2025

I think your other settings PR includes code from 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.

Few minor things but potentially nothing needing changes

Comment on lines 7 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.

No way we could make this a hook eh? I see how you're using it but I believe it could be used in the Router component. It feels weird to use this as a HOC when it's not modifying the component(s) at all.

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 absolutely right, I should have made this a hook from the jump. I've just made that change.

Comment on lines +26 to +30
export const useAuthState = () => useSelector(authActor, (state) => state)
export const useToken = () =>
useSelector(authActor, (state) => state.context.token)
export const useUser = () =>
useSelector(authActor, (state) => state.context.user)
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 personally not a fan of these very shallow uses of useSelector, but up to you :). It hides that useToken and useUser are just simple useSelector 's underneath.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Hm I don't know, I'm trying to make a very simple DX for teammates to use the token in the future. I heard that you should define your selector closures outside of React anyway (here in a comment in an example in the XState docs), and I didn't want every developer to have to remember to do that. What do you think about that, does hiding that detail seem worthwhile?

Copy link
Contributor

@lf94 lf94 Jan 27, 2025

Choose a reason for hiding this comment

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

That XState comment is only talking about the selector function but not useSelector itself (you see they're all inside a React component).

I believe it makes sense to abstract the selector (the developer doesn't need to know the details of what's being selected in fine detail), but not the useSelector hook itself (which dictates a lot of behavior and probably don't want to "clutter" a developer's selection of hooks to chose from with 101 hooks that are all essentially useSelector)

Comment on lines +23 to +25
export const authActor = appActor.system.get(ACTOR_IDS.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.

TypeScript can't infer the type properly I take it?

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 is my biggest beef so far with trying to make use of the XState actor system approach. Maybe I'm missing something but appActor.system.get() has this type signature according to my intellisense:
(property) ActorSystem<any>.get: <string>(key: string) => any

Copy link
Contributor

Choose a reason for hiding this comment

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

Yeah we'll look together at a better solution - not worth blocking IMO.

Comment on lines +1 to +3
export const ACTOR_IDS = {
AUTH: 'auth',
}
Copy link
Contributor

Choose a reason for hiding this comment

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

I would rather each Actor own its id, instead of declaring them all here. If we want to export a full list we can import them into one place but I want each actor to dictate its own information.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

But that information—the actor's src, id, and systemId—are all the same string, and we try to make any repetitive string into a named constant?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Another goofy part of this is that in this first PR I invoked the authMachine within appMachine, but once I got started adding settingsMachine in the next PR I realized I should spawnChild them.

Copy link
Contributor

@lf94 lf94 Jan 27, 2025

Choose a reason for hiding this comment

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

Oh yea, my gripe is the location of the information. I believe it should be more local to the actor, instead of separated out like this :) Just my opinion of course - there is no absolute right.


async function logout() {
localStorage.removeItem(TOKEN_PERSIST_KEY)
if (isDesktop()) return Promise.resolve(null)
Copy link
Contributor

Choose a reason for hiding this comment

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

User's can't logout on desktop? 🤔

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.

2 participants