Skip to content

Commit

Permalink
refactor: rewrite entire function for readability (#21)
Browse files Browse the repository at this point in the history
  • Loading branch information
paulmelnikow authored and gr2m committed Apr 12, 2019
1 parent 60e2e53 commit 5d1ce65
Showing 1 changed file with 41 additions and 59 deletions.
100 changes: 41 additions & 59 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,85 +1,67 @@
'use strict'

function propagate(events, source, dest) {
if (arguments.length < 3) {
dest = source
source = events
events = undefined
}
function propagateKeyedEvents(keyedEventNames, source, dest) {
const keyedListeners = {}
Object.entries(keyedEventNames).forEach(([srcEventName, dstEventName]) => {
keyedListeners[srcEventName] = (...args) => {
dest.emit(dstEventName, ...args)
}
})

// events should be an array or object
const eventsIsObject = typeof events === 'object'
if (events && !eventsIsObject) events = [events]
Object.entries(keyedListeners).forEach(([srcEventName, listener]) => {
source.on(srcEventName, listener)
})

if (eventsIsObject) {
return explicitPropagate(events, source, dest)
return {
end() {
Object.entries(keyedListeners).forEach(([srcEventName, listener]) => {
source.removeListener(srcEventName, listener)
})
},
}
}

const shouldPropagate = eventName =>
events === undefined || events.includes(eventName)

function propagateAllEvents(source, dest) {
const oldEmit = source.emit

// Returns true if the event had listeners, false otherwise.
// https://nodejs.org/api/events.html#events_emitter_emit_eventname_args
source.emit = (eventName, ...args) => {
const oldEmitHadListeners = oldEmit.call(source, eventName, ...args)

let destEmitHadListeners = false
if (shouldPropagate(eventName)) {
destEmitHadListeners = dest.emit(eventName, ...args)
}

const destEmitHadListeners = dest.emit(eventName, ...args)
return oldEmitHadListeners || destEmitHadListeners
}

function end() {
source.emit = oldEmit
}

return {
end,
end() {
source.emit = oldEmit
},
}
}

module.exports = propagate

function explicitPropagate(events, source, dest) {
let eventsIn
let eventsOut
if (Array.isArray(events)) {
eventsIn = events
eventsOut = events
} else {
eventsIn = Object.keys(events)
eventsOut = eventsIn.map(function(key) {
return events[key]
})
}

const listeners = eventsOut.map(function(event) {
return function() {
const args = Array.prototype.slice.call(arguments)
args.unshift(event)
dest.emit.apply(dest, args)
}
})

listeners.forEach(register)

return {
end,
module.exports = function propagate(events, source, dest) {
if (arguments.length < 3) {
dest = source
source = events
events = undefined
}

function register(listener, i) {
source.on(eventsIn[i], listener)
if (events === undefined) {
return propagateAllEvents(source, dest)
}

function unregister(listener, i) {
source.removeListener(eventsIn[i], listener)
let keyedEventNames
if (Array.isArray(events)) {
keyedEventNames = {}
events.forEach(eventName => {
keyedEventNames[eventName] = eventName
})
} else if (typeof events === 'object') {
keyedEventNames = events
} else {
const eventName = events
keyedEventNames = { [eventName]: eventName }
}

function end() {
listeners.forEach(unregister)
}
return propagateKeyedEvents(keyedEventNames, source, dest)
}

0 comments on commit 5d1ce65

Please sign in to comment.