11import { deepEqual } from "fast-equals" ;
22
3- import { FLAG_EVENTS_PER_MIN , FLAGS_EXPIRE_MS } from "../config" ;
3+ import { FLAG_EVENTS_PER_MIN , FLAGS_EXPIRE_MS , IS_SERVER } from "../config" ;
44import { ReflagContext } from "../context" ;
55import { HttpClient } from "../httpClient" ;
66import { Logger , loggerWithPrefix } from "../logger" ;
7- import { OverridesProvider } from "../overrides/overridesProvider" ;
8- import { StorageOverridesProvider } from "../overrides/storageOverridesProvider" ;
97import RateLimiter from "../rateLimiter" ;
108
119import { FlagCache , isObject , parseAPIFlagsResponse } from "./flagCache" ;
@@ -177,16 +175,15 @@ export interface CheckEvent {
177175}
178176
179177const localStorageFetchedFlagsKey = `__reflag_fetched_flags` ;
178+ const storageOverridesKey = `__reflag_overrides` ;
180179
181180export type FlagOverrides = Record < string , boolean | undefined > ;
182181
183182type FlagsClientOptions = Partial < Config > & {
184183 bootstrappedFlags ?: RawFlags ;
185- bootstrappedOverrides ?: FlagOverrides ;
186184 fallbackFlags ?: Record < string , FallbackFlagOverride > | string [ ] ;
187185 cache ?: FlagCache ;
188186 rateLimiter ?: RateLimiter ;
189- overridesProvider ?: OverridesProvider ;
190187} ;
191188
192189/**
@@ -195,7 +192,6 @@ type FlagsClientOptions = Partial<Config> & {
195192export class FlagsClient {
196193 private initialized = false ;
197194 private bootstrapped = false ;
198- private overridesInitialized = false ;
199195
200196 private rateLimiter : RateLimiter ;
201197 private readonly logger : Logger ;
@@ -205,7 +201,6 @@ export class FlagsClient {
205201 private flagOverrides : FlagOverrides = { } ;
206202 private flags : RawFlags = { } ;
207203 private fallbackFlags : FallbackFlags = { } ;
208- private overridesProvider : OverridesProvider ;
209204
210205 private config : Config = DEFAULT_FLAGS_CONFIG ;
211206
@@ -218,11 +213,9 @@ export class FlagsClient {
218213 logger : Logger ,
219214 {
220215 bootstrappedFlags,
221- bootstrappedOverrides,
222216 cache,
223217 rateLimiter,
224218 fallbackFlags,
225- overridesProvider,
226219 ...config
227220 } : FlagsClientOptions = { } ,
228221 ) {
@@ -238,19 +231,13 @@ export class FlagsClient {
238231 cache ??
239232 this . setupCache ( this . config . staleTimeMs , this . config . expireTimeMs ) ;
240233 this . fallbackFlags = this . setupFallbackFlags ( fallbackFlags ) ;
241- this . overridesProvider =
242- overridesProvider ?? new StorageOverridesProvider ( ) ;
243234
244235 if ( bootstrappedFlags ) {
245236 this . bootstrapped = true ;
246- // If bootstrapped flag overrides are provided, use and store them
247- if ( bootstrappedOverrides ) {
248- this . overridesInitialized = true ;
249- this . flagOverrides = bootstrappedOverrides ;
250- void this . overridesProvider . setOverrides ( this . flagOverrides ) ;
251- }
252237 this . setFetchedFlags ( bootstrappedFlags , false ) ;
253238 }
239+
240+ this . flagOverrides = this . getOverridesCache ( ) ;
254241 }
255242
256243 async initialize ( ) {
@@ -260,28 +247,10 @@ export class FlagsClient {
260247 }
261248 this . initialized = true ;
262249
263- const requests = [ ] ;
264-
265- if ( ! this . overridesInitialized ) {
266- this . overridesInitialized = true ;
267- requests . push (
268- this . overridesProvider . getOverrides ( ) . then ( ( overrides ) => {
269- this . flagOverrides = overrides ;
270- } ) ,
271- ) ;
272- }
273-
274250 if ( ! this . bootstrapped ) {
275- requests . push (
276- this . maybeFetchFlags ( ) . then ( ( flags ) => {
277- this . setFetchedFlags ( flags || { } ) ;
278- } ) ,
279- ) ;
251+ this . setFetchedFlags ( ( await this . maybeFetchFlags ( ) ) || { } ) ;
280252 }
281253
282- // Run all requests in parallel
283- await Promise . all ( requests ) ;
284-
285254 // Apply overrides and trigger update if flags have changed
286255 this . updateFlags ( ) ;
287256 }
@@ -320,22 +289,19 @@ export class FlagsClient {
320289 if ( triggerEvent ) this . triggerFlagsUpdated ( ) ;
321290 }
322291
323- async setFlagOverride ( key : string , isEnabled : boolean | null ) {
292+ setFlagOverride ( key : string , isEnabled : boolean | null ) {
324293 if ( ! ( typeof isEnabled === "boolean" || isEnabled === null ) ) {
325294 throw new Error ( "setFlagOverride: isEnabled must be boolean or null" ) ;
326295 }
327296
328297 if ( isEnabled === null ) {
329- const actualValue = ! this . flagOverrides [ key ] ;
330298 delete this . flagOverrides [ key ] ;
331- this . fetchedFlags [ key ] . isEnabled = actualValue ;
332- this . fetchedFlags [ key ] . isEnabledOverride = null ;
333299 } else {
334300 this . flagOverrides [ key ] = isEnabled ;
335301 }
302+ this . setOverridesCache ( this . flagOverrides ) ;
336303
337304 this . updateFlags ( ) ;
338- await this . overridesProvider . setOverrides ( this . flagOverrides ) ;
339305 }
340306
341307 getFlagOverride ( key : string ) : boolean | null {
@@ -432,6 +398,34 @@ export class FlagsClient {
432398 }
433399 }
434400
401+ private setOverridesCache ( overrides : FlagOverrides ) {
402+ if ( IS_SERVER ) return ;
403+ try {
404+ localStorage . setItem ( storageOverridesKey , JSON . stringify ( overrides ) ) ;
405+ } catch ( error ) {
406+ this . logger . warn (
407+ "storing flag overrides in localStorage failed, overrides won't persist" ,
408+ error ,
409+ ) ;
410+ }
411+ }
412+
413+ private getOverridesCache ( ) : FlagOverrides {
414+ if ( IS_SERVER ) return { } ;
415+ try {
416+ const overridesStored = localStorage . getItem ( storageOverridesKey ) ;
417+ const overrides = JSON . parse ( overridesStored || "{}" ) ;
418+ if ( ! isObject ( overrides ) ) throw new Error ( "invalid overrides" ) ;
419+ return overrides ;
420+ } catch ( error ) {
421+ this . logger . warn (
422+ "getting flag overrides from localStorage failed" ,
423+ error ,
424+ ) ;
425+ return { } ;
426+ }
427+ }
428+
435429 private async maybeFetchFlags ( ) : Promise < RawFlags | undefined > {
436430 if ( this . config . offline ) {
437431 return ;
@@ -513,17 +507,16 @@ export class FlagsClient {
513507
514508 private setupCache ( staleTimeMs = 0 , expireTimeMs = FLAGS_EXPIRE_MS ) {
515509 return new FlagCache ( {
516- storage :
517- typeof localStorage !== "undefined"
518- ? {
519- get : ( ) => localStorage . getItem ( localStorageFetchedFlagsKey ) ,
520- set : ( value ) =>
521- localStorage . setItem ( localStorageFetchedFlagsKey , value ) ,
522- }
523- : {
524- get : ( ) => null ,
525- set : ( ) => void 0 ,
526- } ,
510+ storage : ! IS_SERVER
511+ ? {
512+ get : ( ) => localStorage . getItem ( localStorageFetchedFlagsKey ) ,
513+ set : ( value ) =>
514+ localStorage . setItem ( localStorageFetchedFlagsKey , value ) ,
515+ }
516+ : {
517+ get : ( ) => null ,
518+ set : ( ) => void 0 ,
519+ } ,
527520 staleTimeMs,
528521 expireTimeMs,
529522 } ) ;
0 commit comments