@@ -108,6 +108,7 @@ import type {
108
108
JwtHeader ,
109
109
} from './lib/types'
110
110
import { stringToUint8Array } from './lib/base64url'
111
+ import { LockClient } from './lib/lock-client'
111
112
112
113
polyfillGlobalThis ( ) // Make "globalThis" available
113
114
@@ -175,9 +176,7 @@ export default class GoTrueClient {
175
176
protected hasCustomAuthorizationHeader = false
176
177
protected suppressGetSessionWarning = false
177
178
protected fetch : Fetch
178
- protected lock : LockFunc
179
- protected lockAcquired = false
180
- protected pendingInLock : Promise < any > [ ] = [ ]
179
+ protected lock : LockClient
181
180
182
181
/**
183
182
* Used to broadcast state change events to other tabs listening.
@@ -219,17 +218,16 @@ export default class GoTrueClient {
219
218
this . url = settings . url
220
219
this . headers = settings . headers
221
220
this . fetch = resolveFetch ( settings . fetch )
222
- this . lock = settings . lock || lockNoOp
223
221
this . detectSessionInUrl = settings . detectSessionInUrl
224
222
this . flowType = settings . flowType
225
223
this . hasCustomAuthorizationHeader = settings . hasCustomAuthorizationHeader
226
224
227
225
if ( settings . lock ) {
228
- this . lock = settings . lock
226
+ this . lock = new LockClient ( settings . lock , settings . storageKey , this . _debug )
229
227
} else if ( isBrowser ( ) && globalThis ?. navigator ?. locks ) {
230
- this . lock = navigatorLock
228
+ this . lock = new LockClient ( navigatorLock , settings . storageKey , this . _debug )
231
229
} else {
232
- this . lock = lockNoOp
230
+ this . lock = new LockClient ( lockNoOp , settings . storageKey , this . _debug )
233
231
}
234
232
this . jwks = { keys : [ ] }
235
233
this . jwks_cached_at = Number . MIN_SAFE_INTEGER
@@ -301,7 +299,7 @@ export default class GoTrueClient {
301
299
}
302
300
303
301
this . initializePromise = ( async ( ) => {
304
- return await this . _acquireLock ( - 1 , async ( ) => {
302
+ return await this . lock . acquireLock ( - 1 , async ( ) => {
305
303
return await this . _initialize ( )
306
304
} )
307
305
} ) ( )
@@ -596,7 +594,7 @@ export default class GoTrueClient {
596
594
async exchangeCodeForSession ( authCode : string ) : Promise < AuthTokenResponse > {
597
595
await this . initializePromise
598
596
599
- return this . _acquireLock ( - 1 , async ( ) => {
597
+ return this . lock . acquireLock ( - 1 , async ( ) => {
600
598
return this . _exchangeCodeForSession ( authCode )
601
599
} )
602
600
}
@@ -863,7 +861,7 @@ export default class GoTrueClient {
863
861
async reauthenticate ( ) : Promise < AuthResponse > {
864
862
await this . initializePromise
865
863
866
- return await this . _acquireLock ( - 1 , async ( ) => {
864
+ return await this . lock . acquireLock ( - 1 , async ( ) => {
867
865
return await this . _reauthenticate ( )
868
866
} )
869
867
}
@@ -947,7 +945,7 @@ export default class GoTrueClient {
947
945
async getSession ( ) {
948
946
await this . initializePromise
949
947
950
- const result = await this . _acquireLock ( - 1 , async ( ) => {
948
+ const result = await this . lock . acquireLock ( - 1 , async ( ) => {
951
949
return this . _useSession ( async ( result ) => {
952
950
return result
953
951
} )
@@ -956,77 +954,6 @@ export default class GoTrueClient {
956
954
return result
957
955
}
958
956
959
- /**
960
- * Acquires a global lock based on the storage key.
961
- */
962
- private async _acquireLock < R > ( acquireTimeout : number , fn : ( ) => Promise < R > ) : Promise < R > {
963
- this . _debug ( '#_acquireLock' , 'begin' , acquireTimeout )
964
-
965
- try {
966
- if ( this . lockAcquired ) {
967
- const last = this . pendingInLock . length
968
- ? this . pendingInLock [ this . pendingInLock . length - 1 ]
969
- : Promise . resolve ( )
970
-
971
- const result = ( async ( ) => {
972
- await last
973
- return await fn ( )
974
- } ) ( )
975
-
976
- this . pendingInLock . push (
977
- ( async ( ) => {
978
- try {
979
- await result
980
- } catch ( e : any ) {
981
- // we just care if it finished
982
- }
983
- } ) ( )
984
- )
985
-
986
- return result
987
- }
988
-
989
- return await this . lock ( `lock:${ this . storageKey } ` , acquireTimeout , async ( ) => {
990
- this . _debug ( '#_acquireLock' , 'lock acquired for storage key' , this . storageKey )
991
-
992
- try {
993
- this . lockAcquired = true
994
-
995
- const result = fn ( )
996
-
997
- this . pendingInLock . push (
998
- ( async ( ) => {
999
- try {
1000
- await result
1001
- } catch ( e : any ) {
1002
- // we just care if it finished
1003
- }
1004
- } ) ( )
1005
- )
1006
-
1007
- await result
1008
-
1009
- // keep draining the queue until there's nothing to wait on
1010
- while ( this . pendingInLock . length ) {
1011
- const waitOn = [ ...this . pendingInLock ]
1012
-
1013
- await Promise . all ( waitOn )
1014
-
1015
- this . pendingInLock . splice ( 0 , waitOn . length )
1016
- }
1017
-
1018
- return await result
1019
- } finally {
1020
- this . _debug ( '#_acquireLock' , 'lock released for storage key' , this . storageKey )
1021
-
1022
- this . lockAcquired = false
1023
- }
1024
- } )
1025
- } finally {
1026
- this . _debug ( '#_acquireLock' , 'end' )
1027
- }
1028
- }
1029
-
1030
957
/**
1031
958
* Use instead of {@link #getSession} inside the library. It is
1032
959
* semantically usually what you want, as getting a session involves some
@@ -1095,7 +1022,7 @@ export default class GoTrueClient {
1095
1022
> {
1096
1023
this . _debug ( '#__loadSession()' , 'begin' )
1097
1024
1098
- if ( ! this . lockAcquired ) {
1025
+ if ( ! this . lock . lockAcquired ) {
1099
1026
this . _debug ( '#__loadSession()' , 'used outside of an acquired lock!' , new Error ( ) . stack )
1100
1027
}
1101
1028
@@ -1182,7 +1109,7 @@ export default class GoTrueClient {
1182
1109
1183
1110
await this . initializePromise
1184
1111
1185
- const result = await this . _acquireLock ( - 1 , async ( ) => {
1112
+ const result = await this . lock . acquireLock ( - 1 , async ( ) => {
1186
1113
return await this . _getUser ( )
1187
1114
} )
1188
1115
@@ -1244,7 +1171,7 @@ export default class GoTrueClient {
1244
1171
) : Promise < UserResponse > {
1245
1172
await this . initializePromise
1246
1173
1247
- return await this . _acquireLock ( - 1 , async ( ) => {
1174
+ return await this . lock . acquireLock ( - 1 , async ( ) => {
1248
1175
return await this . _updateUser ( attributes , options )
1249
1176
} )
1250
1177
}
@@ -1311,7 +1238,7 @@ export default class GoTrueClient {
1311
1238
} ) : Promise < AuthResponse > {
1312
1239
await this . initializePromise
1313
1240
1314
- return await this . _acquireLock ( - 1 , async ( ) => {
1241
+ return await this . lock . acquireLock ( - 1 , async ( ) => {
1315
1242
return await this . _setSession ( currentSession )
1316
1243
} )
1317
1244
}
@@ -1383,7 +1310,7 @@ export default class GoTrueClient {
1383
1310
async refreshSession ( currentSession ?: { refresh_token : string } ) : Promise < AuthResponse > {
1384
1311
await this . initializePromise
1385
1312
1386
- return await this . _acquireLock ( - 1 , async ( ) => {
1313
+ return await this . lock . acquireLock ( - 1 , async ( ) => {
1387
1314
return await this . _refreshSession ( currentSession )
1388
1315
} )
1389
1316
}
@@ -1590,7 +1517,7 @@ export default class GoTrueClient {
1590
1517
async signOut ( options : SignOut = { scope : 'global' } ) : Promise < { error : AuthError | null } > {
1591
1518
await this . initializePromise
1592
1519
1593
- return await this . _acquireLock ( - 1 , async ( ) => {
1520
+ return await this . lock . acquireLock ( - 1 , async ( ) => {
1594
1521
return await this . _signOut ( options )
1595
1522
} )
1596
1523
}
@@ -1653,7 +1580,7 @@ export default class GoTrueClient {
1653
1580
; ( async ( ) => {
1654
1581
await this . initializePromise
1655
1582
1656
- await this . _acquireLock ( - 1 , async ( ) => {
1583
+ await this . lock . acquireLock ( - 1 , async ( ) => {
1657
1584
this . _emitInitialSession ( id )
1658
1585
} )
1659
1586
} ) ( )
@@ -2197,7 +2124,7 @@ export default class GoTrueClient {
2197
2124
this . _debug ( '#_autoRefreshTokenTick()' , 'begin' )
2198
2125
2199
2126
try {
2200
- await this . _acquireLock ( 0 , async ( ) => {
2127
+ await this . lock . acquireLock ( 0 , async ( ) => {
2201
2128
try {
2202
2129
const now = Date . now ( )
2203
2130
@@ -2296,7 +2223,7 @@ export default class GoTrueClient {
2296
2223
// the lock first asynchronously
2297
2224
await this . initializePromise
2298
2225
2299
- await this . _acquireLock ( - 1 , async ( ) => {
2226
+ await this . lock . acquireLock ( - 1 , async ( ) => {
2300
2227
if ( document . visibilityState !== 'visible' ) {
2301
2228
this . _debug (
2302
2229
methodName ,
@@ -2432,7 +2359,7 @@ export default class GoTrueClient {
2432
2359
* {@see GoTrueMFAApi#verify }
2433
2360
*/
2434
2361
private async _verify ( params : MFAVerifyParams ) : Promise < AuthMFAVerifyResponse > {
2435
- return this . _acquireLock ( - 1 , async ( ) => {
2362
+ return this . lock . acquireLock ( - 1 , async ( ) => {
2436
2363
try {
2437
2364
return await this . _useSession ( async ( result ) => {
2438
2365
const { data : sessionData , error : sessionError } = result
@@ -2475,7 +2402,7 @@ export default class GoTrueClient {
2475
2402
* {@see GoTrueMFAApi#challenge }
2476
2403
*/
2477
2404
private async _challenge ( params : MFAChallengeParams ) : Promise < AuthMFAChallengeResponse > {
2478
- return this . _acquireLock ( - 1 , async ( ) => {
2405
+ return this . lock . acquireLock ( - 1 , async ( ) => {
2479
2406
try {
2480
2407
return await this . _useSession ( async ( result ) => {
2481
2408
const { data : sessionData , error : sessionError } = result
@@ -2561,7 +2488,7 @@ export default class GoTrueClient {
2561
2488
* {@see GoTrueMFAApi#getAuthenticatorAssuranceLevel }
2562
2489
*/
2563
2490
private async _getAuthenticatorAssuranceLevel ( ) : Promise < AuthMFAGetAuthenticatorAssuranceLevelResponse > {
2564
- return this . _acquireLock ( - 1 , async ( ) => {
2491
+ return this . lock . acquireLock ( - 1 , async ( ) => {
2565
2492
return await this . _useSession ( async ( result ) => {
2566
2493
const {
2567
2494
data : { session } ,
0 commit comments