@@ -71,16 +71,13 @@ export async function logout() {
7171 } ) . catch ( ( ) => { } )
7272}
7373
74- let isRefreshing = false // to prevent multiple simultaneous refreshes
75- let refreshPromise : Promise < void > | null = null
76-
7774export async function fetchWithAuth (
7875 path : string ,
7976 options : RequestInit = { } ,
8077 retry = true ,
8178) : Promise < unknown > {
8279 const store = useSessionStore . getState ( )
83- const logout = store . logout
80+ const sessionLogout = store . logout
8481 const authDisabled = useConfigStore . getState ( ) . authDisabled
8582
8683 const headers = new Headers ( options . headers || { } )
@@ -118,21 +115,13 @@ export async function fetchWithAuth(
118115 let res = await doFetch ( )
119116
120117 if ( res . status === 401 && retry && ! authDisabled ) {
121- if ( ! isRefreshing ) {
122- isRefreshing = true
123- refreshPromise = refreshAccessToken ( ) . finally ( ( ) => {
124- isRefreshing = false
125- refreshPromise = null
126- } )
127- }
128-
129118 try {
130- await refreshPromise
119+ await ensureRefresh ( )
131120 res = await doFetch ( )
132121 } catch {
133122 // Refresh token failed, log out the user
134123 if ( ! authDisabled ) {
135- logout ( )
124+ sessionLogout ( )
136125 const { setUser } = useSessionStore . getState ( )
137126 setUser ( null )
138127 }
@@ -161,6 +150,32 @@ export async function fetchWithAuth(
161150 }
162151}
163152
153+ declare global {
154+ // Explicitly initialized below; runtime value is either a Promise or null
155+ var __leafwikiRefreshPromise : Promise < void > | null
156+ }
157+
158+ // Ensure the global is initialized to a known value at module load time.
159+ if ( typeof globalThis . __leafwikiRefreshPromise === 'undefined' ) {
160+ globalThis . __leafwikiRefreshPromise = null
161+ }
162+ /**
163+ * Ensures there is only ONE refresh in-flight across the whole runtime (even if module is duplicated).
164+ */
165+ export function ensureRefresh ( ) : Promise < void > {
166+ const { authDisabled } = useConfigStore . getState ( )
167+ if ( authDisabled ) {
168+ return Promise . resolve ( )
169+ }
170+
171+ if ( ! globalThis . __leafwikiRefreshPromise ) {
172+ globalThis . __leafwikiRefreshPromise = refreshAccessToken ( ) . finally ( ( ) => {
173+ globalThis . __leafwikiRefreshPromise = null
174+ } )
175+ }
176+ return globalThis . __leafwikiRefreshPromise
177+ }
178+
164179async function refreshAccessToken ( ) {
165180 const store = useSessionStore . getState ( )
166181
0 commit comments