From 779543dbaa00d2d2a6f7e5d5eabee1176c8b2404 Mon Sep 17 00:00:00 2001 From: Salah-Eddine Saakoun Date: Tue, 9 Sep 2025 12:25:22 +0200 Subject: [PATCH 1/2] refactor: migrate RemoteFeatureFlagController to @metamask/messenger --- .../CHANGELOG.md | 2 + .../package.json | 1 + .../remote-feature-flag-controller-types.ts | 2 +- .../remote-feature-flag-controller.test.ts | 63 ++++++++++++------- .../src/remote-feature-flag-controller.ts | 42 ++++--------- .../tsconfig.build.json | 5 +- .../tsconfig.json | 2 +- yarn.lock | 1 + 8 files changed, 64 insertions(+), 54 deletions(-) diff --git a/packages/remote-feature-flag-controller/CHANGELOG.md b/packages/remote-feature-flag-controller/CHANGELOG.md index 622fe02d3d3..de456d30d1b 100644 --- a/packages/remote-feature-flag-controller/CHANGELOG.md +++ b/packages/remote-feature-flag-controller/CHANGELOG.md @@ -13,6 +13,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed +- **BREAKING:** Use new `Messenger` from `@metamask/messenger` ([#6502](https://github.com/MetaMask/core/pull/6502)) + - Previously, `RemoteFeatureFlagController` accepted a `RestrictedMessenger` instance from `@metamask/base-controller`. - Bump `@metamask/utils` from `^11.4.2` to `^11.8.1` ([#6588](https://github.com/MetaMask/core/pull/6588), [#6708](https://github.com/MetaMask/core/pull/6708)) - Bump `@metamask/base-controller` from `^8.0.1` to `^8.4.0` ([#6284](https://github.com/MetaMask/core/pull/6284), [#6355](https://github.com/MetaMask/core/pull/6355), [#6465](https://github.com/MetaMask/core/pull/6465), [#6632](https://github.com/MetaMask/core/pull/6632)) - Bump `@metamask/controller-utils` from `^11.11.0` to `^11.14.0` ([#6303](https://github.com/MetaMask/core/pull/6303), [#6620](https://github.com/MetaMask/core/pull/6620), [#6629](https://github.com/MetaMask/core/pull/6629)) diff --git a/packages/remote-feature-flag-controller/package.json b/packages/remote-feature-flag-controller/package.json index 501ee03ffa5..1d77536cddb 100644 --- a/packages/remote-feature-flag-controller/package.json +++ b/packages/remote-feature-flag-controller/package.json @@ -49,6 +49,7 @@ "dependencies": { "@metamask/base-controller": "^8.4.0", "@metamask/controller-utils": "^11.14.0", + "@metamask/messenger": "^0.3.0", "@metamask/utils": "^11.8.1", "uuid": "^8.3.2" }, diff --git a/packages/remote-feature-flag-controller/src/remote-feature-flag-controller-types.ts b/packages/remote-feature-flag-controller/src/remote-feature-flag-controller-types.ts index 56fed8f1e8e..fe2b75f59df 100644 --- a/packages/remote-feature-flag-controller/src/remote-feature-flag-controller-types.ts +++ b/packages/remote-feature-flag-controller/src/remote-feature-flag-controller-types.ts @@ -1,4 +1,4 @@ -import type { ControllerGetStateAction } from '@metamask/base-controller'; +import type { ControllerGetStateAction } from '@metamask/base-controller/next'; import type { Json } from '@metamask/utils'; // Define accepted values for client, distribution, and environment 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 5cd5daa1aca..ae390caed34 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 @@ -1,19 +1,25 @@ -import { Messenger, deriveStateFromMetadata } from '@metamask/base-controller'; +import { deriveStateFromMetadata } from '@metamask/base-controller/next'; +import { + Messenger, + MOCK_ANY_NAMESPACE, + type MessengerActions, + type MessengerEvents, + type MockAnyNamespace, +} from '@metamask/messenger'; import type { AbstractClientConfigApiService } from './client-config-api-service/abstract-client-config-api-service'; import { RemoteFeatureFlagController, - controllerName, DEFAULT_CACHE_DURATION, getDefaultRemoteFeatureFlagControllerState, } from './remote-feature-flag-controller'; +import type { RemoteFeatureFlagControllerMessenger } from './remote-feature-flag-controller'; import type { - RemoteFeatureFlagControllerActions, - RemoteFeatureFlagControllerMessenger, + FeatureFlags, RemoteFeatureFlagControllerState, - RemoteFeatureFlagControllerStateChangeEvent, -} from './remote-feature-flag-controller'; -import type { FeatureFlags } from './remote-feature-flag-controller-types'; +} from './remote-feature-flag-controller-types'; + +const controllerName = 'RemoteFeatureFlagController'; const MOCK_FLAGS: FeatureFlags = { feature1: true, @@ -350,7 +356,7 @@ describe('RemoteFeatureFlagController', () => { deriveStateFromMetadata( controller.state, controller.metadata, - 'anonymous', + 'includeInDebugSnapshot', ), ).toMatchInlineSnapshot(` Object { @@ -412,31 +418,44 @@ describe('RemoteFeatureFlagController', () => { }); }); -type RootAction = RemoteFeatureFlagControllerActions; -type RootEvent = RemoteFeatureFlagControllerStateChangeEvent; +type AllRemoteFeatureFlagControllerActions = + MessengerActions; + +type AllRemoteFeatureFlagControllerEvents = + MessengerEvents; + +type RootMessenger = Messenger< + MockAnyNamespace, + AllRemoteFeatureFlagControllerActions, + AllRemoteFeatureFlagControllerEvents +>; /** * Creates and returns a root messenger for testing * * @returns A messenger instance */ -function getRootMessenger(): Messenger { - return new Messenger(); +function getRootMessenger(): RootMessenger { + return new Messenger({ + namespace: MOCK_ANY_NAMESPACE, + }); } /** - * Creates a restricted messenger for testing + * Creates a messenger for the RemoteFeatureFlagController * - * @param rootMessenger - The root messenger to restrict - * @returns A restricted messenger instance + * @returns A messenger instance */ -function getMessenger( - rootMessenger = getRootMessenger(), -): RemoteFeatureFlagControllerMessenger { - return rootMessenger.getRestricted({ - name: controllerName, - allowedActions: [], - allowedEvents: [], +function getMessenger(): RemoteFeatureFlagControllerMessenger { + const rootMessenger = getRootMessenger(); + return new Messenger< + typeof controllerName, + AllRemoteFeatureFlagControllerActions, + AllRemoteFeatureFlagControllerEvents, + RootMessenger + >({ + namespace: controllerName, + parent: rootMessenger, }); } 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 640d5cac700..30e004d81e4 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 @@ -1,15 +1,16 @@ -import type { - ControllerGetStateAction, - ControllerStateChangeEvent, - RestrictedMessenger, -} from '@metamask/base-controller'; -import { BaseController } from '@metamask/base-controller'; +import { + BaseController, + type ControllerStateChangeEvent, +} from '@metamask/base-controller/next'; +import type { Messenger } from '@metamask/messenger'; import type { AbstractClientConfigApiService } from './client-config-api-service/abstract-client-config-api-service'; import type { FeatureFlags, ServiceResponse, FeatureFlagScopeValue, + RemoteFeatureFlagControllerState, + RemoteFeatureFlagControllerGetStateAction, } from './remote-feature-flag-controller-types'; import { generateDeterministicRandomNumber, @@ -18,39 +19,28 @@ import { // === GENERAL === -export const controllerName = 'RemoteFeatureFlagController'; +const controllerName = 'RemoteFeatureFlagController'; export const DEFAULT_CACHE_DURATION = 24 * 60 * 60 * 1000; // 1 day // === STATE === -export type RemoteFeatureFlagControllerState = { - remoteFeatureFlags: FeatureFlags; - cacheTimestamp: number; -}; - const remoteFeatureFlagControllerMetadata = { remoteFeatureFlags: { includeInStateLogs: true, persist: true, - anonymous: true, + includeInDebugSnapshot: true, usedInUi: true, }, cacheTimestamp: { includeInStateLogs: true, persist: true, - anonymous: true, + includeInDebugSnapshot: true, usedInUi: false, }, }; // === MESSENGER === -export type RemoteFeatureFlagControllerGetStateAction = - ControllerGetStateAction< - typeof controllerName, - RemoteFeatureFlagControllerState - >; - export type RemoteFeatureFlagControllerGetRemoteFeatureFlagAction = { type: `${typeof controllerName}:updateRemoteFeatureFlags`; handler: RemoteFeatureFlagController['updateRemoteFeatureFlags']; @@ -59,8 +49,6 @@ export type RemoteFeatureFlagControllerGetRemoteFeatureFlagAction = { export type RemoteFeatureFlagControllerActions = RemoteFeatureFlagControllerGetStateAction; -export type AllowedActions = never; - export type RemoteFeatureFlagControllerStateChangeEvent = ControllerStateChangeEvent< typeof controllerName, @@ -70,14 +58,10 @@ export type RemoteFeatureFlagControllerStateChangeEvent = export type RemoteFeatureFlagControllerEvents = RemoteFeatureFlagControllerStateChangeEvent; -export type AllowedEvents = never; - -export type RemoteFeatureFlagControllerMessenger = RestrictedMessenger< +export type RemoteFeatureFlagControllerMessenger = Messenger< typeof controllerName, - RemoteFeatureFlagControllerActions | AllowedActions, - RemoteFeatureFlagControllerEvents | AllowedEvents, - AllowedActions['type'], - AllowedEvents['type'] + RemoteFeatureFlagControllerActions, + RemoteFeatureFlagControllerEvents >; /** diff --git a/packages/remote-feature-flag-controller/tsconfig.build.json b/packages/remote-feature-flag-controller/tsconfig.build.json index e5fd7422b9a..931c4d6594b 100644 --- a/packages/remote-feature-flag-controller/tsconfig.build.json +++ b/packages/remote-feature-flag-controller/tsconfig.build.json @@ -5,6 +5,9 @@ "outDir": "./dist", "rootDir": "./src" }, - "references": [{ "path": "../base-controller/tsconfig.build.json" }], + "references": [ + { "path": "../base-controller/tsconfig.build.json" }, + { "path": "../messenger/tsconfig.build.json" } + ], "include": ["../../types", "./src"] } diff --git a/packages/remote-feature-flag-controller/tsconfig.json b/packages/remote-feature-flag-controller/tsconfig.json index 831cc7b8670..68c3ddfc2cd 100644 --- a/packages/remote-feature-flag-controller/tsconfig.json +++ b/packages/remote-feature-flag-controller/tsconfig.json @@ -3,6 +3,6 @@ "compilerOptions": { "baseUrl": "./" }, - "references": [{ "path": "../../packages/base-controller" }], + "references": [{ "path": "../base-controller" }, { "path": "../messenger" }], "include": ["../../types", "./src"] } diff --git a/yarn.lock b/yarn.lock index 4c490b218f9..c1794641c8e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4378,6 +4378,7 @@ __metadata: "@metamask/auto-changelog": "npm:^3.4.4" "@metamask/base-controller": "npm:^8.4.0" "@metamask/controller-utils": "npm:^11.14.0" + "@metamask/messenger": "npm:^0.3.0" "@metamask/utils": "npm:^11.8.1" "@types/jest": "npm:^27.4.1" deepmerge: "npm:^4.2.2" From 07361124f31279f23efea7ccdb0024be37ab2d04 Mon Sep 17 00:00:00 2001 From: Salah-Eddine Saakoun Date: Wed, 15 Oct 2025 15:49:16 +0200 Subject: [PATCH 2/2] fix: unit tests move RemoteFeatureFlagControllerState --- .../src/remote-feature-flag-controller.test.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) 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 ae390caed34..e9a2439955b 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 @@ -13,11 +13,11 @@ import { DEFAULT_CACHE_DURATION, getDefaultRemoteFeatureFlagControllerState, } from './remote-feature-flag-controller'; -import type { RemoteFeatureFlagControllerMessenger } from './remote-feature-flag-controller'; import type { - FeatureFlags, + RemoteFeatureFlagControllerMessenger, RemoteFeatureFlagControllerState, -} from './remote-feature-flag-controller-types'; +} from './remote-feature-flag-controller'; +import type { FeatureFlags } from './remote-feature-flag-controller-types'; const controllerName = 'RemoteFeatureFlagController';