@metamask-previews/base-controller 3.2.0-preview.3dbf14f

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md ADDED
@@ -0,0 +1,72 @@
1
+ # Changelog
2
+ All notable changes to this project will be documented in this file.
3
+
4
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
5
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
+
7
+ ## [Unreleased]
8
+
9
+ ## [3.2.0]
10
+ ### Changed
11
+ - When deriving state, skip properties with invalid metadata ([#1529](https://github.com/MetaMask/core/pull/1529))
12
+ - The previous behavior was to throw an error
13
+ - An error is thrown in a timeout handler so that it can still be captured in the console, and by global unhandled error handlers.
14
+ - Update `@metamask/utils` to `^6.2.0` ([#1514](https://github.com/MetaMask/core/pull/1514))
15
+
16
+ ## [3.1.0]
17
+ ### Changed
18
+ - Prevent event publish from throwing error ([#1475](https://github.com/MetaMask/core/pull/1475))
19
+ - The controller messenger will no longer throw when an event subscriber throws an error. Calls to `publish` (either within controllers or on a messenger instance directly) will no longer throw errors.
20
+ - Errors are thrown in a timeout handler so that they can still be logged and captured.
21
+
22
+ ## [3.0.0]
23
+ ### Changed
24
+ - **BREAKING:** Bump to Node 16 ([#1262](https://github.com/MetaMask/core/pull/1262))
25
+ - Replace `@metamask/controller-utils` dependency with `@metamask/utils` ([#1370](https://github.com/MetaMask/core/pull/1370))
26
+
27
+ ## [2.0.0]
28
+ ### Removed
29
+ - **BREAKING:** Remove `isomorphic-fetch` ([#1106](https://github.com/MetaMask/controllers/pull/1106))
30
+ - Consumers must now import `isomorphic-fetch` or another polyfill themselves if they are running in an environment without `fetch`
31
+
32
+ ## [1.1.2]
33
+ ### Changed
34
+ - Rename this repository to `core` ([#1031](https://github.com/MetaMask/controllers/pull/1031))
35
+ - Update `@metamask/controller-utils` package ([#1041](https://github.com/MetaMask/controllers/pull/1041))
36
+
37
+ ## [1.1.1]
38
+ ### Changed
39
+ - Relax dependency on `@metamask/controller-utils` (use `^` instead of `~`) ([#998](https://github.com/MetaMask/core/pull/998))
40
+
41
+ ## [1.1.0]
42
+ ### Added
43
+ - Add `applyPatches` function to BaseControllerV2 ([#980](https://github.com/MetaMask/core/pull/980))
44
+
45
+ ### Changed
46
+ - Action and event handler types are now exported ([#987](https://github.com/MetaMask/core/pull/987))
47
+ - Update `update` function to expose patches ([#980](https://github.com/MetaMask/core/pull/980))
48
+
49
+ ## [1.0.0]
50
+ ### Added
51
+ - Initial release
52
+ - As a result of converting our shared controllers repo into a monorepo ([#831](https://github.com/MetaMask/core/pull/831)), we've created this package from select parts of [`@metamask/controllers` v33.0.0](https://github.com/MetaMask/core/tree/v33.0.0), namely:
53
+ - `src/BaseController.ts`
54
+ - `src/BaseController.test.ts`
55
+ - `src/BaseControllerV2.ts`
56
+ - `src/BaseControllerV2.test.ts`
57
+ - `src/ComposableController.ts`
58
+ - `src/ComposableController.test.ts`
59
+ - `src/ControllerMessenger.ts`
60
+ - `src/ControllerMessenger.test.ts`
61
+
62
+ All changes listed after this point were applied to this package following the monorepo conversion.
63
+
64
+ [Unreleased]: https://github.com/MetaMask/core/compare/@metamask/base-controller@3.2.0...HEAD
65
+ [3.2.0]: https://github.com/MetaMask/core/compare/@metamask/base-controller@3.1.0...@metamask/base-controller@3.2.0
66
+ [3.1.0]: https://github.com/MetaMask/core/compare/@metamask/base-controller@3.0.0...@metamask/base-controller@3.1.0
67
+ [3.0.0]: https://github.com/MetaMask/core/compare/@metamask/base-controller@2.0.0...@metamask/base-controller@3.0.0
68
+ [2.0.0]: https://github.com/MetaMask/core/compare/@metamask/base-controller@1.1.2...@metamask/base-controller@2.0.0
69
+ [1.1.2]: https://github.com/MetaMask/core/compare/@metamask/base-controller@1.1.1...@metamask/base-controller@1.1.2
70
+ [1.1.1]: https://github.com/MetaMask/core/compare/@metamask/base-controller@1.1.0...@metamask/base-controller@1.1.1
71
+ [1.1.0]: https://github.com/MetaMask/core/compare/@metamask/base-controller@1.0.0...@metamask/base-controller@1.1.0
72
+ [1.0.0]: https://github.com/MetaMask/core/releases/tag/@metamask/base-controller@1.0.0
package/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2018 MetaMask
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
package/README.md ADDED
@@ -0,0 +1,15 @@
1
+ # `@metamask/base-controller`
2
+
3
+ Provides scaffolding for controllers as well a communication system for all controllers.
4
+
5
+ ## Installation
6
+
7
+ `yarn add @metamask/base-controller`
8
+
9
+ or
10
+
11
+ `npm install @metamask/base-controller`
12
+
13
+ ## Contributing
14
+
15
+ This package is part of a monorepo. Instructions for contributing can be found in the [monorepo README](https://github.com/MetaMask/core#readme).
@@ -0,0 +1,114 @@
1
+ /**
2
+ * State change callbacks
3
+ */
4
+ export declare type Listener<T> = (state: T) => void;
5
+ /**
6
+ * @type BaseConfig
7
+ *
8
+ * Base controller configuration
9
+ * @property disabled - Determines if this controller is enabled
10
+ */
11
+ export interface BaseConfig {
12
+ disabled?: boolean;
13
+ }
14
+ /**
15
+ * @type BaseState
16
+ *
17
+ * Base state representation
18
+ * @property name - Unique name for this controller
19
+ */
20
+ export interface BaseState {
21
+ name?: string;
22
+ }
23
+ /**
24
+ * Controller class that provides configuration, state management, and subscriptions.
25
+ *
26
+ * The core purpose of every controller is to maintain an internal data object
27
+ * called "state". Each controller is responsible for its own state, and all global wallet state
28
+ * is tracked in a controller as state.
29
+ */
30
+ export declare class BaseController<C extends BaseConfig, S extends BaseState> {
31
+ /**
32
+ * Default options used to configure this controller
33
+ */
34
+ defaultConfig: C;
35
+ /**
36
+ * Default state set on this controller
37
+ */
38
+ defaultState: S;
39
+ /**
40
+ * Determines if listeners are notified of state changes
41
+ */
42
+ disabled: boolean;
43
+ /**
44
+ * Name of this controller used during composition
45
+ */
46
+ name: string;
47
+ private readonly initialConfig;
48
+ private readonly initialState;
49
+ private internalConfig;
50
+ private internalState;
51
+ private readonly internalListeners;
52
+ /**
53
+ * Creates a BaseController instance. Both initial state and initial
54
+ * configuration options are merged with defaults upon initialization.
55
+ *
56
+ * @param config - Initial options used to configure this controller.
57
+ * @param state - Initial state to set on this controller.
58
+ */
59
+ constructor(config?: Partial<C>, state?: Partial<S>);
60
+ /**
61
+ * Enables the controller. This sets each config option as a member
62
+ * variable on this instance and triggers any defined setters. This
63
+ * also sets initial state and triggers any listeners.
64
+ *
65
+ * @returns This controller instance.
66
+ */
67
+ protected initialize(): this;
68
+ /**
69
+ * Retrieves current controller configuration options.
70
+ *
71
+ * @returns The current configuration.
72
+ */
73
+ get config(): C;
74
+ /**
75
+ * Retrieves current controller state.
76
+ *
77
+ * @returns The current state.
78
+ */
79
+ get state(): S;
80
+ /**
81
+ * Updates controller configuration.
82
+ *
83
+ * @param config - New configuration options.
84
+ * @param overwrite - Overwrite config instead of merging.
85
+ * @param fullUpdate - Boolean that defines if the update is partial or not.
86
+ */
87
+ configure(config: Partial<C>, overwrite?: boolean, fullUpdate?: boolean): void;
88
+ /**
89
+ * Notifies all subscribed listeners of current state.
90
+ */
91
+ notify(): void;
92
+ /**
93
+ * Adds new listener to be notified of state changes.
94
+ *
95
+ * @param listener - The callback triggered when state changes.
96
+ */
97
+ subscribe(listener: Listener<S>): void;
98
+ /**
99
+ * Removes existing listener from receiving state changes.
100
+ *
101
+ * @param listener - The callback to remove.
102
+ * @returns `true` if a listener is found and unsubscribed.
103
+ */
104
+ unsubscribe(listener: Listener<S>): boolean;
105
+ /**
106
+ * Updates controller state.
107
+ *
108
+ * @param state - The new state.
109
+ * @param overwrite - Overwrite state instead of merging.
110
+ */
111
+ update(state: Partial<S>, overwrite?: boolean): void;
112
+ }
113
+ export default BaseController;
114
+ //# sourceMappingURL=BaseController.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BaseController.d.ts","sourceRoot":"","sources":["../src/BaseController.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,oBAAY,QAAQ,CAAC,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,KAAK,IAAI,CAAC;AAE7C;;;;;GAKG;AACH,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED;;;;;GAKG;AACH,MAAM,WAAW,SAAS;IACxB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;;;;;GAMG;AACH,qBAAa,cAAc,CAAC,CAAC,SAAS,UAAU,EAAE,CAAC,SAAS,SAAS;IACnE;;OAEG;IACH,aAAa,EAAE,CAAC,CAAW;IAE3B;;OAEG;IACH,YAAY,EAAE,CAAC,CAAW;IAE1B;;OAEG;IACH,QAAQ,UAAS;IAEjB;;OAEG;IACH,IAAI,SAAoB;IAExB,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAI;IAElC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAI;IAEjC,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,CAAW,EAAE,KAAK,GAAE,OAAO,CAAC,CAAC,CAAW;IAMrE;;;;;;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;IAsBlE;;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,cAAc,CAAC"}
@@ -0,0 +1,146 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.BaseController = void 0;
4
+ /**
5
+ * Controller class that provides configuration, state management, and subscriptions.
6
+ *
7
+ * The core purpose of every controller is to maintain an internal data object
8
+ * called "state". Each controller is responsible for its own state, and all global wallet state
9
+ * is tracked in a controller as state.
10
+ */
11
+ class BaseController {
12
+ /**
13
+ * Creates a BaseController instance. Both initial state and initial
14
+ * configuration options are merged with defaults upon initialization.
15
+ *
16
+ * @param config - Initial options used to configure this controller.
17
+ * @param state - Initial state to set on this controller.
18
+ */
19
+ constructor(config = {}, state = {}) {
20
+ /**
21
+ * Default options used to configure this controller
22
+ */
23
+ this.defaultConfig = {};
24
+ /**
25
+ * Default state set on this controller
26
+ */
27
+ this.defaultState = {};
28
+ /**
29
+ * Determines if listeners are notified of state changes
30
+ */
31
+ this.disabled = false;
32
+ /**
33
+ * Name of this controller used during composition
34
+ */
35
+ this.name = 'BaseController';
36
+ this.internalConfig = this.defaultConfig;
37
+ this.internalState = this.defaultState;
38
+ this.internalListeners = [];
39
+ // Use assign since generics can't be spread: https://git.io/vpRhY
40
+ this.initialState = state;
41
+ this.initialConfig = config;
42
+ }
43
+ /**
44
+ * Enables the controller. This sets each config option as a member
45
+ * variable on this instance and triggers any defined setters. This
46
+ * also sets initial state and triggers any listeners.
47
+ *
48
+ * @returns This controller instance.
49
+ */
50
+ initialize() {
51
+ this.internalState = this.defaultState;
52
+ this.internalConfig = this.defaultConfig;
53
+ this.configure(this.initialConfig);
54
+ this.update(this.initialState);
55
+ return this;
56
+ }
57
+ /**
58
+ * Retrieves current controller configuration options.
59
+ *
60
+ * @returns The current configuration.
61
+ */
62
+ get config() {
63
+ return this.internalConfig;
64
+ }
65
+ /**
66
+ * Retrieves current controller state.
67
+ *
68
+ * @returns The current state.
69
+ */
70
+ get state() {
71
+ return this.internalState;
72
+ }
73
+ /**
74
+ * Updates controller configuration.
75
+ *
76
+ * @param config - New configuration options.
77
+ * @param overwrite - Overwrite config instead of merging.
78
+ * @param fullUpdate - Boolean that defines if the update is partial or not.
79
+ */
80
+ configure(config, overwrite = false, fullUpdate = true) {
81
+ if (fullUpdate) {
82
+ this.internalConfig = overwrite
83
+ ? config
84
+ : Object.assign(this.internalConfig, config);
85
+ for (const key in this.internalConfig) {
86
+ if (typeof this.internalConfig[key] !== 'undefined') {
87
+ this[key] = this.internalConfig[key];
88
+ }
89
+ }
90
+ }
91
+ else {
92
+ for (const key in config) {
93
+ /* istanbul ignore else */
94
+ if (typeof this.internalConfig[key] !== 'undefined') {
95
+ this.internalConfig[key] = config[key];
96
+ this[key] = config[key];
97
+ }
98
+ }
99
+ }
100
+ }
101
+ /**
102
+ * Notifies all subscribed listeners of current state.
103
+ */
104
+ notify() {
105
+ if (this.disabled) {
106
+ return;
107
+ }
108
+ this.internalListeners.forEach((listener) => {
109
+ listener(this.internalState);
110
+ });
111
+ }
112
+ /**
113
+ * Adds new listener to be notified of state changes.
114
+ *
115
+ * @param listener - The callback triggered when state changes.
116
+ */
117
+ subscribe(listener) {
118
+ this.internalListeners.push(listener);
119
+ }
120
+ /**
121
+ * Removes existing listener from receiving state changes.
122
+ *
123
+ * @param listener - The callback to remove.
124
+ * @returns `true` if a listener is found and unsubscribed.
125
+ */
126
+ unsubscribe(listener) {
127
+ const index = this.internalListeners.findIndex((cb) => listener === cb);
128
+ index > -1 && this.internalListeners.splice(index, 1);
129
+ return index > -1;
130
+ }
131
+ /**
132
+ * Updates controller state.
133
+ *
134
+ * @param state - The new state.
135
+ * @param overwrite - Overwrite state instead of merging.
136
+ */
137
+ update(state, overwrite = false) {
138
+ this.internalState = overwrite
139
+ ? Object.assign({}, state)
140
+ : Object.assign({}, this.internalState, state);
141
+ this.notify();
142
+ }
143
+ }
144
+ exports.BaseController = BaseController;
145
+ exports.default = BaseController;
146
+ //# sourceMappingURL=BaseController.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BaseController.js","sourceRoot":"","sources":["../src/BaseController.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * State change callbacks\n */\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 */\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 */\nexport interface BaseState {\n name?: string;\n}\n\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 */\nexport class BaseController<C extends BaseConfig, S extends BaseState> {\n /**\n * Default options used to configure this controller\n */\n defaultConfig: C = {} as C;\n\n /**\n * Default state set on this controller\n */\n defaultState: S = {} as S;\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: C;\n\n private readonly initialState: 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 BaseController 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> = {} as C, state: Partial<S> = {} as S) {\n // Use assign since generics can't be spread: https://git.io/vpRhY\n this.initialState = state as S;\n this.initialConfig = config as C;\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 in this.internalConfig) {\n if (typeof this.internalConfig[key] !== 'undefined') {\n (this as any)[key as string] = this.internalConfig[key];\n }\n }\n } else {\n for (const key in config) {\n /* istanbul ignore else */\n if (typeof this.internalConfig[key] !== 'undefined') {\n this.internalConfig[key] = config[key] as any;\n (this as any)[key as string] = config[key];\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 BaseController;\n"]}
@@ -0,0 +1,147 @@
1
+ import type { Json } from '@metamask/utils';
2
+ import type { Draft, Patch } from 'immer';
3
+ import type { RestrictedControllerMessenger } from './ControllerMessenger';
4
+ /**
5
+ * A state change listener.
6
+ *
7
+ * This function will get called for each state change, and is given a copy of
8
+ * the new state along with a set of patches describing the changes since the
9
+ * last update.
10
+ *
11
+ * @param state - The new controller state.
12
+ * @param patches - A list of patches describing any changes (see here for more
13
+ * information: https://immerjs.github.io/immer/docs/patches)
14
+ */
15
+ export declare type Listener<T> = (state: T, patches: Patch[]) => void;
16
+ /**
17
+ * An function to derive state.
18
+ *
19
+ * This function will accept one piece of the controller state (one property),
20
+ * and will return some derivation of that state.
21
+ *
22
+ * @param value - A piece of controller state.
23
+ * @returns Something derived from controller state.
24
+ */
25
+ export declare type StateDeriver<T extends Json> = (value: T) => Json;
26
+ /**
27
+ * State metadata.
28
+ *
29
+ * This metadata describes which parts of state should be persisted, and how to
30
+ * get an anonymized representation of the state.
31
+ */
32
+ export declare type StateMetadata<T extends Record<string, Json>> = {
33
+ [P in keyof T]: StatePropertyMetadata<T[P]>;
34
+ };
35
+ /**
36
+ * Metadata for a single state property
37
+ *
38
+ * @property persist - Indicates whether this property should be persisted
39
+ * (`true` for persistent, `false` for transient), or is set to a function
40
+ * that derives the persistent state from the state.
41
+ * @property anonymous - Indicates whether this property is already anonymous,
42
+ * (`true` for anonymous, `false` if it has potential to be personally
43
+ * identifiable), or is set to a function that returns an anonymized
44
+ * representation of this state.
45
+ */
46
+ export interface StatePropertyMetadata<T extends Json> {
47
+ persist: boolean | StateDeriver<T>;
48
+ anonymous: boolean | StateDeriver<T>;
49
+ }
50
+ /**
51
+ * Controller class that provides state management, subscriptions, and state metadata
52
+ */
53
+ export declare class BaseController<N extends string, S extends Record<string, Json>, messenger extends RestrictedControllerMessenger<N, any, any, string, string>> {
54
+ private internalState;
55
+ protected messagingSystem: messenger;
56
+ /**
57
+ * The name of the controller.
58
+ *
59
+ * This is used by the ComposableController to construct a composed application state.
60
+ */
61
+ readonly name: N;
62
+ readonly metadata: StateMetadata<S>;
63
+ /**
64
+ * The existence of the `subscribe` property is how the ComposableController detects whether a
65
+ * controller extends the old BaseController or the new one. We set it to `undefined` here to
66
+ * ensure the ComposableController never mistakes them for an older style controller.
67
+ */
68
+ readonly subscribe: undefined;
69
+ /**
70
+ * Creates a BaseController instance.
71
+ *
72
+ * @param options - Controller options.
73
+ * @param options.messenger - Controller messaging system.
74
+ * @param options.metadata - State metadata, describing how to "anonymize" the state, and which
75
+ * parts should be persisted.
76
+ * @param options.name - The name of the controller, used as a namespace for events and actions.
77
+ * @param options.state - Initial controller state.
78
+ */
79
+ constructor({ messenger, metadata, name, state, }: {
80
+ messenger: messenger;
81
+ metadata: StateMetadata<S>;
82
+ name: N;
83
+ state: S;
84
+ });
85
+ /**
86
+ * Retrieves current controller state.
87
+ *
88
+ * @returns The current state.
89
+ */
90
+ get state(): S;
91
+ set state(_: S);
92
+ /**
93
+ * Updates controller state. Accepts a callback that is passed a draft copy
94
+ * of the controller state. If a value is returned, it is set as the new
95
+ * state. Otherwise, any changes made within that callback to the draft are
96
+ * applied to the controller state.
97
+ *
98
+ * @param callback - Callback for updating state, passed a draft state
99
+ * object. Return a new state object or mutate the draft to update state.
100
+ * @returns An object that has the next state, patches applied in the update and inverse patches to
101
+ * rollback the update.
102
+ */
103
+ protected update(callback: (state: Draft<S>) => void | S): {
104
+ nextState: S;
105
+ patches: Patch[];
106
+ inversePatches: Patch[];
107
+ };
108
+ /**
109
+ * Applies immer patches to the current state. The patches come from the
110
+ * update function itself and can either be normal or inverse patches.
111
+ *
112
+ * @param patches - An array of immer patches that are to be applied to make
113
+ * or undo changes.
114
+ */
115
+ protected applyPatches(patches: Patch[]): void;
116
+ /**
117
+ * Prepares the controller for garbage collection. This should be extended
118
+ * by any subclasses to clean up any additional connections or events.
119
+ *
120
+ * The only cleanup performed here is to remove listeners. While technically
121
+ * this is not required to ensure this instance is garbage collected, it at
122
+ * least ensures this instance won't be responsible for preventing the
123
+ * listeners from being garbage collected.
124
+ */
125
+ protected destroy(): void;
126
+ }
127
+ /**
128
+ * Returns an anonymized representation of the controller state.
129
+ *
130
+ * By "anonymized" we mean that it should not contain any information that could be personally
131
+ * identifiable.
132
+ *
133
+ * @param state - The controller state.
134
+ * @param metadata - The controller state metadata, which describes how to derive the
135
+ * anonymized state.
136
+ * @returns The anonymized controller state.
137
+ */
138
+ export declare function getAnonymizedState<S extends Record<string, Json>>(state: S, metadata: StateMetadata<S>): Record<string, Json>;
139
+ /**
140
+ * Returns the subset of state that should be persisted.
141
+ *
142
+ * @param state - The controller state.
143
+ * @param metadata - The controller state metadata, which describes which pieces of state should be persisted.
144
+ * @returns The subset of controller state that should be persisted.
145
+ */
146
+ export declare function getPersistentState<S extends Record<string, Json>>(state: S, metadata: StateMetadata<S>): Record<string, Json>;
147
+ //# sourceMappingURL=BaseControllerV2.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BaseControllerV2.d.ts","sourceRoot":"","sources":["../src/BaseControllerV2.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAE5C,OAAO,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,OAAO,CAAC;AAE1C,OAAO,KAAK,EACV,6BAA6B,EAE9B,MAAM,uBAAuB,CAAC;AAI/B;;;;;;;;;;GAUG;AACH,oBAAY,QAAQ,CAAC,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,IAAI,CAAC;AAE/D;;;;;;;;GAQG;AACH,oBAAY,YAAY,CAAC,CAAC,SAAS,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC,KAAK,IAAI,CAAC;AAE9D;;;;;GAKG;AACH,oBAAY,aAAa,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,IAAI;KACzD,CAAC,IAAI,MAAM,CAAC,GAAG,qBAAqB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;CAC5C,CAAC;AAEF;;;;;;;;;;GAUG;AACH,MAAM,WAAW,qBAAqB,CAAC,CAAC,SAAS,IAAI;IACnD,OAAO,EAAE,OAAO,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC;IACnC,SAAS,EAAE,OAAO,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC;CACtC;AAED;;GAEG;AACH,qBAAa,cAAc,CACzB,CAAC,SAAS,MAAM,EAChB,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,EAC9B,SAAS,SAAS,6BAA6B,CAAC,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC;IAE5E,OAAO,CAAC,aAAa,CAAI;IAEzB,SAAS,CAAC,eAAe,EAAE,SAAS,CAAC;IAErC;;;;OAIG;IACH,SAAgB,IAAI,EAAE,CAAC,CAAC;IAExB,SAAgB,QAAQ,EAAE,aAAa,CAAC,CAAC,CAAC,CAAC;IAE3C;;;;OAIG;IACH,SAAgB,SAAS,EAAE,SAAS,CAAC;IAErC;;;;;;;;;OASG;gBACS,EACV,SAAS,EACT,QAAQ,EACR,IAAI,EACJ,KAAK,GACN,EAAE;QACD,SAAS,EAAE,SAAS,CAAC;QACrB,QAAQ,EAAE,aAAa,CAAC,CAAC,CAAC,CAAC;QAC3B,IAAI,EAAE,CAAC,CAAC;QACR,KAAK,EAAE,CAAC,CAAC;KACV;IAYD;;;;OAIG;IACH,IAAI,KAAK,MAER;IAED,IAAI,KAAK,CAAC,CAAC,GAAA,EAIV;IAED;;;;;;;;;;OAUG;IACH,SAAS,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,KAAK,IAAI,GAAG,CAAC,GAAG;QACzD,SAAS,EAAE,CAAC,CAAC;QACb,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;CAKlB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,kBAAkB,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,EAC/D,KAAK,EAAE,CAAC,EACR,QAAQ,EAAE,aAAa,CAAC,CAAC,CAAC,GACzB,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAEtB;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,EAC/D,KAAK,EAAE,CAAC,EACR,QAAQ,EAAE,aAAa,CAAC,CAAC,CAAC,GACzB,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAEtB"}