@metamask-previews/base-controller 3.2.3-preview.eb58a59 → 4.0.1-preview.353ee83b
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 +33 -1
- package/dist/{BaseController.d.ts → BaseControllerV1.d.ts} +6 -4
- package/dist/BaseControllerV1.d.ts.map +1 -0
- package/dist/{BaseController.js → BaseControllerV1.js} +12 -6
- package/dist/BaseControllerV1.js.map +1 -0
- package/dist/BaseControllerV2.d.ts +6 -2
- package/dist/BaseControllerV2.d.ts.map +1 -1
- package/dist/BaseControllerV2.js.map +1 -1
- package/dist/ControllerMessenger.d.ts +7 -4
- package/dist/ControllerMessenger.d.ts.map +1 -1
- package/dist/ControllerMessenger.js +2 -0
- package/dist/ControllerMessenger.js.map +1 -1
- package/dist/RestrictedControllerMessenger.d.ts +21 -14
- package/dist/RestrictedControllerMessenger.d.ts.map +1 -1
- package/dist/RestrictedControllerMessenger.js +36 -30
- package/dist/RestrictedControllerMessenger.js.map +1 -1
- package/dist/index.d.ts +4 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -4
- package/dist/index.js.map +1 -1
- package/package.json +3 -2
- package/dist/BaseController.d.ts.map +0 -1
- package/dist/BaseController.js.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,36 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
6
6
|
|
|
7
7
|
## [Unreleased]
|
|
8
8
|
|
|
9
|
+
## [4.0.1]
|
|
10
|
+
### Changed
|
|
11
|
+
- Deprecate `subscribe` property from `BaseControllerV2` ([#3590](https://github.com/MetaMask/core/pull/3590), [#3698](https://github.com/MetaMask/core/pull/3698))
|
|
12
|
+
- This property was used to differentiate between `BaseControllerV1` and `BaseControllerV2` controllers. It is no longer used, so it has been marked as deprecated.
|
|
13
|
+
|
|
14
|
+
## [4.0.0]
|
|
15
|
+
### Added
|
|
16
|
+
- Add `ControllerGetStateAction` and `ControllerStateChangeEvent` types ([#1890](https://github.com/MetaMask/core/pull/1890), [#2029](https://github.com/MetaMask/core/pull/2029))
|
|
17
|
+
- Add `NamespacedName` type ([#1890](https://github.com/MetaMask/core/pull/1890))
|
|
18
|
+
- This is the narrowest supertype of all names defined within a given namespace.
|
|
19
|
+
- Add `NotNamespacedBy` type, which matches an action/event name if and only if it is not prefixed by a given namespace ([#2051](https://github.com/MetaMask/core/pull/2051))
|
|
20
|
+
|
|
21
|
+
### Changed
|
|
22
|
+
- **BREAKING:** Alter controller messenger `ActionHandler` type so `Action` type parameter must satisfy (updated) `ActionConstraint` ([#1890](https://github.com/MetaMask/core/pull/1890))
|
|
23
|
+
- **BREAKING:** Alter controller messenger `ExtractActionParameters` utility type so `Action` type parameter must satisfy (updated) `ActionConstraint` ([#1890](https://github.com/MetaMask/core/pull/1890))
|
|
24
|
+
- **BREAKING:** Alter controller messenger `ExtractEventHandler` utility type so `Event` type parameter must satisfy `EventConstraint` ([#1890](https://github.com/MetaMask/core/pull/1890))
|
|
25
|
+
- **BREAKING:** Alter controller messenger `ExtractEventPayload` utility type so `Event` type parameter must satisfy `EventConstraint` and `Event['payload']` must be an array (to match behavior of `ExtractEventHandler`) ([#1890](https://github.com/MetaMask/core/pull/1890))
|
|
26
|
+
- **BREAKING:** Alter controller messenger `SelectorFunction` type so that its generic parameter `Args` is replaced by `Event`, which must satisfy `EventConstraint`, and it returns a function whose arguments satisfy the event payload type specified by `Event` ([#1890](https://github.com/MetaMask/core/pull/1890))
|
|
27
|
+
- **BREAKING:** `BaseController` is now renamed to `BaseControllerV1` and has been deprecated; `BaseController` now points to what was previously called `BaseControllerV2` ([#2078](https://github.com/MetaMask/core/pull/2078))
|
|
28
|
+
- This should encourage use of `BaseController` v2 for new controllers going forward.
|
|
29
|
+
- If your controller is importing `BaseControllerV2`, you will need to import `BaseController` instead.
|
|
30
|
+
- If your controller is still importing `BaseController` v1, you will need to import and use `BaseControllerV1` instead. That said, please consider migrating your controller to v2.
|
|
31
|
+
- **BREAKING:** The restricted controller messenger now allows calling all internal events and actions by default and prohibits explicitly allowlisting any of them ([#2050](https://github.com/MetaMask/core/pull/2050), [#2051](https://github.com/MetaMask/core/pull/2051))
|
|
32
|
+
- Previously internal events and actions were only usable if they were listed as "allowed" via the `allowedActions` or `allowedEvents` options to the `RestrictedControllerMessenger` constructor or `ControllerMessenger.getRestricted()`. Now this works implicitly.
|
|
33
|
+
- In fact, attempting to allowlist any of them will raise a type error, as otherwise, it would be possible to specify a partial list of allowed actions or events, and that would be misleading, since all of them are allowed anyway.
|
|
34
|
+
- **BREAKING:** Rename `Namespaced` type to `NamespacedBy` ([#2051](https://github.com/MetaMask/core/pull/2051))
|
|
35
|
+
- Alter controller messenger `ActionConstraint['handler']` type to remove usage of `any` ([#1890](https://github.com/MetaMask/core/pull/1890))
|
|
36
|
+
- This type is now defined as the universal supertype of all functions, meaning any function can be safely assigned as an action handler, regardless of argument types, number of arguments, or return value type.
|
|
37
|
+
- Bump `@metamask/utils` to ^8.2.0 ([#1957](https://github.com/MetaMask/core/pull/1957))
|
|
38
|
+
|
|
9
39
|
## [3.2.3]
|
|
10
40
|
### Changed
|
|
11
41
|
- Bump dependency on `@metamask/utils` to ^8.1.0 ([#1639](https://github.com/MetaMask/core/pull/1639))
|
|
@@ -73,7 +103,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
73
103
|
|
|
74
104
|
All changes listed after this point were applied to this package following the monorepo conversion.
|
|
75
105
|
|
|
76
|
-
[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/base-controller@
|
|
106
|
+
[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/base-controller@4.0.1...HEAD
|
|
107
|
+
[4.0.1]: https://github.com/MetaMask/core/compare/@metamask/base-controller@4.0.0...@metamask/base-controller@4.0.1
|
|
108
|
+
[4.0.0]: https://github.com/MetaMask/core/compare/@metamask/base-controller@3.2.3...@metamask/base-controller@4.0.0
|
|
77
109
|
[3.2.3]: https://github.com/MetaMask/core/compare/@metamask/base-controller@3.2.2...@metamask/base-controller@3.2.3
|
|
78
110
|
[3.2.2]: https://github.com/MetaMask/core/compare/@metamask/base-controller@3.2.1...@metamask/base-controller@3.2.2
|
|
79
111
|
[3.2.1]: https://github.com/MetaMask/core/compare/@metamask/base-controller@3.2.0...@metamask/base-controller@3.2.1
|
|
@@ -21,13 +21,15 @@ export interface BaseState {
|
|
|
21
21
|
name?: string;
|
|
22
22
|
}
|
|
23
23
|
/**
|
|
24
|
+
* @deprecated This class has been renamed to BaseControllerV1 and is no longer recommended for use for controllers. Please use BaseController (formerly BaseControllerV2) instead.
|
|
25
|
+
*
|
|
24
26
|
* Controller class that provides configuration, state management, and subscriptions.
|
|
25
27
|
*
|
|
26
28
|
* The core purpose of every controller is to maintain an internal data object
|
|
27
29
|
* called "state". Each controller is responsible for its own state, and all global wallet state
|
|
28
30
|
* is tracked in a controller as state.
|
|
29
31
|
*/
|
|
30
|
-
export declare class
|
|
32
|
+
export declare class BaseControllerV1<C extends BaseConfig, S extends BaseState> {
|
|
31
33
|
/**
|
|
32
34
|
* Default options used to configure this controller
|
|
33
35
|
*/
|
|
@@ -50,7 +52,7 @@ export declare class BaseController<C extends BaseConfig, S extends BaseState> {
|
|
|
50
52
|
private internalState;
|
|
51
53
|
private readonly internalListeners;
|
|
52
54
|
/**
|
|
53
|
-
* Creates a
|
|
55
|
+
* Creates a BaseControllerV1 instance. Both initial state and initial
|
|
54
56
|
* configuration options are merged with defaults upon initialization.
|
|
55
57
|
*
|
|
56
58
|
* @param config - Initial options used to configure this controller.
|
|
@@ -110,5 +112,5 @@ export declare class BaseController<C extends BaseConfig, S extends BaseState> {
|
|
|
110
112
|
*/
|
|
111
113
|
update(state: Partial<S>, overwrite?: boolean): void;
|
|
112
114
|
}
|
|
113
|
-
export default
|
|
114
|
-
//# sourceMappingURL=
|
|
115
|
+
export default BaseControllerV1;
|
|
116
|
+
//# sourceMappingURL=BaseControllerV1.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BaseControllerV1.d.ts","sourceRoot":"","sources":["../src/BaseControllerV1.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,oBAAY,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;;;;;;;;GAQG;AACH,qBAAa,gBAAgB,CAAC,CAAC,SAAS,UAAU,EAAE,CAAC,SAAS,SAAS;IACrE;;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;IA0BlE;;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,16 +1,18 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.BaseControllerV1 = void 0;
|
|
4
4
|
/**
|
|
5
|
+
* @deprecated This class has been renamed to BaseControllerV1 and is no longer recommended for use for controllers. Please use BaseController (formerly BaseControllerV2) instead.
|
|
6
|
+
*
|
|
5
7
|
* Controller class that provides configuration, state management, and subscriptions.
|
|
6
8
|
*
|
|
7
9
|
* The core purpose of every controller is to maintain an internal data object
|
|
8
10
|
* called "state". Each controller is responsible for its own state, and all global wallet state
|
|
9
11
|
* is tracked in a controller as state.
|
|
10
12
|
*/
|
|
11
|
-
class
|
|
13
|
+
class BaseControllerV1 {
|
|
12
14
|
/**
|
|
13
|
-
* Creates a
|
|
15
|
+
* Creates a BaseControllerV1 instance. Both initial state and initial
|
|
14
16
|
* configuration options are merged with defaults upon initialization.
|
|
15
17
|
*
|
|
16
18
|
* @param config - Initial options used to configure this controller.
|
|
@@ -84,6 +86,8 @@ class BaseController {
|
|
|
84
86
|
: Object.assign(this.internalConfig, config);
|
|
85
87
|
for (const [key, value] of Object.entries(this.internalConfig)) {
|
|
86
88
|
if (value !== undefined) {
|
|
89
|
+
// TODO: Replace `any` with type
|
|
90
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
87
91
|
this[key] = value;
|
|
88
92
|
}
|
|
89
93
|
}
|
|
@@ -93,6 +97,8 @@ class BaseController {
|
|
|
93
97
|
/* istanbul ignore else */
|
|
94
98
|
if (typeof this.internalConfig[key] !== 'undefined') {
|
|
95
99
|
this.internalConfig[key] = config[key];
|
|
100
|
+
// TODO: Replace `any` with type
|
|
101
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
96
102
|
this[key] = config[key];
|
|
97
103
|
}
|
|
98
104
|
}
|
|
@@ -141,6 +147,6 @@ class BaseController {
|
|
|
141
147
|
this.notify();
|
|
142
148
|
}
|
|
143
149
|
}
|
|
144
|
-
exports.
|
|
145
|
-
exports.default =
|
|
146
|
-
//# sourceMappingURL=
|
|
150
|
+
exports.BaseControllerV1 = BaseControllerV1;
|
|
151
|
+
exports.default = BaseControllerV1;
|
|
152
|
+
//# sourceMappingURL=BaseControllerV1.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BaseControllerV1.js","sourceRoot":"","sources":["../src/BaseControllerV1.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 */\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 * @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 */\nexport class BaseControllerV1<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 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> = {} 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, value] of Object.entries(this.internalConfig)) {\n if (value !== undefined) {\n // TODO: Replace `any` with type\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (this as any)[key] = value;\n }\n }\n } else {\n for (const key of Object.keys(config) as (keyof C)[]) {\n /* istanbul ignore else */\n if (typeof this.internalConfig[key] !== 'undefined') {\n this.internalConfig[key] = (config as C)[key];\n // TODO: Replace `any` with type\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (this as any)[key] = 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 BaseControllerV1;\n"]}
|
|
@@ -72,9 +72,13 @@ export declare class BaseController<ControllerName extends string, ControllerSta
|
|
|
72
72
|
readonly name: ControllerName;
|
|
73
73
|
readonly metadata: StateMetadata<ControllerState>;
|
|
74
74
|
/**
|
|
75
|
-
* The existence of the `subscribe` property is how the ComposableController
|
|
76
|
-
* controller extends the old BaseController or the new one. We set it to `undefined` here to
|
|
75
|
+
* The existence of the `subscribe` property is how the ComposableController used to detect
|
|
76
|
+
* whether a controller extends the old BaseController or the new one. We set it to `undefined` here to
|
|
77
77
|
* ensure the ComposableController never mistakes them for an older style controller.
|
|
78
|
+
*
|
|
79
|
+
* This property is no longer used, and will be removed in a future release.
|
|
80
|
+
*
|
|
81
|
+
* @deprecated This will be removed in a future release
|
|
78
82
|
*/
|
|
79
83
|
readonly subscribe: undefined;
|
|
80
84
|
/**
|
|
@@ -1 +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,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAC/E,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,iCAAiC,CAAC;AAIrF;;;;;;;;;;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;AAIH,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,oBAAY,wBAAwB,CAClC,cAAc,SAAS,MAAM,EAC7B,eAAe,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,IAC7C;IACF,IAAI,EAAE,GAAG,cAAc,WAAW,CAAC;IACnC,OAAO,EAAE,MAAM,eAAe,CAAC;CAChC,CAAC;AAEF,oBAAY,0BAA0B,CACpC,cAAc,SAAS,MAAM,EAC7B,eAAe,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,IAC7C;IACF,IAAI,EAAE,GAAG,cAAc,cAAc,CAAC;IACtC,OAAO,EAAE,CAAC,eAAe,EAAE,KAAK,EAAE,CAAC,CAAC;CACrC,CAAC;AAEF,oBAAY,iBAAiB,CAC3B,cAAc,SAAS,MAAM,EAC7B,eAAe,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,IAC7C,wBAAwB,CAAC,cAAc,EAAE,eAAe,CAAC,CAAC;AAE9D,oBAAY,gBAAgB,CAC1B,cAAc,SAAS,MAAM,EAC7B,eAAe,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,IAC7C,0BAA0B,CAAC,cAAc,EAAE,eAAe,CAAC,CAAC;AAEhE;;GAEG;AACH,qBAAa,cAAc,CACzB,cAAc,SAAS,MAAM,EAC7B,eAAe,SAAS,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,EAC5C,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
|
|
1
|
+
{"version":3,"file":"BaseControllerV2.d.ts","sourceRoot":"","sources":["../src/BaseControllerV2.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BaseControllerV2.js","sourceRoot":"","sources":["../src/BaseControllerV2.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Json } from '@metamask/utils';\nimport { enablePatches, produceWithPatches, applyPatches } from 'immer';\nimport type { Draft, Patch } from 'immer';\n\nimport type { ActionConstraint, EventConstraint } from './ControllerMessenger';\nimport type { RestrictedControllerMessenger } from './RestrictedControllerMessenger';\n\nenablePatches();\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 */\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 */\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 */\nexport type StateMetadata<T extends Record<string, Json>> = {\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// 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 StatePropertyMetadata<T extends Json> {\n persist: boolean | StateDeriver<T>;\n anonymous: boolean | StateDeriver<T>;\n}\n\nexport type ControllerGetStateAction<\n ControllerName extends string,\n ControllerState extends Record<string, unknown>,\n> = {\n type: `${ControllerName}:getState`;\n handler: () => ControllerState;\n};\n\nexport type ControllerStateChangeEvent<\n ControllerName extends string,\n ControllerState extends Record<string, unknown>,\n> = {\n type: `${ControllerName}:stateChange`;\n payload: [ControllerState, Patch[]];\n};\n\nexport type ControllerActions<\n ControllerName extends string,\n ControllerState extends Record<string, unknown>,\n> = ControllerGetStateAction<ControllerName, ControllerState>;\n\nexport type ControllerEvents<\n ControllerName extends string,\n ControllerState extends Record<string, unknown>,\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 Record<string, Json>,\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 * The existence of the `subscribe` property is how the ComposableController detects whether a\n * controller extends the old BaseController or the new one. We set it to `undefined` here to\n * ensure the ComposableController never mistakes them for an older style controller.\n */\n public readonly subscribe: undefined;\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 this.#internalState = state;\n this.metadata = metadata;\n\n this.messagingSystem.registerActionHandler(\n `${name}:getState`,\n () => 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<\n ControllerState extends Record<string, Json>,\n>(\n state: ControllerState,\n metadata: StateMetadata<ControllerState>,\n): Record<string, 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<\n ControllerState extends Record<string, Json>,\n>(\n state: ControllerState,\n metadata: StateMetadata<ControllerState>,\n): Record<string, 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 Record<string, Json>>(\n state: ControllerState,\n metadata: StateMetadata<ControllerState>,\n metadataProperty: 'anonymous' | 'persist',\n): Record<string, Json> {\n return (Object.keys(state) as (keyof ControllerState)[]).reduce<\n Partial<Record<keyof ControllerState, Json>>\n >((persistedState, 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 persistedState[key] = propertyMetadata(stateProperty);\n } else if (propertyMetadata) {\n persistedState[key] = stateProperty;\n }\n return persistedState;\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 persistedState;\n }\n }, {}) as Record<keyof ControllerState, Json>;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"BaseControllerV2.js","sourceRoot":"","sources":["../src/BaseControllerV2.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Json } from '@metamask/utils';\nimport { enablePatches, produceWithPatches, applyPatches } from 'immer';\nimport type { Draft, Patch } from 'immer';\n\nimport type { ActionConstraint, EventConstraint } from './ControllerMessenger';\nimport type { RestrictedControllerMessenger } from './RestrictedControllerMessenger';\n\nenablePatches();\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 */\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 */\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 */\nexport type StateMetadata<T extends Record<string, Json>> = {\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// 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 StatePropertyMetadata<T extends Json> {\n persist: boolean | StateDeriver<T>;\n anonymous: boolean | StateDeriver<T>;\n}\n\nexport type ControllerGetStateAction<\n ControllerName extends string,\n ControllerState extends Record<string, unknown>,\n> = {\n type: `${ControllerName}:getState`;\n handler: () => ControllerState;\n};\n\nexport type ControllerStateChangeEvent<\n ControllerName extends string,\n ControllerState extends Record<string, unknown>,\n> = {\n type: `${ControllerName}:stateChange`;\n payload: [ControllerState, Patch[]];\n};\n\nexport type ControllerActions<\n ControllerName extends string,\n ControllerState extends Record<string, unknown>,\n> = ControllerGetStateAction<ControllerName, ControllerState>;\n\nexport type ControllerEvents<\n ControllerName extends string,\n ControllerState extends Record<string, unknown>,\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 Record<string, Json>,\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 * The existence of the `subscribe` property is how the ComposableController used to detect\n * whether a controller extends the old BaseController or the new one. We set it to `undefined` here to\n * ensure the ComposableController never mistakes them for an older style controller.\n *\n * This property is no longer used, and will be removed in a future release.\n *\n * @deprecated This will be removed in a future release\n */\n public readonly subscribe: undefined;\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 this.#internalState = state;\n this.metadata = metadata;\n\n this.messagingSystem.registerActionHandler(\n `${name}:getState`,\n () => 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<\n ControllerState extends Record<string, Json>,\n>(\n state: ControllerState,\n metadata: StateMetadata<ControllerState>,\n): Record<string, 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<\n ControllerState extends Record<string, Json>,\n>(\n state: ControllerState,\n metadata: StateMetadata<ControllerState>,\n): Record<string, 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 Record<string, Json>>(\n state: ControllerState,\n metadata: StateMetadata<ControllerState>,\n metadataProperty: 'anonymous' | 'persist',\n): Record<string, Json> {\n return (Object.keys(state) as (keyof ControllerState)[]).reduce<\n Partial<Record<keyof ControllerState, Json>>\n >((persistedState, 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 persistedState[key] = propertyMetadata(stateProperty);\n } else if (propertyMetadata) {\n persistedState[key] = stateProperty;\n }\n return persistedState;\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 persistedState;\n }\n }, {}) as Record<keyof ControllerState, Json>;\n}\n"]}
|
|
@@ -35,7 +35,8 @@ export declare type EventConstraint = {
|
|
|
35
35
|
* @template Namespace - The namespace we're checking for.
|
|
36
36
|
* @template Name - The full string, including the namespace.
|
|
37
37
|
*/
|
|
38
|
-
export declare type
|
|
38
|
+
export declare type NamespacedBy<Namespace extends string, Name> = Name extends `${Namespace}:${string}` ? Name : never;
|
|
39
|
+
export declare type NotNamespacedBy<Namespace extends string, Name> = Name extends `${Namespace}:${string}` ? never : Name;
|
|
39
40
|
export declare type NamespacedName<Namespace extends string = string> = `${Namespace}:${string}`;
|
|
40
41
|
declare type NarrowToNamespace<Name, Namespace extends string> = Name extends {
|
|
41
42
|
type: `${Namespace}:${string}`;
|
|
@@ -186,13 +187,15 @@ export declare class ControllerMessenger<Action extends ActionConstraint, Event
|
|
|
186
187
|
* module that this messenger has been created for. The authority to publish events and register
|
|
187
188
|
* actions under this namespace is granted to this restricted messenger instance.
|
|
188
189
|
* @template AllowedAction - A type union of the 'type' string for any allowed actions.
|
|
190
|
+
* This must not include internal actions that are in the messenger's namespace.
|
|
189
191
|
* @template AllowedEvent - A type union of the 'type' string for any allowed events.
|
|
192
|
+
* This must not include internal events that are in the messenger's namespace.
|
|
190
193
|
* @returns The restricted controller messenger.
|
|
191
194
|
*/
|
|
192
|
-
getRestricted<Namespace extends string, AllowedAction extends
|
|
195
|
+
getRestricted<Namespace extends string, AllowedAction extends NotNamespacedBy<Namespace, Action['type']>, AllowedEvent extends NotNamespacedBy<Namespace, Event['type']>>({ name, allowedActions, allowedEvents, }: {
|
|
193
196
|
name: Namespace;
|
|
194
|
-
allowedActions?: Extract<Action['type'], AllowedAction
|
|
195
|
-
allowedEvents?: Extract<Event['type'], AllowedEvent
|
|
197
|
+
allowedActions?: NotNamespacedBy<Namespace, Extract<Action['type'], AllowedAction>>[];
|
|
198
|
+
allowedEvents?: NotNamespacedBy<Namespace, Extract<Event['type'], AllowedEvent>>[];
|
|
196
199
|
}): RestrictedControllerMessenger<Namespace, NarrowToNamespace<Action, Namespace> | NarrowToAllowed<Action, AllowedAction>, NarrowToNamespace<Event, Namespace> | NarrowToAllowed<Event, AllowedEvent>, AllowedAction, AllowedEvent>;
|
|
197
200
|
}
|
|
198
201
|
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ControllerMessenger.d.ts","sourceRoot":"","sources":["../src/ControllerMessenger.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,6BAA6B,EAAE,MAAM,iCAAiC,CAAC;AAEhF,oBAAY,aAAa,CACvB,MAAM,SAAS,gBAAgB,EAC/B,UAAU,GAAG,MAAM,CAAC,MAAM,CAAC,IACzB,CACF,GAAG,IAAI,EAAE,uBAAuB,CAAC,MAAM,EAAE,UAAU,CAAC,KACjD,qBAAqB,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;AAE/C,oBAAY,uBAAuB,CACjC,MAAM,SAAS,gBAAgB,EAC/B,UAAU,GAAG,MAAM,CAAC,MAAM,CAAC,IACzB,MAAM,SAAS;IACjB,IAAI,EAAE,UAAU,CAAC;IACjB,OAAO,EAAE,CAAC,GAAG,IAAI,EAAE,MAAM,WAAW,KAAK,OAAO,CAAC;CAClD,GACG,WAAW,GACX,KAAK,CAAC;AAEV,oBAAY,qBAAqB,CAC/B,MAAM,SAAS,gBAAgB,EAC/B,UAAU,GAAG,MAAM,CAAC,MAAM,CAAC,IACzB,MAAM,SAAS;IACjB,IAAI,EAAE,UAAU,CAAC;IACjB,OAAO,EAAE,CAAC,GAAG,IAAI,EAAE,MAAM,CAAC,KAAK,MAAM,kBAAkB,CAAC;CACzD,GACG,kBAAkB,GAClB,KAAK,CAAC;AAEV,oBAAY,mBAAmB,CAC7B,KAAK,SAAS,eAAe,EAC7B,SAAS,GAAG,KAAK,CAAC,MAAM,CAAC,IACvB,KAAK,SAAS;IAChB,IAAI,EAAE,SAAS,CAAC;IAChB,OAAO,EAAE,MAAM,OAAO,CAAC;CACxB,GACG,OAAO,SAAS,OAAO,EAAE,GACvB,CAAC,GAAG,OAAO,EAAE,OAAO,KAAK,IAAI,GAC7B,KAAK,GACP,KAAK,CAAC;AAEV,oBAAY,mBAAmB,CAC7B,KAAK,SAAS,eAAe,EAC7B,SAAS,GAAG,KAAK,CAAC,MAAM,CAAC,IACvB,KAAK,SAAS;IAChB,IAAI,EAAE,SAAS,CAAC;IAChB,OAAO,EAAE,MAAM,OAAO,CAAC;CACxB,GACG,OAAO,SAAS,OAAO,EAAE,GACvB,OAAO,GACP,KAAK,GACP,KAAK,CAAC;AAEV,oBAAY,mBAAmB,GAAG,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;AAE/D,oBAAY,gBAAgB,CAAC,KAAK,SAAS,eAAe,EAAE,WAAW,IAAI,CACzE,GAAG,IAAI,EAAE,mBAAmB,CAAC,KAAK,CAAC,KAChC,WAAW,CAAC;AACjB,oBAAY,oBAAoB,CAAC,mBAAmB,IAAI,CACtD,QAAQ,EAAE,mBAAmB,EAC7B,aAAa,EAAE,mBAAmB,GAAG,SAAS,KAC3C,IAAI,CAAC;AAEV,oBAAY,gBAAgB,GAAG;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE,KAAK,KAAK,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,IAAI,EAAE,KAAK,EAAE,KAAK,OAAO,CAAC,CAAC;CAC1E,CAAC;AACF,oBAAY,eAAe,GAAG;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,OAAO,EAAE,CAAC;CACpB,CAAC;AAUF;;;;;;;GAOG;AACH,oBAAY,
|
|
1
|
+
{"version":3,"file":"ControllerMessenger.d.ts","sourceRoot":"","sources":["../src/ControllerMessenger.ts"],"names":[],"mappings":"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"}
|
|
@@ -192,7 +192,9 @@ class ControllerMessenger {
|
|
|
192
192
|
* module that this messenger has been created for. The authority to publish events and register
|
|
193
193
|
* actions under this namespace is granted to this restricted messenger instance.
|
|
194
194
|
* @template AllowedAction - A type union of the 'type' string for any allowed actions.
|
|
195
|
+
* This must not include internal actions that are in the messenger's namespace.
|
|
195
196
|
* @template AllowedEvent - A type union of the 'type' string for any allowed events.
|
|
197
|
+
* This must not include internal events that are in the messenger's namespace.
|
|
196
198
|
* @returns The restricted controller messenger.
|
|
197
199
|
*/
|
|
198
200
|
getRestricted({ name, allowedActions, allowedEvents, }) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ControllerMessenger.js","sourceRoot":"","sources":["../src/ControllerMessenger.ts"],"names":[],"mappings":"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","sourcesContent":["import { RestrictedControllerMessenger } from './RestrictedControllerMessenger';\n\nexport type ActionHandler<\n Action extends ActionConstraint,\n ActionType = Action['type'],\n> = (\n ...args: ExtractActionParameters<Action, ActionType>\n) => ExtractActionResponse<Action, ActionType>;\n\nexport type ExtractActionParameters<\n Action extends ActionConstraint,\n ActionType = Action['type'],\n> = Action extends {\n type: ActionType;\n handler: (...args: infer HandlerArgs) => unknown;\n}\n ? HandlerArgs\n : never;\n\nexport type ExtractActionResponse<\n Action extends ActionConstraint,\n ActionType = Action['type'],\n> = Action extends {\n type: ActionType;\n handler: (...args: infer _) => infer HandlerReturnValue;\n}\n ? HandlerReturnValue\n : never;\n\nexport type ExtractEventHandler<\n Event extends EventConstraint,\n EventType = Event['type'],\n> = Event extends {\n type: EventType;\n payload: infer Payload;\n}\n ? Payload extends unknown[]\n ? (...payload: Payload) => void\n : never\n : never;\n\nexport type ExtractEventPayload<\n Event extends EventConstraint,\n EventType = Event['type'],\n> = Event extends {\n type: EventType;\n payload: infer Payload;\n}\n ? Payload extends unknown[]\n ? Payload\n : never\n : never;\n\nexport type GenericEventHandler = (...args: unknown[]) => void;\n\nexport type SelectorFunction<Event extends EventConstraint, ReturnValue> = (\n ...args: ExtractEventPayload<Event>\n) => ReturnValue;\nexport type SelectorEventHandler<SelectorReturnValue> = (\n newValue: SelectorReturnValue,\n previousValue: SelectorReturnValue | undefined,\n) => void;\n\nexport type ActionConstraint = {\n type: string;\n handler: ((...args: never) => unknown) | ((...args: never[]) => unknown);\n};\nexport type EventConstraint = {\n type: string;\n payload: unknown[];\n};\n\ntype EventSubscriptionMap<\n Event extends EventConstraint,\n ReturnValue = unknown,\n> = Map<\n GenericEventHandler | SelectorEventHandler<ReturnValue>,\n SelectorFunction<ExtractEventPayload<Event>, ReturnValue> | undefined\n>;\n\n/**\n * A namespaced string\n *\n * This type verifies that the string Name is prefixed by the string Name followed by a colon.\n *\n * @template Namespace - The namespace we're checking for.\n * @template Name - The full string, including the namespace.\n */\nexport type Namespaced<\n Namespace extends string,\n Name,\n> = Name extends `${Namespace}:${string}` ? Name : never;\n\nexport type NamespacedName<Namespace extends string = string> =\n `${Namespace}:${string}`;\n\ntype NarrowToNamespace<Name, Namespace extends string> = Name extends {\n type: `${Namespace}:${string}`;\n}\n ? Name\n : never;\n\ntype NarrowToAllowed<Name, Allowed extends string> = Name extends {\n type: Allowed;\n}\n ? Name\n : never;\n\n/**\n * A messaging system for controllers.\n *\n * The controller messenger allows registering functions as 'actions' that can be called elsewhere,\n * and it allows publishing and subscribing to events. Both actions and events are identified by\n * unique strings.\n *\n * @template Action - A type union of all Action types.\n * @template Event - A type union of all Event types.\n */\nexport class ControllerMessenger<\n Action extends ActionConstraint,\n Event extends EventConstraint,\n> {\n readonly #actions = new Map<Action['type'], unknown>();\n\n readonly #events = new Map<Event['type'], EventSubscriptionMap<Event>>();\n\n /**\n * A cache of selector return values for their respective handlers.\n */\n readonly #eventPayloadCache = new Map<\n GenericEventHandler,\n unknown | undefined\n >();\n\n /**\n * Register an action handler.\n *\n * This will make the registered function available to call via the `call` method.\n *\n * @param actionType - The action type. This is a unqiue identifier for this action.\n * @param handler - The action handler. This function gets called when the `call` method is\n * invoked with the given action type.\n * @throws Will throw when a handler has been registered for this action type already.\n * @template ActionType - A type union of Action type strings.\n */\n registerActionHandler<ActionType extends Action['type']>(\n actionType: ActionType,\n handler: ActionHandler<Action, ActionType>,\n ) {\n if (this.#actions.has(actionType)) {\n throw new Error(\n `A handler for ${actionType} has already been registered`,\n );\n }\n this.#actions.set(actionType, handler);\n }\n\n /**\n * Unregister an action handler.\n *\n * This will prevent this action from being called.\n *\n * @param actionType - The action type. This is a unqiue identifier for this action.\n * @template ActionType - A type union of Action type strings.\n */\n unregisterActionHandler<ActionType extends Action['type']>(\n actionType: ActionType,\n ) {\n this.#actions.delete(actionType);\n }\n\n /**\n * Unregister all action handlers.\n *\n * This prevents all actions from being called.\n */\n clearActions() {\n this.#actions.clear();\n }\n\n /**\n * Call an action.\n *\n * This function will call the action handler corresponding to the given action type, passing\n * along any parameters given.\n *\n * @param actionType - The action type. This is a unqiue identifier for this action.\n * @param params - The action parameters. These must match the type of the parameters of the\n * registered action handler.\n * @throws Will throw when no handler has been registered for the given type.\n * @template ActionType - A type union of Action type strings.\n * @returns The action return value.\n */\n call<ActionType extends Action['type']>(\n actionType: ActionType,\n ...params: ExtractActionParameters<Action, ActionType>\n ): ExtractActionResponse<Action, ActionType> {\n const handler = this.#actions.get(actionType) as ActionHandler<\n Action,\n ActionType\n >;\n if (!handler) {\n throw new Error(`A handler for ${actionType} has not been registered`);\n }\n return handler(...params);\n }\n\n /**\n * Publish an event.\n *\n * Publishes the given payload to all subscribers of the given event type.\n *\n * Note that this method should never throw directly. Any errors from\n * subscribers are captured and re-thrown in a timeout handler.\n *\n * @param eventType - The event type. This is a unique identifier for this event.\n * @param payload - The event payload. The type of the parameters for each event handler must\n * match the type of this payload.\n * @template EventType - A type union of Event type strings.\n */\n publish<EventType extends Event['type']>(\n eventType: EventType,\n ...payload: ExtractEventPayload<Event, EventType>\n ) {\n const subscribers = this.#events.get(eventType);\n\n if (subscribers) {\n for (const [handler, selector] of subscribers.entries()) {\n try {\n if (selector) {\n const previousValue = this.#eventPayloadCache.get(handler);\n const newValue = selector(...payload);\n\n if (newValue !== previousValue) {\n this.#eventPayloadCache.set(handler, newValue);\n handler(newValue, previousValue);\n }\n } else {\n (handler as GenericEventHandler)(...payload);\n }\n } catch (error) {\n // Throw error after timeout so that it is capured as a console error\n // (and by Sentry) without interrupting the event publishing.\n setTimeout(() => {\n throw error;\n });\n }\n }\n }\n }\n\n /**\n * Subscribe to an event.\n *\n * Registers the given function as an event handler for the given event type.\n *\n * @param eventType - The event type. This is a unique identifier for this event.\n * @param handler - The event handler. The type of the parameters for this event handler must\n * match the type of the payload for this event type.\n * @template EventType - A type union of Event type strings.\n */\n subscribe<EventType extends Event['type']>(\n eventType: EventType,\n handler: ExtractEventHandler<Event, EventType>,\n ): void;\n\n /**\n * Subscribe to an event, with a selector.\n *\n * Registers the given handler function as an event handler for the given\n * event type. When an event is published, its payload is first passed to the\n * selector. The event handler is only called if the selector's return value\n * differs from its last known return value.\n *\n * @param eventType - The event type. This is a unique identifier for this event.\n * @param handler - The event handler. The type of the parameters for this event\n * handler must match the return type of the selector.\n * @param selector - The selector function used to select relevant data from\n * the event payload. The type of the parameters for this selector must match\n * the type of the payload for this event type.\n * @template EventType - A type union of Event type strings.\n * @template SelectorReturnValue - The selector return value.\n */\n subscribe<EventType extends Event['type'], SelectorReturnValue>(\n eventType: EventType,\n handler: SelectorEventHandler<SelectorReturnValue>,\n selector: SelectorFunction<\n ExtractEventPayload<Event, EventType>,\n SelectorReturnValue\n >,\n ): void;\n\n subscribe<EventType extends Event['type'], SelectorReturnValue>(\n eventType: EventType,\n handler: ExtractEventHandler<Event, EventType>,\n selector?: SelectorFunction<\n ExtractEventPayload<Event, EventType>,\n SelectorReturnValue\n >,\n ): void {\n let subscribers = this.#events.get(eventType);\n if (!subscribers) {\n subscribers = new Map();\n this.#events.set(eventType, subscribers);\n }\n\n subscribers.set(handler, selector);\n }\n\n /**\n * Unsubscribe from an event.\n *\n * Unregisters the given function as an event handler for the given event.\n *\n * @param eventType - The event type. This is a unique identifier for this event.\n * @param handler - The event handler to unregister.\n * @throws Will throw when the given event handler is not registered for this event.\n * @template EventType - A type union of Event type strings.\n */\n unsubscribe<EventType extends Event['type']>(\n eventType: EventType,\n handler: ExtractEventHandler<Event, EventType>,\n ) {\n const subscribers = this.#events.get(eventType);\n\n if (!subscribers || !subscribers.has(handler)) {\n throw new Error(`Subscription not found for event: ${eventType}`);\n }\n\n const selector = subscribers.get(handler);\n if (selector) {\n this.#eventPayloadCache.delete(handler);\n }\n\n subscribers.delete(handler);\n }\n\n /**\n * Clear subscriptions for a specific event.\n *\n * This will remove all subscribed handlers for this event.\n *\n * @param eventType - The event type. This is a unique identifier for this event.\n * @template EventType - A type union of Event type strings.\n */\n clearEventSubscriptions<EventType extends Event['type']>(\n eventType: EventType,\n ) {\n this.#events.delete(eventType);\n }\n\n /**\n * Clear all subscriptions.\n *\n * This will remove all subscribed handlers for all events.\n */\n clearSubscriptions() {\n this.#events.clear();\n }\n\n /**\n * Get a restricted controller messenger\n *\n * Returns a wrapper around the controller messenger instance that restricts access to actions\n * and events. The provided allowlists grant the ability to call the listed actions and subscribe\n * to the listed events. The \"name\" provided grants ownership of any actions and events under\n * that namespace. Ownership allows registering actions and publishing events, as well as\n * unregistering actions and clearing event subscriptions.\n *\n * @param options - Controller messenger options.\n * @param options.name - The name of the thing this messenger will be handed to (e.g. the\n * controller name). This grants \"ownership\" of actions and events under this namespace to the\n * restricted controller messenger returned.\n * @param options.allowedActions - The list of actions that this restricted controller messenger\n * should be alowed to call.\n * @param options.allowedEvents - The list of events that this restricted controller messenger\n * should be allowed to subscribe to.\n * @template Namespace - The namespace for this messenger. Typically this is the name of the controller or\n * module that this messenger has been created for. The authority to publish events and register\n * actions under this namespace is granted to this restricted messenger instance.\n * @template AllowedAction - A type union of the 'type' string for any allowed actions.\n * @template AllowedEvent - A type union of the 'type' string for any allowed events.\n * @returns The restricted controller messenger.\n */\n getRestricted<\n Namespace extends string,\n AllowedAction extends string,\n AllowedEvent extends string,\n >({\n name,\n allowedActions,\n allowedEvents,\n }: {\n name: Namespace;\n allowedActions?: Extract<Action['type'], AllowedAction>[];\n allowedEvents?: Extract<Event['type'], AllowedEvent>[];\n }): RestrictedControllerMessenger<\n Namespace,\n | NarrowToNamespace<Action, Namespace>\n | NarrowToAllowed<Action, AllowedAction>,\n NarrowToNamespace<Event, Namespace> | NarrowToAllowed<Event, AllowedEvent>,\n AllowedAction,\n AllowedEvent\n > {\n return new RestrictedControllerMessenger<\n Namespace,\n | NarrowToNamespace<Action, Namespace>\n | NarrowToAllowed<Action, AllowedAction>,\n | NarrowToNamespace<Event, Namespace>\n | NarrowToAllowed<Event, AllowedEvent>,\n AllowedAction,\n AllowedEvent\n >({\n controllerMessenger: this,\n name,\n allowedActions,\n allowedEvents,\n });\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"ControllerMessenger.js","sourceRoot":"","sources":["../src/ControllerMessenger.ts"],"names":[],"mappings":"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","sourcesContent":["import { RestrictedControllerMessenger } from './RestrictedControllerMessenger';\n\nexport type ActionHandler<\n Action extends ActionConstraint,\n ActionType = Action['type'],\n> = (\n ...args: ExtractActionParameters<Action, ActionType>\n) => ExtractActionResponse<Action, ActionType>;\n\nexport type ExtractActionParameters<\n Action extends ActionConstraint,\n ActionType = Action['type'],\n> = Action extends {\n type: ActionType;\n handler: (...args: infer HandlerArgs) => unknown;\n}\n ? HandlerArgs\n : never;\n\nexport type ExtractActionResponse<\n Action extends ActionConstraint,\n ActionType = Action['type'],\n> = Action extends {\n type: ActionType;\n handler: (...args: infer _) => infer HandlerReturnValue;\n}\n ? HandlerReturnValue\n : never;\n\nexport type ExtractEventHandler<\n Event extends EventConstraint,\n EventType = Event['type'],\n> = Event extends {\n type: EventType;\n payload: infer Payload;\n}\n ? Payload extends unknown[]\n ? (...payload: Payload) => void\n : never\n : never;\n\nexport type ExtractEventPayload<\n Event extends EventConstraint,\n EventType = Event['type'],\n> = Event extends {\n type: EventType;\n payload: infer Payload;\n}\n ? Payload extends unknown[]\n ? Payload\n : never\n : never;\n\nexport type GenericEventHandler = (...args: unknown[]) => void;\n\nexport type SelectorFunction<Event extends EventConstraint, ReturnValue> = (\n ...args: ExtractEventPayload<Event>\n) => ReturnValue;\nexport type SelectorEventHandler<SelectorReturnValue> = (\n newValue: SelectorReturnValue,\n previousValue: SelectorReturnValue | undefined,\n) => void;\n\nexport type ActionConstraint = {\n type: string;\n handler: ((...args: never) => unknown) | ((...args: never[]) => unknown);\n};\nexport type EventConstraint = {\n type: string;\n payload: unknown[];\n};\n\ntype EventSubscriptionMap<\n Event extends EventConstraint,\n ReturnValue = unknown,\n> = Map<\n GenericEventHandler | SelectorEventHandler<ReturnValue>,\n SelectorFunction<ExtractEventPayload<Event>, ReturnValue> | undefined\n>;\n\n/**\n * A namespaced string\n *\n * This type verifies that the string Name is prefixed by the string Name followed by a colon.\n *\n * @template Namespace - The namespace we're checking for.\n * @template Name - The full string, including the namespace.\n */\nexport type NamespacedBy<\n Namespace extends string,\n Name,\n> = Name extends `${Namespace}:${string}` ? Name : never;\n\nexport type NotNamespacedBy<\n Namespace extends string,\n Name,\n> = Name extends `${Namespace}:${string}` ? never : Name;\n\nexport type NamespacedName<Namespace extends string = string> =\n `${Namespace}:${string}`;\n\ntype NarrowToNamespace<Name, Namespace extends string> = Name extends {\n type: `${Namespace}:${string}`;\n}\n ? Name\n : never;\n\ntype NarrowToAllowed<Name, Allowed extends string> = Name extends {\n type: Allowed;\n}\n ? Name\n : never;\n\n/**\n * A messaging system for controllers.\n *\n * The controller messenger allows registering functions as 'actions' that can be called elsewhere,\n * and it allows publishing and subscribing to events. Both actions and events are identified by\n * unique strings.\n *\n * @template Action - A type union of all Action types.\n * @template Event - A type union of all Event types.\n */\nexport class ControllerMessenger<\n Action extends ActionConstraint,\n Event extends EventConstraint,\n> {\n readonly #actions = new Map<Action['type'], unknown>();\n\n readonly #events = new Map<Event['type'], EventSubscriptionMap<Event>>();\n\n /**\n * A cache of selector return values for their respective handlers.\n */\n readonly #eventPayloadCache = new Map<\n GenericEventHandler,\n unknown | undefined\n >();\n\n /**\n * Register an action handler.\n *\n * This will make the registered function available to call via the `call` method.\n *\n * @param actionType - The action type. This is a unqiue identifier for this action.\n * @param handler - The action handler. This function gets called when the `call` method is\n * invoked with the given action type.\n * @throws Will throw when a handler has been registered for this action type already.\n * @template ActionType - A type union of Action type strings.\n */\n registerActionHandler<ActionType extends Action['type']>(\n actionType: ActionType,\n handler: ActionHandler<Action, ActionType>,\n ) {\n if (this.#actions.has(actionType)) {\n throw new Error(\n `A handler for ${actionType} has already been registered`,\n );\n }\n this.#actions.set(actionType, handler);\n }\n\n /**\n * Unregister an action handler.\n *\n * This will prevent this action from being called.\n *\n * @param actionType - The action type. This is a unqiue identifier for this action.\n * @template ActionType - A type union of Action type strings.\n */\n unregisterActionHandler<ActionType extends Action['type']>(\n actionType: ActionType,\n ) {\n this.#actions.delete(actionType);\n }\n\n /**\n * Unregister all action handlers.\n *\n * This prevents all actions from being called.\n */\n clearActions() {\n this.#actions.clear();\n }\n\n /**\n * Call an action.\n *\n * This function will call the action handler corresponding to the given action type, passing\n * along any parameters given.\n *\n * @param actionType - The action type. This is a unqiue identifier for this action.\n * @param params - The action parameters. These must match the type of the parameters of the\n * registered action handler.\n * @throws Will throw when no handler has been registered for the given type.\n * @template ActionType - A type union of Action type strings.\n * @returns The action return value.\n */\n call<ActionType extends Action['type']>(\n actionType: ActionType,\n ...params: ExtractActionParameters<Action, ActionType>\n ): ExtractActionResponse<Action, ActionType> {\n const handler = this.#actions.get(actionType) as ActionHandler<\n Action,\n ActionType\n >;\n if (!handler) {\n throw new Error(`A handler for ${actionType} has not been registered`);\n }\n return handler(...params);\n }\n\n /**\n * Publish an event.\n *\n * Publishes the given payload to all subscribers of the given event type.\n *\n * Note that this method should never throw directly. Any errors from\n * subscribers are captured and re-thrown in a timeout handler.\n *\n * @param eventType - The event type. This is a unique identifier for this event.\n * @param payload - The event payload. The type of the parameters for each event handler must\n * match the type of this payload.\n * @template EventType - A type union of Event type strings.\n */\n publish<EventType extends Event['type']>(\n eventType: EventType,\n ...payload: ExtractEventPayload<Event, EventType>\n ) {\n const subscribers = this.#events.get(eventType);\n\n if (subscribers) {\n for (const [handler, selector] of subscribers.entries()) {\n try {\n if (selector) {\n const previousValue = this.#eventPayloadCache.get(handler);\n const newValue = selector(...payload);\n\n if (newValue !== previousValue) {\n this.#eventPayloadCache.set(handler, newValue);\n handler(newValue, previousValue);\n }\n } else {\n (handler as GenericEventHandler)(...payload);\n }\n } catch (error) {\n // Throw error after timeout so that it is capured as a console error\n // (and by Sentry) without interrupting the event publishing.\n setTimeout(() => {\n throw error;\n });\n }\n }\n }\n }\n\n /**\n * Subscribe to an event.\n *\n * Registers the given function as an event handler for the given event type.\n *\n * @param eventType - The event type. This is a unique identifier for this event.\n * @param handler - The event handler. The type of the parameters for this event handler must\n * match the type of the payload for this event type.\n * @template EventType - A type union of Event type strings.\n */\n subscribe<EventType extends Event['type']>(\n eventType: EventType,\n handler: ExtractEventHandler<Event, EventType>,\n ): void;\n\n /**\n * Subscribe to an event, with a selector.\n *\n * Registers the given handler function as an event handler for the given\n * event type. When an event is published, its payload is first passed to the\n * selector. The event handler is only called if the selector's return value\n * differs from its last known return value.\n *\n * @param eventType - The event type. This is a unique identifier for this event.\n * @param handler - The event handler. The type of the parameters for this event\n * handler must match the return type of the selector.\n * @param selector - The selector function used to select relevant data from\n * the event payload. The type of the parameters for this selector must match\n * the type of the payload for this event type.\n * @template EventType - A type union of Event type strings.\n * @template SelectorReturnValue - The selector return value.\n */\n subscribe<EventType extends Event['type'], SelectorReturnValue>(\n eventType: EventType,\n handler: SelectorEventHandler<SelectorReturnValue>,\n selector: SelectorFunction<\n ExtractEventPayload<Event, EventType>,\n SelectorReturnValue\n >,\n ): void;\n\n subscribe<EventType extends Event['type'], SelectorReturnValue>(\n eventType: EventType,\n handler: ExtractEventHandler<Event, EventType>,\n selector?: SelectorFunction<\n ExtractEventPayload<Event, EventType>,\n SelectorReturnValue\n >,\n ): void {\n let subscribers = this.#events.get(eventType);\n if (!subscribers) {\n subscribers = new Map();\n this.#events.set(eventType, subscribers);\n }\n\n subscribers.set(handler, selector);\n }\n\n /**\n * Unsubscribe from an event.\n *\n * Unregisters the given function as an event handler for the given event.\n *\n * @param eventType - The event type. This is a unique identifier for this event.\n * @param handler - The event handler to unregister.\n * @throws Will throw when the given event handler is not registered for this event.\n * @template EventType - A type union of Event type strings.\n */\n unsubscribe<EventType extends Event['type']>(\n eventType: EventType,\n handler: ExtractEventHandler<Event, EventType>,\n ) {\n const subscribers = this.#events.get(eventType);\n\n if (!subscribers || !subscribers.has(handler)) {\n throw new Error(`Subscription not found for event: ${eventType}`);\n }\n\n const selector = subscribers.get(handler);\n if (selector) {\n this.#eventPayloadCache.delete(handler);\n }\n\n subscribers.delete(handler);\n }\n\n /**\n * Clear subscriptions for a specific event.\n *\n * This will remove all subscribed handlers for this event.\n *\n * @param eventType - The event type. This is a unique identifier for this event.\n * @template EventType - A type union of Event type strings.\n */\n clearEventSubscriptions<EventType extends Event['type']>(\n eventType: EventType,\n ) {\n this.#events.delete(eventType);\n }\n\n /**\n * Clear all subscriptions.\n *\n * This will remove all subscribed handlers for all events.\n */\n clearSubscriptions() {\n this.#events.clear();\n }\n\n /**\n * Get a restricted controller messenger\n *\n * Returns a wrapper around the controller messenger instance that restricts access to actions\n * and events. The provided allowlists grant the ability to call the listed actions and subscribe\n * to the listed events. The \"name\" provided grants ownership of any actions and events under\n * that namespace. Ownership allows registering actions and publishing events, as well as\n * unregistering actions and clearing event subscriptions.\n *\n * @param options - Controller messenger options.\n * @param options.name - The name of the thing this messenger will be handed to (e.g. the\n * controller name). This grants \"ownership\" of actions and events under this namespace to the\n * restricted controller messenger returned.\n * @param options.allowedActions - The list of actions that this restricted controller messenger\n * should be alowed to call.\n * @param options.allowedEvents - The list of events that this restricted controller messenger\n * should be allowed to subscribe to.\n * @template Namespace - The namespace for this messenger. Typically this is the name of the controller or\n * module that this messenger has been created for. The authority to publish events and register\n * actions under this namespace is granted to this restricted messenger instance.\n * @template AllowedAction - A type union of the 'type' string for any allowed actions.\n * This must not include internal actions that are in the messenger's namespace.\n * @template AllowedEvent - A type union of the 'type' string for any allowed events.\n * This must not include internal events that are in the messenger's namespace.\n * @returns The restricted controller messenger.\n */\n getRestricted<\n Namespace extends string,\n AllowedAction extends NotNamespacedBy<Namespace, Action['type']>,\n AllowedEvent extends NotNamespacedBy<Namespace, Event['type']>,\n >({\n name,\n allowedActions,\n allowedEvents,\n }: {\n name: Namespace;\n allowedActions?: NotNamespacedBy<\n Namespace,\n Extract<Action['type'], AllowedAction>\n >[];\n allowedEvents?: NotNamespacedBy<\n Namespace,\n Extract<Event['type'], AllowedEvent>\n >[];\n }): RestrictedControllerMessenger<\n Namespace,\n | NarrowToNamespace<Action, Namespace>\n | NarrowToAllowed<Action, AllowedAction>,\n NarrowToNamespace<Event, Namespace> | NarrowToAllowed<Event, AllowedEvent>,\n AllowedAction,\n AllowedEvent\n > {\n return new RestrictedControllerMessenger<\n Namespace,\n | NarrowToNamespace<Action, Namespace>\n | NarrowToAllowed<Action, AllowedAction>,\n | NarrowToNamespace<Event, Namespace>\n | NarrowToAllowed<Event, AllowedEvent>,\n AllowedAction,\n AllowedEvent\n >({\n controllerMessenger: this,\n name,\n allowedActions,\n allowedEvents,\n });\n }\n}\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ActionConstraint, ActionHandler, ControllerMessenger, EventConstraint, ExtractActionParameters, ExtractActionResponse, ExtractEventHandler, ExtractEventPayload, NamespacedName, SelectorEventHandler, SelectorFunction } from './ControllerMessenger';
|
|
1
|
+
import type { ActionConstraint, ActionHandler, ControllerMessenger, EventConstraint, ExtractActionParameters, ExtractActionResponse, ExtractEventHandler, ExtractEventPayload, NamespacedName, NotNamespacedBy, SelectorEventHandler, SelectorFunction } from './ControllerMessenger';
|
|
2
2
|
/**
|
|
3
3
|
* A restricted controller messenger.
|
|
4
4
|
*
|
|
@@ -11,7 +11,9 @@ import type { ActionConstraint, ActionHandler, ControllerMessenger, EventConstra
|
|
|
11
11
|
* @template Action - A type union of all Action types.
|
|
12
12
|
* @template Event - A type union of all Event types.
|
|
13
13
|
* @template AllowedAction - A type union of the 'type' string for any allowed actions.
|
|
14
|
+
* This must not include internal actions that are in the messenger's namespace.
|
|
14
15
|
* @template AllowedEvent - A type union of the 'type' string for any allowed events.
|
|
16
|
+
* This must not include internal events that are in the messenger's namespace.
|
|
15
17
|
*/
|
|
16
18
|
export declare class RestrictedControllerMessenger<Namespace extends string, Action extends ActionConstraint, Event extends EventConstraint, AllowedAction extends string, AllowedEvent extends string> {
|
|
17
19
|
#private;
|
|
@@ -36,8 +38,8 @@ export declare class RestrictedControllerMessenger<Namespace extends string, Act
|
|
|
36
38
|
constructor({ controllerMessenger, name, allowedActions, allowedEvents, }: {
|
|
37
39
|
controllerMessenger: ControllerMessenger<ActionConstraint, EventConstraint>;
|
|
38
40
|
name: Namespace;
|
|
39
|
-
allowedActions?: AllowedAction[];
|
|
40
|
-
allowedEvents?: AllowedEvent[];
|
|
41
|
+
allowedActions?: NotNamespacedBy<Namespace, AllowedAction>[];
|
|
42
|
+
allowedEvents?: NotNamespacedBy<Namespace, AllowedEvent>[];
|
|
41
43
|
});
|
|
42
44
|
/**
|
|
43
45
|
* Register an action handler.
|
|
@@ -52,7 +54,7 @@ export declare class RestrictedControllerMessenger<Namespace extends string, Act
|
|
|
52
54
|
* @throws Will throw if an action handler that is not in the current namespace is being registered.
|
|
53
55
|
* @template ActionType - A type union of Action type strings that are namespaced by Namespace.
|
|
54
56
|
*/
|
|
55
|
-
registerActionHandler<ActionType extends Action['type']
|
|
57
|
+
registerActionHandler<ActionType extends Action['type'] & NamespacedName<Namespace>>(action: ActionType, handler: ActionHandler<Action, ActionType>): void;
|
|
56
58
|
/**
|
|
57
59
|
* Unregister an action handler.
|
|
58
60
|
*
|
|
@@ -60,10 +62,11 @@ export declare class RestrictedControllerMessenger<Namespace extends string, Act
|
|
|
60
62
|
*
|
|
61
63
|
* The action type being unregistered *must* be in the current namespace.
|
|
62
64
|
*
|
|
63
|
-
* @param action - The action type. This is a
|
|
65
|
+
* @param action - The action type. This is a unique identifier for this action.
|
|
66
|
+
* @throws Will throw if an action handler that is not in the current namespace is being unregistered.
|
|
64
67
|
* @template ActionType - A type union of Action type strings that are namespaced by Namespace.
|
|
65
68
|
*/
|
|
66
|
-
unregisterActionHandler<ActionType extends NamespacedName<Namespace>>(action: ActionType): void;
|
|
69
|
+
unregisterActionHandler<ActionType extends Action['type'] & NamespacedName<Namespace>>(action: ActionType): void;
|
|
67
70
|
/**
|
|
68
71
|
* Call an action.
|
|
69
72
|
*
|
|
@@ -72,14 +75,14 @@ export declare class RestrictedControllerMessenger<Namespace extends string, Act
|
|
|
72
75
|
*
|
|
73
76
|
* The action type being called must be on the action allowlist.
|
|
74
77
|
*
|
|
75
|
-
* @param
|
|
78
|
+
* @param actionType - The action type. This is a unqiue identifier for this action.
|
|
76
79
|
* @param params - The action parameters. These must match the type of the parameters of the
|
|
77
80
|
* registered action handler.
|
|
78
81
|
* @throws Will throw when no handler has been registered for the given type.
|
|
79
82
|
* @template ActionType - A type union of allowed Action type strings.
|
|
80
83
|
* @returns The action return value.
|
|
81
84
|
*/
|
|
82
|
-
call<ActionType extends AllowedAction & NamespacedName>(
|
|
85
|
+
call<ActionType extends AllowedAction | (Action['type'] & NamespacedName<Namespace>)>(actionType: ActionType, ...params: ExtractActionParameters<Action, ActionType>): ExtractActionResponse<Action, ActionType>;
|
|
83
86
|
/**
|
|
84
87
|
* Publish an event.
|
|
85
88
|
*
|
|
@@ -90,9 +93,10 @@ export declare class RestrictedControllerMessenger<Namespace extends string, Act
|
|
|
90
93
|
* @param event - The event type. This is a unique identifier for this event.
|
|
91
94
|
* @param payload - The event payload. The type of the parameters for each event handler must
|
|
92
95
|
* match the type of this payload.
|
|
96
|
+
* @throws Will throw if an event that is not in the current namespace is being published.
|
|
93
97
|
* @template EventType - A type union of Event type strings that are namespaced by Namespace.
|
|
94
98
|
*/
|
|
95
|
-
publish<EventType extends NamespacedName<Namespace>>(event: EventType, ...payload: ExtractEventPayload<Event, EventType>): void;
|
|
99
|
+
publish<EventType extends Event['type'] & NamespacedName<Namespace>>(event: EventType, ...payload: ExtractEventPayload<Event, EventType>): void;
|
|
96
100
|
/**
|
|
97
101
|
* Subscribe to an event.
|
|
98
102
|
*
|
|
@@ -103,9 +107,10 @@ export declare class RestrictedControllerMessenger<Namespace extends string, Act
|
|
|
103
107
|
* @param eventType - The event type. This is a unique identifier for this event.
|
|
104
108
|
* @param handler - The event handler. The type of the parameters for this event handler must
|
|
105
109
|
* match the type of the payload for this event type.
|
|
110
|
+
* @throws Will throw if the given event is not an allowed event for this controller messenger.
|
|
106
111
|
* @template EventType - A type union of Event type strings.
|
|
107
112
|
*/
|
|
108
|
-
subscribe<EventType extends AllowedEvent & NamespacedName>(eventType: EventType, handler: ExtractEventHandler<Event, EventType>): void;
|
|
113
|
+
subscribe<EventType extends AllowedEvent | (Event['type'] & NamespacedName<Namespace>)>(eventType: EventType, handler: ExtractEventHandler<Event, EventType>): void;
|
|
109
114
|
/**
|
|
110
115
|
* Subscribe to an event, with a selector.
|
|
111
116
|
*
|
|
@@ -122,10 +127,11 @@ export declare class RestrictedControllerMessenger<Namespace extends string, Act
|
|
|
122
127
|
* @param selector - The selector function used to select relevant data from
|
|
123
128
|
* the event payload. The type of the parameters for this selector must match
|
|
124
129
|
* the type of the payload for this event type.
|
|
130
|
+
* @throws Will throw if the given event is not an allowed event for this controller messenger.
|
|
125
131
|
* @template EventType - A type union of Event type strings.
|
|
126
132
|
* @template SelectorReturnValue - The selector return value.
|
|
127
133
|
*/
|
|
128
|
-
subscribe<EventType extends AllowedEvent & NamespacedName, SelectorReturnValue>(eventType: EventType, handler: SelectorEventHandler<SelectorReturnValue>, selector: SelectorFunction<ExtractEventPayload<Event, EventType>, SelectorReturnValue>): void;
|
|
134
|
+
subscribe<EventType extends AllowedEvent | (Event['type'] & NamespacedName<Namespace>), SelectorReturnValue>(eventType: EventType, handler: SelectorEventHandler<SelectorReturnValue>, selector: SelectorFunction<ExtractEventPayload<Event, EventType>, SelectorReturnValue>): void;
|
|
129
135
|
/**
|
|
130
136
|
* Unsubscribe from an event.
|
|
131
137
|
*
|
|
@@ -135,10 +141,10 @@ export declare class RestrictedControllerMessenger<Namespace extends string, Act
|
|
|
135
141
|
*
|
|
136
142
|
* @param event - The event type. This is a unique identifier for this event.
|
|
137
143
|
* @param handler - The event handler to unregister.
|
|
138
|
-
* @throws Will throw
|
|
144
|
+
* @throws Will throw if the given event is not an allowed event for this controller messenger.
|
|
139
145
|
* @template EventType - A type union of allowed Event type strings.
|
|
140
146
|
*/
|
|
141
|
-
unsubscribe<EventType extends AllowedEvent & NamespacedName>(event: EventType, handler: ExtractEventHandler<Event, EventType>): void;
|
|
147
|
+
unsubscribe<EventType extends AllowedEvent | (Event['type'] & NamespacedName<Namespace>)>(event: EventType, handler: ExtractEventHandler<Event, EventType>): void;
|
|
142
148
|
/**
|
|
143
149
|
* Clear subscriptions for a specific event.
|
|
144
150
|
*
|
|
@@ -147,8 +153,9 @@ export declare class RestrictedControllerMessenger<Namespace extends string, Act
|
|
|
147
153
|
* The event type being cleared *must* be in the current namespace.
|
|
148
154
|
*
|
|
149
155
|
* @param event - The event type. This is a unique identifier for this event.
|
|
156
|
+
* @throws Will throw if a subscription for an event that is not in the current namespace is being cleared.
|
|
150
157
|
* @template EventType - A type union of Event type strings that are namespaced by Namespace.
|
|
151
158
|
*/
|
|
152
|
-
clearEventSubscriptions<EventType extends NamespacedName<Namespace>>(event: EventType): void;
|
|
159
|
+
clearEventSubscriptions<EventType extends Event['type'] & NamespacedName<Namespace>>(event: EventType): void;
|
|
153
160
|
}
|
|
154
161
|
//# sourceMappingURL=RestrictedControllerMessenger.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RestrictedControllerMessenger.d.ts","sourceRoot":"","sources":["../src/RestrictedControllerMessenger.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,gBAAgB,EAChB,aAAa,EACb,mBAAmB,EACnB,eAAe,EACf,uBAAuB,EACvB,qBAAqB,EACrB,mBAAmB,EACnB,mBAAmB,EACnB,cAAc,EACd,oBAAoB,EACpB,gBAAgB,EACjB,MAAM,uBAAuB,CAAC;AAE/B
|
|
1
|
+
{"version":3,"file":"RestrictedControllerMessenger.d.ts","sourceRoot":"","sources":["../src/RestrictedControllerMessenger.ts"],"names":[],"mappings":"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"}
|
|
@@ -10,7 +10,7 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
|
|
|
10
10
|
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
11
11
|
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
12
12
|
};
|
|
13
|
-
var _RestrictedControllerMessenger_controllerMessenger, _RestrictedControllerMessenger_controllerName, _RestrictedControllerMessenger_allowedActions, _RestrictedControllerMessenger_allowedEvents;
|
|
13
|
+
var _RestrictedControllerMessenger_instances, _RestrictedControllerMessenger_controllerMessenger, _RestrictedControllerMessenger_controllerName, _RestrictedControllerMessenger_allowedActions, _RestrictedControllerMessenger_allowedEvents, _RestrictedControllerMessenger_isAllowedEvent, _RestrictedControllerMessenger_isAllowedAction, _RestrictedControllerMessenger_isInCurrentNamespace;
|
|
14
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
15
|
exports.RestrictedControllerMessenger = void 0;
|
|
16
16
|
/**
|
|
@@ -25,7 +25,9 @@ exports.RestrictedControllerMessenger = void 0;
|
|
|
25
25
|
* @template Action - A type union of all Action types.
|
|
26
26
|
* @template Event - A type union of all Event types.
|
|
27
27
|
* @template AllowedAction - A type union of the 'type' string for any allowed actions.
|
|
28
|
+
* This must not include internal actions that are in the messenger's namespace.
|
|
28
29
|
* @template AllowedEvent - A type union of the 'type' string for any allowed events.
|
|
30
|
+
* This must not include internal events that are in the messenger's namespace.
|
|
29
31
|
*/
|
|
30
32
|
class RestrictedControllerMessenger {
|
|
31
33
|
/**
|
|
@@ -47,14 +49,15 @@ class RestrictedControllerMessenger {
|
|
|
47
49
|
* should be allowed to subscribe to.
|
|
48
50
|
*/
|
|
49
51
|
constructor({ controllerMessenger, name, allowedActions, allowedEvents, }) {
|
|
52
|
+
_RestrictedControllerMessenger_instances.add(this);
|
|
50
53
|
_RestrictedControllerMessenger_controllerMessenger.set(this, void 0);
|
|
51
54
|
_RestrictedControllerMessenger_controllerName.set(this, void 0);
|
|
52
55
|
_RestrictedControllerMessenger_allowedActions.set(this, void 0);
|
|
53
56
|
_RestrictedControllerMessenger_allowedEvents.set(this, void 0);
|
|
54
57
|
__classPrivateFieldSet(this, _RestrictedControllerMessenger_controllerMessenger, controllerMessenger, "f");
|
|
55
58
|
__classPrivateFieldSet(this, _RestrictedControllerMessenger_controllerName, name, "f");
|
|
56
|
-
__classPrivateFieldSet(this, _RestrictedControllerMessenger_allowedActions, allowedActions
|
|
57
|
-
__classPrivateFieldSet(this, _RestrictedControllerMessenger_allowedEvents, allowedEvents
|
|
59
|
+
__classPrivateFieldSet(this, _RestrictedControllerMessenger_allowedActions, allowedActions !== null && allowedActions !== void 0 ? allowedActions : null, "f");
|
|
60
|
+
__classPrivateFieldSet(this, _RestrictedControllerMessenger_allowedEvents, allowedEvents !== null && allowedEvents !== void 0 ? allowedEvents : null, "f");
|
|
58
61
|
}
|
|
59
62
|
/**
|
|
60
63
|
* Register an action handler.
|
|
@@ -71,7 +74,7 @@ class RestrictedControllerMessenger {
|
|
|
71
74
|
*/
|
|
72
75
|
registerActionHandler(action, handler) {
|
|
73
76
|
/* istanbul ignore if */ // Branch unreachable with valid types
|
|
74
|
-
if (!
|
|
77
|
+
if (!__classPrivateFieldGet(this, _RestrictedControllerMessenger_instances, "m", _RestrictedControllerMessenger_isInCurrentNamespace).call(this, action)) {
|
|
75
78
|
throw new Error(`Only allowed registering action handlers prefixed by '${__classPrivateFieldGet(this, _RestrictedControllerMessenger_controllerName, "f")}:'`);
|
|
76
79
|
}
|
|
77
80
|
__classPrivateFieldGet(this, _RestrictedControllerMessenger_controllerMessenger, "f").registerActionHandler(action, handler);
|
|
@@ -83,12 +86,13 @@ class RestrictedControllerMessenger {
|
|
|
83
86
|
*
|
|
84
87
|
* The action type being unregistered *must* be in the current namespace.
|
|
85
88
|
*
|
|
86
|
-
* @param action - The action type. This is a
|
|
89
|
+
* @param action - The action type. This is a unique identifier for this action.
|
|
90
|
+
* @throws Will throw if an action handler that is not in the current namespace is being unregistered.
|
|
87
91
|
* @template ActionType - A type union of Action type strings that are namespaced by Namespace.
|
|
88
92
|
*/
|
|
89
93
|
unregisterActionHandler(action) {
|
|
90
94
|
/* istanbul ignore if */ // Branch unreachable with valid types
|
|
91
|
-
if (!
|
|
95
|
+
if (!__classPrivateFieldGet(this, _RestrictedControllerMessenger_instances, "m", _RestrictedControllerMessenger_isInCurrentNamespace).call(this, action)) {
|
|
92
96
|
throw new Error(`Only allowed unregistering action handlers prefixed by '${__classPrivateFieldGet(this, _RestrictedControllerMessenger_controllerName, "f")}:'`);
|
|
93
97
|
}
|
|
94
98
|
__classPrivateFieldGet(this, _RestrictedControllerMessenger_controllerMessenger, "f").unregisterActionHandler(action);
|
|
@@ -101,22 +105,19 @@ class RestrictedControllerMessenger {
|
|
|
101
105
|
*
|
|
102
106
|
* The action type being called must be on the action allowlist.
|
|
103
107
|
*
|
|
104
|
-
* @param
|
|
108
|
+
* @param actionType - The action type. This is a unqiue identifier for this action.
|
|
105
109
|
* @param params - The action parameters. These must match the type of the parameters of the
|
|
106
110
|
* registered action handler.
|
|
107
111
|
* @throws Will throw when no handler has been registered for the given type.
|
|
108
112
|
* @template ActionType - A type union of allowed Action type strings.
|
|
109
113
|
* @returns The action return value.
|
|
110
114
|
*/
|
|
111
|
-
call(
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
throw new Error('No actions allowed');
|
|
115
|
+
call(actionType, ...params) {
|
|
116
|
+
if (!__classPrivateFieldGet(this, _RestrictedControllerMessenger_instances, "m", _RestrictedControllerMessenger_isAllowedAction).call(this, actionType)) {
|
|
117
|
+
throw new Error(`Action missing from allow list: ${actionType}`);
|
|
115
118
|
}
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
}
|
|
119
|
-
return __classPrivateFieldGet(this, _RestrictedControllerMessenger_controllerMessenger, "f").call(action, ...params);
|
|
119
|
+
const response = __classPrivateFieldGet(this, _RestrictedControllerMessenger_controllerMessenger, "f").call(actionType, ...params);
|
|
120
|
+
return response;
|
|
120
121
|
}
|
|
121
122
|
/**
|
|
122
123
|
* Publish an event.
|
|
@@ -128,21 +129,18 @@ class RestrictedControllerMessenger {
|
|
|
128
129
|
* @param event - The event type. This is a unique identifier for this event.
|
|
129
130
|
* @param payload - The event payload. The type of the parameters for each event handler must
|
|
130
131
|
* match the type of this payload.
|
|
132
|
+
* @throws Will throw if an event that is not in the current namespace is being published.
|
|
131
133
|
* @template EventType - A type union of Event type strings that are namespaced by Namespace.
|
|
132
134
|
*/
|
|
133
135
|
publish(event, ...payload) {
|
|
134
136
|
/* istanbul ignore if */ // Branch unreachable with valid types
|
|
135
|
-
if (!
|
|
137
|
+
if (!__classPrivateFieldGet(this, _RestrictedControllerMessenger_instances, "m", _RestrictedControllerMessenger_isInCurrentNamespace).call(this, event)) {
|
|
136
138
|
throw new Error(`Only allowed publishing events prefixed by '${__classPrivateFieldGet(this, _RestrictedControllerMessenger_controllerName, "f")}:'`);
|
|
137
139
|
}
|
|
138
140
|
__classPrivateFieldGet(this, _RestrictedControllerMessenger_controllerMessenger, "f").publish(event, ...payload);
|
|
139
141
|
}
|
|
140
142
|
subscribe(event, handler, selector) {
|
|
141
|
-
|
|
142
|
-
if (__classPrivateFieldGet(this, _RestrictedControllerMessenger_allowedEvents, "f") === null) {
|
|
143
|
-
throw new Error('No events allowed');
|
|
144
|
-
}
|
|
145
|
-
else if (!__classPrivateFieldGet(this, _RestrictedControllerMessenger_allowedEvents, "f").includes(event)) {
|
|
143
|
+
if (!__classPrivateFieldGet(this, _RestrictedControllerMessenger_instances, "m", _RestrictedControllerMessenger_isAllowedEvent).call(this, event)) {
|
|
146
144
|
throw new Error(`Event missing from allow list: ${event}`);
|
|
147
145
|
}
|
|
148
146
|
if (selector) {
|
|
@@ -159,15 +157,11 @@ class RestrictedControllerMessenger {
|
|
|
159
157
|
*
|
|
160
158
|
* @param event - The event type. This is a unique identifier for this event.
|
|
161
159
|
* @param handler - The event handler to unregister.
|
|
162
|
-
* @throws Will throw
|
|
160
|
+
* @throws Will throw if the given event is not an allowed event for this controller messenger.
|
|
163
161
|
* @template EventType - A type union of allowed Event type strings.
|
|
164
162
|
*/
|
|
165
163
|
unsubscribe(event, handler) {
|
|
166
|
-
|
|
167
|
-
if (__classPrivateFieldGet(this, _RestrictedControllerMessenger_allowedEvents, "f") === null) {
|
|
168
|
-
throw new Error('No events allowed');
|
|
169
|
-
}
|
|
170
|
-
else if (!__classPrivateFieldGet(this, _RestrictedControllerMessenger_allowedEvents, "f").includes(event)) {
|
|
164
|
+
if (!__classPrivateFieldGet(this, _RestrictedControllerMessenger_instances, "m", _RestrictedControllerMessenger_isAllowedEvent).call(this, event)) {
|
|
171
165
|
throw new Error(`Event missing from allow list: ${event}`);
|
|
172
166
|
}
|
|
173
167
|
__classPrivateFieldGet(this, _RestrictedControllerMessenger_controllerMessenger, "f").unsubscribe(event, handler);
|
|
@@ -180,16 +174,28 @@ class RestrictedControllerMessenger {
|
|
|
180
174
|
* The event type being cleared *must* be in the current namespace.
|
|
181
175
|
*
|
|
182
176
|
* @param event - The event type. This is a unique identifier for this event.
|
|
177
|
+
* @throws Will throw if a subscription for an event that is not in the current namespace is being cleared.
|
|
183
178
|
* @template EventType - A type union of Event type strings that are namespaced by Namespace.
|
|
184
179
|
*/
|
|
185
180
|
clearEventSubscriptions(event) {
|
|
186
|
-
|
|
187
|
-
if (!event.startsWith(`${__classPrivateFieldGet(this, _RestrictedControllerMessenger_controllerName, "f")}:`)) {
|
|
181
|
+
if (!__classPrivateFieldGet(this, _RestrictedControllerMessenger_instances, "m", _RestrictedControllerMessenger_isInCurrentNamespace).call(this, event)) {
|
|
188
182
|
throw new Error(`Only allowed clearing events prefixed by '${__classPrivateFieldGet(this, _RestrictedControllerMessenger_controllerName, "f")}:'`);
|
|
189
183
|
}
|
|
190
184
|
__classPrivateFieldGet(this, _RestrictedControllerMessenger_controllerMessenger, "f").clearEventSubscriptions(event);
|
|
191
185
|
}
|
|
192
186
|
}
|
|
193
187
|
exports.RestrictedControllerMessenger = RestrictedControllerMessenger;
|
|
194
|
-
_RestrictedControllerMessenger_controllerMessenger = new WeakMap(), _RestrictedControllerMessenger_controllerName = new WeakMap(), _RestrictedControllerMessenger_allowedActions = new WeakMap(), _RestrictedControllerMessenger_allowedEvents = new WeakMap()
|
|
188
|
+
_RestrictedControllerMessenger_controllerMessenger = new WeakMap(), _RestrictedControllerMessenger_controllerName = new WeakMap(), _RestrictedControllerMessenger_allowedActions = new WeakMap(), _RestrictedControllerMessenger_allowedEvents = new WeakMap(), _RestrictedControllerMessenger_instances = new WeakSet(), _RestrictedControllerMessenger_isAllowedEvent = function _RestrictedControllerMessenger_isAllowedEvent(eventType) {
|
|
189
|
+
// Safely upcast to allow runtime check
|
|
190
|
+
const allowedEvents = __classPrivateFieldGet(this, _RestrictedControllerMessenger_allowedEvents, "f");
|
|
191
|
+
return (__classPrivateFieldGet(this, _RestrictedControllerMessenger_instances, "m", _RestrictedControllerMessenger_isInCurrentNamespace).call(this, eventType) ||
|
|
192
|
+
(allowedEvents !== null && allowedEvents.includes(eventType)));
|
|
193
|
+
}, _RestrictedControllerMessenger_isAllowedAction = function _RestrictedControllerMessenger_isAllowedAction(actionType) {
|
|
194
|
+
// Safely upcast to allow runtime check
|
|
195
|
+
const allowedActions = __classPrivateFieldGet(this, _RestrictedControllerMessenger_allowedActions, "f");
|
|
196
|
+
return (__classPrivateFieldGet(this, _RestrictedControllerMessenger_instances, "m", _RestrictedControllerMessenger_isInCurrentNamespace).call(this, actionType) ||
|
|
197
|
+
(allowedActions !== null && allowedActions.includes(actionType)));
|
|
198
|
+
}, _RestrictedControllerMessenger_isInCurrentNamespace = function _RestrictedControllerMessenger_isInCurrentNamespace(name) {
|
|
199
|
+
return name.startsWith(`${__classPrivateFieldGet(this, _RestrictedControllerMessenger_controllerName, "f")}:`);
|
|
200
|
+
};
|
|
195
201
|
//# sourceMappingURL=RestrictedControllerMessenger.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RestrictedControllerMessenger.js","sourceRoot":"","sources":["../src/RestrictedControllerMessenger.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n ActionConstraint,\n ActionHandler,\n ControllerMessenger,\n EventConstraint,\n ExtractActionParameters,\n ExtractActionResponse,\n ExtractEventHandler,\n ExtractEventPayload,\n NamespacedName,\n SelectorEventHandler,\n SelectorFunction,\n} from './ControllerMessenger';\n\n/**\n * A restricted controller messenger.\n *\n * This acts as a wrapper around the controller messenger instance that restricts access to actions\n * and events.\n *\n * @template Namespace - The namespace for this messenger. Typically this is the name of the controller or\n * module that this messenger has been created for. The authority to publish events and register\n * actions under this namespace is granted to this restricted messenger instance.\n * @template Action - A type union of all Action types.\n * @template Event - A type union of all Event types.\n * @template AllowedAction - A type union of the 'type' string for any allowed actions.\n * @template AllowedEvent - A type union of the 'type' string for any allowed events.\n */\nexport class RestrictedControllerMessenger<\n Namespace extends string,\n Action extends ActionConstraint,\n Event extends EventConstraint,\n AllowedAction extends string,\n AllowedEvent extends string,\n> {\n readonly #controllerMessenger: ControllerMessenger<\n ActionConstraint,\n EventConstraint\n >;\n\n readonly #controllerName: Namespace;\n\n readonly #allowedActions: AllowedAction[] | null;\n\n readonly #allowedEvents: AllowedEvent[] | null;\n\n /**\n * Constructs a restricted controller messenger\n *\n * The provided allowlists grant the ability to call the listed actions and subscribe to the\n * listed events. The \"name\" provided grants ownership of any actions and events under that\n * namespace. Ownership allows registering actions and publishing events, as well as\n * unregistering actions and clearing event subscriptions.\n *\n * @param options - The controller options.\n * @param options.controllerMessenger - The controller messenger instance that is being wrapped.\n * @param options.name - The name of the thing this messenger will be handed to (e.g. the\n * controller name). This grants \"ownership\" of actions and events under this namespace to the\n * restricted controller messenger returned.\n * @param options.allowedActions - The list of actions that this restricted controller messenger\n * should be alowed to call.\n * @param options.allowedEvents - The list of events that this restricted controller messenger\n * should be allowed to subscribe to.\n */\n constructor({\n controllerMessenger,\n name,\n allowedActions,\n allowedEvents,\n }: {\n controllerMessenger: ControllerMessenger<ActionConstraint, EventConstraint>;\n name: Namespace;\n allowedActions?: AllowedAction[];\n allowedEvents?: AllowedEvent[];\n }) {\n this.#controllerMessenger = controllerMessenger;\n this.#controllerName = name;\n this.#allowedActions = allowedActions || null;\n this.#allowedEvents = allowedEvents || null;\n }\n\n /**\n * Register an action handler.\n *\n * This will make the registered function available to call via the `call` method.\n *\n * The action type this handler is registered under *must* be in the current namespace.\n *\n * @param action - The action type. This is a unqiue identifier for this action.\n * @param handler - The action handler. This function gets called when the `call` method is\n * invoked with the given action type.\n * @throws Will throw if an action handler that is not in the current namespace is being registered.\n * @template ActionType - A type union of Action type strings that are namespaced by Namespace.\n */\n registerActionHandler<ActionType extends Action['type']>(\n action: ActionType,\n handler: ActionHandler<Action, ActionType>,\n ) {\n /* istanbul ignore if */ // Branch unreachable with valid types\n if (!action.startsWith(`${this.#controllerName}:`)) {\n throw new Error(\n `Only allowed registering action handlers prefixed by '${\n this.#controllerName\n }:'`,\n );\n }\n this.#controllerMessenger.registerActionHandler(action, handler);\n }\n\n /**\n * Unregister an action handler.\n *\n * This will prevent this action from being called.\n *\n * The action type being unregistered *must* be in the current namespace.\n *\n * @param action - The action type. This is a unqiue identifier for this action.\n * @template ActionType - A type union of Action type strings that are namespaced by Namespace.\n */\n unregisterActionHandler<ActionType extends NamespacedName<Namespace>>(\n action: ActionType,\n ) {\n /* istanbul ignore if */ // Branch unreachable with valid types\n if (!action.startsWith(`${this.#controllerName}:`)) {\n throw new Error(\n `Only allowed unregistering action handlers prefixed by '${\n this.#controllerName\n }:'`,\n );\n }\n this.#controllerMessenger.unregisterActionHandler(action);\n }\n\n /**\n * Call an action.\n *\n * This function will call the action handler corresponding to the given action type, passing\n * along any parameters given.\n *\n * The action type being called must be on the action allowlist.\n *\n * @param action - The action type. This is a unqiue identifier for this action.\n * @param params - The action parameters. These must match the type of the parameters of the\n * registered action handler.\n * @throws Will throw when no handler has been registered for the given type.\n * @template ActionType - A type union of allowed Action type strings.\n * @returns The action return value.\n */\n call<ActionType extends AllowedAction & NamespacedName>(\n action: ActionType,\n ...params: ExtractActionParameters<Action, ActionType>\n ): ExtractActionResponse<Action, ActionType> {\n /* istanbul ignore next */ // Branches unreachable with valid types\n if (this.#allowedActions === null) {\n throw new Error('No actions allowed');\n } else if (!this.#allowedActions.includes(action)) {\n throw new Error(`Action missing from allow list: ${action}`);\n }\n return this.#controllerMessenger.call(action, ...params);\n }\n\n /**\n * Publish an event.\n *\n * Publishes the given payload to all subscribers of the given event type.\n *\n * The event type being published *must* be in the current namespace.\n *\n * @param event - The event type. This is a unique identifier for this event.\n * @param payload - The event payload. The type of the parameters for each event handler must\n * match the type of this payload.\n * @template EventType - A type union of Event type strings that are namespaced by Namespace.\n */\n publish<EventType extends NamespacedName<Namespace>>(\n event: EventType,\n ...payload: ExtractEventPayload<Event, EventType>\n ) {\n /* istanbul ignore if */ // Branch unreachable with valid types\n if (!event.startsWith(`${this.#controllerName}:`)) {\n throw new Error(\n `Only allowed publishing events prefixed by '${this.#controllerName}:'`,\n );\n }\n this.#controllerMessenger.publish(event, ...payload);\n }\n\n /**\n * Subscribe to an event.\n *\n * Registers the given function as an event handler for the given event type.\n *\n * The event type being subscribed to must be on the event allowlist.\n *\n * @param eventType - The event type. This is a unique identifier for this event.\n * @param handler - The event handler. The type of the parameters for this event handler must\n * match the type of the payload for this event type.\n * @template EventType - A type union of Event type strings.\n */\n subscribe<EventType extends AllowedEvent & NamespacedName>(\n eventType: EventType,\n handler: ExtractEventHandler<Event, EventType>,\n ): void;\n\n /**\n * Subscribe to an event, with a selector.\n *\n * Registers the given handler function as an event handler for the given\n * event type. When an event is published, its payload is first passed to the\n * selector. The event handler is only called if the selector's return value\n * differs from its last known return value.\n *\n * The event type being subscribed to must be on the event allowlist.\n *\n * @param eventType - The event type. This is a unique identifier for this event.\n * @param handler - The event handler. The type of the parameters for this event\n * handler must match the return type of the selector.\n * @param selector - The selector function used to select relevant data from\n * the event payload. The type of the parameters for this selector must match\n * the type of the payload for this event type.\n * @template EventType - A type union of Event type strings.\n * @template SelectorReturnValue - The selector return value.\n */\n subscribe<\n EventType extends AllowedEvent & NamespacedName,\n SelectorReturnValue,\n >(\n eventType: EventType,\n handler: SelectorEventHandler<SelectorReturnValue>,\n selector: SelectorFunction<\n ExtractEventPayload<Event, EventType>,\n SelectorReturnValue\n >,\n ): void;\n\n subscribe<\n EventType extends AllowedEvent & NamespacedName,\n SelectorReturnValue,\n >(\n event: EventType,\n handler: ExtractEventHandler<Event, EventType>,\n selector?: SelectorFunction<\n ExtractEventPayload<Event, EventType>,\n SelectorReturnValue\n >,\n ) {\n /* istanbul ignore next */ // Branches unreachable with valid types\n if (this.#allowedEvents === null) {\n throw new Error('No events allowed');\n } else if (!this.#allowedEvents.includes(event)) {\n throw new Error(`Event missing from allow list: ${event}`);\n }\n\n if (selector) {\n return this.#controllerMessenger.subscribe(event, handler, selector);\n }\n return this.#controllerMessenger.subscribe(event, handler);\n }\n\n /**\n * Unsubscribe from an event.\n *\n * Unregisters the given function as an event handler for the given event.\n *\n * The event type being unsubscribed to must be on the event allowlist.\n *\n * @param event - The event type. This is a unique identifier for this event.\n * @param handler - The event handler to unregister.\n * @throws Will throw when the given event handler is not registered for this event.\n * @template EventType - A type union of allowed Event type strings.\n */\n unsubscribe<EventType extends AllowedEvent & NamespacedName>(\n event: EventType,\n handler: ExtractEventHandler<Event, EventType>,\n ) {\n /* istanbul ignore next */ // Branches unreachable with valid types\n if (this.#allowedEvents === null) {\n throw new Error('No events allowed');\n } else if (!this.#allowedEvents.includes(event)) {\n throw new Error(`Event missing from allow list: ${event}`);\n }\n this.#controllerMessenger.unsubscribe(event, handler);\n }\n\n /**\n * Clear subscriptions for a specific event.\n *\n * This will remove all subscribed handlers for this event.\n *\n * The event type being cleared *must* be in the current namespace.\n *\n * @param event - The event type. This is a unique identifier for this event.\n * @template EventType - A type union of Event type strings that are namespaced by Namespace.\n */\n clearEventSubscriptions<EventType extends NamespacedName<Namespace>>(\n event: EventType,\n ) {\n /* istanbul ignore if */ // Branch unreachable with valid types\n if (!event.startsWith(`${this.#controllerName}:`)) {\n throw new Error(\n `Only allowed clearing events prefixed by '${this.#controllerName}:'`,\n );\n }\n this.#controllerMessenger.clearEventSubscriptions(event);\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"RestrictedControllerMessenger.js","sourceRoot":"","sources":["../src/RestrictedControllerMessenger.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n ActionConstraint,\n ActionHandler,\n ControllerMessenger,\n EventConstraint,\n ExtractActionParameters,\n ExtractActionResponse,\n ExtractEventHandler,\n ExtractEventPayload,\n NamespacedName,\n NotNamespacedBy,\n SelectorEventHandler,\n SelectorFunction,\n} from './ControllerMessenger';\n\n/**\n * A restricted controller messenger.\n *\n * This acts as a wrapper around the controller messenger instance that restricts access to actions\n * and events.\n *\n * @template Namespace - The namespace for this messenger. Typically this is the name of the controller or\n * module that this messenger has been created for. The authority to publish events and register\n * actions under this namespace is granted to this restricted messenger instance.\n * @template Action - A type union of all Action types.\n * @template Event - A type union of all Event types.\n * @template AllowedAction - A type union of the 'type' string for any allowed actions.\n * This must not include internal actions that are in the messenger's namespace.\n * @template AllowedEvent - A type union of the 'type' string for any allowed events.\n * This must not include internal events that are in the messenger's namespace.\n */\nexport class RestrictedControllerMessenger<\n Namespace extends string,\n Action extends ActionConstraint,\n Event extends EventConstraint,\n AllowedAction extends string,\n AllowedEvent extends string,\n> {\n readonly #controllerMessenger: ControllerMessenger<\n ActionConstraint,\n EventConstraint\n >;\n\n readonly #controllerName: Namespace;\n\n readonly #allowedActions: NotNamespacedBy<Namespace, AllowedAction>[] | null;\n\n readonly #allowedEvents: NotNamespacedBy<Namespace, AllowedEvent>[] | null;\n\n /**\n * Constructs a restricted controller messenger\n *\n * The provided allowlists grant the ability to call the listed actions and subscribe to the\n * listed events. The \"name\" provided grants ownership of any actions and events under that\n * namespace. Ownership allows registering actions and publishing events, as well as\n * unregistering actions and clearing event subscriptions.\n *\n * @param options - The controller options.\n * @param options.controllerMessenger - The controller messenger instance that is being wrapped.\n * @param options.name - The name of the thing this messenger will be handed to (e.g. the\n * controller name). This grants \"ownership\" of actions and events under this namespace to the\n * restricted controller messenger returned.\n * @param options.allowedActions - The list of actions that this restricted controller messenger\n * should be alowed to call.\n * @param options.allowedEvents - The list of events that this restricted controller messenger\n * should be allowed to subscribe to.\n */\n constructor({\n controllerMessenger,\n name,\n allowedActions,\n allowedEvents,\n }: {\n controllerMessenger: ControllerMessenger<ActionConstraint, EventConstraint>;\n name: Namespace;\n allowedActions?: NotNamespacedBy<Namespace, AllowedAction>[];\n allowedEvents?: NotNamespacedBy<Namespace, AllowedEvent>[];\n }) {\n this.#controllerMessenger = controllerMessenger;\n this.#controllerName = name;\n this.#allowedActions = allowedActions ?? null;\n this.#allowedEvents = allowedEvents ?? null;\n }\n\n /**\n * Register an action handler.\n *\n * This will make the registered function available to call via the `call` method.\n *\n * The action type this handler is registered under *must* be in the current namespace.\n *\n * @param action - The action type. This is a unqiue identifier for this action.\n * @param handler - The action handler. This function gets called when the `call` method is\n * invoked with the given action type.\n * @throws Will throw if an action handler that is not in the current namespace is being registered.\n * @template ActionType - A type union of Action type strings that are namespaced by Namespace.\n */\n registerActionHandler<\n ActionType extends Action['type'] & NamespacedName<Namespace>,\n >(action: ActionType, handler: ActionHandler<Action, ActionType>) {\n /* istanbul ignore if */ // Branch unreachable with valid types\n if (!this.#isInCurrentNamespace(action)) {\n throw new Error(\n `Only allowed registering action handlers prefixed by '${\n this.#controllerName\n }:'`,\n );\n }\n this.#controllerMessenger.registerActionHandler(action, handler);\n }\n\n /**\n * Unregister an action handler.\n *\n * This will prevent this action from being called.\n *\n * The action type being unregistered *must* be in the current namespace.\n *\n * @param action - The action type. This is a unique identifier for this action.\n * @throws Will throw if an action handler that is not in the current namespace is being unregistered.\n * @template ActionType - A type union of Action type strings that are namespaced by Namespace.\n */\n unregisterActionHandler<\n ActionType extends Action['type'] & NamespacedName<Namespace>,\n >(action: ActionType) {\n /* istanbul ignore if */ // Branch unreachable with valid types\n if (!this.#isInCurrentNamespace(action)) {\n throw new Error(\n `Only allowed unregistering action handlers prefixed by '${\n this.#controllerName\n }:'`,\n );\n }\n this.#controllerMessenger.unregisterActionHandler(action);\n }\n\n /**\n * Call an action.\n *\n * This function will call the action handler corresponding to the given action type, passing\n * along any parameters given.\n *\n * The action type being called must be on the action allowlist.\n *\n * @param actionType - The action type. This is a unqiue identifier for this action.\n * @param params - The action parameters. These must match the type of the parameters of the\n * registered action handler.\n * @throws Will throw when no handler has been registered for the given type.\n * @template ActionType - A type union of allowed Action type strings.\n * @returns The action return value.\n */\n call<\n ActionType extends\n | AllowedAction\n | (Action['type'] & NamespacedName<Namespace>),\n >(\n actionType: ActionType,\n ...params: ExtractActionParameters<Action, ActionType>\n ): ExtractActionResponse<Action, ActionType> {\n if (!this.#isAllowedAction(actionType)) {\n throw new Error(`Action missing from allow list: ${actionType}`);\n }\n const response = this.#controllerMessenger.call<ActionType>(\n actionType,\n ...params,\n );\n\n return response;\n }\n\n /**\n * Publish an event.\n *\n * Publishes the given payload to all subscribers of the given event type.\n *\n * The event type being published *must* be in the current namespace.\n *\n * @param event - The event type. This is a unique identifier for this event.\n * @param payload - The event payload. The type of the parameters for each event handler must\n * match the type of this payload.\n * @throws Will throw if an event that is not in the current namespace is being published.\n * @template EventType - A type union of Event type strings that are namespaced by Namespace.\n */\n publish<EventType extends Event['type'] & NamespacedName<Namespace>>(\n event: EventType,\n ...payload: ExtractEventPayload<Event, EventType>\n ) {\n /* istanbul ignore if */ // Branch unreachable with valid types\n if (!this.#isInCurrentNamespace(event)) {\n throw new Error(\n `Only allowed publishing events prefixed by '${this.#controllerName}:'`,\n );\n }\n this.#controllerMessenger.publish(event, ...payload);\n }\n\n /**\n * Subscribe to an event.\n *\n * Registers the given function as an event handler for the given event type.\n *\n * The event type being subscribed to must be on the event allowlist.\n *\n * @param eventType - The event type. This is a unique identifier for this event.\n * @param handler - The event handler. The type of the parameters for this event handler must\n * match the type of the payload for this event type.\n * @throws Will throw if the given event is not an allowed event for this controller messenger.\n * @template EventType - A type union of Event type strings.\n */\n subscribe<\n EventType extends\n | AllowedEvent\n | (Event['type'] & NamespacedName<Namespace>),\n >(eventType: EventType, handler: ExtractEventHandler<Event, EventType>): void;\n\n /**\n * Subscribe to an event, with a selector.\n *\n * Registers the given handler function as an event handler for the given\n * event type. When an event is published, its payload is first passed to the\n * selector. The event handler is only called if the selector's return value\n * differs from its last known return value.\n *\n * The event type being subscribed to must be on the event allowlist.\n *\n * @param eventType - The event type. This is a unique identifier for this event.\n * @param handler - The event handler. The type of the parameters for this event\n * handler must match the return type of the selector.\n * @param selector - The selector function used to select relevant data from\n * the event payload. The type of the parameters for this selector must match\n * the type of the payload for this event type.\n * @throws Will throw if the given event is not an allowed event for this controller messenger.\n * @template EventType - A type union of Event type strings.\n * @template SelectorReturnValue - The selector return value.\n */\n subscribe<\n EventType extends\n | AllowedEvent\n | (Event['type'] & NamespacedName<Namespace>),\n SelectorReturnValue,\n >(\n eventType: EventType,\n handler: SelectorEventHandler<SelectorReturnValue>,\n selector: SelectorFunction<\n ExtractEventPayload<Event, EventType>,\n SelectorReturnValue\n >,\n ): void;\n\n subscribe<\n EventType extends\n | AllowedEvent\n | (Event['type'] & NamespacedName<Namespace>),\n SelectorReturnValue,\n >(\n event: EventType,\n handler: ExtractEventHandler<Event, EventType>,\n selector?: SelectorFunction<\n ExtractEventPayload<Event, EventType>,\n SelectorReturnValue\n >,\n ) {\n if (!this.#isAllowedEvent(event)) {\n throw new Error(`Event missing from allow list: ${event}`);\n }\n\n if (selector) {\n return this.#controllerMessenger.subscribe(event, handler, selector);\n }\n return this.#controllerMessenger.subscribe(event, handler);\n }\n\n /**\n * Unsubscribe from an event.\n *\n * Unregisters the given function as an event handler for the given event.\n *\n * The event type being unsubscribed to must be on the event allowlist.\n *\n * @param event - The event type. This is a unique identifier for this event.\n * @param handler - The event handler to unregister.\n * @throws Will throw if the given event is not an allowed event for this controller messenger.\n * @template EventType - A type union of allowed Event type strings.\n */\n unsubscribe<\n EventType extends\n | AllowedEvent\n | (Event['type'] & NamespacedName<Namespace>),\n >(event: EventType, handler: ExtractEventHandler<Event, EventType>) {\n if (!this.#isAllowedEvent(event)) {\n throw new Error(`Event missing from allow list: ${event}`);\n }\n this.#controllerMessenger.unsubscribe(event, handler);\n }\n\n /**\n * Clear subscriptions for a specific event.\n *\n * This will remove all subscribed handlers for this event.\n *\n * The event type being cleared *must* be in the current namespace.\n *\n * @param event - The event type. This is a unique identifier for this event.\n * @throws Will throw if a subscription for an event that is not in the current namespace is being cleared.\n * @template EventType - A type union of Event type strings that are namespaced by Namespace.\n */\n clearEventSubscriptions<\n EventType extends Event['type'] & NamespacedName<Namespace>,\n >(event: EventType) {\n if (!this.#isInCurrentNamespace(event)) {\n throw new Error(\n `Only allowed clearing events prefixed by '${this.#controllerName}:'`,\n );\n }\n this.#controllerMessenger.clearEventSubscriptions(event);\n }\n\n /**\n * Determine whether the given event type is allowed. Event types are\n * allowed if they are in the current namespace or on the list of\n * allowed events.\n *\n * @param eventType - The event type to check.\n * @returns Whether the event type is allowed.\n */\n #isAllowedEvent(\n eventType: Event['type'],\n ): eventType is\n | NamespacedName<Namespace>\n | NotNamespacedBy<Namespace, AllowedEvent> {\n // Safely upcast to allow runtime check\n const allowedEvents: string[] | null = this.#allowedEvents;\n return (\n this.#isInCurrentNamespace(eventType) ||\n (allowedEvents !== null && allowedEvents.includes(eventType))\n );\n }\n\n /**\n * Determine whether the given action type is allowed. Action types\n * are allowed if they are in the current namespace or on the list of\n * allowed actions.\n *\n * @param actionType - The action type to check.\n * @returns Whether the action type is allowed.\n */\n #isAllowedAction(\n actionType: Action['type'],\n ): actionType is\n | NamespacedName<Namespace>\n | NotNamespacedBy<Namespace, AllowedAction> {\n // Safely upcast to allow runtime check\n const allowedActions: string[] | null = this.#allowedActions;\n return (\n this.#isInCurrentNamespace(actionType) ||\n (allowedActions !== null && allowedActions.includes(actionType))\n );\n }\n\n /**\n * Determine whether the given name is within the current namespace.\n *\n * @param name - The name to check\n * @returns Whether the name is within the current namespace\n */\n #isInCurrentNamespace(name: string): name is NamespacedName<Namespace> {\n return name.startsWith(`${this.#controllerName}:`);\n }\n}\n"]}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
export type { BaseConfig, BaseState, Listener } from './
|
|
2
|
-
export {
|
|
3
|
-
export type { Listener as ListenerV2, StateDeriver, StateMetadata, StatePropertyMetadata, } from './BaseControllerV2';
|
|
4
|
-
export { BaseController
|
|
1
|
+
export type { BaseConfig, BaseState, Listener } from './BaseControllerV1';
|
|
2
|
+
export { BaseControllerV1 } from './BaseControllerV1';
|
|
3
|
+
export type { Listener as ListenerV2, StateDeriver, StateMetadata, StatePropertyMetadata, ControllerGetStateAction, ControllerStateChangeEvent, } from './BaseControllerV2';
|
|
4
|
+
export { BaseController, getAnonymizedState, getPersistentState, } from './BaseControllerV2';
|
|
5
5
|
export * from './ControllerMessenger';
|
|
6
6
|
export * from './RestrictedControllerMessenger';
|
|
7
7
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,UAAU,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,UAAU,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC1E,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,YAAY,EACV,QAAQ,IAAI,UAAU,EACtB,YAAY,EACZ,aAAa,EACb,qBAAqB,EACrB,wBAAwB,EACxB,0BAA0B,GAC3B,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,cAAc,EACd,kBAAkB,EAClB,kBAAkB,GACnB,MAAM,oBAAoB,CAAC;AAC5B,cAAc,uBAAuB,CAAC;AACtC,cAAc,iCAAiC,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -14,11 +14,11 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
14
14
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
exports.getPersistentState = exports.getAnonymizedState = exports.
|
|
18
|
-
var
|
|
19
|
-
Object.defineProperty(exports, "
|
|
17
|
+
exports.getPersistentState = exports.getAnonymizedState = exports.BaseController = exports.BaseControllerV1 = void 0;
|
|
18
|
+
var BaseControllerV1_1 = require("./BaseControllerV1");
|
|
19
|
+
Object.defineProperty(exports, "BaseControllerV1", { enumerable: true, get: function () { return BaseControllerV1_1.BaseControllerV1; } });
|
|
20
20
|
var BaseControllerV2_1 = require("./BaseControllerV2");
|
|
21
|
-
Object.defineProperty(exports, "
|
|
21
|
+
Object.defineProperty(exports, "BaseController", { enumerable: true, get: function () { return BaseControllerV2_1.BaseController; } });
|
|
22
22
|
Object.defineProperty(exports, "getAnonymizedState", { enumerable: true, get: function () { return BaseControllerV2_1.getAnonymizedState; } });
|
|
23
23
|
Object.defineProperty(exports, "getPersistentState", { enumerable: true, get: function () { return BaseControllerV2_1.getPersistentState; } });
|
|
24
24
|
__exportStar(require("./ControllerMessenger"), exports);
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AACA,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AACA,uDAAsD;AAA7C,oHAAA,gBAAgB,OAAA;AASzB,uDAI4B;AAH1B,kHAAA,cAAc,OAAA;AACd,sHAAA,kBAAkB,OAAA;AAClB,sHAAA,kBAAkB,OAAA;AAEpB,wDAAsC;AACtC,kEAAgD","sourcesContent":["export type { BaseConfig, BaseState, Listener } from './BaseControllerV1';\nexport { BaseControllerV1 } from './BaseControllerV1';\nexport type {\n Listener as ListenerV2,\n StateDeriver,\n StateMetadata,\n StatePropertyMetadata,\n ControllerGetStateAction,\n ControllerStateChangeEvent,\n} from './BaseControllerV2';\nexport {\n BaseController,\n getAnonymizedState,\n getPersistentState,\n} from './BaseControllerV2';\nexport * from './ControllerMessenger';\nexport * from './RestrictedControllerMessenger';\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@metamask-previews/base-controller",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "4.0.1-preview.353ee83b",
|
|
4
4
|
"description": "Provides scaffolding for controllers as well a communication system for all controllers",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"MetaMask",
|
|
@@ -22,6 +22,7 @@
|
|
|
22
22
|
],
|
|
23
23
|
"scripts": {
|
|
24
24
|
"build:docs": "typedoc",
|
|
25
|
+
"changelog:update": "../../scripts/update-changelog.sh @metamask/base-controller",
|
|
25
26
|
"changelog:validate": "../../scripts/validate-changelog.sh @metamask/base-controller",
|
|
26
27
|
"publish:preview": "yarn npm publish --tag preview",
|
|
27
28
|
"test": "jest --reporters=jest-silent-reporter",
|
|
@@ -34,7 +35,7 @@
|
|
|
34
35
|
"immer": "^9.0.6"
|
|
35
36
|
},
|
|
36
37
|
"devDependencies": {
|
|
37
|
-
"@metamask/auto-changelog": "^3.4.
|
|
38
|
+
"@metamask/auto-changelog": "^3.4.4",
|
|
38
39
|
"@types/jest": "^27.4.1",
|
|
39
40
|
"@types/sinon": "^9.0.10",
|
|
40
41
|
"deepmerge": "^4.2.2",
|
|
@@ -1 +0,0 @@
|
|
|
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;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;;;;;;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"}
|
|
@@ -1 +0,0 @@
|
|
|
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 */\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 * 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, value] of Object.entries(this.internalConfig)) {\n if (value !== undefined) {\n (this as any)[key] = value;\n }\n }\n } else {\n for (const key of Object.keys(config) as (keyof C)[]) {\n /* istanbul ignore else */\n if (typeof this.internalConfig[key] !== 'undefined') {\n this.internalConfig[key] = (config as C)[key];\n (this as any)[key] = 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"]}
|