glot
Version:
EventEmitter with Promises and Generators
204 lines (147 loc) • 5.47 kB
JavaScript
'use strict'
let map = new WeakMap();
let internal = (obj) => {
map.has(obj) || map.set(obj, {});
return map.get(obj);
}
class Glot {
constructor(){
for(let type of ['functions', 'generators', 'promises']) {
internal(this)[type] = new Map();
internal(this)['onces_' + type] = new Map();
internal(this)['onces_wildcards_' + type] = new Map();
internal(this)['wildcards_' + type] = new Map();
}
}
off(evt) {
internal(this).functions.delete(evt);
internal(this).promises.delete(evt);
internal(this).generators.delete(evt);
internal(this).onces_functions.delete(evt);
internal(this).onces_generators.delete(evt);
internal(this).onces_promisess.delete(evt);
}
on(evt, listener){
if(evt == '*') {
if(isPromise(listener)) {
internal(this).wildcards_promises.has(listener) || internal(this).wildcards_promises.set(listener);
return;
}
if(isGenerator(listener)){
internal(this).wildcards_generators.has(listener) || internal(this).wildcards_generators.set(listener);
return;
}
internal(this).wildcards_functions.has(listener) || internal(this).wildcards_functions.set(listener);
return;
}
if(isPromise(listener)) {
internal(this).promises.has(evt) || internal(this).promises.set(evt, new Map());
internal(this).promises.get(evt).set(listener);
return;
}
if(isGenerator(listener)){
internal(this).generators.has(evt) || internal(this).generators.set(evt, new Map());
internal(this).generators.get(evt).set(listener);
return;
}
internal(this).functions.has(evt) || internal(this).functions.set(evt, new Map());
internal(this).functions.get(evt).set(listener);
}
once(evt, listener){
if(evt == '*') {
if(isPromise(listener)) {
internal(this).onces_wildcards_promises.has(listener) || internal(this).onces_wildcards_promises.set(listener);
return;
}
if(isGenerator(listener)){
internal(this).onces_wildcards_generators.has(listener) || internal(this).onces_wildcards_generators.set(listener);
return;
}
internal(this).onces_wildcards_functions.has(listener) || internal(this).onces_wildcards_functions.set(listener);
return;
}
if(isPromise(listener)) {
internal(this).onces_promises.has(evt) || internal(this).onces_promises.set(evt, new Map());
internal(this).onces_promises.get(evt).set(listener);
return;
}
if(isGenerator(listener)){
internal(this).onces_generators.has(evt) || internal(this).onces_generators.set(evt, new Map());
internal(this).onces_generators.get(evt).set(listener);
return;
}
internal(this).onces_functions.has(evt) || internal(this).onces_functions.set(evt, new Map());
internal(this).onces_functions.get(evt).set(listener);
}
emit(evt, ...args){
if(args.length === 1) args = args[0];
for(let [listener] of internal(this).functions.get(evt) || []) {
listener(args);
}
for(let [listener] of internal(this).onces_functions.get(evt) || []) {
internal(this).onces_functions.get(evt).delete(listener);
listener(args);
}
for(let listener of internal(this).wildcards_functions.keys()|| []) {
listener(evt, args);
}
for(let listener of internal(this).onces_wildcards_functions.keys()|| []) {
internal(this).onces_wildcards_functions.delete(listener);
listener(evt, args);
}
}
pmit(evt, ...args){
if(args.length === 1) args = args[0];
return new Promise((resolve, reject) => {
let promises = [];
for(let [listener] of internal(this).promises.get(evt) || []) {
promises.push(listener(args));
}
for(let [listener] of internal(this).onces_promises.get(evt) || []) {
promises.push(listener(args));
internal(this).onces_promises.get(evt).delete(listener);
}
for(let listener of internal(this).wildcards_promises.keys()|| []) {
promises.push(listener(evt, args));
}
if(!promises.length) reject('No Listeners');
Promise.all(promises).then((data) => {
resolve(data)
}).catch((err) => reject(err));
});
}
gmit(evt, ...args){
if(args.length === 1) args = args[0];
return function* (){
let results = [];
try {
for(let [listener] of internal(this).generators.get(evt) || []) {
results.push(yield listener(args));
}
for(let [listener] of internal(this).onces_generators.get(evt) || []) {
internal(this).onces_generators.get(evt).delete(listener);
results.push(yield listener(args));
}
for(let listener of internal(this).wildcards_generators.keys() || []) {
results.push(yield listener(evt, args));
}
for(let listener of internal(this).onces_wildcards_generators.keys() || []) {
internal(this).onces_wildcards_generators.delete(listener);
results.push(yield listener(evt, args));
}
} catch(err) {
console.log(err.stack);
}
return results;
}.bind(this);
}
}
function isPromise(listener){
let str = listener.toString();
//promise/.test(str) is used for transpiled code
return /return new Promise/.test(str) || /promise/.test(str);
}
function isGenerator(listener){
return listener instanceof (function*() {}).constructor;
}
module.exports = Glot;