aleclarson / ee-ts Goto Github PK
View Code? Open in Web Editor NEWType-safe, isomorphic event emitters
License: MIT License
Type-safe, isomorphic event emitters
License: MIT License
So I was thinking about events with multiple listeners, and I have a use case where I need the results back from all of them
I'm wondering what you think about turning the emit
result into an Iterable<EventOut<T,K>>
and making it a generator function.
Either that, or make a second emit
that does that (emitWithResults
?). (since, it's pretty much a breaking change otherwise)
Calling EE.unhandle
twice on the same listener for the same event key makes it so neither is ever called.
Should "unhandlers" only be removable by explicitly passing them to off
?
let ee = new EE<Events>
let fn = EE.unhandle('error', (error) => {
throw error
})
// Current behavior
ee.off('*')
ee.emit('error', new Error('test')) // nothing happens
First, thanks for your project. This library is fabulous for TypeScript as a robust strong-typed event emitter, I doesn't find any other library can do this so well.
However, I found the performance is an issue which cannot be neglected in this library. I profile some EventEmitter libraries:
const Benchmark = require('benchmark')
const EETS = require('ee-ts/lib/ee').EventEmitter
const EE3 = require('eventemitter3')
const FE = require("@foxify/events").default
let TMP = ''
function dummyFn(x) {
TMP = x
}
class KlsOnXXX {
run() {
this.onHello('hello')
}
}
class KlsEETS extends EETS {
run() {
this.emit('hello', 'hello')
}
}
class KlsEE3 extends EE3 {
run () {
this.emit('hello', 'hello')
}
}
class KlsFE extends FE {
run () {
this.emit('hello', 'hello')
}
}
const kls_onxxx = new KlsOnXXX()
const kls_eets = new KlsEETS()
const kls_ee3 = new KlsEE3()
const kls_fe = new KlsFE()
kls_onxxx.onHello = function (ev) { dummyFn(ev) }
kls_eets.on('hello', function (ev) { dummyFn(ev) } )
kls_ee3.on('hello', function (ev) { dummyFn(ev) } )
kls_fe.on('hello', function (ev) { dummyFn(ev) } )
var suite = new Benchmark.Suite
suite
.add('onXXX', function () {
kls_onxxx.run()
})
.add('ee-ts', function () {
kls_eets.run()
})
.add('ee3', function () {
kls_ee3.run()
})
.add('fe', function () {
kls_fe.run()
})
.on('cycle', function(event) {
console.log(String(event.target));
})
.on('complete', function() {
console.log('Fastest is ' + this.filter('fastest').map('name'));
})
.run({
'async': false, // https://benchmarkjs.com/docs#options_async
'delay': 1
});
And the result is astonishing...
onXXX x 193,150,752 ops/sec ±4.00% (88 runs sampled)
ee-ts x 1,732,183 ops/sec ±3.64% (77 runs sampled)
ee3 x 52,713,790 ops/sec ±1.11% (89 runs sampled)
fe x 122,749,677 ops/sec ±0.55% (89 runs sampled)
Fastest is onXXX
Hello!
import { EventEmitter as EE } from 'ee-ts'
type User = { name: string }
// All possible events must be explicitly defined as methods here.
// The return type can be non-void because the `emit` method returns the last non-void value.
// The return type can never be required, because `void` is implicitly added to every event.
interface Events {
login(user: User): void
logout(): string
}
// Make your subclass generic to let users add their own events.
class App<T = {}> extends EE<T & Events> {
foo() {
this.emit('logout');
}
}
This code actually produces this error:
Argument of type '[]' is not assignable to parameter of type 'In<(T & Events)["logout"]>'.
Removing T
fixes the problem:
class App extends EE<Events> {
foo() {
this.emit('logout');
}
}
Seems like TypeScript can't infer argument types in type In<T> = T extends (...args: infer U) => any ? U : []
from generic type.
Currently, using EE.unhandle
triggers an _onEventHandled
method call. Is this the desired behavior?
Proposal: Add a way to listen to all events with a single listener.
interface Events {
foo(): void
bar(x: number, y: number): number
}
let ee = new EE<Events>()
let fn = ee.on((type: "foo" | "bar", args: [] | [number, number]): void => {
if (type == 'foo') {
/* `args` should be narrowed to `[]` */
}
})
ee.off(fn)
Notes:
on()
and one()
void
, because wildcard listeners cannot affect the return value of emit
off('*')
won't affect wildcard listenersA declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.