add persisted.readLatest for cross-tab session reads
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -39,6 +39,29 @@ export function get<K extends keyof Schema>(key: K): Schema[K] {
|
||||
}
|
||||
get satisfies PersistedApi['get']
|
||||
|
||||
/**
|
||||
* Force a fresh synchronous re-read of localStorage and return the requested
|
||||
* key from it, WITHOUT adopting it as `_state`.
|
||||
*
|
||||
* This exists for the cross-tab expiry-rescue path. A frozen tab may not have
|
||||
* processed a queued broadcast yet, so {@link get} (and persisted's in-memory
|
||||
* `_state`) can be stale even though another tab already wrote healthy tokens
|
||||
* to storage. Reading through storage directly here is the only way to see the
|
||||
* true cross-tab-latest tokens on web.
|
||||
*
|
||||
* Crucially we do NOT adopt into `_state`. {@link readFromStorage} memoizes by
|
||||
* raw string and returns the same object reference for unchanged data, so
|
||||
* adopting here would make the later queued broadcast/storage event for that
|
||||
* same write see `next === _state` and suppress its listener notification -
|
||||
* leaving non-current-account changes (removals, other tokens, metadata) stale
|
||||
* indefinitely. Leaving `_state` alone lets that queued event still fire.
|
||||
*/
|
||||
export function readLatest<K extends keyof Schema>(key: K): Schema[K] {
|
||||
const next = readFromStorage()
|
||||
return next?.[key] ?? _state[key]
|
||||
}
|
||||
readLatest satisfies PersistedApi['readLatest']
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/require-await
|
||||
export async function write<K extends keyof Schema>(
|
||||
key: K,
|
||||
|
||||
Reference in New Issue
Block a user