mgraph.events
Version:
Modern eventing library for Node.js and browsers
63 lines (56 loc) • 1.73 kB
JavaScript
// index.js
export default function eventify(subject) {
if (!subject) {
throw new Error('Eventify cannot use a falsy object as events subject');
}
for (const prop of ['on', 'off', 'fire']) {
if (Object.prototype.hasOwnProperty.call(subject, prop)) {
throw new Error(`Subject already has property '${prop}'`);
}
}
// Use a Map to store event listeners:
const events = new Map();
subject.on = function (eventName, callback, ctx) {
if (typeof callback !== 'function') {
throw new Error('Callback is expected to be a function');
}
if (!events.has(eventName)) {
events.set(eventName, []);
}
events.get(eventName).push({ callback, ctx });
return subject;
};
subject.off = function (eventName, callback) {
// Remove all events if eventName is undefined:
if (eventName === undefined) {
events.clear();
return subject;
}
if (events.has(eventName)) {
// Remove all handlers for this event if callback is not a function:
if (typeof callback !== 'function') {
events.delete(eventName);
} else {
const filtered = events.get(eventName).filter(
handler => handler.callback !== callback
);
if (filtered.length) {
events.set(eventName, filtered);
} else {
events.delete(eventName);
}
}
}
return subject;
};
subject.fire = function (eventName, ...args) {
const handlers = events.get(eventName);
if (handlers) {
for (const { callback, ctx } of handlers) {
callback.apply(ctx, args);
}
}
return subject;
};
return subject;
}