Skip to content

Conversation

nikgraf
Copy link
Collaborator

@nikgraf nikgraf commented Jan 28, 2025

By moving auth to the store it's data is available in the core framework and not only React. This also will allows use as a next step to move a lot of the auth functions to the core. Follow up issue: #128

Details:

  • The store now only accepts either to set the full auth or reset it. Before the types allowed only to set e.g. sessionToken. This makes it more type-safe. To achieve this I had to change the functions to return the full auth object. It uncovered one case where we didn't throw an error.
  • In addition I identified two placed loginWithWallet & loginWithKeys where we could end up on an infinite loop. I added retry counts to prevent this and throw if it doesn't work after 3 times.

I changed the check if the user is already authenticated on initial render in a useEffect to be a useLayoutEffect since this will execute the whole state change before anything is commited to the DOM and therefor prevent flickering.

@nikgraf nikgraf self-assigned this Jan 28, 2025
Copy link
Collaborator

@cmwhited cmwhited left a comment

Choose a reason for hiding this comment

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

Good call 🔥 was a bit odd to have these two states separated from the store

Comment on lines +87 to +98
const keys = useSelectorStore(store, (state) => state.context.keys);
const identity: Identity.Identity | null =
accountId && keys
? {
accountId,
encryptionPublicKey: keys.encryptionPublicKey,
encryptionPrivateKey: keys.encryptionPrivateKey,
signaturePublicKey: keys.signaturePublicKey,
signaturePrivateKey: keys.signaturePrivateKey,
}
: null;
return identity;
Copy link
Collaborator

Choose a reason for hiding this comment

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

Could you wrap this in the useSelectorStore fn so its get memoized? Like

export function useHypergraphIdentity() {
  return useSelectorStore(store, (state) => {
    const accountId = state.context.accountId;
    const keys = state.context.keys;
    if (accountId && keys) {
      return { accountId, ...keys }
    }
    return null
  })
}

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! that's a great suggestion. will do, thx

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

this actually doesn't work :(

I get:

The result of getSnapshot should be cached to avoid an infinite loop Error Component Stack

Error: Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops.

I guess the reason is because they are using useSyncExternalStore under the hood and in this case the returned result would be a new object every time and referential equality never results in a true when comparing the previous and new one.

We could create a useRef to store the object, but not sure it's worth the trouble? What do you think? Any other suggestions?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

merged it to continue refactoring, but happy to incorporate any ideas in a new PR

@nikgraf nikgraf force-pushed the ng/move-auth-to-store-and-cleanup branch from c2050a8 to bd468be Compare January 28, 2025 21:25
@nikgraf nikgraf merged commit 86d9676 into main Jan 28, 2025
4 checks passed
@nikgraf nikgraf deleted the ng/move-auth-to-store-and-cleanup branch January 28, 2025 21:27
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