Giter Club home page Giter Club logo

ee-ts's People

Contributors

aleclarson avatar renovate-bot avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

ee-ts's Issues

emit(...) as a generator?

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)

[RFC] off('*') should not affect "unhandlers"

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

Performance issue

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

Example from README doesn't work

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.

[RFC] Wildcard listeners

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:

  • the above API works with both on() and one()
  • the type signature of the listener is entirely optional
  • the return type is always void, because wildcard listeners cannot affect the return value of emit
  • wildcard listeners are always called asynchronously
  • off('*') won't affect wildcard listeners

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.