Memoize persist handler

This commit is contained in:
Eric Bailey
2024-04-08 13:05:30 -05:00
parent d9d9032456
commit 0d88a212ee
+15 -35
View File
@@ -1,9 +1,5 @@
import React from 'react' import React from 'react'
import { import {BSKY_LABELER_DID, BskyAgent} from '@atproto/api'
AtpPersistSessionHandler,
BSKY_LABELER_DID,
BskyAgent,
} from '@atproto/api'
import {jwtDecode} from 'jwt-decode' import {jwtDecode} from 'jwt-decode'
import {track} from '#/lib/analytics/analytics' import {track} from '#/lib/analytics/analytics'
@@ -39,11 +35,6 @@ export function getAgent() {
return __globalAgent return __globalAgent
} }
;(() => {
window.__id = Math.floor(Math.random() * 100).toString(36)
console.log(`\nID ${window.__id}\n\n`)
})()
export type SessionAccount = persisted.PersistedAccount export type SessionAccount = persisted.PersistedAccount
export type StateContext = { export type StateContext = {
@@ -201,17 +192,16 @@ export function Provider({children}: React.PropsWithChildren<{}>) {
BskyAgent.configure({appLabelers: [BSKY_LABELER_DID]}) BskyAgent.configure({appLabelers: [BSKY_LABELER_DID]})
}, [persistNextUpdate, setCurrentAgent]) }, [persistNextUpdate, setCurrentAgent])
const persistSession = React.useCallback< React.useMemo(() => {
(localAgent: BskyAgent) => AtpPersistSessionHandler currentAgent.setPersistSessionHandler(event => {
>(
localAgent => {
return event => {
logger.debug( logger.debug(
`session: persistSession`, `session: persistSession`,
{event}, {event},
logger.DebugContext.session, logger.DebugContext.session,
) )
// console.log('PERSIST', {event, refreshJwt: currentAgent.session?.refreshJwt.slice(-10)})
const expired = event === 'expired' || event === 'create-failed' const expired = event === 'expired' || event === 'create-failed'
if (event === 'network-error') { if (event === 'network-error') {
@@ -221,20 +211,16 @@ export function Provider({children}: React.PropsWithChildren<{}>) {
emitSessionDropped() emitSessionDropped()
clearCurrentAccount() clearCurrentAccount()
setTimeout(() => { setTimeout(() => {
Toast.show( Toast.show(`Your internet connection is unstable. Please try again.`)
`Your internet connection is unstable. Please try again.`,
)
}, 100) }, 100)
return return
} }
// TODO this will get stale with agent.clone() // TODO this will get stale with agent.clone()
const refreshedAccount = agentToSessionAccount(localAgent) const refreshedAccount = agentToSessionAccount(currentAgent)
if (!refreshedAccount) { if (!refreshedAccount) {
logger.error( logger.error(`session: persistSession failed to get refreshed account`)
`session: persistSession failed to get refreshed account`,
)
emitSessionDropped() emitSessionDropped()
clearCurrentAccount() clearCurrentAccount()
setTimeout(() => { setTimeout(() => {
@@ -263,10 +249,8 @@ export function Provider({children}: React.PropsWithChildren<{}>) {
* out. * out.
*/ */
upsertAndPersistAccount(refreshedAccount) upsertAndPersistAccount(refreshedAccount)
} })
}, }, [currentAgent, clearCurrentAccount, upsertAndPersistAccount])
[clearCurrentAccount, upsertAndPersistAccount],
)
const createAccount = React.useCallback<ApiContext['createAccount']>( const createAccount = React.useCallback<ApiContext['createAccount']>(
async ({ async ({
@@ -316,8 +300,6 @@ export function Provider({children}: React.PropsWithChildren<{}>) {
await configureModeration(agent, account) await configureModeration(agent, account)
agent.setPersistSessionHandler(persistSession(agent))
setCurrentAgent(agent) setCurrentAgent(agent)
upsertAndPersistAccount(account) upsertAndPersistAccount(account)
@@ -325,7 +307,7 @@ export function Provider({children}: React.PropsWithChildren<{}>) {
track('Create Account') track('Create Account')
logEvent('account:create:success', {}) logEvent('account:create:success', {})
}, },
[upsertAndPersistAccount, persistSession], [upsertAndPersistAccount],
) )
const login = React.useCallback<ApiContext['login']>( const login = React.useCallback<ApiContext['login']>(
@@ -342,8 +324,6 @@ export function Provider({children}: React.PropsWithChildren<{}>) {
const account = agentToSessionAccount(agent)! const account = agentToSessionAccount(agent)!
await configureModeration(agent, account) await configureModeration(agent, account)
agent.setPersistSessionHandler(persistSession(agent))
setCurrentAgent(agent) setCurrentAgent(agent)
upsertAndPersistAccount(account) upsertAndPersistAccount(account)
@@ -352,7 +332,7 @@ export function Provider({children}: React.PropsWithChildren<{}>) {
track('Sign In', {resumedSession: false}) track('Sign In', {resumedSession: false})
logEvent('account:loggedIn', {logContext, withPassword: true}) logEvent('account:loggedIn', {logContext, withPassword: true})
}, },
[upsertAndPersistAccount, persistSession], [upsertAndPersistAccount],
) )
const logout = React.useCallback<ApiContext['logout']>( const logout = React.useCallback<ApiContext['logout']>(
@@ -381,7 +361,6 @@ export function Provider({children}: React.PropsWithChildren<{}>) {
const agent = new BskyAgent({ const agent = new BskyAgent({
service: account.service, service: account.service,
}) })
agent.setPersistSessionHandler(persistSession(agent))
const prevSession = { const prevSession = {
...account, ...account,
@@ -422,12 +401,12 @@ export function Provider({children}: React.PropsWithChildren<{}>) {
{}, {},
logger.DebugContext.session, logger.DebugContext.session,
) )
// will call `persistSession` on `BskyAgent` instance above if success
await networkRetry(1, () => agent.resumeSession(prevSession)) await networkRetry(1, () => agent.resumeSession(prevSession))
setCurrentAgent(agent) setCurrentAgent(agent)
upsertAndPersistAccount(agentToSessionAccount(agent)!)
} }
}, },
[upsertAndPersistAccount, persistSession], [upsertAndPersistAccount],
) )
const resumeSession = React.useCallback<ApiContext['resumeSession']>( const resumeSession = React.useCallback<ApiContext['resumeSession']>(
@@ -547,6 +526,7 @@ export function Provider({children}: React.PropsWithChildren<{}>) {
{}, {},
logger.DebugContext.session, logger.DebugContext.session,
) )
// console.log('UPDATE', { refreshJwt: selectedAccount.refreshJwt.slice(-10) })
// updates silently, all subsequent calls will use the new session // updates silently, all subsequent calls will use the new session
currentAgent.session = sessionAccountToAgentSession(selectedAccount) currentAgent.session = sessionAccountToAgentSession(selectedAccount)
// replace agent to re-derive currentAccount and trigger rerender with fresh data // replace agent to re-derive currentAccount and trigger rerender with fresh data