11import { Injectable } from '@angular/core' ;
2+ import { navigatorLock } from '@supabase/auth-js' ;
23import { SupabaseClient , createClient } from '@supabase/supabase-js' ;
34import type { Database , Json } from '../../db/database.types' ;
45import { environment } from '../../environments/environment' ;
@@ -69,6 +70,45 @@ interface CreateAiFeedbackDto {
6970 suggestions : AiSuggestionItemDto [ ] ;
7071}
7172
73+ type LockFunction = typeof navigatorLock ;
74+
75+ interface LockRetryConfig {
76+ fallbackAcquireTimeoutMs : number ;
77+ retryIntervalMs : number ;
78+ maxAttempts : number ;
79+ }
80+
81+ const createNavigatorLockWithRetry = ( config : LockRetryConfig ) : LockFunction => {
82+ const { fallbackAcquireTimeoutMs, retryIntervalMs, maxAttempts } = config ;
83+
84+ const delay = ( ms : number ) : Promise < void > =>
85+ new Promise ( resolve => {
86+ setTimeout ( resolve , ms ) ;
87+ } ) ;
88+
89+ const isAcquireTimeoutError = ( error : unknown ) : boolean =>
90+ Boolean ( error && typeof error === 'object' && 'isAcquireTimeout' in error ) ;
91+
92+ return async ( name , acquireTimeout , fn ) => {
93+ let attempt = 0 ;
94+
95+ const effectiveAcquireTimeout =
96+ acquireTimeout === 0 ? fallbackAcquireTimeoutMs : acquireTimeout ;
97+
98+ while ( true ) {
99+ try {
100+ return await navigatorLock ( name , effectiveAcquireTimeout , fn ) ;
101+ } catch ( error ) {
102+ if ( ! isAcquireTimeoutError ( error ) || attempt >= maxAttempts ) {
103+ throw error ;
104+ }
105+ attempt += 1 ;
106+ await delay ( retryIntervalMs ) ;
107+ }
108+ }
109+ } ;
110+ } ;
111+
72112/**
73113 * Service for managing Supabase client and database operations.
74114 * Provides centralized access to Supabase functionality with proper typing.
@@ -94,7 +134,26 @@ export class SupabaseService {
94134 ) ;
95135 }
96136
97- this . client = createClient < Database > ( supabaseUrl , supabaseKey ) ;
137+ const supportsNavigatorLocks = typeof navigator !== 'undefined' && 'locks' in navigator ;
138+
139+ const lockFunction = supportsNavigatorLocks
140+ ? createNavigatorLockWithRetry ( {
141+ fallbackAcquireTimeoutMs : 5000 ,
142+ retryIntervalMs : 200 ,
143+ maxAttempts : 25 ,
144+ } )
145+ : undefined ;
146+
147+ this . client = createClient < Database > ( supabaseUrl , supabaseKey , {
148+ auth : {
149+ // Keep sessions persisted and refreshed automatically
150+ persistSession : true ,
151+ autoRefreshToken : true ,
152+ detectSessionInUrl : true ,
153+ // Configure navigator lock retries to avoid immediate acquire failures
154+ ...( lockFunction ? { lock : lockFunction } : { } ) ,
155+ } ,
156+ } ) ;
98157 }
99158
100159 /**
0 commit comments