aes70 2.0.2 → 2.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/AES70.es5.js CHANGED
@@ -61,6 +61,10 @@
61
61
  * @param {Function} cb - Callback function.
62
62
  */
63
63
  on(name, cb) {
64
+ if (typeof name !== 'string')
65
+ throw new TypeError('Event name must be a string.');
66
+ if (typeof cb !== 'function')
67
+ throw new TypeError('Event handler must be a function.');
64
68
  let handlers = this.event_handlers.get(name);
65
69
 
66
70
  if (!handlers) {
@@ -90,12 +94,36 @@
90
94
  handlers.delete(cb);
91
95
  }
92
96
 
97
+ /**
98
+ * Removes an event handler.
99
+ *
100
+ * @param {strign} name
101
+ * @param {Function} cb
102
+ */
103
+ off(name, cb) {
104
+ this.removeEventListener(name, cb);
105
+ }
106
+
93
107
  /**
94
108
  * Removes all event listeners.
95
109
  */
96
110
  removeAllEventListeners() {
97
111
  this.event_handlers.clear();
98
112
  }
113
+
114
+ /**
115
+ *
116
+ * @param {string} name
117
+ * @param {Function} cb
118
+ */
119
+ subscribe(name, cb) {
120
+ this.on(name, cb);
121
+ return () => {
122
+ if (name === undefined) return;
123
+ this.off(name, cb);
124
+ name = undefined;
125
+ };
126
+ }
99
127
  }
100
128
 
101
129
  class PDU {
@@ -1185,6 +1213,12 @@
1185
1213
  * Keepalive interval in seconds.
1186
1214
  */
1187
1215
  set_keepalive_interval(seconds) {
1216
+ if (!(seconds <= 10)) {
1217
+ console.warn(
1218
+ 'Unusually large keepalive interval %o seconds. Confusion of ms vs. seconds?'
1219
+ );
1220
+ }
1221
+
1188
1222
  const t = seconds * 1000;
1189
1223
 
1190
1224
  if (this._keepalive_interval_id !== null) {
@@ -1782,11 +1816,45 @@
1782
1816
  if (!(o.time > 0)) {
1783
1817
  throw new Error('Bad keepalive timeout.');
1784
1818
  }
1819
+ this.emit('keepalive', o);
1785
1820
  } else {
1786
1821
  throw new Error('Unexpected PDU');
1787
1822
  }
1788
1823
  }
1789
1824
  }
1825
+
1826
+ /**
1827
+ * Activates keepalive handling (using set_keepalive_interval) and waits for
1828
+ * at least one keepalive packet to arrive. If no keepalive message is received,
1829
+ * the connection will be closed and the returned promise will reject.
1830
+ * @param {number} interval
1831
+ * Keepalive interval in seconds.
1832
+ */
1833
+ wait_for_keepalive(interval) {
1834
+ return new Promise((resolve, reject) => {
1835
+ const subscriptions = [];
1836
+
1837
+ const cleanup = () => {
1838
+ subscriptions.forEach((cb) => cb());
1839
+ subscriptions.length = 0;
1840
+ };
1841
+ subscriptions.push(
1842
+ this.subscribe('error', (error) => {
1843
+ reject(error);
1844
+ cleanup();
1845
+ }),
1846
+ this.subscribe('close', () => {
1847
+ reject(new CloseError());
1848
+ cleanup();
1849
+ }),
1850
+ this.subscribe('keepalive', () => {
1851
+ resolve();
1852
+ cleanup();
1853
+ })
1854
+ );
1855
+ this.set_keepalive_interval(interval);
1856
+ });
1857
+ }
1790
1858
  }
1791
1859
 
1792
1860
  function getLengthEncoder(byteLength) {
@@ -7011,7 +7079,7 @@
7011
7079
  ['GetState', 3, 5, [], [OcaTaskManagerState]],
7012
7080
  ['GetTaskStatuses', 3, 6, [], [OcaTaskStatus]],
7013
7081
  ['GetTaskStatus', 3, 7, [OcaUint32], [OcaTaskStatus]],
7014
- ['AddTask', 3, 8, [], []],
7082
+ ['AddTask', 3, 8, [OcaTask], [OcaTask]],
7015
7083
  ['GetTasks', 3, 9, [], [OcaMap(OcaUint32, OcaTask)]],
7016
7084
  ['GetTask', 3, 10, [OcaUint32], [OcaTask]],
7017
7085
  ['SetTask', 3, 11, [OcaUint32, OcaTask], []],
@@ -7096,7 +7164,10 @@
7096
7164
  * successfully created.
7097
7165
  *
7098
7166
  * @method OcaTaskManager#AddTask
7099
- * @returns {Promise<void>}
7167
+ * @param {IOcaTask} Task
7168
+ *
7169
+ * @returns {Promise<OcaTask>}
7170
+ * A promise which resolves to a single value of type :class:`OcaTask`.
7100
7171
  */
7101
7172
  /**
7102
7173
  * Gets map of Tasks in the device. Return value indicates whether map was
@@ -20326,7 +20397,13 @@
20326
20397
  [OcaMediaSourceConnector, OcaMediaConnectorState],
20327
20398
  [],
20328
20399
  ],
20329
- ['AddSinkConnector', 3, 16, [OcaMediaConnectorStatus], []],
20400
+ [
20401
+ 'AddSinkConnector',
20402
+ 3,
20403
+ 16,
20404
+ [OcaMediaConnectorStatus, OcaMediaSinkConnector],
20405
+ [OcaMediaSinkConnector],
20406
+ ],
20330
20407
  ['ControlConnector', 3, 17, [OcaUint16, OcaMediaConnectorCommand], []],
20331
20408
  [
20332
20409
  'SetSourceConnectorPinMap',
@@ -20514,8 +20591,10 @@
20514
20591
  *
20515
20592
  * @method OcaMediaTransportNetwork#AddSinkConnector
20516
20593
  * @param {IOcaMediaConnectorStatus} InitialStatus
20594
+ * @param {IOcaMediaSinkConnector} Connector
20517
20595
  *
20518
- * @returns {Promise<void>}
20596
+ * @returns {Promise<OcaMediaSinkConnector>}
20597
+ * A promise which resolves to a single value of type :class:`OcaMediaSinkConnector`.
20519
20598
  */
20520
20599
  /**
20521
20600
  * Change the state of a given connector. Return status indicates the success of
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "aes70",
3
- "version": "2.0.2",
3
+ "version": "2.0.4",
4
4
  "description": "A controller library for the AES70 protocol.",
5
5
  "type": "module",
6
6
  "main": "src/index.js",
package/src/connection.js CHANGED
@@ -186,6 +186,12 @@ export class Connection extends Events {
186
186
  * Keepalive interval in seconds.
187
187
  */
188
188
  set_keepalive_interval(seconds) {
189
+ if (!(seconds <= 10)) {
190
+ console.warn(
191
+ 'Unusually large keepalive interval %o seconds. Confusion of ms vs. seconds?'
192
+ );
193
+ }
194
+
189
195
  const t = seconds * 1000;
190
196
 
191
197
  if (this._keepalive_interval_id !== null) {
@@ -1,7 +1,10 @@
1
1
  import { OcaCounter } from '../../types/OcaCounter';
2
2
  import { OcaCounterSet } from '../../types/OcaCounterSet';
3
3
  import { IOcaIODirection } from '../../types/OcaIODirection';
4
- import { OcaMediaStreamEndpoint } from '../../types/OcaMediaStreamEndpoint';
4
+ import {
5
+ IOcaMediaStreamEndpoint,
6
+ OcaMediaStreamEndpoint,
7
+ } from '../../types/OcaMediaStreamEndpoint';
5
8
  import { IOcaMediaStreamEndpointCommand } from '../../types/OcaMediaStreamEndpointCommand';
6
9
  import { IOcaMediaStreamEndpointState } from '../../types/OcaMediaStreamEndpointState';
7
10
  import { OcaMediaStreamEndpointStatus } from '../../types/OcaMediaStreamEndpointStatus';
@@ -375,11 +378,16 @@ export declare class OcaMediaTransportApplication extends OcaNetworkApplication
375
378
  * property **AlignmentLevelLimits**.
376
379
  *
377
380
  * @method OcaMediaTransportApplication#AddEndpoint
381
+ * @param {IOcaMediaStreamEndpoint} Endpoint
378
382
  * @param {IOcaMediaStreamEndpointState} InitialStatus
379
383
  *
380
- * @returns {Promise<void>}
384
+ * @returns {Promise<OcaMediaStreamEndpoint>}
385
+ * A promise which resolves to a single value of type :class:`OcaMediaStreamEndpoint`.
381
386
  */
382
- AddEndpoint(InitialStatus: IOcaMediaStreamEndpointState): Promise<void>;
387
+ AddEndpoint(
388
+ Endpoint: IOcaMediaStreamEndpoint,
389
+ InitialStatus: IOcaMediaStreamEndpointState
390
+ ): Promise<OcaMediaStreamEndpoint>;
383
391
 
384
392
  /**
385
393
  * Deletes a stream endpoint from this media transport application object.
@@ -99,7 +99,13 @@ export const OcaMediaTransportApplication = make_control_class(
99
99
  [OcaMap(OcaUint32, OcaMediaStreamEndpointStatus)],
100
100
  ],
101
101
  ['GetEndpointStatus', 3, 24, [OcaUint32], [OcaMediaStreamEndpointStatus]],
102
- ['AddEndpoint', 3, 25, [OcaMediaStreamEndpointState], []],
102
+ [
103
+ 'AddEndpoint',
104
+ 3,
105
+ 25,
106
+ [OcaMediaStreamEndpoint, OcaMediaStreamEndpointState],
107
+ [OcaMediaStreamEndpoint],
108
+ ],
103
109
  ['DeleteEndpoint', 3, 26, [OcaUint32], []],
104
110
  [
105
111
  'ApplyEndpointCommand',
@@ -427,9 +433,11 @@ export const OcaMediaTransportApplication = make_control_class(
427
433
  * property **AlignmentLevelLimits**.
428
434
  *
429
435
  * @method OcaMediaTransportApplication#AddEndpoint
436
+ * @param {IOcaMediaStreamEndpoint} Endpoint
430
437
  * @param {IOcaMediaStreamEndpointState} InitialStatus
431
438
  *
432
- * @returns {Promise<void>}
439
+ * @returns {Promise<OcaMediaStreamEndpoint>}
440
+ * A promise which resolves to a single value of type :class:`OcaMediaStreamEndpoint`.
433
441
  */
434
442
  /**
435
443
  * Deletes a stream endpoint from this media transport application object.
@@ -6,7 +6,10 @@ import {
6
6
  IOcaMediaConnectorStatus,
7
7
  OcaMediaConnectorStatus,
8
8
  } from '../../types/OcaMediaConnectorStatus';
9
- import { OcaMediaSinkConnector } from '../../types/OcaMediaSinkConnector';
9
+ import {
10
+ IOcaMediaSinkConnector,
11
+ OcaMediaSinkConnector,
12
+ } from '../../types/OcaMediaSinkConnector';
10
13
  import {
11
14
  IOcaMediaSourceConnector,
12
15
  OcaMediaSourceConnector,
@@ -267,10 +270,15 @@ export declare class OcaMediaTransportNetwork extends OcaApplicationNetwork {
267
270
  *
268
271
  * @method OcaMediaTransportNetwork#AddSinkConnector
269
272
  * @param {IOcaMediaConnectorStatus} InitialStatus
273
+ * @param {IOcaMediaSinkConnector} Connector
270
274
  *
271
- * @returns {Promise<void>}
275
+ * @returns {Promise<OcaMediaSinkConnector>}
276
+ * A promise which resolves to a single value of type :class:`OcaMediaSinkConnector`.
272
277
  */
273
- AddSinkConnector(InitialStatus: IOcaMediaConnectorStatus): Promise<void>;
278
+ AddSinkConnector(
279
+ InitialStatus: IOcaMediaConnectorStatus,
280
+ Connector: IOcaMediaSinkConnector
281
+ ): Promise<OcaMediaSinkConnector>;
274
282
 
275
283
  /**
276
284
  * Change the state of a given connector. Return status indicates the success
@@ -51,7 +51,13 @@ export const OcaMediaTransportNetwork = make_control_class(
51
51
  [OcaMediaSourceConnector, OcaMediaConnectorState],
52
52
  [],
53
53
  ],
54
- ['AddSinkConnector', 3, 16, [OcaMediaConnectorStatus], []],
54
+ [
55
+ 'AddSinkConnector',
56
+ 3,
57
+ 16,
58
+ [OcaMediaConnectorStatus, OcaMediaSinkConnector],
59
+ [OcaMediaSinkConnector],
60
+ ],
55
61
  ['ControlConnector', 3, 17, [OcaUint16, OcaMediaConnectorCommand], []],
56
62
  [
57
63
  'SetSourceConnectorPinMap',
@@ -239,8 +245,10 @@ export const OcaMediaTransportNetwork = make_control_class(
239
245
  *
240
246
  * @method OcaMediaTransportNetwork#AddSinkConnector
241
247
  * @param {IOcaMediaConnectorStatus} InitialStatus
248
+ * @param {IOcaMediaSinkConnector} Connector
242
249
  *
243
- * @returns {Promise<void>}
250
+ * @returns {Promise<OcaMediaSinkConnector>}
251
+ * A promise which resolves to a single value of type :class:`OcaMediaSinkConnector`.
244
252
  */
245
253
  /**
246
254
  * Change the state of a given connector. Return status indicates the success of
@@ -1,4 +1,11 @@
1
- import { OcaMediaTransportSession } from '../../types/OcaMediaTransportSession';
1
+ import {
2
+ IOcaMediaTransportSession,
3
+ OcaMediaTransportSession,
4
+ } from '../../types/OcaMediaTransportSession';
5
+ import {
6
+ IOcaMediaTransportSessionConnection,
7
+ OcaMediaTransportSessionConnection,
8
+ } from '../../types/OcaMediaTransportSessionConnection';
2
9
  import { OcaMediaTransportSessionStatus } from '../../types/OcaMediaTransportSessionStatus';
3
10
  import { PropertyEvent } from '../property_event';
4
11
  import { RemoteDevice } from '../remote_device';
@@ -66,9 +73,14 @@ export declare class OcaMediaTransportSessionAgent extends OcaAgent {
66
73
  * with session ID filled in.
67
74
  *
68
75
  * @method OcaMediaTransportSessionAgent#AddSession
69
- * @returns {Promise<void>}
76
+ * @param {IOcaMediaTransportSession} Session
77
+ *
78
+ * @returns {Promise<OcaMediaTransportSession>}
79
+ * A promise which resolves to a single value of type :class:`OcaMediaTransportSession`.
70
80
  */
71
- AddSession(): Promise<void>;
81
+ AddSession(
82
+ Session: IOcaMediaTransportSession
83
+ ): Promise<OcaMediaTransportSession>;
72
84
 
73
85
  /**
74
86
  * Configures a session.
@@ -170,10 +182,15 @@ export declare class OcaMediaTransportSessionAgent extends OcaAgent {
170
182
  *
171
183
  * @method OcaMediaTransportSessionAgent#AddConnection
172
184
  * @param {number} SessionID
185
+ * @param {IOcaMediaTransportSessionConnection} Connection
173
186
  *
174
- * @returns {Promise<void>}
187
+ * @returns {Promise<OcaMediaTransportSessionConnection>}
188
+ * A promise which resolves to a single value of type :class:`OcaMediaTransportSessionConnection`.
175
189
  */
176
- AddConnection(SessionID: number): Promise<void>;
190
+ AddConnection(
191
+ SessionID: number,
192
+ Connection: IOcaMediaTransportSessionConnection
193
+ ): Promise<OcaMediaTransportSessionConnection>;
177
194
 
178
195
  /**
179
196
  * Configures a connection.
@@ -3,6 +3,7 @@ import { OcaBoolean } from '../../OCP1/OcaBoolean.js';
3
3
  import { OcaList } from '../../OCP1/OcaList.js';
4
4
  import { OcaMap } from '../../OCP1/OcaMap.js';
5
5
  import { OcaMediaTransportSession } from '../../OCP1/OcaMediaTransportSession.js';
6
+ import { OcaMediaTransportSessionConnection } from '../../OCP1/OcaMediaTransportSessionConnection.js';
6
7
  import { OcaMediaTransportSessionStatus } from '../../OCP1/OcaMediaTransportSessionStatus.js';
7
8
  import { OcaString } from '../../OCP1/OcaString.js';
8
9
  import { OcaUint32 } from '../../OCP1/OcaUint32.js';
@@ -27,7 +28,13 @@ export const OcaMediaTransportSessionAgent = make_control_class(
27
28
  ['GetSessionType', 3, 1, [], [OcaString]],
28
29
  ['GetSessions', 3, 2, [], [OcaList(OcaMediaTransportSession)]],
29
30
  ['GetSession', 3, 3, [OcaUint32], [OcaMediaTransportSession]],
30
- ['AddSession', 3, 4, [], []],
31
+ [
32
+ 'AddSession',
33
+ 3,
34
+ 4,
35
+ [OcaMediaTransportSession],
36
+ [OcaMediaTransportSession],
37
+ ],
31
38
  ['ConfigureSession', 3, 5, [OcaUint32, OcaBlob, OcaString, OcaBlob], []],
32
39
  ['DeleteSession', 3, 6, [OcaUint32], []],
33
40
  ['ResetSession', 3, 7, [OcaUint32], []],
@@ -42,7 +49,13 @@ export const OcaMediaTransportSessionAgent = make_control_class(
42
49
  [OcaMap(OcaUint32, OcaMediaTransportSessionStatus)],
43
50
  ],
44
51
  ['GetSessionStatus', 3, 12, [OcaUint32], [OcaMediaTransportSessionStatus]],
45
- ['AddConnection', 3, 13, [OcaUint32], []],
52
+ [
53
+ 'AddConnection',
54
+ 3,
55
+ 13,
56
+ [OcaUint32, OcaMediaTransportSessionConnection],
57
+ [OcaMediaTransportSessionConnection],
58
+ ],
46
59
  [
47
60
  'ConfigureConnection',
48
61
  3,
@@ -100,7 +113,10 @@ export const OcaMediaTransportSessionAgent = make_control_class(
100
113
  * session ID filled in.
101
114
  *
102
115
  * @method OcaMediaTransportSessionAgent#AddSession
103
- * @returns {Promise<void>}
116
+ * @param {IOcaMediaTransportSession} Session
117
+ *
118
+ * @returns {Promise<OcaMediaTransportSession>}
119
+ * A promise which resolves to a single value of type :class:`OcaMediaTransportSession`.
104
120
  */
105
121
  /**
106
122
  * Configures a session.
@@ -180,8 +196,10 @@ export const OcaMediaTransportSessionAgent = make_control_class(
180
196
  *
181
197
  * @method OcaMediaTransportSessionAgent#AddConnection
182
198
  * @param {number} SessionID
199
+ * @param {IOcaMediaTransportSessionConnection} Connection
183
200
  *
184
- * @returns {Promise<void>}
201
+ * @returns {Promise<OcaMediaTransportSessionConnection>}
202
+ * A promise which resolves to a single value of type :class:`OcaMediaTransportSessionConnection`.
185
203
  */
186
204
  /**
187
205
  * Configures a connection.
@@ -149,9 +149,12 @@ export declare class OcaTaskManager extends OcaManager {
149
149
  * successfully created.
150
150
  *
151
151
  * @method OcaTaskManager#AddTask
152
- * @returns {Promise<void>}
152
+ * @param {IOcaTask} Task
153
+ *
154
+ * @returns {Promise<OcaTask>}
155
+ * A promise which resolves to a single value of type :class:`OcaTask`.
153
156
  */
154
- AddTask(): Promise<void>;
157
+ AddTask(Task: IOcaTask): Promise<OcaTask>;
155
158
 
156
159
  /**
157
160
  * Gets map of Tasks in the device. Return value indicates whether map was
@@ -53,7 +53,7 @@ export const OcaTaskManager = make_control_class(
53
53
  ['GetState', 3, 5, [], [OcaTaskManagerState]],
54
54
  ['GetTaskStatuses', 3, 6, [], [OcaTaskStatus]],
55
55
  ['GetTaskStatus', 3, 7, [OcaUint32], [OcaTaskStatus]],
56
- ['AddTask', 3, 8, [], []],
56
+ ['AddTask', 3, 8, [OcaTask], [OcaTask]],
57
57
  ['GetTasks', 3, 9, [], [OcaMap(OcaUint32, OcaTask)]],
58
58
  ['GetTask', 3, 10, [OcaUint32], [OcaTask]],
59
59
  ['SetTask', 3, 11, [OcaUint32, OcaTask], []],
@@ -138,7 +138,10 @@ export const OcaTaskManager = make_control_class(
138
138
  * successfully created.
139
139
  *
140
140
  * @method OcaTaskManager#AddTask
141
- * @returns {Promise<void>}
141
+ * @param {IOcaTask} Task
142
+ *
143
+ * @returns {Promise<OcaTask>}
144
+ * A promise which resolves to a single value of type :class:`OcaTask`.
142
145
  */
143
146
  /**
144
147
  * Gets map of Tasks in the device. Return value indicates whether map was
@@ -33,4 +33,13 @@ export interface PendingCommand {
33
33
  */
34
34
  export declare class ClientConnection extends Connection {
35
35
  constructor(options: IClientConnectionOptions);
36
+
37
+ /**
38
+ * Activates keepalive handling (using set_keepalive_interval) and waits for
39
+ * at least one keepalive packet to arrive. If no keepalive message is received,
40
+ * the connection will be closed and the returned promise will reject.
41
+ * @param {number} interval
42
+ * Keepalive interval in seconds.
43
+ */
44
+ wait_for_keepalive(interval: number): Promise<void>;
36
45
  }
@@ -241,9 +241,43 @@ export class ClientConnection extends Connection {
241
241
  if (!(o.time > 0)) {
242
242
  throw new Error('Bad keepalive timeout.');
243
243
  }
244
+ this.emit('keepalive', o);
244
245
  } else {
245
246
  throw new Error('Unexpected PDU');
246
247
  }
247
248
  }
248
249
  }
250
+
251
+ /**
252
+ * Activates keepalive handling (using set_keepalive_interval) and waits for
253
+ * at least one keepalive packet to arrive. If no keepalive message is received,
254
+ * the connection will be closed and the returned promise will reject.
255
+ * @param {number} interval
256
+ * Keepalive interval in seconds.
257
+ */
258
+ wait_for_keepalive(interval) {
259
+ return new Promise((resolve, reject) => {
260
+ const subscriptions = [];
261
+
262
+ const cleanup = () => {
263
+ subscriptions.forEach((cb) => cb());
264
+ subscriptions.length = 0;
265
+ };
266
+ subscriptions.push(
267
+ this.subscribe('error', (error) => {
268
+ reject(error);
269
+ cleanup();
270
+ }),
271
+ this.subscribe('close', () => {
272
+ reject(new CloseError());
273
+ cleanup();
274
+ }),
275
+ this.subscribe('keepalive', () => {
276
+ resolve();
277
+ cleanup();
278
+ })
279
+ );
280
+ this.set_keepalive_interval(interval);
281
+ });
282
+ }
249
283
  }
package/src/events.d.ts CHANGED
@@ -24,8 +24,19 @@ export class Events {
24
24
  */
25
25
  removeEventListener(name: string, cb: (...args) => void): void;
26
26
 
27
+ /**
28
+ * Unsubscribe from an event.
29
+ */
30
+ off(name: string, cb: (...args) => void): void;
31
+
27
32
  /**
28
33
  * Removes all event listeners.
29
34
  */
30
35
  removeAllEventListeners(): void;
36
+
37
+ /**
38
+ * Subscribe to an event. Returns a cleanup function which can be called to
39
+ * unsubscribe.
40
+ */
41
+ subscribe(name: string, cb: (...args) => void): () => void;
31
42
  }
package/src/events.js CHANGED
@@ -34,6 +34,10 @@ export class Events {
34
34
  * @param {Function} cb - Callback function.
35
35
  */
36
36
  on(name, cb) {
37
+ if (typeof name !== 'string')
38
+ throw new TypeError('Event name must be a string.');
39
+ if (typeof cb !== 'function')
40
+ throw new TypeError('Event handler must be a function.');
37
41
  let handlers = this.event_handlers.get(name);
38
42
 
39
43
  if (!handlers) {
@@ -63,10 +67,34 @@ export class Events {
63
67
  handlers.delete(cb);
64
68
  }
65
69
 
70
+ /**
71
+ * Removes an event handler.
72
+ *
73
+ * @param {strign} name
74
+ * @param {Function} cb
75
+ */
76
+ off(name, cb) {
77
+ this.removeEventListener(name, cb);
78
+ }
79
+
66
80
  /**
67
81
  * Removes all event listeners.
68
82
  */
69
83
  removeAllEventListeners() {
70
84
  this.event_handlers.clear();
71
85
  }
86
+
87
+ /**
88
+ *
89
+ * @param {string} name
90
+ * @param {Function} cb
91
+ */
92
+ subscribe(name, cb) {
93
+ this.on(name, cb);
94
+ return () => {
95
+ if (name === undefined) return;
96
+ this.off(name, cb);
97
+ name = undefined;
98
+ };
99
+ }
72
100
  }