11import { EventEmitter } from 'node:events' ;
22import { UnleashEvents } from '../events' ;
3- import type {
4- ApiResponse ,
5- ClientFeaturesResponse ,
6- EnhancedFeatureInterface ,
7- FeatureInterface ,
3+ import {
4+ type ApiResponse ,
5+ type ClientFeaturesResponse ,
6+ type EnhancedFeatureInterface ,
7+ type FeatureInterface ,
8+ parseApiResponse ,
89} from '../feature' ;
910import type { CustomHeaders , CustomHeadersFunction } from '../headers' ;
1011import type { HttpOptions } from '../http-options' ;
@@ -232,47 +233,50 @@ export default class Repository extends EventEmitter implements EventEmitter {
232233 }
233234
234235 private applyFeatureResponse ( response : ApiResponse ) : void {
235- if ( 'events' in response ) {
236- response . events . forEach ( ( event ) => {
237- switch ( event . type ) {
238- case 'feature-updated' : {
239- this . data [ event . feature . name ] = event . feature ;
240- break ;
241- }
242- case 'feature-removed' : {
243- delete this . data [ event . featureName ] ;
244- break ;
245- }
246- case 'segment-updated' : {
247- this . segments . set ( event . segment . id , event . segment ) ;
248- break ;
249- }
250- case 'segment-removed' : {
251- this . segments . delete ( event . segmentId ) ;
252- break ;
253- }
254- case 'hydration' : {
255- this . data = this . convertToMap ( event . features ) ;
256- this . segments = this . createSegmentLookup ( event . segments ) ;
257- break ;
236+ switch ( response . type ) {
237+ case 'delta' : {
238+ response . events . forEach ( ( event ) => {
239+ switch ( event . type ) {
240+ case 'feature-updated' : {
241+ this . data [ event . feature . name ] = event . feature ;
242+ break ;
243+ }
244+ case 'feature-removed' : {
245+ delete this . data [ event . featureName ] ;
246+ break ;
247+ }
248+ case 'segment-updated' : {
249+ this . segments . set ( event . segment . id , event . segment ) ;
250+ break ;
251+ }
252+ case 'segment-removed' : {
253+ this . segments . delete ( event . segmentId ) ;
254+ break ;
255+ }
256+ case 'hydration' : {
257+ this . data = this . convertToMap ( event . features ) ;
258+ this . segments = this . createSegmentLookup ( event . segments ) ;
259+ break ;
260+ }
261+ default : {
262+ this . emit (
263+ UnleashEvents . Warn ,
264+ `Unknown event type received, this may or may not cause features to evaluate incorrectly: ${ JSON . stringify ( event ) } ` ,
265+ ) ;
266+ break ;
267+ }
258268 }
259- default : {
260- this . emit (
261- UnleashEvents . Warn ,
262- `Unknown event type received, this may or may not cause features to evaluate incorrectly: ${ JSON . stringify ( event ) } ` ,
263- ) ;
264- break ;
265- }
266- }
267- } ) ;
268- } else if ( 'features' in response ) {
269- this . data = this . convertToMap ( response . features ) ;
270- this . segments = this . createSegmentLookup ( response . segments ) ;
271- } else {
272- this . emit (
273- UnleashEvents . Warn ,
274- `Unknown response when applying feature response: ${ JSON . stringify ( response ) } ` ,
275- ) ;
269+ } ) ;
270+ break ;
271+ }
272+ case 'full' : {
273+ this . data = this . convertToMap ( response . features ) ;
274+ this . segments = this . createSegmentLookup ( response . segments ) ;
275+ break ;
276+ }
277+ default : {
278+ assertNever ( response ) ;
279+ }
276280 }
277281 }
278282
@@ -290,7 +294,7 @@ export default class Repository extends EventEmitter implements EventEmitter {
290294 }
291295
292296 if ( content && this . notEmpty ( content ) ) {
293- await this . save ( content , false ) ;
297+ await this . save ( parseApiResponse ( content ) , false ) ;
294298 }
295299 } catch ( err : unknown ) {
296300 const message = err instanceof Error ? err . message : 'Unknown error' ;
@@ -302,17 +306,16 @@ Message: ${message}`,
302306 }
303307 }
304308
305- private convertToMap ( features : FeatureInterface [ ] ) : FeatureToggleData {
306- const obj = ( features || [ ] ) . reduce (
307- ( o : { [ s : string ] : FeatureInterface } , feature : FeatureInterface ) => {
308- this . validateFeature ( feature ) ;
309- o [ feature . name ] = feature ;
310- return o ;
311- } ,
312- { } as { [ s : string ] : FeatureInterface } ,
313- ) ;
314-
315- return obj ;
309+ private convertToMap ( features : FeatureInterface [ ] | undefined | null ) : FeatureToggleData {
310+ const result : FeatureToggleData = { } ;
311+ if ( ! features ?. length ) return { } ;
312+
313+ for ( const feature of features ) {
314+ this . validateFeature ( feature ) ;
315+ result [ feature . name ] = feature ;
316+ }
317+
318+ return result ;
316319 }
317320
318321 stop ( ) {
@@ -373,3 +376,7 @@ Message: ${message}`,
373376 } ) ;
374377 } ;
375378}
379+
380+ const assertNever = ( value : never ) : never => {
381+ throw new Error ( `Unexpected value: ${ JSON . stringify ( value ) } ` ) ;
382+ } ;
0 commit comments