@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 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))
@@ -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
- constructor() {
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 (__classPrivateFieldGet(this, _Messenger_actions, "f").has(actionType)) {
49
- throw new Error(`A handler for ${actionType} has already been registered`);
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, _Messenger_actions, "f").set(actionType, handler);
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
- __classPrivateFieldGet(this, _Messenger_actions, "f").delete(actionType);
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").clear();
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
- __classPrivateFieldGet(this, _Messenger_initialEventPayloadGetters, "f").set(eventType, getPayload);
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
- const subscribers = __classPrivateFieldGet(this, _Messenger_events, "f").get(eventType);
140
- if (subscribers) {
141
- for (const [handler, { selector }] of subscribers.entries()) {
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 contravarient over the parameter type. This means the type is no
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
- subscribers.set(widenedHandler, { selector });
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 contravarient over the parameter type. This means the type is no
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 || !subscribers.has(widenedHandler)) {
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?.selector) {
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").delete(eventType);
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").clear();
275
+ for (const eventType of __classPrivateFieldGet(this, _Messenger_events, "f").keys()) {
276
+ this.clearEventSubscriptions(eventType);
277
+ }
241
278
  }
242
279
  /**
243
- * Get a restricted messenger
244
- *
245
- * Returns a wrapper around the messenger instance that restricts access to actions and events.
246
- * The provided allowlists grant the ability to call the listed actions and subscribe to the
247
- * listed events. The "name" provided grants ownership of any actions and events under that
248
- * namespace. Ownership allows registering actions and publishing events, as well as
249
- * unregistering actions and clearing event subscriptions.
250
- *
251
- * @param options - Messenger options.
252
- * @param options.name - The name of the thing this messenger will be handed to (e.g. the
253
- * controller name). This grants "ownership" of actions and events under this namespace to the
254
- * restricted messenger returned.
255
- * @param options.allowedActions - The list of actions that this restricted messenger should be
256
- * allowed to call.
257
- * @param options.allowedEvents - The list of events that this restricted messenger should be
258
- * allowed to subscribe to.
259
- * @template Namespace - The namespace for this messenger. Typically this is the name of the
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
- getRestricted({ name, allowedActions, allowedEvents, }) {
269
- return new RestrictedMessenger_1.RestrictedMessenger({
270
- messenger: this,
271
- name,
272
- allowedActions,
273
- allowedEvents,
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