1 | import "core-js/modules/web.immediate.js";
|
2 | import deprecate from 'util-deprecate';
|
3 | import dedent from 'ts-dedent';
|
4 |
|
5 | const generateRandomId = () => {
|
6 |
|
7 | return Math.random().toString(16).slice(2);
|
8 | };
|
9 |
|
10 | export class Channel {
|
11 | constructor({
|
12 | transport,
|
13 | async = false
|
14 | } = {}) {
|
15 | this.isAsync = void 0;
|
16 | this.sender = generateRandomId();
|
17 | this.events = {};
|
18 | this.data = {};
|
19 | this.transport = void 0;
|
20 | this.addPeerListener = deprecate((eventName, listener) => {
|
21 | this.addListener(eventName, listener);
|
22 | }, dedent`
|
23 | channel.addPeerListener is deprecated
|
24 | `);
|
25 | this.isAsync = async;
|
26 |
|
27 | if (transport) {
|
28 | this.transport = transport;
|
29 | this.transport.setHandler(event => this.handleEvent(event));
|
30 | }
|
31 | }
|
32 |
|
33 | get hasTransport() {
|
34 | return !!this.transport;
|
35 | }
|
36 |
|
37 | addListener(eventName, listener) {
|
38 | this.events[eventName] = this.events[eventName] || [];
|
39 | this.events[eventName].push(listener);
|
40 | }
|
41 |
|
42 | emit(eventName, ...args) {
|
43 | const event = {
|
44 | type: eventName,
|
45 | args,
|
46 | from: this.sender
|
47 | };
|
48 | let options = {};
|
49 |
|
50 | if (args.length >= 1 && args[0] && args[0].options) {
|
51 | options = args[0].options;
|
52 | }
|
53 |
|
54 | const handler = () => {
|
55 | if (this.transport) {
|
56 | this.transport.send(event, options);
|
57 | }
|
58 |
|
59 | this.handleEvent(event);
|
60 | };
|
61 |
|
62 | if (this.isAsync) {
|
63 |
|
64 | setImmediate(handler);
|
65 | } else {
|
66 | handler();
|
67 | }
|
68 | }
|
69 |
|
70 | last(eventName) {
|
71 | return this.data[eventName];
|
72 | }
|
73 |
|
74 | eventNames() {
|
75 | return Object.keys(this.events);
|
76 | }
|
77 |
|
78 | listenerCount(eventName) {
|
79 | const listeners = this.listeners(eventName);
|
80 | return listeners ? listeners.length : 0;
|
81 | }
|
82 |
|
83 | listeners(eventName) {
|
84 | const listeners = this.events[eventName];
|
85 | return listeners || undefined;
|
86 | }
|
87 |
|
88 | once(eventName, listener) {
|
89 | const onceListener = this.onceListener(eventName, listener);
|
90 | this.addListener(eventName, onceListener);
|
91 | }
|
92 |
|
93 | removeAllListeners(eventName) {
|
94 | if (!eventName) {
|
95 | this.events = {};
|
96 | } else if (this.events[eventName]) {
|
97 | delete this.events[eventName];
|
98 | }
|
99 | }
|
100 |
|
101 | removeListener(eventName, listener) {
|
102 | const listeners = this.listeners(eventName);
|
103 |
|
104 | if (listeners) {
|
105 | this.events[eventName] = listeners.filter(l => l !== listener);
|
106 | }
|
107 | }
|
108 |
|
109 | on(eventName, listener) {
|
110 | this.addListener(eventName, listener);
|
111 | }
|
112 |
|
113 | off(eventName, listener) {
|
114 | this.removeListener(eventName, listener);
|
115 | }
|
116 |
|
117 | handleEvent(event) {
|
118 | const listeners = this.listeners(event.type);
|
119 |
|
120 | if (listeners && listeners.length) {
|
121 | listeners.forEach(fn => {
|
122 | fn.apply(event, event.args);
|
123 | });
|
124 | }
|
125 |
|
126 | this.data[event.type] = event.args;
|
127 | }
|
128 |
|
129 | onceListener(eventName, listener) {
|
130 | const onceListener = (...args) => {
|
131 | this.removeListener(eventName, onceListener);
|
132 | return listener(...args);
|
133 | };
|
134 |
|
135 | return onceListener;
|
136 | }
|
137 |
|
138 | }
|
139 | export default Channel; |
\ | No newline at end of file |