@metamask-previews/composable-controller 11.1.0-preview-1f64ffa6 → 11.1.0-preview-6fbb0db6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -9,13 +9,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
9
9
 
10
10
  ### Changed
11
11
 
12
- - **BREAKING:** Migrate `ComposableController` to new `Messenger` from `@metamask/messenger` ([#6710](https://github.com/MetaMask/core/pull/6710))
13
- - Previously, the controller accepted a `RestrictedMessenger` instance from `@metamask/base-controller`.
14
-
15
- ### Fixed
16
-
17
- - Resolve incompatibility of `ChildControllerStateChangeEvents` type with `BaseController` (when used in the `Events` type argument of `ComposableControllerMessenger`) by removing unnecessary nested logic from definition ([#6904](https://github.com/MetaMask/core/pull/6904))
18
- - Also update generic parameter names `ControllerName` and `ControllerState` to `ChildControllerName`, `ChildControllerState` for reduced ambiguity.
19
12
  - Bump `@metamask/base-controller` from `^8.4.1` to `^8.4.2` ([#6917](https://github.com/MetaMask/core/pull/6917))
20
13
 
21
14
  ## [11.1.0]
@@ -7,7 +7,7 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
7
7
  var _ComposableController_instances, _ComposableController_updateChildController;
8
8
  Object.defineProperty(exports, "__esModule", { value: true });
9
9
  exports.ComposableController = exports.INVALID_CONTROLLER_ERROR = exports.controllerName = void 0;
10
- const next_1 = require("@metamask/base-controller/next");
10
+ const base_controller_1 = require("@metamask/base-controller");
11
11
  exports.controllerName = 'ComposableController';
12
12
  exports.INVALID_CONTROLLER_ERROR = 'Invalid controller: controller must have a `messagingSystem` and inherit from `BaseController`.';
13
13
  /**
@@ -16,13 +16,13 @@ exports.INVALID_CONTROLLER_ERROR = 'Invalid controller: controller must have a `
16
16
  * @template ComposableControllerState - A type object containing the names and state types of the child controllers.
17
17
  * @template ChildControllersMap - A type object that specifies the child controllers which are used to instantiate the {@link ComposableController}.
18
18
  */
19
- class ComposableController extends next_1.BaseController {
19
+ class ComposableController extends base_controller_1.BaseController {
20
20
  /**
21
21
  * Creates a ComposableController instance.
22
22
  *
23
23
  * @param options - Initial options used to configure this controller
24
24
  * @param options.controllers - An object that contains child controllers keyed by their names.
25
- * @param options.messenger - A controller messenger.
25
+ * @param options.messenger - A restricted messenger.
26
26
  */
27
27
  constructor({ controllers, messenger, }) {
28
28
  if (messenger === undefined) {
@@ -35,7 +35,7 @@ class ComposableController extends next_1.BaseController {
35
35
  metadata[name] = {
36
36
  includeInStateLogs: false,
37
37
  persist: true,
38
- includeInDebugSnapshot: true,
38
+ anonymous: true,
39
39
  usedInUi: false,
40
40
  };
41
41
  return metadata;
@@ -64,11 +64,16 @@ _ComposableController_instances = new WeakSet(), _ComposableController_updateChi
64
64
  delete this.state[name];
65
65
  // eslint-disable-next-line no-empty
66
66
  }
67
- catch { }
67
+ catch (_) { }
68
+ // False negative. `name` is a string type.
69
+ // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
68
70
  throw new Error(`${name} - ${exports.INVALID_CONTROLLER_ERROR}`);
69
71
  }
70
72
  try {
71
- this.messenger.subscribe(`${name}:stateChange`, (childState) => {
73
+ this.messagingSystem.subscribe(
74
+ // False negative. `name` is a string type.
75
+ // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
76
+ `${name}:stateChange`, (childState) => {
72
77
  this.update((state) => {
73
78
  // Type assertion is necessary for property assignment to a generic type. This does not pollute or widen the type of the asserted variable.
74
79
  // @ts-expect-error "Type instantiation is excessively deep"
@@ -1 +1 @@
1
- {"version":3,"file":"ComposableController.cjs","sourceRoot":"","sources":["../src/ComposableController.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n StateConstraint,\n StateMetadata,\n StateMetadataConstraint,\n ControllerStateChangeEvent,\n ControllerGetStateAction,\n BaseControllerInstance as ControllerInstance,\n} from '@metamask/base-controller/next';\nimport { BaseController } from '@metamask/base-controller/next';\nimport type { Messenger } from '@metamask/messenger';\n\nexport const controllerName = 'ComposableController';\n\nexport const INVALID_CONTROLLER_ERROR =\n 'Invalid controller: controller must have a `messagingSystem` and inherit from `BaseController`.';\n\n/**\n * The narrowest supertype for the composable controller state object.\n */\nexport type ComposableControllerStateConstraint = {\n [controllerName: string]: StateConstraint;\n};\n\n/**\n * The `getState` action type for the {@link ComposableControllerMessenger}.\n *\n * @template ComposableControllerState - A type object that maps controller names to their state types.\n */\nexport type ComposableControllerGetStateAction<\n ComposableControllerState extends ComposableControllerStateConstraint,\n> = ControllerGetStateAction<typeof controllerName, ComposableControllerState>;\n\n/**\n * The `stateChange` event type for the {@link ComposableControllerMessenger}.\n *\n * @template ComposableControllerState - A type object that maps controller names to their state types.\n */\nexport type ComposableControllerStateChangeEvent<\n ComposableControllerState extends ComposableControllerStateConstraint,\n> = ControllerStateChangeEvent<\n typeof controllerName,\n ComposableControllerState\n>;\n\n/**\n * A union type of internal event types available to the {@link ComposableControllerMessenger}.\n *\n * @template ComposableControllerState - A type object that maps controller names to their state types.\n */\nexport type ComposableControllerEvents<\n ComposableControllerState extends ComposableControllerStateConstraint,\n> = ComposableControllerStateChangeEvent<ComposableControllerState>;\n\n/**\n * A union type of action types available to the {@link ComposableControllerMessenger}.\n *\n * @template ComposableControllerState - A type object that maps controller names to their state types.\n */\nexport type ComposableControllerActions<\n ComposableControllerState extends ComposableControllerStateConstraint,\n> = ComposableControllerGetStateAction<ComposableControllerState>;\n\n/**\n * A utility type that extracts controllers from the {@link ComposableControllerState} type,\n * and derives a union type of all of their corresponding `stateChange` events.\n *\n * @template ComposableControllerState - A type object that maps controller names to their state types.\n */\nexport type ChildControllerStateChangeEvents<\n ComposableControllerState extends ComposableControllerStateConstraint,\n> =\n ComposableControllerState extends Record<\n infer ChildControllerName extends string,\n infer ChildControllerState extends StateConstraint\n >\n ? ControllerStateChangeEvent<ChildControllerName, ChildControllerState>\n : never;\n\n/**\n * A union type of external event types available to the {@link ComposableControllerMessenger}.\n *\n * @template ComposableControllerState - A type object that maps controller names to their state types.\n */\nexport type AllowedEvents<\n ComposableControllerState extends ComposableControllerStateConstraint,\n> = ChildControllerStateChangeEvents<ComposableControllerState>;\n\n/**\n * The messenger of the {@link ComposableController}.\n *\n * @template ComposableControllerState - A type object that maps controller names to their state types.\n */\nexport type ComposableControllerMessenger<\n ComposableControllerState extends ComposableControllerStateConstraint,\n> = Messenger<\n typeof controllerName,\n ComposableControllerActions<ComposableControllerState>,\n | ComposableControllerEvents<ComposableControllerState>\n | AllowedEvents<ComposableControllerState>\n>;\n\n/**\n * Controller that composes multiple child controllers and maintains up-to-date composed state.\n *\n * @template ComposableControllerState - A type object containing the names and state types of the child controllers.\n * @template ChildControllersMap - A type object that specifies the child controllers which are used to instantiate the {@link ComposableController}.\n */\nexport class ComposableController<\n ComposableControllerState extends ComposableControllerStateConstraint,\n ChildControllersMap extends Record<\n keyof ComposableControllerState,\n ControllerInstance\n >,\n> extends BaseController<\n typeof controllerName,\n ComposableControllerState,\n ComposableControllerMessenger<ComposableControllerState>\n> {\n /**\n * Creates a ComposableController instance.\n *\n * @param options - Initial options used to configure this controller\n * @param options.controllers - An object that contains child controllers keyed by their names.\n * @param options.messenger - A controller messenger.\n */\n constructor({\n controllers,\n messenger,\n }: {\n controllers: ChildControllersMap;\n messenger: ComposableControllerMessenger<ComposableControllerState>;\n }) {\n if (messenger === undefined) {\n throw new Error(`Messaging system is required`);\n }\n\n super({\n name: controllerName,\n // This reduce operation intentionally reuses its output object. This provides a significant performance benefit over returning a new object on each iteration.\n metadata: Object.keys(controllers).reduce<\n StateMetadata<ComposableControllerState>\n >((metadata, name) => {\n (metadata as StateMetadataConstraint)[name] = {\n includeInStateLogs: false,\n persist: true,\n includeInDebugSnapshot: true,\n usedInUi: false,\n };\n return metadata;\n }, {} as never),\n // This reduce operation intentionally reuses its output object. This provides a significant performance benefit over returning a new object on each iteration.\n state: Object.values(controllers).reduce<ComposableControllerState>(\n (state, controller) => {\n // Type assertion is necessary for property assignment to a generic type. This does not pollute or widen the type of the asserted variable.\n (state as ComposableControllerStateConstraint)[controller.name] =\n controller.state;\n return state;\n },\n {} as never,\n ),\n messenger,\n });\n\n Object.values(controllers).forEach((controller) => {\n this.#updateChildController(controller);\n });\n }\n\n /**\n * Constructor helper that subscribes to child controller state changes.\n *\n * @param controller - Controller instance to update\n */\n #updateChildController(controller: ControllerInstance): void {\n const { name } = controller;\n if (!isBaseController(controller)) {\n try {\n delete this.metadata[name];\n delete this.state[name];\n // eslint-disable-next-line no-empty\n } catch {}\n throw new Error(`${name} - ${INVALID_CONTROLLER_ERROR}`);\n }\n try {\n this.messenger.subscribe<\n // The type intersection with \"ComposableController:stateChange\" is added by one of the `Messenger.subscribe` overloads, but that constraint is unnecessary here,\n // since this method only subscribes the messenger to child controller `stateChange` events.\n // @ts-expect-error \"Type '`${string}:stateChange`' is not assignable to parameter of type '\"ComposableController:stateChange\" & ChildControllerStateChangeEvents<ComposableControllerState>[\"type\"]'.\"\n ChildControllerStateChangeEvents<ComposableControllerState>['type']\n >(`${name}:stateChange`, (childState: StateConstraint) => {\n this.update((state) => {\n // Type assertion is necessary for property assignment to a generic type. This does not pollute or widen the type of the asserted variable.\n // @ts-expect-error \"Type instantiation is excessively deep\"\n (state as ComposableControllerStateConstraint)[name] = childState;\n });\n });\n } catch (error: unknown) {\n // False negative. `name` is a string type.\n // eslint-disable-next-line @typescript-eslint/restrict-template-expressions\n console.error(`${name} - ${String(error)}`);\n }\n }\n}\n\n/**\n * Determines if the given controller is an instance of `BaseController`\n *\n * @param controller - Controller instance to check\n * @returns True if the controller is an instance of `BaseController`\n */\nfunction isBaseController(\n controller: unknown,\n): controller is ControllerInstance {\n return (\n typeof controller === 'object' &&\n controller !== null &&\n 'name' in controller &&\n typeof controller.name === 'string' &&\n 'state' in controller &&\n typeof controller.state === 'object' &&\n 'metadata' in controller &&\n typeof controller.metadata === 'object'\n );\n}\n\nexport default ComposableController;\n"]}
1
+ {"version":3,"file":"ComposableController.cjs","sourceRoot":"","sources":["../src/ComposableController.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n RestrictedMessenger,\n StateConstraint,\n StateMetadata,\n StateMetadataConstraint,\n ControllerStateChangeEvent,\n BaseControllerInstance as ControllerInstance,\n} from '@metamask/base-controller';\nimport { BaseController } from '@metamask/base-controller';\n\nexport const controllerName = 'ComposableController';\n\nexport const INVALID_CONTROLLER_ERROR =\n 'Invalid controller: controller must have a `messagingSystem` and inherit from `BaseController`.';\n\n/**\n * The narrowest supertype for the composable controller state object.\n */\nexport type ComposableControllerStateConstraint = {\n [controllerName: string]: StateConstraint;\n};\n\n/**\n * The `stateChange` event type for the {@link ComposableControllerMessenger}.\n *\n * @template ComposableControllerState - A type object that maps controller names to their state types.\n */\nexport type ComposableControllerStateChangeEvent<\n ComposableControllerState extends ComposableControllerStateConstraint,\n> = ControllerStateChangeEvent<\n typeof controllerName,\n ComposableControllerState\n>;\n\n/**\n * A union type of internal event types available to the {@link ComposableControllerMessenger}.\n *\n * @template ComposableControllerState - A type object that maps controller names to their state types.\n */\nexport type ComposableControllerEvents<\n ComposableControllerState extends ComposableControllerStateConstraint,\n> = ComposableControllerStateChangeEvent<ComposableControllerState>;\n\n/**\n * A utility type that extracts controllers from the {@link ComposableControllerState} type,\n * and derives a union type of all of their corresponding `stateChange` events.\n *\n * @template ComposableControllerState - A type object that maps controller names to their state types.\n */\nexport type ChildControllerStateChangeEvents<\n ComposableControllerState extends ComposableControllerStateConstraint,\n> =\n ComposableControllerState extends Record<\n infer ControllerName extends string,\n infer ControllerState\n >\n ? ControllerState extends StateConstraint\n ? ControllerStateChangeEvent<ControllerName, ControllerState>\n : never\n : never;\n\n/**\n * A union type of external event types available to the {@link ComposableControllerMessenger}.\n *\n * @template ComposableControllerState - A type object that maps controller names to their state types.\n */\nexport type AllowedEvents<\n ComposableControllerState extends ComposableControllerStateConstraint,\n> = ChildControllerStateChangeEvents<ComposableControllerState>;\n\n/**\n * The messenger of the {@link ComposableController}.\n *\n * @template ComposableControllerState - A type object that maps controller names to their state types.\n */\nexport type ComposableControllerMessenger<\n ComposableControllerState extends ComposableControllerStateConstraint,\n> = RestrictedMessenger<\n typeof controllerName,\n never,\n | ComposableControllerEvents<ComposableControllerState>\n | AllowedEvents<ComposableControllerState>,\n never,\n AllowedEvents<ComposableControllerState>['type']\n>;\n\n/**\n * Controller that composes multiple child controllers and maintains up-to-date composed state.\n *\n * @template ComposableControllerState - A type object containing the names and state types of the child controllers.\n * @template ChildControllersMap - A type object that specifies the child controllers which are used to instantiate the {@link ComposableController}.\n */\nexport class ComposableController<\n ComposableControllerState extends ComposableControllerStateConstraint,\n ChildControllersMap extends Record<\n keyof ComposableControllerState,\n ControllerInstance\n >,\n> extends BaseController<\n typeof controllerName,\n ComposableControllerState,\n ComposableControllerMessenger<ComposableControllerState>\n> {\n /**\n * Creates a ComposableController instance.\n *\n * @param options - Initial options used to configure this controller\n * @param options.controllers - An object that contains child controllers keyed by their names.\n * @param options.messenger - A restricted messenger.\n */\n constructor({\n controllers,\n messenger,\n }: {\n controllers: ChildControllersMap;\n messenger: ComposableControllerMessenger<ComposableControllerState>;\n }) {\n if (messenger === undefined) {\n throw new Error(`Messaging system is required`);\n }\n\n super({\n name: controllerName,\n // This reduce operation intentionally reuses its output object. This provides a significant performance benefit over returning a new object on each iteration.\n metadata: Object.keys(controllers).reduce<\n StateMetadata<ComposableControllerState>\n >((metadata, name) => {\n (metadata as StateMetadataConstraint)[name] = {\n includeInStateLogs: false,\n persist: true,\n anonymous: true,\n usedInUi: false,\n };\n return metadata;\n }, {} as never),\n // This reduce operation intentionally reuses its output object. This provides a significant performance benefit over returning a new object on each iteration.\n state: Object.values(controllers).reduce<ComposableControllerState>(\n (state, controller) => {\n // Type assertion is necessary for property assignment to a generic type. This does not pollute or widen the type of the asserted variable.\n (state as ComposableControllerStateConstraint)[controller.name] =\n controller.state;\n return state;\n },\n {} as never,\n ),\n messenger,\n });\n\n Object.values(controllers).forEach((controller) => {\n this.#updateChildController(controller);\n });\n }\n\n /**\n * Constructor helper that subscribes to child controller state changes.\n *\n * @param controller - Controller instance to update\n */\n #updateChildController(controller: ControllerInstance): void {\n const { name } = controller;\n if (!isBaseController(controller)) {\n try {\n delete this.metadata[name];\n delete this.state[name];\n // eslint-disable-next-line no-empty\n } catch (_) {}\n // False negative. `name` is a string type.\n // eslint-disable-next-line @typescript-eslint/restrict-template-expressions\n throw new Error(`${name} - ${INVALID_CONTROLLER_ERROR}`);\n }\n try {\n this.messagingSystem.subscribe(\n // False negative. `name` is a string type.\n // eslint-disable-next-line @typescript-eslint/restrict-template-expressions\n `${name}:stateChange`,\n (childState: StateConstraint) => {\n this.update((state) => {\n // Type assertion is necessary for property assignment to a generic type. This does not pollute or widen the type of the asserted variable.\n // @ts-expect-error \"Type instantiation is excessively deep\"\n (state as ComposableControllerStateConstraint)[name] = childState;\n });\n },\n );\n } catch (error: unknown) {\n // False negative. `name` is a string type.\n // eslint-disable-next-line @typescript-eslint/restrict-template-expressions\n console.error(`${name} - ${String(error)}`);\n }\n }\n}\n\n/**\n * Determines if the given controller is an instance of `BaseController`\n *\n * @param controller - Controller instance to check\n * @returns True if the controller is an instance of `BaseController`\n */\nfunction isBaseController(\n controller: unknown,\n): controller is ControllerInstance {\n return (\n typeof controller === 'object' &&\n controller !== null &&\n 'name' in controller &&\n typeof controller.name === 'string' &&\n 'state' in controller &&\n typeof controller.state === 'object' &&\n 'metadata' in controller &&\n typeof controller.metadata === 'object'\n );\n}\n\nexport default ComposableController;\n"]}
@@ -1,6 +1,5 @@
1
- import type { StateConstraint, ControllerStateChangeEvent, ControllerGetStateAction, BaseControllerInstance as ControllerInstance } from "@metamask/base-controller/next";
2
- import { BaseController } from "@metamask/base-controller/next";
3
- import type { Messenger } from "@metamask/messenger";
1
+ import type { RestrictedMessenger, StateConstraint, ControllerStateChangeEvent, BaseControllerInstance as ControllerInstance } from "@metamask/base-controller";
2
+ import { BaseController } from "@metamask/base-controller";
4
3
  export declare const controllerName = "ComposableController";
5
4
  export declare const INVALID_CONTROLLER_ERROR = "Invalid controller: controller must have a `messagingSystem` and inherit from `BaseController`.";
6
5
  /**
@@ -9,12 +8,6 @@ export declare const INVALID_CONTROLLER_ERROR = "Invalid controller: controller
9
8
  export type ComposableControllerStateConstraint = {
10
9
  [controllerName: string]: StateConstraint;
11
10
  };
12
- /**
13
- * The `getState` action type for the {@link ComposableControllerMessenger}.
14
- *
15
- * @template ComposableControllerState - A type object that maps controller names to their state types.
16
- */
17
- export type ComposableControllerGetStateAction<ComposableControllerState extends ComposableControllerStateConstraint> = ControllerGetStateAction<typeof controllerName, ComposableControllerState>;
18
11
  /**
19
12
  * The `stateChange` event type for the {@link ComposableControllerMessenger}.
20
13
  *
@@ -27,19 +20,13 @@ export type ComposableControllerStateChangeEvent<ComposableControllerState exten
27
20
  * @template ComposableControllerState - A type object that maps controller names to their state types.
28
21
  */
29
22
  export type ComposableControllerEvents<ComposableControllerState extends ComposableControllerStateConstraint> = ComposableControllerStateChangeEvent<ComposableControllerState>;
30
- /**
31
- * A union type of action types available to the {@link ComposableControllerMessenger}.
32
- *
33
- * @template ComposableControllerState - A type object that maps controller names to their state types.
34
- */
35
- export type ComposableControllerActions<ComposableControllerState extends ComposableControllerStateConstraint> = ComposableControllerGetStateAction<ComposableControllerState>;
36
23
  /**
37
24
  * A utility type that extracts controllers from the {@link ComposableControllerState} type,
38
25
  * and derives a union type of all of their corresponding `stateChange` events.
39
26
  *
40
27
  * @template ComposableControllerState - A type object that maps controller names to their state types.
41
28
  */
42
- export type ChildControllerStateChangeEvents<ComposableControllerState extends ComposableControllerStateConstraint> = ComposableControllerState extends Record<infer ChildControllerName extends string, infer ChildControllerState extends StateConstraint> ? ControllerStateChangeEvent<ChildControllerName, ChildControllerState> : never;
29
+ export type ChildControllerStateChangeEvents<ComposableControllerState extends ComposableControllerStateConstraint> = ComposableControllerState extends Record<infer ControllerName extends string, infer ControllerState> ? ControllerState extends StateConstraint ? ControllerStateChangeEvent<ControllerName, ControllerState> : never : never;
43
30
  /**
44
31
  * A union type of external event types available to the {@link ComposableControllerMessenger}.
45
32
  *
@@ -51,7 +38,7 @@ export type AllowedEvents<ComposableControllerState extends ComposableController
51
38
  *
52
39
  * @template ComposableControllerState - A type object that maps controller names to their state types.
53
40
  */
54
- export type ComposableControllerMessenger<ComposableControllerState extends ComposableControllerStateConstraint> = Messenger<typeof controllerName, ComposableControllerActions<ComposableControllerState>, ComposableControllerEvents<ComposableControllerState> | AllowedEvents<ComposableControllerState>>;
41
+ export type ComposableControllerMessenger<ComposableControllerState extends ComposableControllerStateConstraint> = RestrictedMessenger<typeof controllerName, never, ComposableControllerEvents<ComposableControllerState> | AllowedEvents<ComposableControllerState>, never, AllowedEvents<ComposableControllerState>['type']>;
55
42
  /**
56
43
  * Controller that composes multiple child controllers and maintains up-to-date composed state.
57
44
  *
@@ -65,7 +52,7 @@ export declare class ComposableController<ComposableControllerState extends Comp
65
52
  *
66
53
  * @param options - Initial options used to configure this controller
67
54
  * @param options.controllers - An object that contains child controllers keyed by their names.
68
- * @param options.messenger - A controller messenger.
55
+ * @param options.messenger - A restricted messenger.
69
56
  */
70
57
  constructor({ controllers, messenger, }: {
71
58
  controllers: ChildControllersMap;
@@ -1 +1 @@
1
- {"version":3,"file":"ComposableController.d.cts","sourceRoot":"","sources":["../src/ComposableController.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,eAAe,EAGf,0BAA0B,EAC1B,wBAAwB,EACxB,sBAAsB,IAAI,kBAAkB,EAC7C,uCAAuC;AACxC,OAAO,EAAE,cAAc,EAAE,uCAAuC;AAChE,OAAO,KAAK,EAAE,SAAS,EAAE,4BAA4B;AAErD,eAAO,MAAM,cAAc,yBAAyB,CAAC;AAErD,eAAO,MAAM,wBAAwB,oGAC8D,CAAC;AAEpG;;GAEG;AACH,MAAM,MAAM,mCAAmC,GAAG;IAChD,CAAC,cAAc,EAAE,MAAM,GAAG,eAAe,CAAC;CAC3C,CAAC;AAEF;;;;GAIG;AACH,MAAM,MAAM,kCAAkC,CAC5C,yBAAyB,SAAS,mCAAmC,IACnE,wBAAwB,CAAC,OAAO,cAAc,EAAE,yBAAyB,CAAC,CAAC;AAE/E;;;;GAIG;AACH,MAAM,MAAM,oCAAoC,CAC9C,yBAAyB,SAAS,mCAAmC,IACnE,0BAA0B,CAC5B,OAAO,cAAc,EACrB,yBAAyB,CAC1B,CAAC;AAEF;;;;GAIG;AACH,MAAM,MAAM,0BAA0B,CACpC,yBAAyB,SAAS,mCAAmC,IACnE,oCAAoC,CAAC,yBAAyB,CAAC,CAAC;AAEpE;;;;GAIG;AACH,MAAM,MAAM,2BAA2B,CACrC,yBAAyB,SAAS,mCAAmC,IACnE,kCAAkC,CAAC,yBAAyB,CAAC,CAAC;AAElE;;;;;GAKG;AACH,MAAM,MAAM,gCAAgC,CAC1C,yBAAyB,SAAS,mCAAmC,IAErE,yBAAyB,SAAS,MAAM,CACtC,MAAM,mBAAmB,SAAS,MAAM,EACxC,MAAM,oBAAoB,SAAS,eAAe,CACnD,GACG,0BAA0B,CAAC,mBAAmB,EAAE,oBAAoB,CAAC,GACrE,KAAK,CAAC;AAEZ;;;;GAIG;AACH,MAAM,MAAM,aAAa,CACvB,yBAAyB,SAAS,mCAAmC,IACnE,gCAAgC,CAAC,yBAAyB,CAAC,CAAC;AAEhE;;;;GAIG;AACH,MAAM,MAAM,6BAA6B,CACvC,yBAAyB,SAAS,mCAAmC,IACnE,SAAS,CACX,OAAO,cAAc,EACrB,2BAA2B,CAAC,yBAAyB,CAAC,EACpD,0BAA0B,CAAC,yBAAyB,CAAC,GACrD,aAAa,CAAC,yBAAyB,CAAC,CAC3C,CAAC;AAEF;;;;;GAKG;AACH,qBAAa,oBAAoB,CAC/B,yBAAyB,SAAS,mCAAmC,EACrE,mBAAmB,SAAS,MAAM,CAChC,MAAM,yBAAyB,EAC/B,kBAAkB,CACnB,CACD,SAAQ,cAAc,CACtB,OAAO,cAAc,EACrB,yBAAyB,EACzB,6BAA6B,CAAC,yBAAyB,CAAC,CACzD;;IACC;;;;;;OAMG;gBACS,EACV,WAAW,EACX,SAAS,GACV,EAAE;QACD,WAAW,EAAE,mBAAmB,CAAC;QACjC,SAAS,EAAE,6BAA6B,CAAC,yBAAyB,CAAC,CAAC;KACrE;CAuEF;AAuBD,eAAe,oBAAoB,CAAC"}
1
+ {"version":3,"file":"ComposableController.d.cts","sourceRoot":"","sources":["../src/ComposableController.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,mBAAmB,EACnB,eAAe,EAGf,0BAA0B,EAC1B,sBAAsB,IAAI,kBAAkB,EAC7C,kCAAkC;AACnC,OAAO,EAAE,cAAc,EAAE,kCAAkC;AAE3D,eAAO,MAAM,cAAc,yBAAyB,CAAC;AAErD,eAAO,MAAM,wBAAwB,oGAC8D,CAAC;AAEpG;;GAEG;AACH,MAAM,MAAM,mCAAmC,GAAG;IAChD,CAAC,cAAc,EAAE,MAAM,GAAG,eAAe,CAAC;CAC3C,CAAC;AAEF;;;;GAIG;AACH,MAAM,MAAM,oCAAoC,CAC9C,yBAAyB,SAAS,mCAAmC,IACnE,0BAA0B,CAC5B,OAAO,cAAc,EACrB,yBAAyB,CAC1B,CAAC;AAEF;;;;GAIG;AACH,MAAM,MAAM,0BAA0B,CACpC,yBAAyB,SAAS,mCAAmC,IACnE,oCAAoC,CAAC,yBAAyB,CAAC,CAAC;AAEpE;;;;;GAKG;AACH,MAAM,MAAM,gCAAgC,CAC1C,yBAAyB,SAAS,mCAAmC,IAErE,yBAAyB,SAAS,MAAM,CACtC,MAAM,cAAc,SAAS,MAAM,EACnC,MAAM,eAAe,CACtB,GACG,eAAe,SAAS,eAAe,GACrC,0BAA0B,CAAC,cAAc,EAAE,eAAe,CAAC,GAC3D,KAAK,GACP,KAAK,CAAC;AAEZ;;;;GAIG;AACH,MAAM,MAAM,aAAa,CACvB,yBAAyB,SAAS,mCAAmC,IACnE,gCAAgC,CAAC,yBAAyB,CAAC,CAAC;AAEhE;;;;GAIG;AACH,MAAM,MAAM,6BAA6B,CACvC,yBAAyB,SAAS,mCAAmC,IACnE,mBAAmB,CACrB,OAAO,cAAc,EACrB,KAAK,EACH,0BAA0B,CAAC,yBAAyB,CAAC,GACrD,aAAa,CAAC,yBAAyB,CAAC,EAC1C,KAAK,EACL,aAAa,CAAC,yBAAyB,CAAC,CAAC,MAAM,CAAC,CACjD,CAAC;AAEF;;;;;GAKG;AACH,qBAAa,oBAAoB,CAC/B,yBAAyB,SAAS,mCAAmC,EACrE,mBAAmB,SAAS,MAAM,CAChC,MAAM,yBAAyB,EAC/B,kBAAkB,CACnB,CACD,SAAQ,cAAc,CACtB,OAAO,cAAc,EACrB,yBAAyB,EACzB,6BAA6B,CAAC,yBAAyB,CAAC,CACzD;;IACC;;;;;;OAMG;gBACS,EACV,WAAW,EACX,SAAS,GACV,EAAE;QACD,WAAW,EAAE,mBAAmB,CAAC;QACjC,SAAS,EAAE,6BAA6B,CAAC,yBAAyB,CAAC,CAAC;KACrE;CAyEF;AAuBD,eAAe,oBAAoB,CAAC"}
@@ -1,6 +1,5 @@
1
- import type { StateConstraint, ControllerStateChangeEvent, ControllerGetStateAction, BaseControllerInstance as ControllerInstance } from "@metamask/base-controller/next";
2
- import { BaseController } from "@metamask/base-controller/next";
3
- import type { Messenger } from "@metamask/messenger";
1
+ import type { RestrictedMessenger, StateConstraint, ControllerStateChangeEvent, BaseControllerInstance as ControllerInstance } from "@metamask/base-controller";
2
+ import { BaseController } from "@metamask/base-controller";
4
3
  export declare const controllerName = "ComposableController";
5
4
  export declare const INVALID_CONTROLLER_ERROR = "Invalid controller: controller must have a `messagingSystem` and inherit from `BaseController`.";
6
5
  /**
@@ -9,12 +8,6 @@ export declare const INVALID_CONTROLLER_ERROR = "Invalid controller: controller
9
8
  export type ComposableControllerStateConstraint = {
10
9
  [controllerName: string]: StateConstraint;
11
10
  };
12
- /**
13
- * The `getState` action type for the {@link ComposableControllerMessenger}.
14
- *
15
- * @template ComposableControllerState - A type object that maps controller names to their state types.
16
- */
17
- export type ComposableControllerGetStateAction<ComposableControllerState extends ComposableControllerStateConstraint> = ControllerGetStateAction<typeof controllerName, ComposableControllerState>;
18
11
  /**
19
12
  * The `stateChange` event type for the {@link ComposableControllerMessenger}.
20
13
  *
@@ -27,19 +20,13 @@ export type ComposableControllerStateChangeEvent<ComposableControllerState exten
27
20
  * @template ComposableControllerState - A type object that maps controller names to their state types.
28
21
  */
29
22
  export type ComposableControllerEvents<ComposableControllerState extends ComposableControllerStateConstraint> = ComposableControllerStateChangeEvent<ComposableControllerState>;
30
- /**
31
- * A union type of action types available to the {@link ComposableControllerMessenger}.
32
- *
33
- * @template ComposableControllerState - A type object that maps controller names to their state types.
34
- */
35
- export type ComposableControllerActions<ComposableControllerState extends ComposableControllerStateConstraint> = ComposableControllerGetStateAction<ComposableControllerState>;
36
23
  /**
37
24
  * A utility type that extracts controllers from the {@link ComposableControllerState} type,
38
25
  * and derives a union type of all of their corresponding `stateChange` events.
39
26
  *
40
27
  * @template ComposableControllerState - A type object that maps controller names to their state types.
41
28
  */
42
- export type ChildControllerStateChangeEvents<ComposableControllerState extends ComposableControllerStateConstraint> = ComposableControllerState extends Record<infer ChildControllerName extends string, infer ChildControllerState extends StateConstraint> ? ControllerStateChangeEvent<ChildControllerName, ChildControllerState> : never;
29
+ export type ChildControllerStateChangeEvents<ComposableControllerState extends ComposableControllerStateConstraint> = ComposableControllerState extends Record<infer ControllerName extends string, infer ControllerState> ? ControllerState extends StateConstraint ? ControllerStateChangeEvent<ControllerName, ControllerState> : never : never;
43
30
  /**
44
31
  * A union type of external event types available to the {@link ComposableControllerMessenger}.
45
32
  *
@@ -51,7 +38,7 @@ export type AllowedEvents<ComposableControllerState extends ComposableController
51
38
  *
52
39
  * @template ComposableControllerState - A type object that maps controller names to their state types.
53
40
  */
54
- export type ComposableControllerMessenger<ComposableControllerState extends ComposableControllerStateConstraint> = Messenger<typeof controllerName, ComposableControllerActions<ComposableControllerState>, ComposableControllerEvents<ComposableControllerState> | AllowedEvents<ComposableControllerState>>;
41
+ export type ComposableControllerMessenger<ComposableControllerState extends ComposableControllerStateConstraint> = RestrictedMessenger<typeof controllerName, never, ComposableControllerEvents<ComposableControllerState> | AllowedEvents<ComposableControllerState>, never, AllowedEvents<ComposableControllerState>['type']>;
55
42
  /**
56
43
  * Controller that composes multiple child controllers and maintains up-to-date composed state.
57
44
  *
@@ -65,7 +52,7 @@ export declare class ComposableController<ComposableControllerState extends Comp
65
52
  *
66
53
  * @param options - Initial options used to configure this controller
67
54
  * @param options.controllers - An object that contains child controllers keyed by their names.
68
- * @param options.messenger - A controller messenger.
55
+ * @param options.messenger - A restricted messenger.
69
56
  */
70
57
  constructor({ controllers, messenger, }: {
71
58
  controllers: ChildControllersMap;
@@ -1 +1 @@
1
- {"version":3,"file":"ComposableController.d.mts","sourceRoot":"","sources":["../src/ComposableController.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,eAAe,EAGf,0BAA0B,EAC1B,wBAAwB,EACxB,sBAAsB,IAAI,kBAAkB,EAC7C,uCAAuC;AACxC,OAAO,EAAE,cAAc,EAAE,uCAAuC;AAChE,OAAO,KAAK,EAAE,SAAS,EAAE,4BAA4B;AAErD,eAAO,MAAM,cAAc,yBAAyB,CAAC;AAErD,eAAO,MAAM,wBAAwB,oGAC8D,CAAC;AAEpG;;GAEG;AACH,MAAM,MAAM,mCAAmC,GAAG;IAChD,CAAC,cAAc,EAAE,MAAM,GAAG,eAAe,CAAC;CAC3C,CAAC;AAEF;;;;GAIG;AACH,MAAM,MAAM,kCAAkC,CAC5C,yBAAyB,SAAS,mCAAmC,IACnE,wBAAwB,CAAC,OAAO,cAAc,EAAE,yBAAyB,CAAC,CAAC;AAE/E;;;;GAIG;AACH,MAAM,MAAM,oCAAoC,CAC9C,yBAAyB,SAAS,mCAAmC,IACnE,0BAA0B,CAC5B,OAAO,cAAc,EACrB,yBAAyB,CAC1B,CAAC;AAEF;;;;GAIG;AACH,MAAM,MAAM,0BAA0B,CACpC,yBAAyB,SAAS,mCAAmC,IACnE,oCAAoC,CAAC,yBAAyB,CAAC,CAAC;AAEpE;;;;GAIG;AACH,MAAM,MAAM,2BAA2B,CACrC,yBAAyB,SAAS,mCAAmC,IACnE,kCAAkC,CAAC,yBAAyB,CAAC,CAAC;AAElE;;;;;GAKG;AACH,MAAM,MAAM,gCAAgC,CAC1C,yBAAyB,SAAS,mCAAmC,IAErE,yBAAyB,SAAS,MAAM,CACtC,MAAM,mBAAmB,SAAS,MAAM,EACxC,MAAM,oBAAoB,SAAS,eAAe,CACnD,GACG,0BAA0B,CAAC,mBAAmB,EAAE,oBAAoB,CAAC,GACrE,KAAK,CAAC;AAEZ;;;;GAIG;AACH,MAAM,MAAM,aAAa,CACvB,yBAAyB,SAAS,mCAAmC,IACnE,gCAAgC,CAAC,yBAAyB,CAAC,CAAC;AAEhE;;;;GAIG;AACH,MAAM,MAAM,6BAA6B,CACvC,yBAAyB,SAAS,mCAAmC,IACnE,SAAS,CACX,OAAO,cAAc,EACrB,2BAA2B,CAAC,yBAAyB,CAAC,EACpD,0BAA0B,CAAC,yBAAyB,CAAC,GACrD,aAAa,CAAC,yBAAyB,CAAC,CAC3C,CAAC;AAEF;;;;;GAKG;AACH,qBAAa,oBAAoB,CAC/B,yBAAyB,SAAS,mCAAmC,EACrE,mBAAmB,SAAS,MAAM,CAChC,MAAM,yBAAyB,EAC/B,kBAAkB,CACnB,CACD,SAAQ,cAAc,CACtB,OAAO,cAAc,EACrB,yBAAyB,EACzB,6BAA6B,CAAC,yBAAyB,CAAC,CACzD;;IACC;;;;;;OAMG;gBACS,EACV,WAAW,EACX,SAAS,GACV,EAAE;QACD,WAAW,EAAE,mBAAmB,CAAC;QACjC,SAAS,EAAE,6BAA6B,CAAC,yBAAyB,CAAC,CAAC;KACrE;CAuEF;AAuBD,eAAe,oBAAoB,CAAC"}
1
+ {"version":3,"file":"ComposableController.d.mts","sourceRoot":"","sources":["../src/ComposableController.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,mBAAmB,EACnB,eAAe,EAGf,0BAA0B,EAC1B,sBAAsB,IAAI,kBAAkB,EAC7C,kCAAkC;AACnC,OAAO,EAAE,cAAc,EAAE,kCAAkC;AAE3D,eAAO,MAAM,cAAc,yBAAyB,CAAC;AAErD,eAAO,MAAM,wBAAwB,oGAC8D,CAAC;AAEpG;;GAEG;AACH,MAAM,MAAM,mCAAmC,GAAG;IAChD,CAAC,cAAc,EAAE,MAAM,GAAG,eAAe,CAAC;CAC3C,CAAC;AAEF;;;;GAIG;AACH,MAAM,MAAM,oCAAoC,CAC9C,yBAAyB,SAAS,mCAAmC,IACnE,0BAA0B,CAC5B,OAAO,cAAc,EACrB,yBAAyB,CAC1B,CAAC;AAEF;;;;GAIG;AACH,MAAM,MAAM,0BAA0B,CACpC,yBAAyB,SAAS,mCAAmC,IACnE,oCAAoC,CAAC,yBAAyB,CAAC,CAAC;AAEpE;;;;;GAKG;AACH,MAAM,MAAM,gCAAgC,CAC1C,yBAAyB,SAAS,mCAAmC,IAErE,yBAAyB,SAAS,MAAM,CACtC,MAAM,cAAc,SAAS,MAAM,EACnC,MAAM,eAAe,CACtB,GACG,eAAe,SAAS,eAAe,GACrC,0BAA0B,CAAC,cAAc,EAAE,eAAe,CAAC,GAC3D,KAAK,GACP,KAAK,CAAC;AAEZ;;;;GAIG;AACH,MAAM,MAAM,aAAa,CACvB,yBAAyB,SAAS,mCAAmC,IACnE,gCAAgC,CAAC,yBAAyB,CAAC,CAAC;AAEhE;;;;GAIG;AACH,MAAM,MAAM,6BAA6B,CACvC,yBAAyB,SAAS,mCAAmC,IACnE,mBAAmB,CACrB,OAAO,cAAc,EACrB,KAAK,EACH,0BAA0B,CAAC,yBAAyB,CAAC,GACrD,aAAa,CAAC,yBAAyB,CAAC,EAC1C,KAAK,EACL,aAAa,CAAC,yBAAyB,CAAC,CAAC,MAAM,CAAC,CACjD,CAAC;AAEF;;;;;GAKG;AACH,qBAAa,oBAAoB,CAC/B,yBAAyB,SAAS,mCAAmC,EACrE,mBAAmB,SAAS,MAAM,CAChC,MAAM,yBAAyB,EAC/B,kBAAkB,CACnB,CACD,SAAQ,cAAc,CACtB,OAAO,cAAc,EACrB,yBAAyB,EACzB,6BAA6B,CAAC,yBAAyB,CAAC,CACzD;;IACC;;;;;;OAMG;gBACS,EACV,WAAW,EACX,SAAS,GACV,EAAE;QACD,WAAW,EAAE,mBAAmB,CAAC;QACjC,SAAS,EAAE,6BAA6B,CAAC,yBAAyB,CAAC,CAAC;KACrE;CAyEF;AAuBD,eAAe,oBAAoB,CAAC"}
@@ -4,7 +4,7 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
4
4
  return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
5
5
  };
6
6
  var _ComposableController_instances, _ComposableController_updateChildController;
7
- import { BaseController } from "@metamask/base-controller/next";
7
+ import { BaseController } from "@metamask/base-controller";
8
8
  export const controllerName = 'ComposableController';
9
9
  export const INVALID_CONTROLLER_ERROR = 'Invalid controller: controller must have a `messagingSystem` and inherit from `BaseController`.';
10
10
  /**
@@ -19,7 +19,7 @@ export class ComposableController extends BaseController {
19
19
  *
20
20
  * @param options - Initial options used to configure this controller
21
21
  * @param options.controllers - An object that contains child controllers keyed by their names.
22
- * @param options.messenger - A controller messenger.
22
+ * @param options.messenger - A restricted messenger.
23
23
  */
24
24
  constructor({ controllers, messenger, }) {
25
25
  if (messenger === undefined) {
@@ -32,7 +32,7 @@ export class ComposableController extends BaseController {
32
32
  metadata[name] = {
33
33
  includeInStateLogs: false,
34
34
  persist: true,
35
- includeInDebugSnapshot: true,
35
+ anonymous: true,
36
36
  usedInUi: false,
37
37
  };
38
38
  return metadata;
@@ -60,11 +60,16 @@ _ComposableController_instances = new WeakSet(), _ComposableController_updateChi
60
60
  delete this.state[name];
61
61
  // eslint-disable-next-line no-empty
62
62
  }
63
- catch { }
63
+ catch (_) { }
64
+ // False negative. `name` is a string type.
65
+ // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
64
66
  throw new Error(`${name} - ${INVALID_CONTROLLER_ERROR}`);
65
67
  }
66
68
  try {
67
- this.messenger.subscribe(`${name}:stateChange`, (childState) => {
69
+ this.messagingSystem.subscribe(
70
+ // False negative. `name` is a string type.
71
+ // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
72
+ `${name}:stateChange`, (childState) => {
68
73
  this.update((state) => {
69
74
  // Type assertion is necessary for property assignment to a generic type. This does not pollute or widen the type of the asserted variable.
70
75
  // @ts-expect-error "Type instantiation is excessively deep"
@@ -1 +1 @@
1
- {"version":3,"file":"ComposableController.mjs","sourceRoot":"","sources":["../src/ComposableController.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n StateConstraint,\n StateMetadata,\n StateMetadataConstraint,\n ControllerStateChangeEvent,\n ControllerGetStateAction,\n BaseControllerInstance as ControllerInstance,\n} from '@metamask/base-controller/next';\nimport { BaseController } from '@metamask/base-controller/next';\nimport type { Messenger } from '@metamask/messenger';\n\nexport const controllerName = 'ComposableController';\n\nexport const INVALID_CONTROLLER_ERROR =\n 'Invalid controller: controller must have a `messagingSystem` and inherit from `BaseController`.';\n\n/**\n * The narrowest supertype for the composable controller state object.\n */\nexport type ComposableControllerStateConstraint = {\n [controllerName: string]: StateConstraint;\n};\n\n/**\n * The `getState` action type for the {@link ComposableControllerMessenger}.\n *\n * @template ComposableControllerState - A type object that maps controller names to their state types.\n */\nexport type ComposableControllerGetStateAction<\n ComposableControllerState extends ComposableControllerStateConstraint,\n> = ControllerGetStateAction<typeof controllerName, ComposableControllerState>;\n\n/**\n * The `stateChange` event type for the {@link ComposableControllerMessenger}.\n *\n * @template ComposableControllerState - A type object that maps controller names to their state types.\n */\nexport type ComposableControllerStateChangeEvent<\n ComposableControllerState extends ComposableControllerStateConstraint,\n> = ControllerStateChangeEvent<\n typeof controllerName,\n ComposableControllerState\n>;\n\n/**\n * A union type of internal event types available to the {@link ComposableControllerMessenger}.\n *\n * @template ComposableControllerState - A type object that maps controller names to their state types.\n */\nexport type ComposableControllerEvents<\n ComposableControllerState extends ComposableControllerStateConstraint,\n> = ComposableControllerStateChangeEvent<ComposableControllerState>;\n\n/**\n * A union type of action types available to the {@link ComposableControllerMessenger}.\n *\n * @template ComposableControllerState - A type object that maps controller names to their state types.\n */\nexport type ComposableControllerActions<\n ComposableControllerState extends ComposableControllerStateConstraint,\n> = ComposableControllerGetStateAction<ComposableControllerState>;\n\n/**\n * A utility type that extracts controllers from the {@link ComposableControllerState} type,\n * and derives a union type of all of their corresponding `stateChange` events.\n *\n * @template ComposableControllerState - A type object that maps controller names to their state types.\n */\nexport type ChildControllerStateChangeEvents<\n ComposableControllerState extends ComposableControllerStateConstraint,\n> =\n ComposableControllerState extends Record<\n infer ChildControllerName extends string,\n infer ChildControllerState extends StateConstraint\n >\n ? ControllerStateChangeEvent<ChildControllerName, ChildControllerState>\n : never;\n\n/**\n * A union type of external event types available to the {@link ComposableControllerMessenger}.\n *\n * @template ComposableControllerState - A type object that maps controller names to their state types.\n */\nexport type AllowedEvents<\n ComposableControllerState extends ComposableControllerStateConstraint,\n> = ChildControllerStateChangeEvents<ComposableControllerState>;\n\n/**\n * The messenger of the {@link ComposableController}.\n *\n * @template ComposableControllerState - A type object that maps controller names to their state types.\n */\nexport type ComposableControllerMessenger<\n ComposableControllerState extends ComposableControllerStateConstraint,\n> = Messenger<\n typeof controllerName,\n ComposableControllerActions<ComposableControllerState>,\n | ComposableControllerEvents<ComposableControllerState>\n | AllowedEvents<ComposableControllerState>\n>;\n\n/**\n * Controller that composes multiple child controllers and maintains up-to-date composed state.\n *\n * @template ComposableControllerState - A type object containing the names and state types of the child controllers.\n * @template ChildControllersMap - A type object that specifies the child controllers which are used to instantiate the {@link ComposableController}.\n */\nexport class ComposableController<\n ComposableControllerState extends ComposableControllerStateConstraint,\n ChildControllersMap extends Record<\n keyof ComposableControllerState,\n ControllerInstance\n >,\n> extends BaseController<\n typeof controllerName,\n ComposableControllerState,\n ComposableControllerMessenger<ComposableControllerState>\n> {\n /**\n * Creates a ComposableController instance.\n *\n * @param options - Initial options used to configure this controller\n * @param options.controllers - An object that contains child controllers keyed by their names.\n * @param options.messenger - A controller messenger.\n */\n constructor({\n controllers,\n messenger,\n }: {\n controllers: ChildControllersMap;\n messenger: ComposableControllerMessenger<ComposableControllerState>;\n }) {\n if (messenger === undefined) {\n throw new Error(`Messaging system is required`);\n }\n\n super({\n name: controllerName,\n // This reduce operation intentionally reuses its output object. This provides a significant performance benefit over returning a new object on each iteration.\n metadata: Object.keys(controllers).reduce<\n StateMetadata<ComposableControllerState>\n >((metadata, name) => {\n (metadata as StateMetadataConstraint)[name] = {\n includeInStateLogs: false,\n persist: true,\n includeInDebugSnapshot: true,\n usedInUi: false,\n };\n return metadata;\n }, {} as never),\n // This reduce operation intentionally reuses its output object. This provides a significant performance benefit over returning a new object on each iteration.\n state: Object.values(controllers).reduce<ComposableControllerState>(\n (state, controller) => {\n // Type assertion is necessary for property assignment to a generic type. This does not pollute or widen the type of the asserted variable.\n (state as ComposableControllerStateConstraint)[controller.name] =\n controller.state;\n return state;\n },\n {} as never,\n ),\n messenger,\n });\n\n Object.values(controllers).forEach((controller) => {\n this.#updateChildController(controller);\n });\n }\n\n /**\n * Constructor helper that subscribes to child controller state changes.\n *\n * @param controller - Controller instance to update\n */\n #updateChildController(controller: ControllerInstance): void {\n const { name } = controller;\n if (!isBaseController(controller)) {\n try {\n delete this.metadata[name];\n delete this.state[name];\n // eslint-disable-next-line no-empty\n } catch {}\n throw new Error(`${name} - ${INVALID_CONTROLLER_ERROR}`);\n }\n try {\n this.messenger.subscribe<\n // The type intersection with \"ComposableController:stateChange\" is added by one of the `Messenger.subscribe` overloads, but that constraint is unnecessary here,\n // since this method only subscribes the messenger to child controller `stateChange` events.\n // @ts-expect-error \"Type '`${string}:stateChange`' is not assignable to parameter of type '\"ComposableController:stateChange\" & ChildControllerStateChangeEvents<ComposableControllerState>[\"type\"]'.\"\n ChildControllerStateChangeEvents<ComposableControllerState>['type']\n >(`${name}:stateChange`, (childState: StateConstraint) => {\n this.update((state) => {\n // Type assertion is necessary for property assignment to a generic type. This does not pollute or widen the type of the asserted variable.\n // @ts-expect-error \"Type instantiation is excessively deep\"\n (state as ComposableControllerStateConstraint)[name] = childState;\n });\n });\n } catch (error: unknown) {\n // False negative. `name` is a string type.\n // eslint-disable-next-line @typescript-eslint/restrict-template-expressions\n console.error(`${name} - ${String(error)}`);\n }\n }\n}\n\n/**\n * Determines if the given controller is an instance of `BaseController`\n *\n * @param controller - Controller instance to check\n * @returns True if the controller is an instance of `BaseController`\n */\nfunction isBaseController(\n controller: unknown,\n): controller is ControllerInstance {\n return (\n typeof controller === 'object' &&\n controller !== null &&\n 'name' in controller &&\n typeof controller.name === 'string' &&\n 'state' in controller &&\n typeof controller.state === 'object' &&\n 'metadata' in controller &&\n typeof controller.metadata === 'object'\n );\n}\n\nexport default ComposableController;\n"]}
1
+ {"version":3,"file":"ComposableController.mjs","sourceRoot":"","sources":["../src/ComposableController.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n RestrictedMessenger,\n StateConstraint,\n StateMetadata,\n StateMetadataConstraint,\n ControllerStateChangeEvent,\n BaseControllerInstance as ControllerInstance,\n} from '@metamask/base-controller';\nimport { BaseController } from '@metamask/base-controller';\n\nexport const controllerName = 'ComposableController';\n\nexport const INVALID_CONTROLLER_ERROR =\n 'Invalid controller: controller must have a `messagingSystem` and inherit from `BaseController`.';\n\n/**\n * The narrowest supertype for the composable controller state object.\n */\nexport type ComposableControllerStateConstraint = {\n [controllerName: string]: StateConstraint;\n};\n\n/**\n * The `stateChange` event type for the {@link ComposableControllerMessenger}.\n *\n * @template ComposableControllerState - A type object that maps controller names to their state types.\n */\nexport type ComposableControllerStateChangeEvent<\n ComposableControllerState extends ComposableControllerStateConstraint,\n> = ControllerStateChangeEvent<\n typeof controllerName,\n ComposableControllerState\n>;\n\n/**\n * A union type of internal event types available to the {@link ComposableControllerMessenger}.\n *\n * @template ComposableControllerState - A type object that maps controller names to their state types.\n */\nexport type ComposableControllerEvents<\n ComposableControllerState extends ComposableControllerStateConstraint,\n> = ComposableControllerStateChangeEvent<ComposableControllerState>;\n\n/**\n * A utility type that extracts controllers from the {@link ComposableControllerState} type,\n * and derives a union type of all of their corresponding `stateChange` events.\n *\n * @template ComposableControllerState - A type object that maps controller names to their state types.\n */\nexport type ChildControllerStateChangeEvents<\n ComposableControllerState extends ComposableControllerStateConstraint,\n> =\n ComposableControllerState extends Record<\n infer ControllerName extends string,\n infer ControllerState\n >\n ? ControllerState extends StateConstraint\n ? ControllerStateChangeEvent<ControllerName, ControllerState>\n : never\n : never;\n\n/**\n * A union type of external event types available to the {@link ComposableControllerMessenger}.\n *\n * @template ComposableControllerState - A type object that maps controller names to their state types.\n */\nexport type AllowedEvents<\n ComposableControllerState extends ComposableControllerStateConstraint,\n> = ChildControllerStateChangeEvents<ComposableControllerState>;\n\n/**\n * The messenger of the {@link ComposableController}.\n *\n * @template ComposableControllerState - A type object that maps controller names to their state types.\n */\nexport type ComposableControllerMessenger<\n ComposableControllerState extends ComposableControllerStateConstraint,\n> = RestrictedMessenger<\n typeof controllerName,\n never,\n | ComposableControllerEvents<ComposableControllerState>\n | AllowedEvents<ComposableControllerState>,\n never,\n AllowedEvents<ComposableControllerState>['type']\n>;\n\n/**\n * Controller that composes multiple child controllers and maintains up-to-date composed state.\n *\n * @template ComposableControllerState - A type object containing the names and state types of the child controllers.\n * @template ChildControllersMap - A type object that specifies the child controllers which are used to instantiate the {@link ComposableController}.\n */\nexport class ComposableController<\n ComposableControllerState extends ComposableControllerStateConstraint,\n ChildControllersMap extends Record<\n keyof ComposableControllerState,\n ControllerInstance\n >,\n> extends BaseController<\n typeof controllerName,\n ComposableControllerState,\n ComposableControllerMessenger<ComposableControllerState>\n> {\n /**\n * Creates a ComposableController instance.\n *\n * @param options - Initial options used to configure this controller\n * @param options.controllers - An object that contains child controllers keyed by their names.\n * @param options.messenger - A restricted messenger.\n */\n constructor({\n controllers,\n messenger,\n }: {\n controllers: ChildControllersMap;\n messenger: ComposableControllerMessenger<ComposableControllerState>;\n }) {\n if (messenger === undefined) {\n throw new Error(`Messaging system is required`);\n }\n\n super({\n name: controllerName,\n // This reduce operation intentionally reuses its output object. This provides a significant performance benefit over returning a new object on each iteration.\n metadata: Object.keys(controllers).reduce<\n StateMetadata<ComposableControllerState>\n >((metadata, name) => {\n (metadata as StateMetadataConstraint)[name] = {\n includeInStateLogs: false,\n persist: true,\n anonymous: true,\n usedInUi: false,\n };\n return metadata;\n }, {} as never),\n // This reduce operation intentionally reuses its output object. This provides a significant performance benefit over returning a new object on each iteration.\n state: Object.values(controllers).reduce<ComposableControllerState>(\n (state, controller) => {\n // Type assertion is necessary for property assignment to a generic type. This does not pollute or widen the type of the asserted variable.\n (state as ComposableControllerStateConstraint)[controller.name] =\n controller.state;\n return state;\n },\n {} as never,\n ),\n messenger,\n });\n\n Object.values(controllers).forEach((controller) => {\n this.#updateChildController(controller);\n });\n }\n\n /**\n * Constructor helper that subscribes to child controller state changes.\n *\n * @param controller - Controller instance to update\n */\n #updateChildController(controller: ControllerInstance): void {\n const { name } = controller;\n if (!isBaseController(controller)) {\n try {\n delete this.metadata[name];\n delete this.state[name];\n // eslint-disable-next-line no-empty\n } catch (_) {}\n // False negative. `name` is a string type.\n // eslint-disable-next-line @typescript-eslint/restrict-template-expressions\n throw new Error(`${name} - ${INVALID_CONTROLLER_ERROR}`);\n }\n try {\n this.messagingSystem.subscribe(\n // False negative. `name` is a string type.\n // eslint-disable-next-line @typescript-eslint/restrict-template-expressions\n `${name}:stateChange`,\n (childState: StateConstraint) => {\n this.update((state) => {\n // Type assertion is necessary for property assignment to a generic type. This does not pollute or widen the type of the asserted variable.\n // @ts-expect-error \"Type instantiation is excessively deep\"\n (state as ComposableControllerStateConstraint)[name] = childState;\n });\n },\n );\n } catch (error: unknown) {\n // False negative. `name` is a string type.\n // eslint-disable-next-line @typescript-eslint/restrict-template-expressions\n console.error(`${name} - ${String(error)}`);\n }\n }\n}\n\n/**\n * Determines if the given controller is an instance of `BaseController`\n *\n * @param controller - Controller instance to check\n * @returns True if the controller is an instance of `BaseController`\n */\nfunction isBaseController(\n controller: unknown,\n): controller is ControllerInstance {\n return (\n typeof controller === 'object' &&\n controller !== null &&\n 'name' in controller &&\n typeof controller.name === 'string' &&\n 'state' in controller &&\n typeof controller.state === 'object' &&\n 'metadata' in controller &&\n typeof controller.metadata === 'object'\n );\n}\n\nexport default ComposableController;\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@metamask-previews/composable-controller",
3
- "version": "11.1.0-preview-1f64ffa6",
3
+ "version": "11.1.0-preview-6fbb0db6",
4
4
  "description": "Consolidates the state from multiple controllers into one",
5
5
  "keywords": [
6
6
  "MetaMask",
@@ -47,8 +47,7 @@
47
47
  "test:watch": "NODE_OPTIONS=--experimental-vm-modules jest --watch"
48
48
  },
49
49
  "dependencies": {
50
- "@metamask/base-controller": "^8.4.2",
51
- "@metamask/messenger": "^0.3.0"
50
+ "@metamask/base-controller": "^8.4.2"
52
51
  },
53
52
  "devDependencies": {
54
53
  "@metamask/auto-changelog": "^3.4.4",