diff --git a/packages/remote-feature-flag-controller/src/remote-feature-flag-controller.test.ts b/packages/remote-feature-flag-controller/src/remote-feature-flag-controller.test.ts index 4c78be8f93e..84e1e224a40 100644 --- a/packages/remote-feature-flag-controller/src/remote-feature-flag-controller.test.ts +++ b/packages/remote-feature-flag-controller/src/remote-feature-flag-controller.test.ts @@ -59,7 +59,7 @@ function createController( state: Partial; clientConfigApiService: AbstractClientConfigApiService; disabled: boolean; - metaMetricsId: string; + getMetaMetricsId: Promise; }> = {}, ) { return new RemoteFeatureFlagController({ @@ -68,7 +68,7 @@ function createController( clientConfigApiService: options.clientConfigApiService ?? buildClientConfigApiService(), disabled: options.disabled, - metaMetricsId: options.metaMetricsId, + getMetaMetricsId: options.getMetaMetricsId, }); } @@ -271,7 +271,7 @@ describe('RemoteFeatureFlagController', () => { }); const controller = createController({ clientConfigApiService, - metaMetricsId: MOCK_METRICS_ID, + getMetaMetricsId: Promise.resolve(MOCK_METRICS_ID), }); await controller.updateRemoteFeatureFlags(); @@ -289,7 +289,7 @@ describe('RemoteFeatureFlagController', () => { }); const controller = createController({ clientConfigApiService, - metaMetricsId: MOCK_METRICS_ID, + getMetaMetricsId: Promise.resolve(MOCK_METRICS_ID), }); await controller.updateRemoteFeatureFlags(); diff --git a/packages/remote-feature-flag-controller/src/remote-feature-flag-controller.ts b/packages/remote-feature-flag-controller/src/remote-feature-flag-controller.ts index 37c8d64c58d..81f78f5afae 100644 --- a/packages/remote-feature-flag-controller/src/remote-feature-flag-controller.ts +++ b/packages/remote-feature-flag-controller/src/remote-feature-flag-controller.ts @@ -103,7 +103,7 @@ export class RemoteFeatureFlagController extends BaseController< #inProgressFlagUpdate?: Promise; - #metaMetricsId?: string | undefined; + #getMetaMetricsId?: Promise; /** * Constructs a new RemoteFeatureFlagController instance. @@ -114,7 +114,7 @@ export class RemoteFeatureFlagController extends BaseController< * @param options.clientConfigApiService - The service instance to fetch remote feature flags. * @param options.fetchInterval - The interval in milliseconds before cached flags expire. Defaults to 1 day. * @param options.disabled - Determines if the controller should be disabled initially. Defaults to false. - * @param options.metaMetricsId - Determines the threshold value for the feature flag to return + * @param options.getMetaMetricsId - Promise that resolves to a metaMetricsId. */ constructor({ messenger, @@ -122,12 +122,12 @@ export class RemoteFeatureFlagController extends BaseController< clientConfigApiService, fetchInterval = DEFAULT_CACHE_DURATION, disabled = false, - metaMetricsId, + getMetaMetricsId, }: { messenger: RemoteFeatureFlagControllerMessenger; state?: Partial; clientConfigApiService: AbstractClientConfigApiService; - metaMetricsId?: string | undefined; + getMetaMetricsId?: Promise; fetchInterval?: number; disabled?: boolean; }) { @@ -144,7 +144,7 @@ export class RemoteFeatureFlagController extends BaseController< this.#fetchInterval = fetchInterval; this.#disabled = disabled; this.#clientConfigApiService = clientConfigApiService; - this.#metaMetricsId = metaMetricsId; + this.#getMetaMetricsId = getMetaMetricsId; } /** @@ -184,7 +184,7 @@ export class RemoteFeatureFlagController extends BaseController< this.#inProgressFlagUpdate = undefined; } - this.#updateCache(serverData.remoteFeatureFlags); + await this.#updateCache(serverData.remoteFeatureFlags); } /** @@ -193,9 +193,10 @@ export class RemoteFeatureFlagController extends BaseController< * @param remoteFeatureFlags - The new feature flags to cache. * @private */ - #updateCache(remoteFeatureFlags: FeatureFlags) { - const processedRemoteFeatureFlags = - this.#processRemoteFeatureFlags(remoteFeatureFlags); + async #updateCache(remoteFeatureFlags: FeatureFlags) { + const processedRemoteFeatureFlags = await this.#processRemoteFeatureFlags( + remoteFeatureFlags, + ); this.update(() => { return { remoteFeatureFlags: processedRemoteFeatureFlags, @@ -204,17 +205,20 @@ export class RemoteFeatureFlagController extends BaseController< }); } - #processRemoteFeatureFlags(remoteFeatureFlags: FeatureFlags): FeatureFlags { + async #processRemoteFeatureFlags( + remoteFeatureFlags: FeatureFlags, + ): Promise { const processedRemoteFeatureFlags: FeatureFlags = {}; - const thresholdValue = generateDeterministicRandomNumber( - this.#metaMetricsId || generateFallbackMetaMetricsId(), - ); + const metaMetricsId = + (await this.#getMetaMetricsId) || generateFallbackMetaMetricsId(); + const thresholdValue = generateDeterministicRandomNumber(metaMetricsId); for (const [ remoteFeatureFlagName, remoteFeatureFlagValue, ] of Object.entries(remoteFeatureFlags)) { let processedValue = remoteFeatureFlagValue; + if (Array.isArray(remoteFeatureFlagValue) && thresholdValue) { const selectedGroup = remoteFeatureFlagValue.find( (featureFlag): featureFlag is FeatureFlagScopeValue => { @@ -235,7 +239,6 @@ export class RemoteFeatureFlagController extends BaseController< processedRemoteFeatureFlags[remoteFeatureFlagName] = processedValue; } - return processedRemoteFeatureFlags; }