-
Notifications
You must be signed in to change notification settings - Fork 1
/
index.js
151 lines (135 loc) · 3.75 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
export const send = events => to => {
Object.keys(events).forEach(evt => {
events[evt].forEach(cb => to.on(evt, cb))
})
return to
}
export default function Eventbus(eventsList) {
eventsList = (eventsList && Object.assign({}, eventsList)) || {}
this.events = eventsList
/**
* Adds event listener
* @param {String} evt Event name
* @param {function} cb Callback
* @returns Emitter instance or instance with binded emitter
*/
this.on = function(evt, cb) {
if (evt in eventsList) {
eventsList[evt] = eventsList[evt].concat(cb)
} else {
eventsList[evt] = [cb]
}
return this
}
/**
* Adds event listener that will be removed after emit
* @param {String} evt Event name
* @param {function} cb Callback
* @returns Emitter instance or instance with binded emitter
*/
this.once = function(evt, cb) {
const self = this
let isCalled = false
const selfDesctructable = function() {
if (!isCalled) {
isCalled = true
cb.apply(cb, arguments)
}
// self.off(evt, selfDesctructable)
}
return self.on(evt, selfDesctructable)
}
/**
* Unbind event listener
* @param {String} evt Event name
* @param {function} cb Callback
* @returns Emitter instance or instance with binded emitter
*/
this.off = function(evt, cb) {
if (!(evt in eventsList)) return this
const idx = eventsList[evt].indexOf(cb)
if (idx !== -1) eventsList[evt].splice(idx, 1)
return this
}
/**
* Unbind all event listeners
* @returns Emitter instance or instance with binded emitter
*/
this.offAll = function() {
eventsList = {}
return this
}
/**
* Emits event
* @param {String} evt Event name
* @param {...*} arguments Arguments list
* @returns {void}
*/
this.emit = function(evt) {
if (!(evt in eventsList)) return
eventsList[evt].forEach(cb => cb.apply(cb, [].slice.call(arguments, 1)))
}
/**
* Adds list of event listeners
* @param {Object} events Object with listeners lists (`eventName: [cb1, cb2]`)
* @returns Instance
*/
this.onMany = function(events) {
return send(events)(this)
}
/**
* Removes list of event listeners
* @param {Object} events Object with listeners list (`eventName: [cb1, cb2]`)
* @returns Instance
*/
this.offMany = function(events) {
Object.keys(events).forEach(evt => {
events[evt].forEach(cb => {
this.off(evt, cb)
})
})
}
/**
* Shares own events with another bus and returns that bus
* @param {Eventbus} bus Target event bus
* @returns {Eventbus} Target event bus
*/
this.sendTo = send(eventsList)
/**
* Creates a copy of Eventbus
* @returns {Eventbus} Cloed event bus
*/
this.fork = () => new Eventbus(eventsList)
/**
* Merge two event buses into one
* @param {Eventbus} bus Event bus to merge with
* @returns {Eventbus} Event bus with both listeners
*/
this.merge = bus => this.fork().onMany(eventsList)
/**
* Adds `.on`, `.once`, `.off`, `.onMany`, `.offMany`, `.offAll` and `.emit` methods to object
* @param {Object} newInstance Target object
* @returns {Object} Target object
*/
this.injectTo = newInstance => {
newInstance.on = this.on
newInstance.off = this.off
newInstance.once = this.once
newInstance.emit = this.emit
newInstance.onMany = this.onMany
newInstance.offAll = this.offAll
newInstance.offMany = this.offMany
return newInstance
}
/**
* Adds `.on`, `.once` and `.off` methods to object
* @param {Object} newInstance Target object
* @returns {Object} Target object
*/
this.injectObserverTo = newInstance => {
newInstance.on = this.on
newInstance.off = this.off
newInstance.once = this.once
return newInstance
}
}