@metamask-previews/messenger 0.0.0-preview-2fd8e984 → 0.0.0-preview-343f3d69
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 +13 -0
- package/dist/Messenger.cjs +343 -84
- package/dist/Messenger.cjs.map +1 -1
- package/dist/Messenger.d.cts +163 -53
- package/dist/Messenger.d.cts.map +1 -1
- package/dist/Messenger.d.mts +163 -53
- package/dist/Messenger.d.mts.map +1 -1
- package/dist/Messenger.mjs +343 -84
- package/dist/Messenger.mjs.map +1 -1
- package/dist/index.cjs +1 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +0 -2
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +0 -2
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +0 -1
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/dist/RestrictedMessenger.cjs +0 -239
- package/dist/RestrictedMessenger.cjs.map +0 -1
- package/dist/RestrictedMessenger.d.cts +0 -197
- package/dist/RestrictedMessenger.d.cts.map +0 -1
- package/dist/RestrictedMessenger.d.mts +0 -197
- package/dist/RestrictedMessenger.d.mts.map +0 -1
- package/dist/RestrictedMessenger.mjs +0 -235
- package/dist/RestrictedMessenger.mjs.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -10,11 +10,24 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
10
10
|
### Added
|
|
11
11
|
|
|
12
12
|
- Migrate `Messenger` class from `@metamask/base-controller` package ([#6127](https://github.com/MetaMask/core/pull/6127))
|
|
13
|
+
- Add `delegate` and `revoke` methods ([#6132](https://github.com/MetaMask/core/pull/6132))
|
|
14
|
+
- These allow delegating or revoking capabilities (actions or events) from one `Messenger` instance to another.
|
|
15
|
+
- This allows passing capabilities through chains of messengers of arbitrary length
|
|
16
|
+
- See this ADR for details: https://github.com/MetaMask/decisions/blob/main/decisions/core/0012-messenger-delegation.md
|
|
13
17
|
|
|
14
18
|
### Changed
|
|
15
19
|
|
|
20
|
+
- **BREAKING:** Add `Namespace` type parameter and required `namespace` constructor parameter ([#6132](https://github.com/MetaMask/core/pull/6132))
|
|
21
|
+
- All published events and registered actions should fall under the given namespace. Typically the namespace is the controller or service name. This is the equivalent to the `Namespace` parameter from the old `RestrictedMessenger` class.
|
|
22
|
+
- **BREAKING:** The `type` property of `ActionConstraint` and `EventConstraint` is now a `NamespacedName` rather than a string ([#6132](https://github.com/MetaMask/core/pull/6132))
|
|
16
23
|
- Add default for `ReturnHandler` type parameter of `SelectorEventHandler` and `SelectorFunction` ([#6262](https://github.com/MetaMask/core/pull/6262), [#6264](https://github.com/MetaMask/core/pull/6264))
|
|
17
24
|
|
|
25
|
+
### Removed
|
|
26
|
+
|
|
27
|
+
- **BREAKING:** Remove `RestrictedMessenger` class ([#6132](https://github.com/MetaMask/core/pull/6132))
|
|
28
|
+
- Existing `RestrictedMessenger` instances should be replaced with a `Messenger`. We can now use the same class everywhere, passing capabilities using `delegate`.
|
|
29
|
+
- See this ADR for details: https://github.com/MetaMask/decisions/blob/main/decisions/core/0012-messenger-delegation.md
|
|
30
|
+
|
|
18
31
|
### Fixed
|
|
19
32
|
|
|
20
33
|
- Update `unsubscribe` type signature to support selector event handlers ([#6262](https://github.com/MetaMask/core/pull/6262))
|
package/dist/Messenger.cjs
CHANGED
|
@@ -1,27 +1,50 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
|
|
3
|
+
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
4
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
5
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
6
|
+
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
7
|
+
};
|
|
2
8
|
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
3
9
|
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
4
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");
|
|
5
11
|
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
6
12
|
};
|
|
7
|
-
var _Messenger_actions, _Messenger_events, _Messenger_initialEventPayloadGetters, _Messenger_eventPayloadCache;
|
|
13
|
+
var _Messenger_instances, _Messenger_namespace, _Messenger_actions, _Messenger_events, _Messenger_subscriptionDelegationTargets, _Messenger_actionDelegationTargets, _Messenger_initialEventPayloadGetters, _Messenger_eventPayloadCache, _Messenger_registerActionHandler, _Messenger_unregisterActionHandler, _Messenger_registerInitialEventPayload, _Messenger_publish, _Messenger_subscribe, _Messenger_isInCurrentNamespace;
|
|
8
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
15
|
exports.Messenger = void 0;
|
|
10
|
-
const RestrictedMessenger_1 = require("./RestrictedMessenger.cjs");
|
|
11
16
|
/**
|
|
12
17
|
* A message broker for "actions" and "events".
|
|
13
18
|
*
|
|
14
19
|
* The messenger allows registering functions as 'actions' that can be called elsewhere,
|
|
15
20
|
* and it allows publishing and subscribing to events. Both actions and events are identified by
|
|
16
|
-
* unique strings.
|
|
21
|
+
* unique strings prefixed by a namespace (which is delimited by a colon, e.g.
|
|
22
|
+
* `Namespace:actionName`).
|
|
17
23
|
*
|
|
18
24
|
* @template Action - A type union of all Action types.
|
|
19
25
|
* @template Event - A type union of all Event types.
|
|
26
|
+
* @template Namespace - The namespace for the messenger.
|
|
20
27
|
*/
|
|
21
28
|
class Messenger {
|
|
22
|
-
|
|
29
|
+
/**
|
|
30
|
+
* Construct a messenger.
|
|
31
|
+
*
|
|
32
|
+
* @param args - Constructor arguments
|
|
33
|
+
* @param args.namespace - The messenger namespace.
|
|
34
|
+
*/
|
|
35
|
+
constructor({ namespace }) {
|
|
36
|
+
_Messenger_instances.add(this);
|
|
37
|
+
_Messenger_namespace.set(this, void 0);
|
|
23
38
|
_Messenger_actions.set(this, new Map());
|
|
24
39
|
_Messenger_events.set(this, new Map());
|
|
40
|
+
/**
|
|
41
|
+
* The set of messengers we've delegated events to and their event handlers, by event type.
|
|
42
|
+
*/
|
|
43
|
+
_Messenger_subscriptionDelegationTargets.set(this, new Map());
|
|
44
|
+
/**
|
|
45
|
+
* The set of messengers we've delegated actions to, by action type.
|
|
46
|
+
*/
|
|
47
|
+
_Messenger_actionDelegationTargets.set(this, new Map());
|
|
25
48
|
/**
|
|
26
49
|
* A map of functions for getting the initial event payload.
|
|
27
50
|
*
|
|
@@ -32,23 +55,27 @@ class Messenger {
|
|
|
32
55
|
* A cache of selector return values for their respective handlers.
|
|
33
56
|
*/
|
|
34
57
|
_Messenger_eventPayloadCache.set(this, new Map());
|
|
58
|
+
__classPrivateFieldSet(this, _Messenger_namespace, namespace, "f");
|
|
35
59
|
}
|
|
36
60
|
/**
|
|
37
61
|
* Register an action handler.
|
|
38
62
|
*
|
|
39
63
|
* This will make the registered function available to call via the `call` method.
|
|
40
64
|
*
|
|
65
|
+
* The action being registered must be under the same namespace as the messenger.
|
|
66
|
+
*
|
|
41
67
|
* @param actionType - The action type. This is a unique identifier for this action.
|
|
42
68
|
* @param handler - The action handler. This function gets called when the `call` method is
|
|
43
69
|
* invoked with the given action type.
|
|
44
70
|
* @throws Will throw when a handler has been registered for this action type already.
|
|
45
|
-
* @template ActionType - A type union of Action type strings.
|
|
71
|
+
* @template ActionType - A type union of Action type strings under this messenger's namespace.
|
|
46
72
|
*/
|
|
47
73
|
registerActionHandler(actionType, handler) {
|
|
48
|
-
if
|
|
49
|
-
|
|
74
|
+
/* istanbul ignore if */ // Branch unreachable with valid types
|
|
75
|
+
if (!__classPrivateFieldGet(this, _Messenger_instances, "m", _Messenger_isInCurrentNamespace).call(this, actionType)) {
|
|
76
|
+
throw new Error(`Only allowed registering action handlers prefixed by '${__classPrivateFieldGet(this, _Messenger_namespace, "f")}:'`);
|
|
50
77
|
}
|
|
51
|
-
__classPrivateFieldGet(this,
|
|
78
|
+
__classPrivateFieldGet(this, _Messenger_instances, "m", _Messenger_registerActionHandler).call(this, actionType, handler);
|
|
52
79
|
}
|
|
53
80
|
/**
|
|
54
81
|
* Registers action handlers for a list of methods on a messenger client
|
|
@@ -73,11 +100,17 @@ class Messenger {
|
|
|
73
100
|
*
|
|
74
101
|
* This will prevent this action from being called.
|
|
75
102
|
*
|
|
103
|
+
* The action being unregistered must be under the same namespace as the messenger.
|
|
104
|
+
*
|
|
76
105
|
* @param actionType - The action type. This is a unique identifier for this action.
|
|
77
|
-
* @template ActionType - A type union of Action type strings.
|
|
106
|
+
* @template ActionType - A type union of Action type strings under this messenger's namespace.
|
|
78
107
|
*/
|
|
79
108
|
unregisterActionHandler(actionType) {
|
|
80
|
-
|
|
109
|
+
/* istanbul ignore if */ // Branch unreachable with valid types
|
|
110
|
+
if (!__classPrivateFieldGet(this, _Messenger_instances, "m", _Messenger_isInCurrentNamespace).call(this, actionType)) {
|
|
111
|
+
throw new Error(`Only allowed unregistering action handlers prefixed by '${__classPrivateFieldGet(this, _Messenger_namespace, "f")}:'`);
|
|
112
|
+
}
|
|
113
|
+
__classPrivateFieldGet(this, _Messenger_instances, "m", _Messenger_unregisterActionHandler).call(this, actionType);
|
|
81
114
|
}
|
|
82
115
|
/**
|
|
83
116
|
* Unregister all action handlers.
|
|
@@ -85,7 +118,9 @@ class Messenger {
|
|
|
85
118
|
* This prevents all actions from being called.
|
|
86
119
|
*/
|
|
87
120
|
clearActions() {
|
|
88
|
-
__classPrivateFieldGet(this, _Messenger_actions, "f").
|
|
121
|
+
for (const actionType of __classPrivateFieldGet(this, _Messenger_actions, "f").keys()) {
|
|
122
|
+
__classPrivateFieldGet(this, _Messenger_instances, "m", _Messenger_unregisterActionHandler).call(this, actionType);
|
|
123
|
+
}
|
|
89
124
|
}
|
|
90
125
|
/**
|
|
91
126
|
* Call an action.
|
|
@@ -114,13 +149,19 @@ class Messenger {
|
|
|
114
149
|
* Registering a function for getting the payload allows event selectors to have a point of
|
|
115
150
|
* comparison the first time state changes.
|
|
116
151
|
*
|
|
152
|
+
* The event type must be under the same namespace as the messenger.
|
|
153
|
+
*
|
|
117
154
|
* @param args - The arguments to this function
|
|
118
155
|
* @param args.eventType - The event type to register a payload for.
|
|
119
156
|
* @param args.getPayload - A function for retrieving the event payload.
|
|
120
|
-
* @template EventType - A type union of Event type strings.
|
|
157
|
+
* @template EventType - A type union of Event type strings under this messenger's namespace.
|
|
121
158
|
*/
|
|
122
159
|
registerInitialEventPayload({ eventType, getPayload, }) {
|
|
123
|
-
|
|
160
|
+
/* istanbul ignore if */ // Branch unreachable with valid types
|
|
161
|
+
if (!__classPrivateFieldGet(this, _Messenger_instances, "m", _Messenger_isInCurrentNamespace).call(this, eventType)) {
|
|
162
|
+
throw new Error(`Only allowed registering initial payloads for events prefixed by '${__classPrivateFieldGet(this, _Messenger_namespace, "f")}:'`);
|
|
163
|
+
}
|
|
164
|
+
__classPrivateFieldGet(this, _Messenger_instances, "m", _Messenger_registerInitialEventPayload).call(this, { eventType, getPayload });
|
|
124
165
|
}
|
|
125
166
|
/**
|
|
126
167
|
* Publish an event.
|
|
@@ -130,48 +171,25 @@ class Messenger {
|
|
|
130
171
|
* Note that this method should never throw directly. Any errors from
|
|
131
172
|
* subscribers are captured and re-thrown in a timeout handler.
|
|
132
173
|
*
|
|
174
|
+
* The event being published must be under the same namespace as the messenger.
|
|
175
|
+
*
|
|
133
176
|
* @param eventType - The event type. This is a unique identifier for this event.
|
|
134
177
|
* @param payload - The event payload. The type of the parameters for each event handler must
|
|
135
178
|
* match the type of this payload.
|
|
136
|
-
* @template EventType - A type union of Event type strings.
|
|
179
|
+
* @template EventType - A type union of Event type strings under this messenger's namespace.
|
|
137
180
|
*/
|
|
138
181
|
publish(eventType, ...payload) {
|
|
139
|
-
|
|
140
|
-
if (
|
|
141
|
-
|
|
142
|
-
try {
|
|
143
|
-
if (selector) {
|
|
144
|
-
const previousValue = __classPrivateFieldGet(this, _Messenger_eventPayloadCache, "f").get(handler);
|
|
145
|
-
const newValue = selector(...payload);
|
|
146
|
-
if (newValue !== previousValue) {
|
|
147
|
-
__classPrivateFieldGet(this, _Messenger_eventPayloadCache, "f").set(handler, newValue);
|
|
148
|
-
handler(newValue, previousValue);
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
else {
|
|
152
|
-
handler(...payload);
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
catch (error) {
|
|
156
|
-
// Throw error after timeout so that it is capured as a console error
|
|
157
|
-
// (and by Sentry) without interrupting the event publishing.
|
|
158
|
-
setTimeout(() => {
|
|
159
|
-
throw error;
|
|
160
|
-
});
|
|
161
|
-
}
|
|
162
|
-
}
|
|
182
|
+
/* istanbul ignore if */ // Branch unreachable with valid types
|
|
183
|
+
if (!__classPrivateFieldGet(this, _Messenger_instances, "m", _Messenger_isInCurrentNamespace).call(this, eventType)) {
|
|
184
|
+
throw new Error(`Only allowed publishing events prefixed by '${__classPrivateFieldGet(this, _Messenger_namespace, "f")}:'`);
|
|
163
185
|
}
|
|
186
|
+
__classPrivateFieldGet(this, _Messenger_instances, "m", _Messenger_publish).call(this, eventType, ...payload);
|
|
164
187
|
}
|
|
165
188
|
subscribe(eventType, handler, selector) {
|
|
166
|
-
let subscribers = __classPrivateFieldGet(this, _Messenger_events, "f").get(eventType);
|
|
167
|
-
if (!subscribers) {
|
|
168
|
-
subscribers = new Map();
|
|
169
|
-
__classPrivateFieldGet(this, _Messenger_events, "f").set(eventType, subscribers);
|
|
170
|
-
}
|
|
171
189
|
// Widen type of event handler by dropping ReturnType parameter.
|
|
172
190
|
//
|
|
173
191
|
// We need to drop it here because it's used as the parameter to the event handler, and
|
|
174
|
-
// functions in general are
|
|
192
|
+
// functions in general are contravariant over the parameter type. This means the type is no
|
|
175
193
|
// longer valid once it's added to a broader type union with other handlers (because as far
|
|
176
194
|
// as TypeScript knows, we might call the handler with output from a different selector).
|
|
177
195
|
//
|
|
@@ -180,7 +198,7 @@ class Messenger {
|
|
|
180
198
|
// called, but past that point we need to make sure of that with manual review and tests
|
|
181
199
|
// instead.
|
|
182
200
|
const widenedHandler = handler;
|
|
183
|
-
|
|
201
|
+
__classPrivateFieldGet(this, _Messenger_instances, "m", _Messenger_subscribe).call(this, eventType, widenedHandler, { delegation: false, selector });
|
|
184
202
|
if (selector) {
|
|
185
203
|
const getPayload = __classPrivateFieldGet(this, _Messenger_initialEventPayloadGetters, "f").get(eventType);
|
|
186
204
|
if (getPayload) {
|
|
@@ -205,17 +223,20 @@ class Messenger {
|
|
|
205
223
|
// Widen type of event handler by dropping ReturnType parameter.
|
|
206
224
|
//
|
|
207
225
|
// We need to drop it here because it's used as the parameter to the event handler, and
|
|
208
|
-
// functions in general are
|
|
226
|
+
// functions in general are contravariant over the parameter type. This means the type is no
|
|
209
227
|
// longer valid once it's added to a broader type union with other handlers (because as far
|
|
210
228
|
// as TypeScript knows, we might call the handler with output from a different selector).
|
|
211
229
|
//
|
|
212
230
|
// This poses no risk in this case, since we never call the handler past this point.
|
|
213
231
|
const widenedHandler = handler;
|
|
214
|
-
if (!subscribers
|
|
232
|
+
if (!subscribers) {
|
|
215
233
|
throw new Error(`Subscription not found for event: ${eventType}`);
|
|
216
234
|
}
|
|
217
235
|
const metadata = subscribers.get(widenedHandler);
|
|
218
|
-
if (metadata
|
|
236
|
+
if (!metadata) {
|
|
237
|
+
throw new Error(`Subscription not found for event: ${eventType}`);
|
|
238
|
+
}
|
|
239
|
+
if (metadata.selector) {
|
|
219
240
|
__classPrivateFieldGet(this, _Messenger_eventPayloadCache, "f").delete(widenedHandler);
|
|
220
241
|
}
|
|
221
242
|
subscribers.delete(widenedHandler);
|
|
@@ -223,57 +244,295 @@ class Messenger {
|
|
|
223
244
|
/**
|
|
224
245
|
* Clear subscriptions for a specific event.
|
|
225
246
|
*
|
|
226
|
-
* This will remove all subscribed handlers for this event.
|
|
247
|
+
* This will remove all subscribed handlers for this event registered from this messenger. The
|
|
248
|
+
* event may still have subscribers if it has been delegated to another messenger.
|
|
227
249
|
*
|
|
228
250
|
* @param eventType - The event type. This is a unique identifier for this event.
|
|
229
251
|
* @template EventType - A type union of Event type strings.
|
|
230
252
|
*/
|
|
231
253
|
clearEventSubscriptions(eventType) {
|
|
232
|
-
__classPrivateFieldGet(this, _Messenger_events, "f").
|
|
254
|
+
const subscriptions = __classPrivateFieldGet(this, _Messenger_events, "f").get(eventType);
|
|
255
|
+
if (!subscriptions) {
|
|
256
|
+
return;
|
|
257
|
+
}
|
|
258
|
+
for (const [handler, metadata] of subscriptions.entries()) {
|
|
259
|
+
if (metadata.delegation) {
|
|
260
|
+
continue;
|
|
261
|
+
}
|
|
262
|
+
subscriptions.delete(handler);
|
|
263
|
+
}
|
|
264
|
+
if (subscriptions.size === 0) {
|
|
265
|
+
__classPrivateFieldGet(this, _Messenger_events, "f").delete(eventType);
|
|
266
|
+
}
|
|
233
267
|
}
|
|
234
268
|
/**
|
|
235
269
|
* Clear all subscriptions.
|
|
236
270
|
*
|
|
237
|
-
* This will remove all subscribed handlers for all events.
|
|
271
|
+
* This will remove all subscribed handlers for all events registered from this messenger. Events
|
|
272
|
+
* may still have subscribers if they are delegated to another messenger.
|
|
238
273
|
*/
|
|
239
274
|
clearSubscriptions() {
|
|
240
|
-
__classPrivateFieldGet(this, _Messenger_events, "f").
|
|
275
|
+
for (const eventType of __classPrivateFieldGet(this, _Messenger_events, "f").keys()) {
|
|
276
|
+
this.clearEventSubscriptions(eventType);
|
|
277
|
+
}
|
|
241
278
|
}
|
|
242
279
|
/**
|
|
243
|
-
*
|
|
244
|
-
*
|
|
245
|
-
*
|
|
246
|
-
*
|
|
247
|
-
*
|
|
248
|
-
*
|
|
249
|
-
*
|
|
250
|
-
*
|
|
251
|
-
*
|
|
252
|
-
*
|
|
253
|
-
*
|
|
254
|
-
*
|
|
255
|
-
* @param
|
|
256
|
-
*
|
|
257
|
-
* @
|
|
258
|
-
*
|
|
259
|
-
* @template
|
|
260
|
-
* module that this messenger has been created for. The authority to publish events and register
|
|
261
|
-
* actions under this namespace is granted to this restricted messenger instance.
|
|
262
|
-
* @template AllowedAction - A type union of the 'type' string for any allowed actions.
|
|
263
|
-
* This must not include internal actions that are in the messenger's namespace.
|
|
264
|
-
* @template AllowedEvent - A type union of the 'type' string for any allowed events.
|
|
265
|
-
* This must not include internal events that are in the messenger's namespace.
|
|
266
|
-
* @returns The restricted messenger.
|
|
280
|
+
* Delegate actions and/or events to another messenger.
|
|
281
|
+
*
|
|
282
|
+
* The messenger these actions/events are delegated to will be able to call these actions and
|
|
283
|
+
* subscribe to these events.
|
|
284
|
+
*
|
|
285
|
+
* Note that the messenger these actions/events are delegated to must still have these
|
|
286
|
+
* actions/events included in its type definition (as part of the Action and Event type
|
|
287
|
+
* parameters). Actions and events are statically type checked, they cannot be delegated
|
|
288
|
+
* dynamically at runtime.
|
|
289
|
+
*
|
|
290
|
+
* @param args - Arguments.
|
|
291
|
+
* @param args.actions - The action types to delegate.
|
|
292
|
+
* @param args.events - The event types to delegate.
|
|
293
|
+
* @param args.messenger - The messenger to delegate to.
|
|
294
|
+
* @template Delegatee - The messenger the actions/events are delegated to.
|
|
295
|
+
* @template DelegatedActions - An array of delegated action types.
|
|
296
|
+
* @template DelegatedEvents - An array of delegated event types.
|
|
267
297
|
*/
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
298
|
+
delegate({ actions, events, messenger, }) {
|
|
299
|
+
for (const actionType of actions || []) {
|
|
300
|
+
const delegatedActionHandler = (...args) => {
|
|
301
|
+
// Cast to get more specific type, for this specific action
|
|
302
|
+
// The types get collapsed by `this.#actions`
|
|
303
|
+
const actionHandler = __classPrivateFieldGet(this, _Messenger_actions, "f").get(actionType);
|
|
304
|
+
if (!actionHandler) {
|
|
305
|
+
throw new Error(`Cannot call '${actionType}', action not registered.`);
|
|
306
|
+
}
|
|
307
|
+
return actionHandler(...args);
|
|
308
|
+
};
|
|
309
|
+
let delegationTargets = __classPrivateFieldGet(this, _Messenger_actionDelegationTargets, "f").get(actionType);
|
|
310
|
+
if (!delegationTargets) {
|
|
311
|
+
delegationTargets = new Set();
|
|
312
|
+
__classPrivateFieldGet(this, _Messenger_actionDelegationTargets, "f").set(actionType, delegationTargets);
|
|
313
|
+
}
|
|
314
|
+
if (delegationTargets.has(messenger)) {
|
|
315
|
+
throw new Error(`The action '${actionType}' has already been delegated to this messenger`);
|
|
316
|
+
}
|
|
317
|
+
delegationTargets.add(messenger);
|
|
318
|
+
messenger._internalRegisterDelegatedActionHandler(actionType, delegatedActionHandler);
|
|
319
|
+
}
|
|
320
|
+
for (const eventType of events || []) {
|
|
321
|
+
const untypedSubscriber = (...payload) => {
|
|
322
|
+
messenger._internalPublishDelegated(eventType, ...payload);
|
|
323
|
+
};
|
|
324
|
+
// Cast to get more specific subscriber type for this specific event.
|
|
325
|
+
// The types get collapsed here to the type union of all delegated
|
|
326
|
+
// events, rather than the single subscriber type corresponding to this
|
|
327
|
+
// event.
|
|
328
|
+
const subscriber = untypedSubscriber;
|
|
329
|
+
let delegatedEventSubscriptions = __classPrivateFieldGet(this, _Messenger_subscriptionDelegationTargets, "f").get(eventType);
|
|
330
|
+
if (!delegatedEventSubscriptions) {
|
|
331
|
+
delegatedEventSubscriptions = new Map();
|
|
332
|
+
__classPrivateFieldGet(this, _Messenger_subscriptionDelegationTargets, "f").set(eventType, delegatedEventSubscriptions);
|
|
333
|
+
}
|
|
334
|
+
if (delegatedEventSubscriptions.has(messenger)) {
|
|
335
|
+
throw new Error(`The event '${eventType}' has already been delegated to this messenger`);
|
|
336
|
+
}
|
|
337
|
+
delegatedEventSubscriptions.set(messenger, subscriber);
|
|
338
|
+
const getPayload = __classPrivateFieldGet(this, _Messenger_initialEventPayloadGetters, "f").get(eventType);
|
|
339
|
+
if (getPayload) {
|
|
340
|
+
messenger._internalRegisterDelegatedInitialEventPayload({
|
|
341
|
+
eventType,
|
|
342
|
+
getPayload,
|
|
343
|
+
});
|
|
344
|
+
}
|
|
345
|
+
__classPrivateFieldGet(this, _Messenger_instances, "m", _Messenger_subscribe).call(this, eventType, subscriber, { delegation: true });
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
/**
|
|
349
|
+
* Revoke delegated actions and/or events from another messenger.
|
|
350
|
+
*
|
|
351
|
+
* The messenger these actions/events are delegated to will no longer be able to call these
|
|
352
|
+
* actions or subscribe to these events.
|
|
353
|
+
*
|
|
354
|
+
* @param args - Arguments.
|
|
355
|
+
* @param args.actions - The action types to revoke.
|
|
356
|
+
* @param args.events - The event types to revoke.
|
|
357
|
+
* @param args.messenger - The messenger these actions/events were delegated to.
|
|
358
|
+
* @template Delegatee - The messenger the actions/events are being revoked from.
|
|
359
|
+
* @template DelegatedActions - An array of delegated action types.
|
|
360
|
+
* @template DelegatedEvents - An array of delegated event types.
|
|
361
|
+
*/
|
|
362
|
+
revoke({ actions, events, messenger, }) {
|
|
363
|
+
for (const actionType of actions || []) {
|
|
364
|
+
const delegationTargets = __classPrivateFieldGet(this, _Messenger_actionDelegationTargets, "f").get(actionType);
|
|
365
|
+
if (!delegationTargets || !delegationTargets.has(messenger)) {
|
|
366
|
+
// Nothing to revoke
|
|
367
|
+
continue;
|
|
368
|
+
}
|
|
369
|
+
messenger._internalUnregisterDelegatedActionHandler(actionType);
|
|
370
|
+
delegationTargets.delete(messenger);
|
|
371
|
+
if (delegationTargets.size === 0) {
|
|
372
|
+
__classPrivateFieldGet(this, _Messenger_actionDelegationTargets, "f").delete(actionType);
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
for (const eventType of events || []) {
|
|
376
|
+
const delegationTargets = __classPrivateFieldGet(this, _Messenger_subscriptionDelegationTargets, "f").get(eventType);
|
|
377
|
+
if (!delegationTargets) {
|
|
378
|
+
// Nothing to revoke
|
|
379
|
+
continue;
|
|
380
|
+
}
|
|
381
|
+
const delegatedSubscriber = delegationTargets.get(messenger);
|
|
382
|
+
if (!delegatedSubscriber) {
|
|
383
|
+
// Nothing to revoke
|
|
384
|
+
continue;
|
|
385
|
+
}
|
|
386
|
+
this.unsubscribe(eventType, delegatedSubscriber);
|
|
387
|
+
delegationTargets.delete(messenger);
|
|
388
|
+
if (delegationTargets.size === 0) {
|
|
389
|
+
__classPrivateFieldGet(this, _Messenger_subscriptionDelegationTargets, "f").delete(eventType);
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
/**
|
|
394
|
+
* Register an action handler for an action delegated from another messenger.
|
|
395
|
+
*
|
|
396
|
+
* This will make the registered function available to call via the `call` method.
|
|
397
|
+
*
|
|
398
|
+
* Note: This is an internal method. Never access this property from another module. This must be
|
|
399
|
+
* exposed as a public property so that these methods can be called internally on other messenger
|
|
400
|
+
* instances.
|
|
401
|
+
*
|
|
402
|
+
* @deprecated Internal use only. Use the `delegate` method for delegation.
|
|
403
|
+
* @param actionType - The action type. This is a unique identifier for this action.
|
|
404
|
+
* @param handler - The action handler. This function gets called when the `call` method is
|
|
405
|
+
* invoked with the given action type.
|
|
406
|
+
* @throws Will throw when a handler has been registered for this action type already.
|
|
407
|
+
* @template ActionType - A type union of Action type strings.
|
|
408
|
+
*/
|
|
409
|
+
_internalRegisterDelegatedActionHandler(actionType,
|
|
410
|
+
// Using wider `ActionConstraint` type here rather than `Action` because the `Action` type is
|
|
411
|
+
// contravariant over the handler parameter type. Using `Action` would lead to a type error
|
|
412
|
+
// here because the messenger we've delegated to supports _additional_ actions.
|
|
413
|
+
handler) {
|
|
414
|
+
__classPrivateFieldGet(this, _Messenger_instances, "m", _Messenger_registerActionHandler).call(this, actionType, handler);
|
|
415
|
+
}
|
|
416
|
+
/**
|
|
417
|
+
* Unregister an action handler for an action delegated from another messenger.
|
|
418
|
+
*
|
|
419
|
+
* This will prevent this action from being called.
|
|
420
|
+
*
|
|
421
|
+
* Note: This is an internal method. Never access this property from another module. This must be
|
|
422
|
+
* exposed as a public property so that these methods can be called internally on other messenger
|
|
423
|
+
* instances.
|
|
424
|
+
*
|
|
425
|
+
* @deprecated Internal use only. Use the `delegate` method for delegation.
|
|
426
|
+
* @param actionType - The action type. This is a unqiue identifier for this action.
|
|
427
|
+
* @template ActionType - A type union of Action type strings.
|
|
428
|
+
*/
|
|
429
|
+
_internalUnregisterDelegatedActionHandler(actionType) {
|
|
430
|
+
__classPrivateFieldGet(this, _Messenger_instances, "m", _Messenger_unregisterActionHandler).call(this, actionType);
|
|
431
|
+
}
|
|
432
|
+
/**
|
|
433
|
+
* Register a function for getting the initial payload for an event that has been delegated from
|
|
434
|
+
* another messenger.
|
|
435
|
+
*
|
|
436
|
+
* This is used for events that represent a state change, where the payload is the state.
|
|
437
|
+
* Registering a function for getting the payload allows event selectors to have a point of
|
|
438
|
+
* comparison the first time state changes.
|
|
439
|
+
*
|
|
440
|
+
* Note: This is an internal method. Never access this property from another module. This must be
|
|
441
|
+
* exposed as a public property so that these methods can be called internally on other messenger
|
|
442
|
+
* instances.
|
|
443
|
+
*
|
|
444
|
+
* @deprecated Internal use only. Use the `delegate` method for delegation.
|
|
445
|
+
* @param args - The arguments to this function
|
|
446
|
+
* @param args.eventType - The event type to register a payload for.
|
|
447
|
+
* @param args.getPayload - A function for retrieving the event payload.
|
|
448
|
+
*/
|
|
449
|
+
_internalRegisterDelegatedInitialEventPayload({ eventType, getPayload, }) {
|
|
450
|
+
__classPrivateFieldGet(this, _Messenger_instances, "m", _Messenger_registerInitialEventPayload).call(this, { eventType, getPayload });
|
|
451
|
+
}
|
|
452
|
+
/**
|
|
453
|
+
* Publish an event that was delegated from another messenger.
|
|
454
|
+
*
|
|
455
|
+
* Publishes the given payload to all subscribers of the given event type.
|
|
456
|
+
*
|
|
457
|
+
* Note that this method should never throw directly. Any errors from
|
|
458
|
+
* subscribers are captured and re-thrown in a timeout handler.
|
|
459
|
+
*
|
|
460
|
+
* Note: This is an internal method. Never access this property from another module. This must be
|
|
461
|
+
* exposed as a public property so that these methods can be called internally on other messenger
|
|
462
|
+
* instances.
|
|
463
|
+
*
|
|
464
|
+
* @deprecated Internal use only. Use the `delegate` method for delegation.
|
|
465
|
+
* @param eventType - The event type. This is a unique identifier for this event.
|
|
466
|
+
* @param payload - The event payload. The type of the parameters for each event handler must
|
|
467
|
+
* match the type of this payload.
|
|
468
|
+
* @template EventType - A type union of Event type strings.
|
|
469
|
+
*/
|
|
470
|
+
_internalPublishDelegated(eventType, ...payload) {
|
|
471
|
+
__classPrivateFieldGet(this, _Messenger_instances, "m", _Messenger_publish).call(this, eventType, ...payload);
|
|
275
472
|
}
|
|
276
473
|
}
|
|
277
474
|
exports.Messenger = Messenger;
|
|
278
|
-
_Messenger_actions = new WeakMap(), _Messenger_events = new WeakMap(), _Messenger_initialEventPayloadGetters = new WeakMap(), _Messenger_eventPayloadCache = new WeakMap()
|
|
475
|
+
_Messenger_namespace = new WeakMap(), _Messenger_actions = new WeakMap(), _Messenger_events = new WeakMap(), _Messenger_subscriptionDelegationTargets = new WeakMap(), _Messenger_actionDelegationTargets = new WeakMap(), _Messenger_initialEventPayloadGetters = new WeakMap(), _Messenger_eventPayloadCache = new WeakMap(), _Messenger_instances = new WeakSet(), _Messenger_registerActionHandler = function _Messenger_registerActionHandler(actionType, handler) {
|
|
476
|
+
if (__classPrivateFieldGet(this, _Messenger_actions, "f").has(actionType)) {
|
|
477
|
+
throw new Error(`A handler for ${actionType} has already been registered`);
|
|
478
|
+
}
|
|
479
|
+
__classPrivateFieldGet(this, _Messenger_actions, "f").set(actionType, handler);
|
|
480
|
+
}, _Messenger_unregisterActionHandler = function _Messenger_unregisterActionHandler(actionType) {
|
|
481
|
+
__classPrivateFieldGet(this, _Messenger_actions, "f").delete(actionType);
|
|
482
|
+
const delegationTargets = __classPrivateFieldGet(this, _Messenger_actionDelegationTargets, "f").get(actionType);
|
|
483
|
+
if (!delegationTargets) {
|
|
484
|
+
return;
|
|
485
|
+
}
|
|
486
|
+
for (const messenger of delegationTargets) {
|
|
487
|
+
messenger._internalUnregisterDelegatedActionHandler(actionType);
|
|
488
|
+
}
|
|
489
|
+
__classPrivateFieldGet(this, _Messenger_actionDelegationTargets, "f").delete(actionType);
|
|
490
|
+
}, _Messenger_registerInitialEventPayload = function _Messenger_registerInitialEventPayload({ eventType, getPayload, }) {
|
|
491
|
+
__classPrivateFieldGet(this, _Messenger_initialEventPayloadGetters, "f").set(eventType, getPayload);
|
|
492
|
+
const delegationTargets = __classPrivateFieldGet(this, _Messenger_subscriptionDelegationTargets, "f").get(eventType);
|
|
493
|
+
if (!delegationTargets) {
|
|
494
|
+
return;
|
|
495
|
+
}
|
|
496
|
+
for (const messenger of delegationTargets.keys()) {
|
|
497
|
+
messenger._internalRegisterDelegatedInitialEventPayload({
|
|
498
|
+
eventType,
|
|
499
|
+
getPayload,
|
|
500
|
+
});
|
|
501
|
+
}
|
|
502
|
+
}, _Messenger_publish = function _Messenger_publish(eventType, ...payload) {
|
|
503
|
+
const subscribers = __classPrivateFieldGet(this, _Messenger_events, "f").get(eventType);
|
|
504
|
+
if (subscribers) {
|
|
505
|
+
for (const [handler, { selector }] of subscribers.entries()) {
|
|
506
|
+
try {
|
|
507
|
+
if (selector) {
|
|
508
|
+
const previousValue = __classPrivateFieldGet(this, _Messenger_eventPayloadCache, "f").get(handler);
|
|
509
|
+
const newValue = selector(...payload);
|
|
510
|
+
if (newValue !== previousValue) {
|
|
511
|
+
__classPrivateFieldGet(this, _Messenger_eventPayloadCache, "f").set(handler, newValue);
|
|
512
|
+
handler(newValue, previousValue);
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
else {
|
|
516
|
+
handler(...payload);
|
|
517
|
+
}
|
|
518
|
+
}
|
|
519
|
+
catch (error) {
|
|
520
|
+
// Throw error after timeout so that it is capured as a console error
|
|
521
|
+
// (and by Sentry) without interrupting the event publishing.
|
|
522
|
+
setTimeout(() => {
|
|
523
|
+
throw error;
|
|
524
|
+
});
|
|
525
|
+
}
|
|
526
|
+
}
|
|
527
|
+
}
|
|
528
|
+
}, _Messenger_subscribe = function _Messenger_subscribe(eventType, handler, metadata) {
|
|
529
|
+
let subscribers = __classPrivateFieldGet(this, _Messenger_events, "f").get(eventType);
|
|
530
|
+
if (!subscribers) {
|
|
531
|
+
subscribers = new Map();
|
|
532
|
+
__classPrivateFieldGet(this, _Messenger_events, "f").set(eventType, subscribers);
|
|
533
|
+
}
|
|
534
|
+
subscribers.set(handler, metadata);
|
|
535
|
+
}, _Messenger_isInCurrentNamespace = function _Messenger_isInCurrentNamespace(name) {
|
|
536
|
+
return name.startsWith(`${__classPrivateFieldGet(this, _Messenger_namespace, "f")}:`);
|
|
537
|
+
};
|
|
279
538
|
//# sourceMappingURL=Messenger.cjs.map
|