@metamask-previews/base-controller 7.0.2-preview-913113cf → 7.0.2-preview-bb2f1fdd
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/dist/BaseControllerV1.cjs +4 -1
- package/dist/BaseControllerV1.cjs.map +1 -1
- package/dist/BaseControllerV1.d.cts +2 -3
- package/dist/BaseControllerV1.d.cts.map +1 -1
- package/dist/BaseControllerV1.d.mts +2 -3
- package/dist/BaseControllerV1.d.mts.map +1 -1
- package/dist/BaseControllerV1.mjs +4 -1
- package/dist/BaseControllerV1.mjs.map +1 -1
- package/dist/BaseControllerV2.cjs +4 -1
- package/dist/BaseControllerV2.cjs.map +1 -1
- package/dist/BaseControllerV2.d.cts +4 -4
- package/dist/BaseControllerV2.d.cts.map +1 -1
- package/dist/BaseControllerV2.d.mts +4 -4
- package/dist/BaseControllerV2.d.mts.map +1 -1
- package/dist/BaseControllerV2.mjs +4 -1
- package/dist/BaseControllerV2.mjs.map +1 -1
- package/package.json +1 -1
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.BaseControllerV1 = exports.isBaseControllerV1 = void 0;
|
|
4
|
+
const utils_1 = require("@metamask/utils");
|
|
4
5
|
/**
|
|
5
6
|
* Determines if the given controller is an instance of `BaseControllerV1`
|
|
6
7
|
*
|
|
@@ -8,7 +9,9 @@ exports.BaseControllerV1 = exports.isBaseControllerV1 = void 0;
|
|
|
8
9
|
* @returns True if the controller is an instance of `BaseControllerV1`
|
|
9
10
|
*/
|
|
10
11
|
function isBaseControllerV1(controller) {
|
|
11
|
-
return ('
|
|
12
|
+
return (typeof controller === 'object' &&
|
|
13
|
+
!(0, utils_1.isNullOrUndefined)(controller) &&
|
|
14
|
+
'name' in controller &&
|
|
12
15
|
typeof controller.name === 'string' &&
|
|
13
16
|
'config' in controller &&
|
|
14
17
|
typeof controller.config === 'object' &&
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BaseControllerV1.cjs","sourceRoot":"","sources":["../src/BaseControllerV1.ts"],"names":[],"mappings":"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","sourcesContent":["import type { PublicInterface } from '@metamask/utils';\n\nimport type { ControllerInstance } from './BaseControllerV2';\n\n/**\n * Determines if the given controller is an instance of `BaseControllerV1`\n *\n * @param controller - Controller instance to check\n * @returns True if the controller is an instance of `BaseControllerV1`\n */\nexport function isBaseControllerV1(\n controller: ControllerInstance,\n): controller is BaseControllerV1Instance {\n return (\n 'name' in controller &&\n typeof controller.name === 'string' &&\n 'config' in controller &&\n typeof controller.config === 'object' &&\n 'defaultConfig' in controller &&\n typeof controller.defaultConfig === 'object' &&\n 'state' in controller &&\n typeof controller.state === 'object' &&\n 'defaultState' in controller &&\n typeof controller.defaultState === 'object' &&\n 'disabled' in controller &&\n typeof controller.disabled === 'boolean' &&\n 'subscribe' in controller &&\n typeof controller.subscribe === 'function'\n );\n}\n\n/**\n * State change callbacks\n */\n// TODO: Either fix this lint violation or explain why it's necessary to ignore.\n// eslint-disable-next-line @typescript-eslint/naming-convention\nexport type Listener<T> = (state: T) => void;\n\n/**\n * @type BaseConfig\n *\n * Base controller configuration\n * @property disabled - Determines if this controller is enabled\n */\n// This interface was created before this ESLint rule was added.\n// Convert to a `type` in a future major version.\n// eslint-disable-next-line @typescript-eslint/consistent-type-definitions\nexport interface BaseConfig {\n disabled?: boolean;\n}\n\n/**\n * @type BaseState\n *\n * Base state representation\n * @property name - Unique name for this controller\n */\n// This interface was created before this ESLint rule was added.\n// Convert to a `type` in a future major version.\n// eslint-disable-next-line @typescript-eslint/consistent-type-definitions\nexport interface BaseState {\n name?: string;\n}\n\n/**\n * The narrowest supertype for `BaseControllerV1` config objects.\n * This type can be assigned to any `BaseControllerV1` config object.\n */\nexport type ConfigConstraint = BaseConfig & object;\n\n/**\n * The narrowest supertype for `BaseControllerV1` state objects.\n * This type can be assigned to any `BaseControllerV1` state object.\n */\nexport type StateConstraint = BaseState & object;\n\n/**\n * The widest subtype of all controller instances that extend from `BaseControllerV1`.\n * Any `BaseControllerV1` instance can be assigned to this type.\n */\nexport type BaseControllerV1Instance = PublicInterface<\n BaseControllerV1<ConfigConstraint, StateConstraint>\n>;\n\n/**\n * @deprecated This class has been renamed to BaseControllerV1 and is no longer recommended for use for controllers. Please use BaseController (formerly BaseControllerV2) instead.\n *\n * Controller class that provides configuration, state management, and subscriptions.\n *\n * The core purpose of every controller is to maintain an internal data object\n * called \"state\". Each controller is responsible for its own state, and all global wallet state\n * is tracked in a controller as state.\n */\n// TODO: Either fix this lint violation or explain why it's necessary to ignore.\n// eslint-disable-next-line @typescript-eslint/naming-convention\nexport class BaseControllerV1<C extends BaseConfig, S extends BaseState> {\n /**\n * Default options used to configure this controller\n */\n defaultConfig: C = {} as never;\n\n /**\n * Default state set on this controller\n */\n defaultState: S = {} as never;\n\n /**\n * Determines if listeners are notified of state changes\n */\n disabled = false;\n\n /**\n * Name of this controller used during composition\n */\n name = 'BaseController';\n\n private readonly initialConfig: Partial<C>;\n\n private readonly initialState: Partial<S>;\n\n private internalConfig: C = this.defaultConfig;\n\n private internalState: S = this.defaultState;\n\n private readonly internalListeners: Listener<S>[] = [];\n\n /**\n * Creates a BaseControllerV1 instance. Both initial state and initial\n * configuration options are merged with defaults upon initialization.\n *\n * @param config - Initial options used to configure this controller.\n * @param state - Initial state to set on this controller.\n */\n constructor(config: Partial<C> = {}, state: Partial<S> = {}) {\n this.initialState = state;\n this.initialConfig = config;\n }\n\n /**\n * Enables the controller. This sets each config option as a member\n * variable on this instance and triggers any defined setters. This\n * also sets initial state and triggers any listeners.\n *\n * @returns This controller instance.\n */\n protected initialize() {\n this.internalState = this.defaultState;\n this.internalConfig = this.defaultConfig;\n this.configure(this.initialConfig);\n this.update(this.initialState);\n return this;\n }\n\n /**\n * Retrieves current controller configuration options.\n *\n * @returns The current configuration.\n */\n get config() {\n return this.internalConfig;\n }\n\n /**\n * Retrieves current controller state.\n *\n * @returns The current state.\n */\n get state() {\n return this.internalState;\n }\n\n /**\n * Updates controller configuration.\n *\n * @param config - New configuration options.\n * @param overwrite - Overwrite config instead of merging.\n * @param fullUpdate - Boolean that defines if the update is partial or not.\n */\n configure(config: Partial<C>, overwrite = false, fullUpdate = true) {\n if (fullUpdate) {\n this.internalConfig = overwrite\n ? (config as C)\n : Object.assign(this.internalConfig, config);\n\n for (const key of Object.keys(this.internalConfig) as (keyof C)[]) {\n const value = this.internalConfig[key];\n if (value !== undefined) {\n (this as unknown as C)[key] = value;\n }\n }\n } else {\n for (const key of Object.keys(config) as (keyof C)[]) {\n /* istanbul ignore else */\n if (this.internalConfig[key] !== undefined) {\n const value = (config as C)[key];\n this.internalConfig[key] = value;\n (this as unknown as C)[key] = value;\n }\n }\n }\n }\n\n /**\n * Notifies all subscribed listeners of current state.\n */\n notify() {\n if (this.disabled) {\n return;\n }\n\n this.internalListeners.forEach((listener) => {\n listener(this.internalState);\n });\n }\n\n /**\n * Adds new listener to be notified of state changes.\n *\n * @param listener - The callback triggered when state changes.\n */\n subscribe(listener: Listener<S>) {\n this.internalListeners.push(listener);\n }\n\n /**\n * Removes existing listener from receiving state changes.\n *\n * @param listener - The callback to remove.\n * @returns `true` if a listener is found and unsubscribed.\n */\n unsubscribe(listener: Listener<S>) {\n const index = this.internalListeners.findIndex((cb) => listener === cb);\n index > -1 && this.internalListeners.splice(index, 1);\n return index > -1;\n }\n\n /**\n * Updates controller state.\n *\n * @param state - The new state.\n * @param overwrite - Overwrite state instead of merging.\n */\n update(state: Partial<S>, overwrite = false) {\n this.internalState = overwrite\n ? Object.assign({}, state as S)\n : Object.assign({}, this.internalState, state);\n this.notify();\n }\n}\n\nexport default BaseControllerV1;\n"]}
|
|
1
|
+
{"version":3,"file":"BaseControllerV1.cjs","sourceRoot":"","sources":["../src/BaseControllerV1.ts"],"names":[],"mappings":"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","sourcesContent":["import { isNullOrUndefined, type PublicInterface } from '@metamask/utils';\n\n/**\n * Determines if the given controller is an instance of `BaseControllerV1`\n *\n * @param controller - Controller instance to check\n * @returns True if the controller is an instance of `BaseControllerV1`\n */\nexport function isBaseControllerV1(\n controller: unknown,\n): controller is BaseControllerV1Instance {\n return (\n typeof controller === 'object' &&\n !isNullOrUndefined(controller) &&\n 'name' in controller &&\n typeof controller.name === 'string' &&\n 'config' in controller &&\n typeof controller.config === 'object' &&\n 'defaultConfig' in controller &&\n typeof controller.defaultConfig === 'object' &&\n 'state' in controller &&\n typeof controller.state === 'object' &&\n 'defaultState' in controller &&\n typeof controller.defaultState === 'object' &&\n 'disabled' in controller &&\n typeof controller.disabled === 'boolean' &&\n 'subscribe' in controller &&\n typeof controller.subscribe === 'function'\n );\n}\n\n/**\n * State change callbacks\n */\n// TODO: Either fix this lint violation or explain why it's necessary to ignore.\n// eslint-disable-next-line @typescript-eslint/naming-convention\nexport type Listener<T> = (state: T) => void;\n\n/**\n * @type BaseConfig\n *\n * Base controller configuration\n * @property disabled - Determines if this controller is enabled\n */\n// This interface was created before this ESLint rule was added.\n// Convert to a `type` in a future major version.\n// eslint-disable-next-line @typescript-eslint/consistent-type-definitions\nexport interface BaseConfig {\n disabled?: boolean;\n}\n\n/**\n * @type BaseState\n *\n * Base state representation\n * @property name - Unique name for this controller\n */\n// This interface was created before this ESLint rule was added.\n// Convert to a `type` in a future major version.\n// eslint-disable-next-line @typescript-eslint/consistent-type-definitions\nexport interface BaseState {\n name?: string;\n}\n\n/**\n * The narrowest supertype for `BaseControllerV1` config objects.\n * This type can be assigned to any `BaseControllerV1` config object.\n */\nexport type ConfigConstraint = BaseConfig & object;\n\n/**\n * The narrowest supertype for `BaseControllerV1` state objects.\n * This type can be assigned to any `BaseControllerV1` state object.\n */\nexport type StateConstraint = BaseState & object;\n\n/**\n * The widest subtype of all controller instances that extend from `BaseControllerV1`.\n * Any `BaseControllerV1` instance can be assigned to this type.\n */\nexport type BaseControllerV1Instance = PublicInterface<\n BaseControllerV1<ConfigConstraint, StateConstraint>\n>;\n\n/**\n * @deprecated This class has been renamed to BaseControllerV1 and is no longer recommended for use for controllers. Please use BaseController (formerly BaseControllerV2) instead.\n *\n * Controller class that provides configuration, state management, and subscriptions.\n *\n * The core purpose of every controller is to maintain an internal data object\n * called \"state\". Each controller is responsible for its own state, and all global wallet state\n * is tracked in a controller as state.\n */\n// TODO: Either fix this lint violation or explain why it's necessary to ignore.\n// eslint-disable-next-line @typescript-eslint/naming-convention\nexport class BaseControllerV1<C extends BaseConfig, S extends BaseState> {\n /**\n * Default options used to configure this controller\n */\n defaultConfig: C = {} as never;\n\n /**\n * Default state set on this controller\n */\n defaultState: S = {} as never;\n\n /**\n * Determines if listeners are notified of state changes\n */\n disabled = false;\n\n /**\n * Name of this controller used during composition\n */\n name = 'BaseController';\n\n private readonly initialConfig: Partial<C>;\n\n private readonly initialState: Partial<S>;\n\n private internalConfig: C = this.defaultConfig;\n\n private internalState: S = this.defaultState;\n\n private readonly internalListeners: Listener<S>[] = [];\n\n /**\n * Creates a BaseControllerV1 instance. Both initial state and initial\n * configuration options are merged with defaults upon initialization.\n *\n * @param config - Initial options used to configure this controller.\n * @param state - Initial state to set on this controller.\n */\n constructor(config: Partial<C> = {}, state: Partial<S> = {}) {\n this.initialState = state;\n this.initialConfig = config;\n }\n\n /**\n * Enables the controller. This sets each config option as a member\n * variable on this instance and triggers any defined setters. This\n * also sets initial state and triggers any listeners.\n *\n * @returns This controller instance.\n */\n protected initialize() {\n this.internalState = this.defaultState;\n this.internalConfig = this.defaultConfig;\n this.configure(this.initialConfig);\n this.update(this.initialState);\n return this;\n }\n\n /**\n * Retrieves current controller configuration options.\n *\n * @returns The current configuration.\n */\n get config() {\n return this.internalConfig;\n }\n\n /**\n * Retrieves current controller state.\n *\n * @returns The current state.\n */\n get state() {\n return this.internalState;\n }\n\n /**\n * Updates controller configuration.\n *\n * @param config - New configuration options.\n * @param overwrite - Overwrite config instead of merging.\n * @param fullUpdate - Boolean that defines if the update is partial or not.\n */\n configure(config: Partial<C>, overwrite = false, fullUpdate = true) {\n if (fullUpdate) {\n this.internalConfig = overwrite\n ? (config as C)\n : Object.assign(this.internalConfig, config);\n\n for (const key of Object.keys(this.internalConfig) as (keyof C)[]) {\n const value = this.internalConfig[key];\n if (value !== undefined) {\n (this as unknown as C)[key] = value;\n }\n }\n } else {\n for (const key of Object.keys(config) as (keyof C)[]) {\n /* istanbul ignore else */\n if (this.internalConfig[key] !== undefined) {\n const value = (config as C)[key];\n this.internalConfig[key] = value;\n (this as unknown as C)[key] = value;\n }\n }\n }\n }\n\n /**\n * Notifies all subscribed listeners of current state.\n */\n notify() {\n if (this.disabled) {\n return;\n }\n\n this.internalListeners.forEach((listener) => {\n listener(this.internalState);\n });\n }\n\n /**\n * Adds new listener to be notified of state changes.\n *\n * @param listener - The callback triggered when state changes.\n */\n subscribe(listener: Listener<S>) {\n this.internalListeners.push(listener);\n }\n\n /**\n * Removes existing listener from receiving state changes.\n *\n * @param listener - The callback to remove.\n * @returns `true` if a listener is found and unsubscribed.\n */\n unsubscribe(listener: Listener<S>) {\n const index = this.internalListeners.findIndex((cb) => listener === cb);\n index > -1 && this.internalListeners.splice(index, 1);\n return index > -1;\n }\n\n /**\n * Updates controller state.\n *\n * @param state - The new state.\n * @param overwrite - Overwrite state instead of merging.\n */\n update(state: Partial<S>, overwrite = false) {\n this.internalState = overwrite\n ? Object.assign({}, state as S)\n : Object.assign({}, this.internalState, state);\n this.notify();\n }\n}\n\nexport default BaseControllerV1;\n"]}
|
|
@@ -1,12 +1,11 @@
|
|
|
1
|
-
import type
|
|
2
|
-
import type { ControllerInstance } from "./BaseControllerV2.cjs";
|
|
1
|
+
import { type PublicInterface } from "@metamask/utils";
|
|
3
2
|
/**
|
|
4
3
|
* Determines if the given controller is an instance of `BaseControllerV1`
|
|
5
4
|
*
|
|
6
5
|
* @param controller - Controller instance to check
|
|
7
6
|
* @returns True if the controller is an instance of `BaseControllerV1`
|
|
8
7
|
*/
|
|
9
|
-
export declare function isBaseControllerV1(controller:
|
|
8
|
+
export declare function isBaseControllerV1(controller: unknown): controller is BaseControllerV1Instance;
|
|
10
9
|
/**
|
|
11
10
|
* State change callbacks
|
|
12
11
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BaseControllerV1.d.cts","sourceRoot":"","sources":["../src/BaseControllerV1.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"BaseControllerV1.d.cts","sourceRoot":"","sources":["../src/BaseControllerV1.ts"],"names":[],"mappings":"AAAA,OAAO,EAAqB,KAAK,eAAe,EAAE,wBAAwB;AAE1E;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAChC,UAAU,EAAE,OAAO,GAClB,UAAU,IAAI,wBAAwB,CAmBxC;AAED;;GAEG;AAGH,MAAM,MAAM,QAAQ,CAAC,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,KAAK,IAAI,CAAC;AAE7C;;;;;GAKG;AAIH,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED;;;;;GAKG;AAIH,MAAM,WAAW,SAAS;IACxB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;;GAGG;AACH,MAAM,MAAM,gBAAgB,GAAG,UAAU,GAAG,MAAM,CAAC;AAEnD;;;GAGG;AACH,MAAM,MAAM,eAAe,GAAG,SAAS,GAAG,MAAM,CAAC;AAEjD;;;GAGG;AACH,MAAM,MAAM,wBAAwB,GAAG,eAAe,CACpD,gBAAgB,CAAC,gBAAgB,EAAE,eAAe,CAAC,CACpD,CAAC;AAEF;;;;;;;;GAQG;AAGH,qBAAa,gBAAgB,CAAC,CAAC,SAAS,UAAU,EAAE,CAAC,SAAS,SAAS;IACrE;;OAEG;IACH,aAAa,EAAE,CAAC,CAAe;IAE/B;;OAEG;IACH,YAAY,EAAE,CAAC,CAAe;IAE9B;;OAEG;IACH,QAAQ,UAAS;IAEjB;;OAEG;IACH,IAAI,SAAoB;IAExB,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAa;IAE3C,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAa;IAE1C,OAAO,CAAC,cAAc,CAAyB;IAE/C,OAAO,CAAC,aAAa,CAAwB;IAE7C,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAqB;IAEvD;;;;;;OAMG;gBACS,MAAM,GAAE,OAAO,CAAC,CAAC,CAAM,EAAE,KAAK,GAAE,OAAO,CAAC,CAAC,CAAM;IAK3D;;;;;;OAMG;IACH,SAAS,CAAC,UAAU;IAQpB;;;;OAIG;IACH,IAAI,MAAM,MAET;IAED;;;;OAIG;IACH,IAAI,KAAK,MAER;IAED;;;;;;OAMG;IACH,SAAS,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,SAAS,UAAQ,EAAE,UAAU,UAAO;IAwBlE;;OAEG;IACH,MAAM;IAUN;;;;OAIG;IACH,SAAS,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC;IAI/B;;;;;OAKG;IACH,WAAW,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC;IAMjC;;;;;OAKG;IACH,MAAM,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,SAAS,UAAQ;CAM5C;AAED,eAAe,gBAAgB,CAAC"}
|
|
@@ -1,12 +1,11 @@
|
|
|
1
|
-
import type
|
|
2
|
-
import type { ControllerInstance } from "./BaseControllerV2.mjs";
|
|
1
|
+
import { type PublicInterface } from "@metamask/utils";
|
|
3
2
|
/**
|
|
4
3
|
* Determines if the given controller is an instance of `BaseControllerV1`
|
|
5
4
|
*
|
|
6
5
|
* @param controller - Controller instance to check
|
|
7
6
|
* @returns True if the controller is an instance of `BaseControllerV1`
|
|
8
7
|
*/
|
|
9
|
-
export declare function isBaseControllerV1(controller:
|
|
8
|
+
export declare function isBaseControllerV1(controller: unknown): controller is BaseControllerV1Instance;
|
|
10
9
|
/**
|
|
11
10
|
* State change callbacks
|
|
12
11
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BaseControllerV1.d.mts","sourceRoot":"","sources":["../src/BaseControllerV1.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"BaseControllerV1.d.mts","sourceRoot":"","sources":["../src/BaseControllerV1.ts"],"names":[],"mappings":"AAAA,OAAO,EAAqB,KAAK,eAAe,EAAE,wBAAwB;AAE1E;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAChC,UAAU,EAAE,OAAO,GAClB,UAAU,IAAI,wBAAwB,CAmBxC;AAED;;GAEG;AAGH,MAAM,MAAM,QAAQ,CAAC,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,KAAK,IAAI,CAAC;AAE7C;;;;;GAKG;AAIH,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED;;;;;GAKG;AAIH,MAAM,WAAW,SAAS;IACxB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;;GAGG;AACH,MAAM,MAAM,gBAAgB,GAAG,UAAU,GAAG,MAAM,CAAC;AAEnD;;;GAGG;AACH,MAAM,MAAM,eAAe,GAAG,SAAS,GAAG,MAAM,CAAC;AAEjD;;;GAGG;AACH,MAAM,MAAM,wBAAwB,GAAG,eAAe,CACpD,gBAAgB,CAAC,gBAAgB,EAAE,eAAe,CAAC,CACpD,CAAC;AAEF;;;;;;;;GAQG;AAGH,qBAAa,gBAAgB,CAAC,CAAC,SAAS,UAAU,EAAE,CAAC,SAAS,SAAS;IACrE;;OAEG;IACH,aAAa,EAAE,CAAC,CAAe;IAE/B;;OAEG;IACH,YAAY,EAAE,CAAC,CAAe;IAE9B;;OAEG;IACH,QAAQ,UAAS;IAEjB;;OAEG;IACH,IAAI,SAAoB;IAExB,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAa;IAE3C,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAa;IAE1C,OAAO,CAAC,cAAc,CAAyB;IAE/C,OAAO,CAAC,aAAa,CAAwB;IAE7C,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAqB;IAEvD;;;;;;OAMG;gBACS,MAAM,GAAE,OAAO,CAAC,CAAC,CAAM,EAAE,KAAK,GAAE,OAAO,CAAC,CAAC,CAAM;IAK3D;;;;;;OAMG;IACH,SAAS,CAAC,UAAU;IAQpB;;;;OAIG;IACH,IAAI,MAAM,MAET;IAED;;;;OAIG;IACH,IAAI,KAAK,MAER;IAED;;;;;;OAMG;IACH,SAAS,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,SAAS,UAAQ,EAAE,UAAU,UAAO;IAwBlE;;OAEG;IACH,MAAM;IAUN;;;;OAIG;IACH,SAAS,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC;IAI/B;;;;;OAKG;IACH,WAAW,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC;IAMjC;;;;;OAKG;IACH,MAAM,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,SAAS,UAAQ;CAM5C;AAED,eAAe,gBAAgB,CAAC"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { isNullOrUndefined } from "@metamask/utils";
|
|
1
2
|
/**
|
|
2
3
|
* Determines if the given controller is an instance of `BaseControllerV1`
|
|
3
4
|
*
|
|
@@ -5,7 +6,9 @@
|
|
|
5
6
|
* @returns True if the controller is an instance of `BaseControllerV1`
|
|
6
7
|
*/
|
|
7
8
|
export function isBaseControllerV1(controller) {
|
|
8
|
-
return ('
|
|
9
|
+
return (typeof controller === 'object' &&
|
|
10
|
+
!isNullOrUndefined(controller) &&
|
|
11
|
+
'name' in controller &&
|
|
9
12
|
typeof controller.name === 'string' &&
|
|
10
13
|
'config' in controller &&
|
|
11
14
|
typeof controller.config === 'object' &&
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BaseControllerV1.mjs","sourceRoot":"","sources":["../src/BaseControllerV1.ts"],"names":[],"mappings":"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","sourcesContent":["import type { PublicInterface } from '@metamask/utils';\n\nimport type { ControllerInstance } from './BaseControllerV2';\n\n/**\n * Determines if the given controller is an instance of `BaseControllerV1`\n *\n * @param controller - Controller instance to check\n * @returns True if the controller is an instance of `BaseControllerV1`\n */\nexport function isBaseControllerV1(\n controller: ControllerInstance,\n): controller is BaseControllerV1Instance {\n return (\n 'name' in controller &&\n typeof controller.name === 'string' &&\n 'config' in controller &&\n typeof controller.config === 'object' &&\n 'defaultConfig' in controller &&\n typeof controller.defaultConfig === 'object' &&\n 'state' in controller &&\n typeof controller.state === 'object' &&\n 'defaultState' in controller &&\n typeof controller.defaultState === 'object' &&\n 'disabled' in controller &&\n typeof controller.disabled === 'boolean' &&\n 'subscribe' in controller &&\n typeof controller.subscribe === 'function'\n );\n}\n\n/**\n * State change callbacks\n */\n// TODO: Either fix this lint violation or explain why it's necessary to ignore.\n// eslint-disable-next-line @typescript-eslint/naming-convention\nexport type Listener<T> = (state: T) => void;\n\n/**\n * @type BaseConfig\n *\n * Base controller configuration\n * @property disabled - Determines if this controller is enabled\n */\n// This interface was created before this ESLint rule was added.\n// Convert to a `type` in a future major version.\n// eslint-disable-next-line @typescript-eslint/consistent-type-definitions\nexport interface BaseConfig {\n disabled?: boolean;\n}\n\n/**\n * @type BaseState\n *\n * Base state representation\n * @property name - Unique name for this controller\n */\n// This interface was created before this ESLint rule was added.\n// Convert to a `type` in a future major version.\n// eslint-disable-next-line @typescript-eslint/consistent-type-definitions\nexport interface BaseState {\n name?: string;\n}\n\n/**\n * The narrowest supertype for `BaseControllerV1` config objects.\n * This type can be assigned to any `BaseControllerV1` config object.\n */\nexport type ConfigConstraint = BaseConfig & object;\n\n/**\n * The narrowest supertype for `BaseControllerV1` state objects.\n * This type can be assigned to any `BaseControllerV1` state object.\n */\nexport type StateConstraint = BaseState & object;\n\n/**\n * The widest subtype of all controller instances that extend from `BaseControllerV1`.\n * Any `BaseControllerV1` instance can be assigned to this type.\n */\nexport type BaseControllerV1Instance = PublicInterface<\n BaseControllerV1<ConfigConstraint, StateConstraint>\n>;\n\n/**\n * @deprecated This class has been renamed to BaseControllerV1 and is no longer recommended for use for controllers. Please use BaseController (formerly BaseControllerV2) instead.\n *\n * Controller class that provides configuration, state management, and subscriptions.\n *\n * The core purpose of every controller is to maintain an internal data object\n * called \"state\". Each controller is responsible for its own state, and all global wallet state\n * is tracked in a controller as state.\n */\n// TODO: Either fix this lint violation or explain why it's necessary to ignore.\n// eslint-disable-next-line @typescript-eslint/naming-convention\nexport class BaseControllerV1<C extends BaseConfig, S extends BaseState> {\n /**\n * Default options used to configure this controller\n */\n defaultConfig: C = {} as never;\n\n /**\n * Default state set on this controller\n */\n defaultState: S = {} as never;\n\n /**\n * Determines if listeners are notified of state changes\n */\n disabled = false;\n\n /**\n * Name of this controller used during composition\n */\n name = 'BaseController';\n\n private readonly initialConfig: Partial<C>;\n\n private readonly initialState: Partial<S>;\n\n private internalConfig: C = this.defaultConfig;\n\n private internalState: S = this.defaultState;\n\n private readonly internalListeners: Listener<S>[] = [];\n\n /**\n * Creates a BaseControllerV1 instance. Both initial state and initial\n * configuration options are merged with defaults upon initialization.\n *\n * @param config - Initial options used to configure this controller.\n * @param state - Initial state to set on this controller.\n */\n constructor(config: Partial<C> = {}, state: Partial<S> = {}) {\n this.initialState = state;\n this.initialConfig = config;\n }\n\n /**\n * Enables the controller. This sets each config option as a member\n * variable on this instance and triggers any defined setters. This\n * also sets initial state and triggers any listeners.\n *\n * @returns This controller instance.\n */\n protected initialize() {\n this.internalState = this.defaultState;\n this.internalConfig = this.defaultConfig;\n this.configure(this.initialConfig);\n this.update(this.initialState);\n return this;\n }\n\n /**\n * Retrieves current controller configuration options.\n *\n * @returns The current configuration.\n */\n get config() {\n return this.internalConfig;\n }\n\n /**\n * Retrieves current controller state.\n *\n * @returns The current state.\n */\n get state() {\n return this.internalState;\n }\n\n /**\n * Updates controller configuration.\n *\n * @param config - New configuration options.\n * @param overwrite - Overwrite config instead of merging.\n * @param fullUpdate - Boolean that defines if the update is partial or not.\n */\n configure(config: Partial<C>, overwrite = false, fullUpdate = true) {\n if (fullUpdate) {\n this.internalConfig = overwrite\n ? (config as C)\n : Object.assign(this.internalConfig, config);\n\n for (const key of Object.keys(this.internalConfig) as (keyof C)[]) {\n const value = this.internalConfig[key];\n if (value !== undefined) {\n (this as unknown as C)[key] = value;\n }\n }\n } else {\n for (const key of Object.keys(config) as (keyof C)[]) {\n /* istanbul ignore else */\n if (this.internalConfig[key] !== undefined) {\n const value = (config as C)[key];\n this.internalConfig[key] = value;\n (this as unknown as C)[key] = value;\n }\n }\n }\n }\n\n /**\n * Notifies all subscribed listeners of current state.\n */\n notify() {\n if (this.disabled) {\n return;\n }\n\n this.internalListeners.forEach((listener) => {\n listener(this.internalState);\n });\n }\n\n /**\n * Adds new listener to be notified of state changes.\n *\n * @param listener - The callback triggered when state changes.\n */\n subscribe(listener: Listener<S>) {\n this.internalListeners.push(listener);\n }\n\n /**\n * Removes existing listener from receiving state changes.\n *\n * @param listener - The callback to remove.\n * @returns `true` if a listener is found and unsubscribed.\n */\n unsubscribe(listener: Listener<S>) {\n const index = this.internalListeners.findIndex((cb) => listener === cb);\n index > -1 && this.internalListeners.splice(index, 1);\n return index > -1;\n }\n\n /**\n * Updates controller state.\n *\n * @param state - The new state.\n * @param overwrite - Overwrite state instead of merging.\n */\n update(state: Partial<S>, overwrite = false) {\n this.internalState = overwrite\n ? Object.assign({}, state as S)\n : Object.assign({}, this.internalState, state);\n this.notify();\n }\n}\n\nexport default BaseControllerV1;\n"]}
|
|
1
|
+
{"version":3,"file":"BaseControllerV1.mjs","sourceRoot":"","sources":["../src/BaseControllerV1.ts"],"names":[],"mappings":"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","sourcesContent":["import { isNullOrUndefined, type PublicInterface } from '@metamask/utils';\n\n/**\n * Determines if the given controller is an instance of `BaseControllerV1`\n *\n * @param controller - Controller instance to check\n * @returns True if the controller is an instance of `BaseControllerV1`\n */\nexport function isBaseControllerV1(\n controller: unknown,\n): controller is BaseControllerV1Instance {\n return (\n typeof controller === 'object' &&\n !isNullOrUndefined(controller) &&\n 'name' in controller &&\n typeof controller.name === 'string' &&\n 'config' in controller &&\n typeof controller.config === 'object' &&\n 'defaultConfig' in controller &&\n typeof controller.defaultConfig === 'object' &&\n 'state' in controller &&\n typeof controller.state === 'object' &&\n 'defaultState' in controller &&\n typeof controller.defaultState === 'object' &&\n 'disabled' in controller &&\n typeof controller.disabled === 'boolean' &&\n 'subscribe' in controller &&\n typeof controller.subscribe === 'function'\n );\n}\n\n/**\n * State change callbacks\n */\n// TODO: Either fix this lint violation or explain why it's necessary to ignore.\n// eslint-disable-next-line @typescript-eslint/naming-convention\nexport type Listener<T> = (state: T) => void;\n\n/**\n * @type BaseConfig\n *\n * Base controller configuration\n * @property disabled - Determines if this controller is enabled\n */\n// This interface was created before this ESLint rule was added.\n// Convert to a `type` in a future major version.\n// eslint-disable-next-line @typescript-eslint/consistent-type-definitions\nexport interface BaseConfig {\n disabled?: boolean;\n}\n\n/**\n * @type BaseState\n *\n * Base state representation\n * @property name - Unique name for this controller\n */\n// This interface was created before this ESLint rule was added.\n// Convert to a `type` in a future major version.\n// eslint-disable-next-line @typescript-eslint/consistent-type-definitions\nexport interface BaseState {\n name?: string;\n}\n\n/**\n * The narrowest supertype for `BaseControllerV1` config objects.\n * This type can be assigned to any `BaseControllerV1` config object.\n */\nexport type ConfigConstraint = BaseConfig & object;\n\n/**\n * The narrowest supertype for `BaseControllerV1` state objects.\n * This type can be assigned to any `BaseControllerV1` state object.\n */\nexport type StateConstraint = BaseState & object;\n\n/**\n * The widest subtype of all controller instances that extend from `BaseControllerV1`.\n * Any `BaseControllerV1` instance can be assigned to this type.\n */\nexport type BaseControllerV1Instance = PublicInterface<\n BaseControllerV1<ConfigConstraint, StateConstraint>\n>;\n\n/**\n * @deprecated This class has been renamed to BaseControllerV1 and is no longer recommended for use for controllers. Please use BaseController (formerly BaseControllerV2) instead.\n *\n * Controller class that provides configuration, state management, and subscriptions.\n *\n * The core purpose of every controller is to maintain an internal data object\n * called \"state\". Each controller is responsible for its own state, and all global wallet state\n * is tracked in a controller as state.\n */\n// TODO: Either fix this lint violation or explain why it's necessary to ignore.\n// eslint-disable-next-line @typescript-eslint/naming-convention\nexport class BaseControllerV1<C extends BaseConfig, S extends BaseState> {\n /**\n * Default options used to configure this controller\n */\n defaultConfig: C = {} as never;\n\n /**\n * Default state set on this controller\n */\n defaultState: S = {} as never;\n\n /**\n * Determines if listeners are notified of state changes\n */\n disabled = false;\n\n /**\n * Name of this controller used during composition\n */\n name = 'BaseController';\n\n private readonly initialConfig: Partial<C>;\n\n private readonly initialState: Partial<S>;\n\n private internalConfig: C = this.defaultConfig;\n\n private internalState: S = this.defaultState;\n\n private readonly internalListeners: Listener<S>[] = [];\n\n /**\n * Creates a BaseControllerV1 instance. Both initial state and initial\n * configuration options are merged with defaults upon initialization.\n *\n * @param config - Initial options used to configure this controller.\n * @param state - Initial state to set on this controller.\n */\n constructor(config: Partial<C> = {}, state: Partial<S> = {}) {\n this.initialState = state;\n this.initialConfig = config;\n }\n\n /**\n * Enables the controller. This sets each config option as a member\n * variable on this instance and triggers any defined setters. This\n * also sets initial state and triggers any listeners.\n *\n * @returns This controller instance.\n */\n protected initialize() {\n this.internalState = this.defaultState;\n this.internalConfig = this.defaultConfig;\n this.configure(this.initialConfig);\n this.update(this.initialState);\n return this;\n }\n\n /**\n * Retrieves current controller configuration options.\n *\n * @returns The current configuration.\n */\n get config() {\n return this.internalConfig;\n }\n\n /**\n * Retrieves current controller state.\n *\n * @returns The current state.\n */\n get state() {\n return this.internalState;\n }\n\n /**\n * Updates controller configuration.\n *\n * @param config - New configuration options.\n * @param overwrite - Overwrite config instead of merging.\n * @param fullUpdate - Boolean that defines if the update is partial or not.\n */\n configure(config: Partial<C>, overwrite = false, fullUpdate = true) {\n if (fullUpdate) {\n this.internalConfig = overwrite\n ? (config as C)\n : Object.assign(this.internalConfig, config);\n\n for (const key of Object.keys(this.internalConfig) as (keyof C)[]) {\n const value = this.internalConfig[key];\n if (value !== undefined) {\n (this as unknown as C)[key] = value;\n }\n }\n } else {\n for (const key of Object.keys(config) as (keyof C)[]) {\n /* istanbul ignore else */\n if (this.internalConfig[key] !== undefined) {\n const value = (config as C)[key];\n this.internalConfig[key] = value;\n (this as unknown as C)[key] = value;\n }\n }\n }\n }\n\n /**\n * Notifies all subscribed listeners of current state.\n */\n notify() {\n if (this.disabled) {\n return;\n }\n\n this.internalListeners.forEach((listener) => {\n listener(this.internalState);\n });\n }\n\n /**\n * Adds new listener to be notified of state changes.\n *\n * @param listener - The callback triggered when state changes.\n */\n subscribe(listener: Listener<S>) {\n this.internalListeners.push(listener);\n }\n\n /**\n * Removes existing listener from receiving state changes.\n *\n * @param listener - The callback to remove.\n * @returns `true` if a listener is found and unsubscribed.\n */\n unsubscribe(listener: Listener<S>) {\n const index = this.internalListeners.findIndex((cb) => listener === cb);\n index > -1 && this.internalListeners.splice(index, 1);\n return index > -1;\n }\n\n /**\n * Updates controller state.\n *\n * @param state - The new state.\n * @param overwrite - Overwrite state instead of merging.\n */\n update(state: Partial<S>, overwrite = false) {\n this.internalState = overwrite\n ? Object.assign({}, state as S)\n : Object.assign({}, this.internalState, state);\n this.notify();\n }\n}\n\nexport default BaseControllerV1;\n"]}
|
|
@@ -13,6 +13,7 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
|
|
|
13
13
|
var _BaseController_internalState;
|
|
14
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
15
|
exports.getPersistentState = exports.getAnonymizedState = exports.BaseController = exports.isBaseController = void 0;
|
|
16
|
+
const utils_1 = require("@metamask/utils");
|
|
16
17
|
const immer_1 = require("immer");
|
|
17
18
|
(0, immer_1.enablePatches)();
|
|
18
19
|
/**
|
|
@@ -22,7 +23,9 @@ const immer_1 = require("immer");
|
|
|
22
23
|
* @returns True if the controller is an instance of `BaseController`
|
|
23
24
|
*/
|
|
24
25
|
function isBaseController(controller) {
|
|
25
|
-
return ('
|
|
26
|
+
return (typeof controller === 'object' &&
|
|
27
|
+
!(0, utils_1.isNullOrUndefined)(controller) &&
|
|
28
|
+
'name' in controller &&
|
|
26
29
|
typeof controller.name === 'string' &&
|
|
27
30
|
'state' in controller &&
|
|
28
31
|
typeof controller.state === 'object' &&
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BaseControllerV2.cjs","sourceRoot":"","sources":["../src/BaseControllerV2.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Json, PublicInterface } from '@metamask/utils';\nimport { enablePatches, produceWithPatches, applyPatches, freeze } from 'immer';\nimport type { Draft, Patch } from 'immer';\n\nimport type {\n BaseControllerV1Instance,\n StateConstraint as StateConstraintV1,\n} from './BaseControllerV1';\nimport type { ActionConstraint, EventConstraint } from './ControllerMessenger';\nimport type {\n RestrictedControllerMessenger,\n RestrictedControllerMessengerConstraint,\n} from './RestrictedControllerMessenger';\n\nenablePatches();\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 */\nexport function isBaseController(\n controller: ControllerInstance,\n): controller is BaseControllerInstance {\n return (\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\n/**\n * A type that constrains the state of all controllers.\n *\n * In other words, the narrowest supertype encompassing all controller state.\n */\nexport type StateConstraint = Record<string, Json>;\n\n/**\n * A universal supertype for the controller state object, encompassing both `BaseControllerV1` and `BaseControllerV2` state.\n */\n// TODO: Remove once BaseControllerV2 migrations are completed for all controllers.\nexport type LegacyControllerStateConstraint =\n | StateConstraintV1\n | StateConstraint;\n\n/**\n * A state change listener.\n *\n * This function will get called for each state change, and is given a copy of\n * the new state along with a set of patches describing the changes since the\n * last update.\n *\n * @param state - The new controller state.\n * @param patches - A list of patches describing any changes (see here for more\n * information: https://immerjs.github.io/immer/docs/patches)\n */\n// TODO: Either fix this lint violation or explain why it's necessary to ignore.\n// eslint-disable-next-line @typescript-eslint/naming-convention\nexport type Listener<T> = (state: T, patches: Patch[]) => void;\n\n/**\n * An function to derive state.\n *\n * This function will accept one piece of the controller state (one property),\n * and will return some derivation of that state.\n *\n * @param value - A piece of controller state.\n * @returns Something derived from controller state.\n */\n// TODO: Either fix this lint violation or explain why it's necessary to ignore.\n// eslint-disable-next-line @typescript-eslint/naming-convention\nexport type StateDeriver<T extends Json> = (value: T) => Json;\n\n/**\n * State metadata.\n *\n * This metadata describes which parts of state should be persisted, and how to\n * get an anonymized representation of the state.\n */\n// TODO: Either fix this lint violation or explain why it's necessary to ignore.\n// eslint-disable-next-line @typescript-eslint/naming-convention\nexport type StateMetadata<T extends StateConstraint> = {\n [P in keyof T]-?: StatePropertyMetadata<T[P]>;\n};\n\n/**\n * Metadata for a single state property\n *\n * @property persist - Indicates whether this property should be persisted\n * (`true` for persistent, `false` for transient), or is set to a function\n * that derives the persistent state from the state.\n * @property anonymous - Indicates whether this property is already anonymous,\n * (`true` for anonymous, `false` if it has potential to be personally\n * identifiable), or is set to a function that returns an anonymized\n * representation of this state.\n */\n// TODO: Either fix this lint violation or explain why it's necessary to ignore.\n// eslint-disable-next-line @typescript-eslint/naming-convention\nexport type StatePropertyMetadata<T extends Json> = {\n persist: boolean | StateDeriver<T>;\n anonymous: boolean | StateDeriver<T>;\n};\n\n/**\n * A universal supertype of `StateDeriver` types.\n * This type can be assigned to any `StateDeriver` type.\n */\nexport type StateDeriverConstraint = (value: never) => Json;\n\n/**\n * A universal supertype of `StatePropertyMetadata` types.\n * This type can be assigned to any `StatePropertyMetadata` type.\n */\nexport type StatePropertyMetadataConstraint = {\n [P in 'anonymous' | 'persist']: boolean | StateDeriverConstraint;\n};\n\n/**\n * A universal supertype of `StateMetadata` types.\n * This type can be assigned to any `StateMetadata` type.\n */\nexport type StateMetadataConstraint = Record<\n string,\n StatePropertyMetadataConstraint\n>;\n\n/**\n * The widest subtype of all controller instances that inherit from `BaseController` (formerly `BaseControllerV2`).\n * Any `BaseController` subclass instance can be assigned to this type.\n */\nexport type BaseControllerInstance = Omit<\n PublicInterface<\n BaseController<\n string,\n StateConstraint,\n RestrictedControllerMessengerConstraint\n >\n >,\n 'metadata'\n> & {\n metadata: StateMetadataConstraint;\n};\n\n/**\n * A widest subtype of all controller instances that inherit from `BaseController` (formerly `BaseControllerV2`) or `BaseControllerV1`.\n * Any `BaseController` or `BaseControllerV1` subclass instance can be assigned to this type.\n */\n// TODO: Remove once BaseControllerV2 migrations are completed for all controllers.\nexport type ControllerInstance =\n | BaseControllerV1Instance\n | BaseControllerInstance;\n\nexport type ControllerGetStateAction<\n ControllerName extends string,\n ControllerState extends StateConstraint,\n> = {\n type: `${ControllerName}:getState`;\n handler: () => ControllerState;\n};\n\nexport type ControllerStateChangeEvent<\n ControllerName extends string,\n ControllerState extends StateConstraint,\n> = {\n type: `${ControllerName}:stateChange`;\n payload: [ControllerState, Patch[]];\n};\n\nexport type ControllerActions<\n ControllerName extends string,\n ControllerState extends StateConstraint,\n> = ControllerGetStateAction<ControllerName, ControllerState>;\n\nexport type ControllerEvents<\n ControllerName extends string,\n ControllerState extends StateConstraint,\n> = ControllerStateChangeEvent<ControllerName, ControllerState>;\n\n/**\n * Controller class that provides state management, subscriptions, and state metadata\n */\nexport class BaseController<\n ControllerName extends string,\n ControllerState extends StateConstraint,\n // TODO: Either fix this lint violation or explain why it's necessary to ignore.\n // eslint-disable-next-line @typescript-eslint/naming-convention\n messenger extends RestrictedControllerMessenger<\n ControllerName,\n ActionConstraint | ControllerActions<ControllerName, ControllerState>,\n EventConstraint | ControllerEvents<ControllerName, ControllerState>,\n string,\n string\n >,\n> {\n #internalState: ControllerState;\n\n protected messagingSystem: messenger;\n\n /**\n * The name of the controller.\n *\n * This is used by the ComposableController to construct a composed application state.\n */\n public readonly name: ControllerName;\n\n public readonly metadata: StateMetadata<ControllerState>;\n\n /**\n * Creates a BaseController instance.\n *\n * @param options - Controller options.\n * @param options.messenger - Controller messaging system.\n * @param options.metadata - ControllerState metadata, describing how to \"anonymize\" the state, and which\n * parts should be persisted.\n * @param options.name - The name of the controller, used as a namespace for events and actions.\n * @param options.state - Initial controller state.\n */\n constructor({\n messenger,\n metadata,\n name,\n state,\n }: {\n messenger: messenger;\n metadata: StateMetadata<ControllerState>;\n name: ControllerName;\n state: ControllerState;\n }) {\n this.messagingSystem = messenger;\n this.name = name;\n // Here we use `freeze` from Immer to enforce that the state is deeply\n // immutable. Note that this is a runtime check, not a compile-time check.\n // That is, unlike `Object.freeze`, this does not narrow the type\n // recursively to `Readonly`. The equivalent in Immer is `Immutable`, but\n // `Immutable` does not handle recursive types such as our `Json` type.\n this.#internalState = freeze(state, true);\n this.metadata = metadata;\n\n this.messagingSystem.registerActionHandler(\n `${name}:getState`,\n () => this.state,\n );\n\n this.messagingSystem.registerInitialEventPayload({\n eventType: `${name}:stateChange`,\n getPayload: () => [this.state, []],\n });\n }\n\n /**\n * Retrieves current controller state.\n *\n * @returns The current state.\n */\n get state() {\n return this.#internalState;\n }\n\n set state(_) {\n throw new Error(\n `Controller state cannot be directly mutated; use 'update' method instead.`,\n );\n }\n\n /**\n * Updates controller state. Accepts a callback that is passed a draft copy\n * of the controller state. If a value is returned, it is set as the new\n * state. Otherwise, any changes made within that callback to the draft are\n * applied to the controller state.\n *\n * @param callback - Callback for updating state, passed a draft state\n * object. Return a new state object or mutate the draft to update state.\n * @returns An object that has the next state, patches applied in the update and inverse patches to\n * rollback the update.\n */\n protected update(\n callback: (state: Draft<ControllerState>) => void | ControllerState,\n ): {\n nextState: ControllerState;\n patches: Patch[];\n inversePatches: Patch[];\n } {\n // We run into ts2589, \"infinite type depth\", if we don't cast\n // produceWithPatches here.\n const [nextState, patches, inversePatches] = (\n produceWithPatches as unknown as (\n state: ControllerState,\n cb: typeof callback,\n ) => [ControllerState, Patch[], Patch[]]\n )(this.#internalState, callback);\n\n this.#internalState = nextState;\n this.messagingSystem.publish(\n `${this.name}:stateChange`,\n nextState,\n patches,\n );\n\n return { nextState, patches, inversePatches };\n }\n\n /**\n * Applies immer patches to the current state. The patches come from the\n * update function itself and can either be normal or inverse patches.\n *\n * @param patches - An array of immer patches that are to be applied to make\n * or undo changes.\n */\n protected applyPatches(patches: Patch[]) {\n const nextState = applyPatches(this.#internalState, patches);\n this.#internalState = nextState;\n this.messagingSystem.publish(\n `${this.name}:stateChange`,\n nextState,\n patches,\n );\n }\n\n /**\n * Prepares the controller for garbage collection. This should be extended\n * by any subclasses to clean up any additional connections or events.\n *\n * The only cleanup performed here is to remove listeners. While technically\n * this is not required to ensure this instance is garbage collected, it at\n * least ensures this instance won't be responsible for preventing the\n * listeners from being garbage collected.\n */\n protected destroy() {\n this.messagingSystem.clearEventSubscriptions(`${this.name}:stateChange`);\n }\n}\n\n/**\n * Returns an anonymized representation of the controller state.\n *\n * By \"anonymized\" we mean that it should not contain any information that could be personally\n * identifiable.\n *\n * @param state - The controller state.\n * @param metadata - The controller state metadata, which describes how to derive the\n * anonymized state.\n * @returns The anonymized controller state.\n */\nexport function getAnonymizedState<ControllerState extends StateConstraint>(\n state: ControllerState,\n metadata: StateMetadata<ControllerState>,\n): Record<keyof ControllerState, Json> {\n return deriveStateFromMetadata(state, metadata, 'anonymous');\n}\n\n/**\n * Returns the subset of state that should be persisted.\n *\n * @param state - The controller state.\n * @param metadata - The controller state metadata, which describes which pieces of state should be persisted.\n * @returns The subset of controller state that should be persisted.\n */\nexport function getPersistentState<ControllerState extends StateConstraint>(\n state: ControllerState,\n metadata: StateMetadata<ControllerState>,\n): Record<keyof ControllerState, Json> {\n return deriveStateFromMetadata(state, metadata, 'persist');\n}\n\n/**\n * Use the metadata to derive state according to the given metadata property.\n *\n * @param state - The full controller state.\n * @param metadata - The controller metadata.\n * @param metadataProperty - The metadata property to use to derive state.\n * @returns The metadata-derived controller state.\n */\nfunction deriveStateFromMetadata<ControllerState extends StateConstraint>(\n state: ControllerState,\n metadata: StateMetadata<ControllerState>,\n metadataProperty: 'anonymous' | 'persist',\n): Record<keyof ControllerState, Json> {\n return (Object.keys(state) as (keyof ControllerState)[]).reduce<\n Record<keyof ControllerState, Json>\n >((derivedState, key) => {\n try {\n const stateMetadata = metadata[key];\n if (!stateMetadata) {\n throw new Error(`No metadata found for '${String(key)}'`);\n }\n const propertyMetadata = stateMetadata[metadataProperty];\n const stateProperty = state[key];\n if (typeof propertyMetadata === 'function') {\n derivedState[key] = propertyMetadata(stateProperty);\n } else if (propertyMetadata) {\n derivedState[key] = stateProperty;\n }\n return derivedState;\n } catch (error) {\n // Throw error after timeout so that it is captured as a console error\n // (and by Sentry) without interrupting state-related operations\n setTimeout(() => {\n throw error;\n });\n return derivedState;\n }\n }, {} as never);\n}\n"]}
|
|
1
|
+
{"version":3,"file":"BaseControllerV2.cjs","sourceRoot":"","sources":["../src/BaseControllerV2.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n isNullOrUndefined,\n type Json,\n type PublicInterface,\n} from '@metamask/utils';\nimport { enablePatches, produceWithPatches, applyPatches, freeze } from 'immer';\nimport type { Draft, Patch } from 'immer';\n\nimport type {\n BaseControllerV1Instance,\n StateConstraint as StateConstraintV1,\n} from './BaseControllerV1';\nimport type { ActionConstraint, EventConstraint } from './ControllerMessenger';\nimport type {\n RestrictedControllerMessenger,\n RestrictedControllerMessengerConstraint,\n} from './RestrictedControllerMessenger';\n\nenablePatches();\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 */\nexport function isBaseController(\n controller: unknown,\n): controller is BaseControllerInstance {\n return (\n typeof controller === 'object' &&\n !isNullOrUndefined(controller) &&\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\n/**\n * A type that constrains the state of all controllers.\n *\n * In other words, the narrowest supertype encompassing all controller state.\n */\nexport type StateConstraint = Record<string, Json>;\n\n/**\n * A universal supertype for the controller state object, encompassing both `BaseControllerV1` and `BaseControllerV2` state.\n */\n// TODO: Remove once BaseControllerV2 migrations are completed for all controllers.\nexport type LegacyControllerStateConstraint =\n | StateConstraintV1\n | StateConstraint;\n\n/**\n * A state change listener.\n *\n * This function will get called for each state change, and is given a copy of\n * the new state along with a set of patches describing the changes since the\n * last update.\n *\n * @param state - The new controller state.\n * @param patches - A list of patches describing any changes (see here for more\n * information: https://immerjs.github.io/immer/docs/patches)\n */\n// TODO: Either fix this lint violation or explain why it's necessary to ignore.\n// eslint-disable-next-line @typescript-eslint/naming-convention\nexport type Listener<T> = (state: T, patches: Patch[]) => void;\n\n/**\n * An function to derive state.\n *\n * This function will accept one piece of the controller state (one property),\n * and will return some derivation of that state.\n *\n * @param value - A piece of controller state.\n * @returns Something derived from controller state.\n */\n// TODO: Either fix this lint violation or explain why it's necessary to ignore.\n// eslint-disable-next-line @typescript-eslint/naming-convention\nexport type StateDeriver<T extends Json> = (value: T) => Json;\n\n/**\n * State metadata.\n *\n * This metadata describes which parts of state should be persisted, and how to\n * get an anonymized representation of the state.\n */\n// TODO: Either fix this lint violation or explain why it's necessary to ignore.\n// eslint-disable-next-line @typescript-eslint/naming-convention\nexport type StateMetadata<T extends StateConstraint> = {\n [P in keyof T]-?: StatePropertyMetadata<T[P]>;\n};\n\n/**\n * Metadata for a single state property\n *\n * @property persist - Indicates whether this property should be persisted\n * (`true` for persistent, `false` for transient), or is set to a function\n * that derives the persistent state from the state.\n * @property anonymous - Indicates whether this property is already anonymous,\n * (`true` for anonymous, `false` if it has potential to be personally\n * identifiable), or is set to a function that returns an anonymized\n * representation of this state.\n */\n// TODO: Either fix this lint violation or explain why it's necessary to ignore.\n// eslint-disable-next-line @typescript-eslint/naming-convention\nexport type StatePropertyMetadata<T extends Json> = {\n persist: boolean | StateDeriver<T>;\n anonymous: boolean | StateDeriver<T>;\n};\n\n/**\n * A universal supertype of `StateDeriver` types.\n * This type can be assigned to any `StateDeriver` type.\n */\nexport type StateDeriverConstraint = (value: never) => Json;\n\n/**\n * A universal supertype of `StatePropertyMetadata` types.\n * This type can be assigned to any `StatePropertyMetadata` type.\n */\nexport type StatePropertyMetadataConstraint = {\n [P in 'anonymous' | 'persist']: boolean | StateDeriverConstraint;\n};\n\n/**\n * A universal supertype of `StateMetadata` types.\n * This type can be assigned to any `StateMetadata` type.\n */\nexport type StateMetadataConstraint = Record<\n string,\n StatePropertyMetadataConstraint\n>;\n\n/**\n * The narrowest supertype of all controller instances that inherit from `BaseController` (formerly `BaseControllerV2`).\n * Any `BaseController` subclass instance can be assigned to this type.\n */\nexport type BaseControllerInstance = Omit<\n PublicInterface<\n BaseController<\n string,\n StateConstraint,\n RestrictedControllerMessengerConstraint\n >\n >,\n 'metadata'\n> & {\n metadata: StateMetadataConstraint;\n};\n\n/**\n * A narrowest supertype of all controller instances that inherit from `BaseController` (formerly `BaseControllerV2`) or `BaseControllerV1`.\n * Any `BaseController` or `BaseControllerV1` subclass instance can be assigned to this type.\n */\n// TODO: Remove once BaseControllerV2 migrations are completed for all controllers.\nexport type ControllerInstance =\n | BaseControllerV1Instance\n | BaseControllerInstance;\n\nexport type ControllerGetStateAction<\n ControllerName extends string,\n ControllerState extends StateConstraint,\n> = {\n type: `${ControllerName}:getState`;\n handler: () => ControllerState;\n};\n\nexport type ControllerStateChangeEvent<\n ControllerName extends string,\n ControllerState extends StateConstraint,\n> = {\n type: `${ControllerName}:stateChange`;\n payload: [ControllerState, Patch[]];\n};\n\nexport type ControllerActions<\n ControllerName extends string,\n ControllerState extends StateConstraint,\n> = ControllerGetStateAction<ControllerName, ControllerState>;\n\nexport type ControllerEvents<\n ControllerName extends string,\n ControllerState extends StateConstraint,\n> = ControllerStateChangeEvent<ControllerName, ControllerState>;\n\n/**\n * Controller class that provides state management, subscriptions, and state metadata\n */\nexport class BaseController<\n ControllerName extends string,\n ControllerState extends StateConstraint,\n // TODO: Either fix this lint violation or explain why it's necessary to ignore.\n // eslint-disable-next-line @typescript-eslint/naming-convention\n messenger extends RestrictedControllerMessenger<\n ControllerName,\n ActionConstraint | ControllerActions<ControllerName, ControllerState>,\n EventConstraint | ControllerEvents<ControllerName, ControllerState>,\n string,\n string\n >,\n> {\n #internalState: ControllerState;\n\n protected messagingSystem: messenger;\n\n /**\n * The name of the controller.\n *\n * This is used by the ComposableController to construct a composed application state.\n */\n public readonly name: ControllerName;\n\n public readonly metadata: StateMetadata<ControllerState>;\n\n /**\n * Creates a BaseController instance.\n *\n * @param options - Controller options.\n * @param options.messenger - Controller messaging system.\n * @param options.metadata - ControllerState metadata, describing how to \"anonymize\" the state, and which\n * parts should be persisted.\n * @param options.name - The name of the controller, used as a namespace for events and actions.\n * @param options.state - Initial controller state.\n */\n constructor({\n messenger,\n metadata,\n name,\n state,\n }: {\n messenger: messenger;\n metadata: StateMetadata<ControllerState>;\n name: ControllerName;\n state: ControllerState;\n }) {\n this.messagingSystem = messenger;\n this.name = name;\n // Here we use `freeze` from Immer to enforce that the state is deeply\n // immutable. Note that this is a runtime check, not a compile-time check.\n // That is, unlike `Object.freeze`, this does not narrow the type\n // recursively to `Readonly`. The equivalent in Immer is `Immutable`, but\n // `Immutable` does not handle recursive types such as our `Json` type.\n this.#internalState = freeze(state, true);\n this.metadata = metadata;\n\n this.messagingSystem.registerActionHandler(\n `${name}:getState`,\n () => this.state,\n );\n\n this.messagingSystem.registerInitialEventPayload({\n eventType: `${name}:stateChange`,\n getPayload: () => [this.state, []],\n });\n }\n\n /**\n * Retrieves current controller state.\n *\n * @returns The current state.\n */\n get state() {\n return this.#internalState;\n }\n\n set state(_) {\n throw new Error(\n `Controller state cannot be directly mutated; use 'update' method instead.`,\n );\n }\n\n /**\n * Updates controller state. Accepts a callback that is passed a draft copy\n * of the controller state. If a value is returned, it is set as the new\n * state. Otherwise, any changes made within that callback to the draft are\n * applied to the controller state.\n *\n * @param callback - Callback for updating state, passed a draft state\n * object. Return a new state object or mutate the draft to update state.\n * @returns An object that has the next state, patches applied in the update and inverse patches to\n * rollback the update.\n */\n protected update(\n callback: (state: Draft<ControllerState>) => void | ControllerState,\n ): {\n nextState: ControllerState;\n patches: Patch[];\n inversePatches: Patch[];\n } {\n // We run into ts2589, \"infinite type depth\", if we don't cast\n // produceWithPatches here.\n const [nextState, patches, inversePatches] = (\n produceWithPatches as unknown as (\n state: ControllerState,\n cb: typeof callback,\n ) => [ControllerState, Patch[], Patch[]]\n )(this.#internalState, callback);\n\n this.#internalState = nextState;\n this.messagingSystem.publish(\n `${this.name}:stateChange`,\n nextState,\n patches,\n );\n\n return { nextState, patches, inversePatches };\n }\n\n /**\n * Applies immer patches to the current state. The patches come from the\n * update function itself and can either be normal or inverse patches.\n *\n * @param patches - An array of immer patches that are to be applied to make\n * or undo changes.\n */\n protected applyPatches(patches: Patch[]) {\n const nextState = applyPatches(this.#internalState, patches);\n this.#internalState = nextState;\n this.messagingSystem.publish(\n `${this.name}:stateChange`,\n nextState,\n patches,\n );\n }\n\n /**\n * Prepares the controller for garbage collection. This should be extended\n * by any subclasses to clean up any additional connections or events.\n *\n * The only cleanup performed here is to remove listeners. While technically\n * this is not required to ensure this instance is garbage collected, it at\n * least ensures this instance won't be responsible for preventing the\n * listeners from being garbage collected.\n */\n protected destroy() {\n this.messagingSystem.clearEventSubscriptions(`${this.name}:stateChange`);\n }\n}\n\n/**\n * Returns an anonymized representation of the controller state.\n *\n * By \"anonymized\" we mean that it should not contain any information that could be personally\n * identifiable.\n *\n * @param state - The controller state.\n * @param metadata - The controller state metadata, which describes how to derive the\n * anonymized state.\n * @returns The anonymized controller state.\n */\nexport function getAnonymizedState<ControllerState extends StateConstraint>(\n state: ControllerState,\n metadata: StateMetadata<ControllerState>,\n): Record<keyof ControllerState, Json> {\n return deriveStateFromMetadata(state, metadata, 'anonymous');\n}\n\n/**\n * Returns the subset of state that should be persisted.\n *\n * @param state - The controller state.\n * @param metadata - The controller state metadata, which describes which pieces of state should be persisted.\n * @returns The subset of controller state that should be persisted.\n */\nexport function getPersistentState<ControllerState extends StateConstraint>(\n state: ControllerState,\n metadata: StateMetadata<ControllerState>,\n): Record<keyof ControllerState, Json> {\n return deriveStateFromMetadata(state, metadata, 'persist');\n}\n\n/**\n * Use the metadata to derive state according to the given metadata property.\n *\n * @param state - The full controller state.\n * @param metadata - The controller metadata.\n * @param metadataProperty - The metadata property to use to derive state.\n * @returns The metadata-derived controller state.\n */\nfunction deriveStateFromMetadata<ControllerState extends StateConstraint>(\n state: ControllerState,\n metadata: StateMetadata<ControllerState>,\n metadataProperty: 'anonymous' | 'persist',\n): Record<keyof ControllerState, Json> {\n return (Object.keys(state) as (keyof ControllerState)[]).reduce<\n Record<keyof ControllerState, Json>\n >((derivedState, key) => {\n try {\n const stateMetadata = metadata[key];\n if (!stateMetadata) {\n throw new Error(`No metadata found for '${String(key)}'`);\n }\n const propertyMetadata = stateMetadata[metadataProperty];\n const stateProperty = state[key];\n if (typeof propertyMetadata === 'function') {\n derivedState[key] = propertyMetadata(stateProperty);\n } else if (propertyMetadata) {\n derivedState[key] = stateProperty;\n }\n return derivedState;\n } catch (error) {\n // Throw error after timeout so that it is captured as a console error\n // (and by Sentry) without interrupting state-related operations\n setTimeout(() => {\n throw error;\n });\n return derivedState;\n }\n }, {} as never);\n}\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type Json, type PublicInterface } from "@metamask/utils";
|
|
2
2
|
import type { Draft, Patch } from "immer";
|
|
3
3
|
import type { BaseControllerV1Instance, StateConstraint as StateConstraintV1 } from "./BaseControllerV1.cjs";
|
|
4
4
|
import type { ActionConstraint, EventConstraint } from "./ControllerMessenger.cjs";
|
|
@@ -9,7 +9,7 @@ import type { RestrictedControllerMessenger, RestrictedControllerMessengerConstr
|
|
|
9
9
|
* @param controller - Controller instance to check
|
|
10
10
|
* @returns True if the controller is an instance of `BaseController`
|
|
11
11
|
*/
|
|
12
|
-
export declare function isBaseController(controller:
|
|
12
|
+
export declare function isBaseController(controller: unknown): controller is BaseControllerInstance;
|
|
13
13
|
/**
|
|
14
14
|
* A type that constrains the state of all controllers.
|
|
15
15
|
*
|
|
@@ -84,14 +84,14 @@ export type StatePropertyMetadataConstraint = {
|
|
|
84
84
|
*/
|
|
85
85
|
export type StateMetadataConstraint = Record<string, StatePropertyMetadataConstraint>;
|
|
86
86
|
/**
|
|
87
|
-
* The
|
|
87
|
+
* The narrowest supertype of all controller instances that inherit from `BaseController` (formerly `BaseControllerV2`).
|
|
88
88
|
* Any `BaseController` subclass instance can be assigned to this type.
|
|
89
89
|
*/
|
|
90
90
|
export type BaseControllerInstance = Omit<PublicInterface<BaseController<string, StateConstraint, RestrictedControllerMessengerConstraint>>, 'metadata'> & {
|
|
91
91
|
metadata: StateMetadataConstraint;
|
|
92
92
|
};
|
|
93
93
|
/**
|
|
94
|
-
* A
|
|
94
|
+
* A narrowest supertype of all controller instances that inherit from `BaseController` (formerly `BaseControllerV2`) or `BaseControllerV1`.
|
|
95
95
|
* Any `BaseController` or `BaseControllerV1` subclass instance can be assigned to this type.
|
|
96
96
|
*/
|
|
97
97
|
export type ControllerInstance = BaseControllerV1Instance | BaseControllerInstance;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BaseControllerV2.d.cts","sourceRoot":"","sources":["../src/BaseControllerV2.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"BaseControllerV2.d.cts","sourceRoot":"","sources":["../src/BaseControllerV2.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,IAAI,EACT,KAAK,eAAe,EACrB,wBAAwB;AAEzB,OAAO,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,cAAc;AAE1C,OAAO,KAAK,EACV,wBAAwB,EACxB,eAAe,IAAI,iBAAiB,EACrC,+BAA2B;AAC5B,OAAO,KAAK,EAAE,gBAAgB,EAAE,eAAe,EAAE,kCAA8B;AAC/E,OAAO,KAAK,EACV,6BAA6B,EAC7B,uCAAuC,EACxC,4CAAwC;AAIzC;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAC9B,UAAU,EAAE,OAAO,GAClB,UAAU,IAAI,sBAAsB,CAWtC;AAED;;;;GAIG;AACH,MAAM,MAAM,eAAe,GAAG,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;AAEnD;;GAEG;AAEH,MAAM,MAAM,+BAA+B,GACvC,iBAAiB,GACjB,eAAe,CAAC;AAEpB;;;;;;;;;;GAUG;AAGH,MAAM,MAAM,QAAQ,CAAC,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,IAAI,CAAC;AAE/D;;;;;;;;GAQG;AAGH,MAAM,MAAM,YAAY,CAAC,CAAC,SAAS,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC,KAAK,IAAI,CAAC;AAE9D;;;;;GAKG;AAGH,MAAM,MAAM,aAAa,CAAC,CAAC,SAAS,eAAe,IAAI;KACpD,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,GAAG,qBAAqB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;CAC9C,CAAC;AAEF;;;;;;;;;;GAUG;AAGH,MAAM,MAAM,qBAAqB,CAAC,CAAC,SAAS,IAAI,IAAI;IAClD,OAAO,EAAE,OAAO,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC;IACnC,SAAS,EAAE,OAAO,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC;CACtC,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,sBAAsB,GAAG,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;AAE5D;;;GAGG;AACH,MAAM,MAAM,+BAA+B,GAAG;KAC3C,CAAC,IAAI,WAAW,GAAG,SAAS,GAAG,OAAO,GAAG,sBAAsB;CACjE,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,uBAAuB,GAAG,MAAM,CAC1C,MAAM,EACN,+BAA+B,CAChC,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,sBAAsB,GAAG,IAAI,CACvC,eAAe,CACb,cAAc,CACZ,MAAM,EACN,eAAe,EACf,uCAAuC,CACxC,CACF,EACD,UAAU,CACX,GAAG;IACF,QAAQ,EAAE,uBAAuB,CAAC;CACnC,CAAC;AAEF;;;GAGG;AAEH,MAAM,MAAM,kBAAkB,GAC1B,wBAAwB,GACxB,sBAAsB,CAAC;AAE3B,MAAM,MAAM,wBAAwB,CAClC,cAAc,SAAS,MAAM,EAC7B,eAAe,SAAS,eAAe,IACrC;IACF,IAAI,EAAE,GAAG,cAAc,WAAW,CAAC;IACnC,OAAO,EAAE,MAAM,eAAe,CAAC;CAChC,CAAC;AAEF,MAAM,MAAM,0BAA0B,CACpC,cAAc,SAAS,MAAM,EAC7B,eAAe,SAAS,eAAe,IACrC;IACF,IAAI,EAAE,GAAG,cAAc,cAAc,CAAC;IACtC,OAAO,EAAE,CAAC,eAAe,EAAE,KAAK,EAAE,CAAC,CAAC;CACrC,CAAC;AAEF,MAAM,MAAM,iBAAiB,CAC3B,cAAc,SAAS,MAAM,EAC7B,eAAe,SAAS,eAAe,IACrC,wBAAwB,CAAC,cAAc,EAAE,eAAe,CAAC,CAAC;AAE9D,MAAM,MAAM,gBAAgB,CAC1B,cAAc,SAAS,MAAM,EAC7B,eAAe,SAAS,eAAe,IACrC,0BAA0B,CAAC,cAAc,EAAE,eAAe,CAAC,CAAC;AAEhE;;GAEG;AACH,qBAAa,cAAc,CACzB,cAAc,SAAS,MAAM,EAC7B,eAAe,SAAS,eAAe,EAGvC,SAAS,SAAS,6BAA6B,CAC7C,cAAc,EACd,gBAAgB,GAAG,iBAAiB,CAAC,cAAc,EAAE,eAAe,CAAC,EACrE,eAAe,GAAG,gBAAgB,CAAC,cAAc,EAAE,eAAe,CAAC,EACnE,MAAM,EACN,MAAM,CACP;;IAID,SAAS,CAAC,eAAe,EAAE,SAAS,CAAC;IAErC;;;;OAIG;IACH,SAAgB,IAAI,EAAE,cAAc,CAAC;IAErC,SAAgB,QAAQ,EAAE,aAAa,CAAC,eAAe,CAAC,CAAC;IAEzD;;;;;;;;;OASG;gBACS,EACV,SAAS,EACT,QAAQ,EACR,IAAI,EACJ,KAAK,GACN,EAAE;QACD,SAAS,EAAE,SAAS,CAAC;QACrB,QAAQ,EAAE,aAAa,CAAC,eAAe,CAAC,CAAC;QACzC,IAAI,EAAE,cAAc,CAAC;QACrB,KAAK,EAAE,eAAe,CAAC;KACxB;IAsBD;;;;OAIG;IACH,IAAI,KAAK,oBAER;IAED,IAAI,KAAK,CAAC,CAAC,iBAAA,EAIV;IAED;;;;;;;;;;OAUG;IACH,SAAS,CAAC,MAAM,CACd,QAAQ,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,eAAe,CAAC,KAAK,IAAI,GAAG,eAAe,GAClE;QACD,SAAS,EAAE,eAAe,CAAC;QAC3B,OAAO,EAAE,KAAK,EAAE,CAAC;QACjB,cAAc,EAAE,KAAK,EAAE,CAAC;KACzB;IAoBD;;;;;;OAMG;IACH,SAAS,CAAC,YAAY,CAAC,OAAO,EAAE,KAAK,EAAE;IAUvC;;;;;;;;OAQG;IACH,SAAS,CAAC,OAAO;CAGlB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,kBAAkB,CAAC,eAAe,SAAS,eAAe,EACxE,KAAK,EAAE,eAAe,EACtB,QAAQ,EAAE,aAAa,CAAC,eAAe,CAAC,GACvC,MAAM,CAAC,MAAM,eAAe,EAAE,IAAI,CAAC,CAErC;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,eAAe,SAAS,eAAe,EACxE,KAAK,EAAE,eAAe,EACtB,QAAQ,EAAE,aAAa,CAAC,eAAe,CAAC,GACvC,MAAM,CAAC,MAAM,eAAe,EAAE,IAAI,CAAC,CAErC"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type Json, type PublicInterface } from "@metamask/utils";
|
|
2
2
|
import type { Draft, Patch } from "immer";
|
|
3
3
|
import type { BaseControllerV1Instance, StateConstraint as StateConstraintV1 } from "./BaseControllerV1.mjs";
|
|
4
4
|
import type { ActionConstraint, EventConstraint } from "./ControllerMessenger.mjs";
|
|
@@ -9,7 +9,7 @@ import type { RestrictedControllerMessenger, RestrictedControllerMessengerConstr
|
|
|
9
9
|
* @param controller - Controller instance to check
|
|
10
10
|
* @returns True if the controller is an instance of `BaseController`
|
|
11
11
|
*/
|
|
12
|
-
export declare function isBaseController(controller:
|
|
12
|
+
export declare function isBaseController(controller: unknown): controller is BaseControllerInstance;
|
|
13
13
|
/**
|
|
14
14
|
* A type that constrains the state of all controllers.
|
|
15
15
|
*
|
|
@@ -84,14 +84,14 @@ export type StatePropertyMetadataConstraint = {
|
|
|
84
84
|
*/
|
|
85
85
|
export type StateMetadataConstraint = Record<string, StatePropertyMetadataConstraint>;
|
|
86
86
|
/**
|
|
87
|
-
* The
|
|
87
|
+
* The narrowest supertype of all controller instances that inherit from `BaseController` (formerly `BaseControllerV2`).
|
|
88
88
|
* Any `BaseController` subclass instance can be assigned to this type.
|
|
89
89
|
*/
|
|
90
90
|
export type BaseControllerInstance = Omit<PublicInterface<BaseController<string, StateConstraint, RestrictedControllerMessengerConstraint>>, 'metadata'> & {
|
|
91
91
|
metadata: StateMetadataConstraint;
|
|
92
92
|
};
|
|
93
93
|
/**
|
|
94
|
-
* A
|
|
94
|
+
* A narrowest supertype of all controller instances that inherit from `BaseController` (formerly `BaseControllerV2`) or `BaseControllerV1`.
|
|
95
95
|
* Any `BaseController` or `BaseControllerV1` subclass instance can be assigned to this type.
|
|
96
96
|
*/
|
|
97
97
|
export type ControllerInstance = BaseControllerV1Instance | BaseControllerInstance;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BaseControllerV2.d.mts","sourceRoot":"","sources":["../src/BaseControllerV2.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"BaseControllerV2.d.mts","sourceRoot":"","sources":["../src/BaseControllerV2.ts"],"names":[],"mappings":"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"}
|
|
@@ -10,6 +10,7 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
|
|
|
10
10
|
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
11
11
|
};
|
|
12
12
|
var _BaseController_internalState;
|
|
13
|
+
import { isNullOrUndefined } from "@metamask/utils";
|
|
13
14
|
import { enablePatches, produceWithPatches, applyPatches, freeze } from "immer";
|
|
14
15
|
enablePatches();
|
|
15
16
|
/**
|
|
@@ -19,7 +20,9 @@ enablePatches();
|
|
|
19
20
|
* @returns True if the controller is an instance of `BaseController`
|
|
20
21
|
*/
|
|
21
22
|
export function isBaseController(controller) {
|
|
22
|
-
return ('
|
|
23
|
+
return (typeof controller === 'object' &&
|
|
24
|
+
!isNullOrUndefined(controller) &&
|
|
25
|
+
'name' in controller &&
|
|
23
26
|
typeof controller.name === 'string' &&
|
|
24
27
|
'state' in controller &&
|
|
25
28
|
typeof controller.state === 'object' &&
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BaseControllerV2.mjs","sourceRoot":"","sources":["../src/BaseControllerV2.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Json, PublicInterface } from '@metamask/utils';\nimport { enablePatches, produceWithPatches, applyPatches, freeze } from 'immer';\nimport type { Draft, Patch } from 'immer';\n\nimport type {\n BaseControllerV1Instance,\n StateConstraint as StateConstraintV1,\n} from './BaseControllerV1';\nimport type { ActionConstraint, EventConstraint } from './ControllerMessenger';\nimport type {\n RestrictedControllerMessenger,\n RestrictedControllerMessengerConstraint,\n} from './RestrictedControllerMessenger';\n\nenablePatches();\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 */\nexport function isBaseController(\n controller: ControllerInstance,\n): controller is BaseControllerInstance {\n return (\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\n/**\n * A type that constrains the state of all controllers.\n *\n * In other words, the narrowest supertype encompassing all controller state.\n */\nexport type StateConstraint = Record<string, Json>;\n\n/**\n * A universal supertype for the controller state object, encompassing both `BaseControllerV1` and `BaseControllerV2` state.\n */\n// TODO: Remove once BaseControllerV2 migrations are completed for all controllers.\nexport type LegacyControllerStateConstraint =\n | StateConstraintV1\n | StateConstraint;\n\n/**\n * A state change listener.\n *\n * This function will get called for each state change, and is given a copy of\n * the new state along with a set of patches describing the changes since the\n * last update.\n *\n * @param state - The new controller state.\n * @param patches - A list of patches describing any changes (see here for more\n * information: https://immerjs.github.io/immer/docs/patches)\n */\n// TODO: Either fix this lint violation or explain why it's necessary to ignore.\n// eslint-disable-next-line @typescript-eslint/naming-convention\nexport type Listener<T> = (state: T, patches: Patch[]) => void;\n\n/**\n * An function to derive state.\n *\n * This function will accept one piece of the controller state (one property),\n * and will return some derivation of that state.\n *\n * @param value - A piece of controller state.\n * @returns Something derived from controller state.\n */\n// TODO: Either fix this lint violation or explain why it's necessary to ignore.\n// eslint-disable-next-line @typescript-eslint/naming-convention\nexport type StateDeriver<T extends Json> = (value: T) => Json;\n\n/**\n * State metadata.\n *\n * This metadata describes which parts of state should be persisted, and how to\n * get an anonymized representation of the state.\n */\n// TODO: Either fix this lint violation or explain why it's necessary to ignore.\n// eslint-disable-next-line @typescript-eslint/naming-convention\nexport type StateMetadata<T extends StateConstraint> = {\n [P in keyof T]-?: StatePropertyMetadata<T[P]>;\n};\n\n/**\n * Metadata for a single state property\n *\n * @property persist - Indicates whether this property should be persisted\n * (`true` for persistent, `false` for transient), or is set to a function\n * that derives the persistent state from the state.\n * @property anonymous - Indicates whether this property is already anonymous,\n * (`true` for anonymous, `false` if it has potential to be personally\n * identifiable), or is set to a function that returns an anonymized\n * representation of this state.\n */\n// TODO: Either fix this lint violation or explain why it's necessary to ignore.\n// eslint-disable-next-line @typescript-eslint/naming-convention\nexport type StatePropertyMetadata<T extends Json> = {\n persist: boolean | StateDeriver<T>;\n anonymous: boolean | StateDeriver<T>;\n};\n\n/**\n * A universal supertype of `StateDeriver` types.\n * This type can be assigned to any `StateDeriver` type.\n */\nexport type StateDeriverConstraint = (value: never) => Json;\n\n/**\n * A universal supertype of `StatePropertyMetadata` types.\n * This type can be assigned to any `StatePropertyMetadata` type.\n */\nexport type StatePropertyMetadataConstraint = {\n [P in 'anonymous' | 'persist']: boolean | StateDeriverConstraint;\n};\n\n/**\n * A universal supertype of `StateMetadata` types.\n * This type can be assigned to any `StateMetadata` type.\n */\nexport type StateMetadataConstraint = Record<\n string,\n StatePropertyMetadataConstraint\n>;\n\n/**\n * The widest subtype of all controller instances that inherit from `BaseController` (formerly `BaseControllerV2`).\n * Any `BaseController` subclass instance can be assigned to this type.\n */\nexport type BaseControllerInstance = Omit<\n PublicInterface<\n BaseController<\n string,\n StateConstraint,\n RestrictedControllerMessengerConstraint\n >\n >,\n 'metadata'\n> & {\n metadata: StateMetadataConstraint;\n};\n\n/**\n * A widest subtype of all controller instances that inherit from `BaseController` (formerly `BaseControllerV2`) or `BaseControllerV1`.\n * Any `BaseController` or `BaseControllerV1` subclass instance can be assigned to this type.\n */\n// TODO: Remove once BaseControllerV2 migrations are completed for all controllers.\nexport type ControllerInstance =\n | BaseControllerV1Instance\n | BaseControllerInstance;\n\nexport type ControllerGetStateAction<\n ControllerName extends string,\n ControllerState extends StateConstraint,\n> = {\n type: `${ControllerName}:getState`;\n handler: () => ControllerState;\n};\n\nexport type ControllerStateChangeEvent<\n ControllerName extends string,\n ControllerState extends StateConstraint,\n> = {\n type: `${ControllerName}:stateChange`;\n payload: [ControllerState, Patch[]];\n};\n\nexport type ControllerActions<\n ControllerName extends string,\n ControllerState extends StateConstraint,\n> = ControllerGetStateAction<ControllerName, ControllerState>;\n\nexport type ControllerEvents<\n ControllerName extends string,\n ControllerState extends StateConstraint,\n> = ControllerStateChangeEvent<ControllerName, ControllerState>;\n\n/**\n * Controller class that provides state management, subscriptions, and state metadata\n */\nexport class BaseController<\n ControllerName extends string,\n ControllerState extends StateConstraint,\n // TODO: Either fix this lint violation or explain why it's necessary to ignore.\n // eslint-disable-next-line @typescript-eslint/naming-convention\n messenger extends RestrictedControllerMessenger<\n ControllerName,\n ActionConstraint | ControllerActions<ControllerName, ControllerState>,\n EventConstraint | ControllerEvents<ControllerName, ControllerState>,\n string,\n string\n >,\n> {\n #internalState: ControllerState;\n\n protected messagingSystem: messenger;\n\n /**\n * The name of the controller.\n *\n * This is used by the ComposableController to construct a composed application state.\n */\n public readonly name: ControllerName;\n\n public readonly metadata: StateMetadata<ControllerState>;\n\n /**\n * Creates a BaseController instance.\n *\n * @param options - Controller options.\n * @param options.messenger - Controller messaging system.\n * @param options.metadata - ControllerState metadata, describing how to \"anonymize\" the state, and which\n * parts should be persisted.\n * @param options.name - The name of the controller, used as a namespace for events and actions.\n * @param options.state - Initial controller state.\n */\n constructor({\n messenger,\n metadata,\n name,\n state,\n }: {\n messenger: messenger;\n metadata: StateMetadata<ControllerState>;\n name: ControllerName;\n state: ControllerState;\n }) {\n this.messagingSystem = messenger;\n this.name = name;\n // Here we use `freeze` from Immer to enforce that the state is deeply\n // immutable. Note that this is a runtime check, not a compile-time check.\n // That is, unlike `Object.freeze`, this does not narrow the type\n // recursively to `Readonly`. The equivalent in Immer is `Immutable`, but\n // `Immutable` does not handle recursive types such as our `Json` type.\n this.#internalState = freeze(state, true);\n this.metadata = metadata;\n\n this.messagingSystem.registerActionHandler(\n `${name}:getState`,\n () => this.state,\n );\n\n this.messagingSystem.registerInitialEventPayload({\n eventType: `${name}:stateChange`,\n getPayload: () => [this.state, []],\n });\n }\n\n /**\n * Retrieves current controller state.\n *\n * @returns The current state.\n */\n get state() {\n return this.#internalState;\n }\n\n set state(_) {\n throw new Error(\n `Controller state cannot be directly mutated; use 'update' method instead.`,\n );\n }\n\n /**\n * Updates controller state. Accepts a callback that is passed a draft copy\n * of the controller state. If a value is returned, it is set as the new\n * state. Otherwise, any changes made within that callback to the draft are\n * applied to the controller state.\n *\n * @param callback - Callback for updating state, passed a draft state\n * object. Return a new state object or mutate the draft to update state.\n * @returns An object that has the next state, patches applied in the update and inverse patches to\n * rollback the update.\n */\n protected update(\n callback: (state: Draft<ControllerState>) => void | ControllerState,\n ): {\n nextState: ControllerState;\n patches: Patch[];\n inversePatches: Patch[];\n } {\n // We run into ts2589, \"infinite type depth\", if we don't cast\n // produceWithPatches here.\n const [nextState, patches, inversePatches] = (\n produceWithPatches as unknown as (\n state: ControllerState,\n cb: typeof callback,\n ) => [ControllerState, Patch[], Patch[]]\n )(this.#internalState, callback);\n\n this.#internalState = nextState;\n this.messagingSystem.publish(\n `${this.name}:stateChange`,\n nextState,\n patches,\n );\n\n return { nextState, patches, inversePatches };\n }\n\n /**\n * Applies immer patches to the current state. The patches come from the\n * update function itself and can either be normal or inverse patches.\n *\n * @param patches - An array of immer patches that are to be applied to make\n * or undo changes.\n */\n protected applyPatches(patches: Patch[]) {\n const nextState = applyPatches(this.#internalState, patches);\n this.#internalState = nextState;\n this.messagingSystem.publish(\n `${this.name}:stateChange`,\n nextState,\n patches,\n );\n }\n\n /**\n * Prepares the controller for garbage collection. This should be extended\n * by any subclasses to clean up any additional connections or events.\n *\n * The only cleanup performed here is to remove listeners. While technically\n * this is not required to ensure this instance is garbage collected, it at\n * least ensures this instance won't be responsible for preventing the\n * listeners from being garbage collected.\n */\n protected destroy() {\n this.messagingSystem.clearEventSubscriptions(`${this.name}:stateChange`);\n }\n}\n\n/**\n * Returns an anonymized representation of the controller state.\n *\n * By \"anonymized\" we mean that it should not contain any information that could be personally\n * identifiable.\n *\n * @param state - The controller state.\n * @param metadata - The controller state metadata, which describes how to derive the\n * anonymized state.\n * @returns The anonymized controller state.\n */\nexport function getAnonymizedState<ControllerState extends StateConstraint>(\n state: ControllerState,\n metadata: StateMetadata<ControllerState>,\n): Record<keyof ControllerState, Json> {\n return deriveStateFromMetadata(state, metadata, 'anonymous');\n}\n\n/**\n * Returns the subset of state that should be persisted.\n *\n * @param state - The controller state.\n * @param metadata - The controller state metadata, which describes which pieces of state should be persisted.\n * @returns The subset of controller state that should be persisted.\n */\nexport function getPersistentState<ControllerState extends StateConstraint>(\n state: ControllerState,\n metadata: StateMetadata<ControllerState>,\n): Record<keyof ControllerState, Json> {\n return deriveStateFromMetadata(state, metadata, 'persist');\n}\n\n/**\n * Use the metadata to derive state according to the given metadata property.\n *\n * @param state - The full controller state.\n * @param metadata - The controller metadata.\n * @param metadataProperty - The metadata property to use to derive state.\n * @returns The metadata-derived controller state.\n */\nfunction deriveStateFromMetadata<ControllerState extends StateConstraint>(\n state: ControllerState,\n metadata: StateMetadata<ControllerState>,\n metadataProperty: 'anonymous' | 'persist',\n): Record<keyof ControllerState, Json> {\n return (Object.keys(state) as (keyof ControllerState)[]).reduce<\n Record<keyof ControllerState, Json>\n >((derivedState, key) => {\n try {\n const stateMetadata = metadata[key];\n if (!stateMetadata) {\n throw new Error(`No metadata found for '${String(key)}'`);\n }\n const propertyMetadata = stateMetadata[metadataProperty];\n const stateProperty = state[key];\n if (typeof propertyMetadata === 'function') {\n derivedState[key] = propertyMetadata(stateProperty);\n } else if (propertyMetadata) {\n derivedState[key] = stateProperty;\n }\n return derivedState;\n } catch (error) {\n // Throw error after timeout so that it is captured as a console error\n // (and by Sentry) without interrupting state-related operations\n setTimeout(() => {\n throw error;\n });\n return derivedState;\n }\n }, {} as never);\n}\n"]}
|
|
1
|
+
{"version":3,"file":"BaseControllerV2.mjs","sourceRoot":"","sources":["../src/BaseControllerV2.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,OAAO,EACL,iBAAiB,EAGlB,wBAAwB;AACzB,OAAO,EAAE,aAAa,EAAE,kBAAkB,EAAE,YAAY,EAAE,MAAM,EAAE,cAAc;AAahF,aAAa,EAAE,CAAC;AAEhB;;;;;GAKG;AACH,MAAM,UAAU,gBAAgB,CAC9B,UAAmB;IAEnB,OAAO,CACL,OAAO,UAAU,KAAK,QAAQ;QAC9B,CAAC,iBAAiB,CAAC,UAAU,CAAC;QAC9B,MAAM,IAAI,UAAU;QACpB,OAAO,UAAU,CAAC,IAAI,KAAK,QAAQ;QACnC,OAAO,IAAI,UAAU;QACrB,OAAO,UAAU,CAAC,KAAK,KAAK,QAAQ;QACpC,UAAU,IAAI,UAAU;QACxB,OAAO,UAAU,CAAC,QAAQ,KAAK,QAAQ,CACxC,CAAC;AACJ,CAAC;AAsJD;;GAEG;AACH,MAAM,OAAO,cAAc;IA0BzB;;;;;;;;;OASG;IACH,YAAY,EACV,SAAS,EACT,QAAQ,EACR,IAAI,EACJ,KAAK,GAMN;QAjCD,gDAAgC;QAkC9B,IAAI,CAAC,eAAe,GAAG,SAAS,CAAC;QACjC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,sEAAsE;QACtE,0EAA0E;QAC1E,iEAAiE;QACjE,yEAAyE;QACzE,uEAAuE;QACvE,uBAAA,IAAI,iCAAkB,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,MAAA,CAAC;QAC1C,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QAEzB,IAAI,CAAC,eAAe,CAAC,qBAAqB,CACxC,GAAG,IAAI,WAAW,EAClB,GAAG,EAAE,CAAC,IAAI,CAAC,KAAK,CACjB,CAAC;QAEF,IAAI,CAAC,eAAe,CAAC,2BAA2B,CAAC;YAC/C,SAAS,EAAE,GAAG,IAAI,cAAc;YAChC,UAAU,EAAE,GAAG,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK,EAAE,EAAE,CAAC;SACnC,CAAC,CAAC;IACL,CAAC;IAED;;;;OAIG;IACH,IAAI,KAAK;QACP,OAAO,uBAAA,IAAI,qCAAe,CAAC;IAC7B,CAAC;IAED,IAAI,KAAK,CAAC,CAAC;QACT,MAAM,IAAI,KAAK,CACb,2EAA2E,CAC5E,CAAC;IACJ,CAAC;IAED;;;;;;;;;;OAUG;IACO,MAAM,CACd,QAAmE;QAMnE,8DAA8D;QAC9D,2BAA2B;QAC3B,MAAM,CAAC,SAAS,EAAE,OAAO,EAAE,cAAc,CAAC,GACxC,kBAID,CAAC,uBAAA,IAAI,qCAAe,EAAE,QAAQ,CAAC,CAAC;QAEjC,uBAAA,IAAI,iCAAkB,SAAS,MAAA,CAAC;QAChC,IAAI,CAAC,eAAe,CAAC,OAAO,CAC1B,GAAG,IAAI,CAAC,IAAI,cAAc,EAC1B,SAAS,EACT,OAAO,CACR,CAAC;QAEF,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,cAAc,EAAE,CAAC;IAChD,CAAC;IAED;;;;;;OAMG;IACO,YAAY,CAAC,OAAgB;QACrC,MAAM,SAAS,GAAG,YAAY,CAAC,uBAAA,IAAI,qCAAe,EAAE,OAAO,CAAC,CAAC;QAC7D,uBAAA,IAAI,iCAAkB,SAAS,MAAA,CAAC;QAChC,IAAI,CAAC,eAAe,CAAC,OAAO,CAC1B,GAAG,IAAI,CAAC,IAAI,cAAc,EAC1B,SAAS,EACT,OAAO,CACR,CAAC;IACJ,CAAC;IAED;;;;;;;;OAQG;IACO,OAAO;QACf,IAAI,CAAC,eAAe,CAAC,uBAAuB,CAAC,GAAG,IAAI,CAAC,IAAI,cAAc,CAAC,CAAC;IAC3E,CAAC;CACF;;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,kBAAkB,CAChC,KAAsB,EACtB,QAAwC;IAExC,OAAO,uBAAuB,CAAC,KAAK,EAAE,QAAQ,EAAE,WAAW,CAAC,CAAC;AAC/D,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,kBAAkB,CAChC,KAAsB,EACtB,QAAwC;IAExC,OAAO,uBAAuB,CAAC,KAAK,EAAE,QAAQ,EAAE,SAAS,CAAC,CAAC;AAC7D,CAAC;AAED;;;;;;;GAOG;AACH,SAAS,uBAAuB,CAC9B,KAAsB,EACtB,QAAwC,EACxC,gBAAyC;IAEzC,OAAQ,MAAM,CAAC,IAAI,CAAC,KAAK,CAA+B,CAAC,MAAM,CAE7D,CAAC,YAAY,EAAE,GAAG,EAAE,EAAE;QACtB,IAAI;YACF,MAAM,aAAa,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC;YACpC,IAAI,CAAC,aAAa,EAAE;gBAClB,MAAM,IAAI,KAAK,CAAC,0BAA0B,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;aAC3D;YACD,MAAM,gBAAgB,GAAG,aAAa,CAAC,gBAAgB,CAAC,CAAC;YACzD,MAAM,aAAa,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC;YACjC,IAAI,OAAO,gBAAgB,KAAK,UAAU,EAAE;gBAC1C,YAAY,CAAC,GAAG,CAAC,GAAG,gBAAgB,CAAC,aAAa,CAAC,CAAC;aACrD;iBAAM,IAAI,gBAAgB,EAAE;gBAC3B,YAAY,CAAC,GAAG,CAAC,GAAG,aAAa,CAAC;aACnC;YACD,OAAO,YAAY,CAAC;SACrB;QAAC,OAAO,KAAK,EAAE;YACd,sEAAsE;YACtE,gEAAgE;YAChE,UAAU,CAAC,GAAG,EAAE;gBACd,MAAM,KAAK,CAAC;YACd,CAAC,CAAC,CAAC;YACH,OAAO,YAAY,CAAC;SACrB;IACH,CAAC,EAAE,EAAW,CAAC,CAAC;AAClB,CAAC","sourcesContent":["import {\n isNullOrUndefined,\n type Json,\n type PublicInterface,\n} from '@metamask/utils';\nimport { enablePatches, produceWithPatches, applyPatches, freeze } from 'immer';\nimport type { Draft, Patch } from 'immer';\n\nimport type {\n BaseControllerV1Instance,\n StateConstraint as StateConstraintV1,\n} from './BaseControllerV1';\nimport type { ActionConstraint, EventConstraint } from './ControllerMessenger';\nimport type {\n RestrictedControllerMessenger,\n RestrictedControllerMessengerConstraint,\n} from './RestrictedControllerMessenger';\n\nenablePatches();\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 */\nexport function isBaseController(\n controller: unknown,\n): controller is BaseControllerInstance {\n return (\n typeof controller === 'object' &&\n !isNullOrUndefined(controller) &&\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\n/**\n * A type that constrains the state of all controllers.\n *\n * In other words, the narrowest supertype encompassing all controller state.\n */\nexport type StateConstraint = Record<string, Json>;\n\n/**\n * A universal supertype for the controller state object, encompassing both `BaseControllerV1` and `BaseControllerV2` state.\n */\n// TODO: Remove once BaseControllerV2 migrations are completed for all controllers.\nexport type LegacyControllerStateConstraint =\n | StateConstraintV1\n | StateConstraint;\n\n/**\n * A state change listener.\n *\n * This function will get called for each state change, and is given a copy of\n * the new state along with a set of patches describing the changes since the\n * last update.\n *\n * @param state - The new controller state.\n * @param patches - A list of patches describing any changes (see here for more\n * information: https://immerjs.github.io/immer/docs/patches)\n */\n// TODO: Either fix this lint violation or explain why it's necessary to ignore.\n// eslint-disable-next-line @typescript-eslint/naming-convention\nexport type Listener<T> = (state: T, patches: Patch[]) => void;\n\n/**\n * An function to derive state.\n *\n * This function will accept one piece of the controller state (one property),\n * and will return some derivation of that state.\n *\n * @param value - A piece of controller state.\n * @returns Something derived from controller state.\n */\n// TODO: Either fix this lint violation or explain why it's necessary to ignore.\n// eslint-disable-next-line @typescript-eslint/naming-convention\nexport type StateDeriver<T extends Json> = (value: T) => Json;\n\n/**\n * State metadata.\n *\n * This metadata describes which parts of state should be persisted, and how to\n * get an anonymized representation of the state.\n */\n// TODO: Either fix this lint violation or explain why it's necessary to ignore.\n// eslint-disable-next-line @typescript-eslint/naming-convention\nexport type StateMetadata<T extends StateConstraint> = {\n [P in keyof T]-?: StatePropertyMetadata<T[P]>;\n};\n\n/**\n * Metadata for a single state property\n *\n * @property persist - Indicates whether this property should be persisted\n * (`true` for persistent, `false` for transient), or is set to a function\n * that derives the persistent state from the state.\n * @property anonymous - Indicates whether this property is already anonymous,\n * (`true` for anonymous, `false` if it has potential to be personally\n * identifiable), or is set to a function that returns an anonymized\n * representation of this state.\n */\n// TODO: Either fix this lint violation or explain why it's necessary to ignore.\n// eslint-disable-next-line @typescript-eslint/naming-convention\nexport type StatePropertyMetadata<T extends Json> = {\n persist: boolean | StateDeriver<T>;\n anonymous: boolean | StateDeriver<T>;\n};\n\n/**\n * A universal supertype of `StateDeriver` types.\n * This type can be assigned to any `StateDeriver` type.\n */\nexport type StateDeriverConstraint = (value: never) => Json;\n\n/**\n * A universal supertype of `StatePropertyMetadata` types.\n * This type can be assigned to any `StatePropertyMetadata` type.\n */\nexport type StatePropertyMetadataConstraint = {\n [P in 'anonymous' | 'persist']: boolean | StateDeriverConstraint;\n};\n\n/**\n * A universal supertype of `StateMetadata` types.\n * This type can be assigned to any `StateMetadata` type.\n */\nexport type StateMetadataConstraint = Record<\n string,\n StatePropertyMetadataConstraint\n>;\n\n/**\n * The narrowest supertype of all controller instances that inherit from `BaseController` (formerly `BaseControllerV2`).\n * Any `BaseController` subclass instance can be assigned to this type.\n */\nexport type BaseControllerInstance = Omit<\n PublicInterface<\n BaseController<\n string,\n StateConstraint,\n RestrictedControllerMessengerConstraint\n >\n >,\n 'metadata'\n> & {\n metadata: StateMetadataConstraint;\n};\n\n/**\n * A narrowest supertype of all controller instances that inherit from `BaseController` (formerly `BaseControllerV2`) or `BaseControllerV1`.\n * Any `BaseController` or `BaseControllerV1` subclass instance can be assigned to this type.\n */\n// TODO: Remove once BaseControllerV2 migrations are completed for all controllers.\nexport type ControllerInstance =\n | BaseControllerV1Instance\n | BaseControllerInstance;\n\nexport type ControllerGetStateAction<\n ControllerName extends string,\n ControllerState extends StateConstraint,\n> = {\n type: `${ControllerName}:getState`;\n handler: () => ControllerState;\n};\n\nexport type ControllerStateChangeEvent<\n ControllerName extends string,\n ControllerState extends StateConstraint,\n> = {\n type: `${ControllerName}:stateChange`;\n payload: [ControllerState, Patch[]];\n};\n\nexport type ControllerActions<\n ControllerName extends string,\n ControllerState extends StateConstraint,\n> = ControllerGetStateAction<ControllerName, ControllerState>;\n\nexport type ControllerEvents<\n ControllerName extends string,\n ControllerState extends StateConstraint,\n> = ControllerStateChangeEvent<ControllerName, ControllerState>;\n\n/**\n * Controller class that provides state management, subscriptions, and state metadata\n */\nexport class BaseController<\n ControllerName extends string,\n ControllerState extends StateConstraint,\n // TODO: Either fix this lint violation or explain why it's necessary to ignore.\n // eslint-disable-next-line @typescript-eslint/naming-convention\n messenger extends RestrictedControllerMessenger<\n ControllerName,\n ActionConstraint | ControllerActions<ControllerName, ControllerState>,\n EventConstraint | ControllerEvents<ControllerName, ControllerState>,\n string,\n string\n >,\n> {\n #internalState: ControllerState;\n\n protected messagingSystem: messenger;\n\n /**\n * The name of the controller.\n *\n * This is used by the ComposableController to construct a composed application state.\n */\n public readonly name: ControllerName;\n\n public readonly metadata: StateMetadata<ControllerState>;\n\n /**\n * Creates a BaseController instance.\n *\n * @param options - Controller options.\n * @param options.messenger - Controller messaging system.\n * @param options.metadata - ControllerState metadata, describing how to \"anonymize\" the state, and which\n * parts should be persisted.\n * @param options.name - The name of the controller, used as a namespace for events and actions.\n * @param options.state - Initial controller state.\n */\n constructor({\n messenger,\n metadata,\n name,\n state,\n }: {\n messenger: messenger;\n metadata: StateMetadata<ControllerState>;\n name: ControllerName;\n state: ControllerState;\n }) {\n this.messagingSystem = messenger;\n this.name = name;\n // Here we use `freeze` from Immer to enforce that the state is deeply\n // immutable. Note that this is a runtime check, not a compile-time check.\n // That is, unlike `Object.freeze`, this does not narrow the type\n // recursively to `Readonly`. The equivalent in Immer is `Immutable`, but\n // `Immutable` does not handle recursive types such as our `Json` type.\n this.#internalState = freeze(state, true);\n this.metadata = metadata;\n\n this.messagingSystem.registerActionHandler(\n `${name}:getState`,\n () => this.state,\n );\n\n this.messagingSystem.registerInitialEventPayload({\n eventType: `${name}:stateChange`,\n getPayload: () => [this.state, []],\n });\n }\n\n /**\n * Retrieves current controller state.\n *\n * @returns The current state.\n */\n get state() {\n return this.#internalState;\n }\n\n set state(_) {\n throw new Error(\n `Controller state cannot be directly mutated; use 'update' method instead.`,\n );\n }\n\n /**\n * Updates controller state. Accepts a callback that is passed a draft copy\n * of the controller state. If a value is returned, it is set as the new\n * state. Otherwise, any changes made within that callback to the draft are\n * applied to the controller state.\n *\n * @param callback - Callback for updating state, passed a draft state\n * object. Return a new state object or mutate the draft to update state.\n * @returns An object that has the next state, patches applied in the update and inverse patches to\n * rollback the update.\n */\n protected update(\n callback: (state: Draft<ControllerState>) => void | ControllerState,\n ): {\n nextState: ControllerState;\n patches: Patch[];\n inversePatches: Patch[];\n } {\n // We run into ts2589, \"infinite type depth\", if we don't cast\n // produceWithPatches here.\n const [nextState, patches, inversePatches] = (\n produceWithPatches as unknown as (\n state: ControllerState,\n cb: typeof callback,\n ) => [ControllerState, Patch[], Patch[]]\n )(this.#internalState, callback);\n\n this.#internalState = nextState;\n this.messagingSystem.publish(\n `${this.name}:stateChange`,\n nextState,\n patches,\n );\n\n return { nextState, patches, inversePatches };\n }\n\n /**\n * Applies immer patches to the current state. The patches come from the\n * update function itself and can either be normal or inverse patches.\n *\n * @param patches - An array of immer patches that are to be applied to make\n * or undo changes.\n */\n protected applyPatches(patches: Patch[]) {\n const nextState = applyPatches(this.#internalState, patches);\n this.#internalState = nextState;\n this.messagingSystem.publish(\n `${this.name}:stateChange`,\n nextState,\n patches,\n );\n }\n\n /**\n * Prepares the controller for garbage collection. This should be extended\n * by any subclasses to clean up any additional connections or events.\n *\n * The only cleanup performed here is to remove listeners. While technically\n * this is not required to ensure this instance is garbage collected, it at\n * least ensures this instance won't be responsible for preventing the\n * listeners from being garbage collected.\n */\n protected destroy() {\n this.messagingSystem.clearEventSubscriptions(`${this.name}:stateChange`);\n }\n}\n\n/**\n * Returns an anonymized representation of the controller state.\n *\n * By \"anonymized\" we mean that it should not contain any information that could be personally\n * identifiable.\n *\n * @param state - The controller state.\n * @param metadata - The controller state metadata, which describes how to derive the\n * anonymized state.\n * @returns The anonymized controller state.\n */\nexport function getAnonymizedState<ControllerState extends StateConstraint>(\n state: ControllerState,\n metadata: StateMetadata<ControllerState>,\n): Record<keyof ControllerState, Json> {\n return deriveStateFromMetadata(state, metadata, 'anonymous');\n}\n\n/**\n * Returns the subset of state that should be persisted.\n *\n * @param state - The controller state.\n * @param metadata - The controller state metadata, which describes which pieces of state should be persisted.\n * @returns The subset of controller state that should be persisted.\n */\nexport function getPersistentState<ControllerState extends StateConstraint>(\n state: ControllerState,\n metadata: StateMetadata<ControllerState>,\n): Record<keyof ControllerState, Json> {\n return deriveStateFromMetadata(state, metadata, 'persist');\n}\n\n/**\n * Use the metadata to derive state according to the given metadata property.\n *\n * @param state - The full controller state.\n * @param metadata - The controller metadata.\n * @param metadataProperty - The metadata property to use to derive state.\n * @returns The metadata-derived controller state.\n */\nfunction deriveStateFromMetadata<ControllerState extends StateConstraint>(\n state: ControllerState,\n metadata: StateMetadata<ControllerState>,\n metadataProperty: 'anonymous' | 'persist',\n): Record<keyof ControllerState, Json> {\n return (Object.keys(state) as (keyof ControllerState)[]).reduce<\n Record<keyof ControllerState, Json>\n >((derivedState, key) => {\n try {\n const stateMetadata = metadata[key];\n if (!stateMetadata) {\n throw new Error(`No metadata found for '${String(key)}'`);\n }\n const propertyMetadata = stateMetadata[metadataProperty];\n const stateProperty = state[key];\n if (typeof propertyMetadata === 'function') {\n derivedState[key] = propertyMetadata(stateProperty);\n } else if (propertyMetadata) {\n derivedState[key] = stateProperty;\n }\n return derivedState;\n } catch (error) {\n // Throw error after timeout so that it is captured as a console error\n // (and by Sentry) without interrupting state-related operations\n setTimeout(() => {\n throw error;\n });\n return derivedState;\n }\n }, {} as never);\n}\n"]}
|
package/package.json
CHANGED