Coder Social home page Coder Social logo

Comments (6)

Morglod avatar Morglod commented on May 25, 2024 2

I think in this cases you could just pass some payload as arguments to distinguish this wildcard levels.

For example with DBs:

type DbInitEvent = {
   type: 'mysql',
   // mysql payload
} | {
   type: 'pg',
   // pg payload
};

emitter.on('db:init', e => {
   if (e.type === 'mysql') {
      // handle mysql
   }
   // etc
});

I mean you could move this abstractions somewhere else. It will be lighter, much more readable and maintainable.

Then also all logic around wildcards will disappear and there will be no need to optimize it 😄.

from tseep.

Morglod avatar Morglod commented on May 25, 2024 1

Hi! Thank you

tseep is highly optimized around emit so I can't change emit method to support wildcard calls.

I think I'll add wildcard later in core if there will be more issues about it.

Right now you could implement it like this in your project:

import { EventEmitter as Tseep, DefaultEventMap } from 'tseep';

export class EventEmitter<EventMap extends DefaultEventMap> extends Tseep<EventMap> {
    emitw(wildcard: string, ...args: any[]) {
       for (const ename of this.eventNames()) {
           // if ename extends wildcard
           this.emit(ename, ...args);
       }
    }
}

And check args with types like this:

type FilterKeys<ww extends string, EventKeys extends string> = ww extends `${infer E extends string}:*:${infer Rest extends string}` ?
        FilterKeys<Rest, Extract<EventKeys, `${E}:${string}`>> :
    ww extends `${infer E extends string}:*` ?
        Extract<EventKeys, `${E}:${string}`>
    : never;


// inside class
emitw<
    Wildcard extends string,
    Keys = FilterKeys<Wildcard, Extract<keyof EventMap, string>>
>(w: Wildcard, ...args: Keys extends keyof EventMap ? Parameters<EventMap[Keys]> : never) {
     for (const ename of this.eventNames()) {
           // if ename extends wildcard
           this.emit(ename, ...args);
     }
}

After all if you want to optimize it, you should have some special graph structure around event name list, so you could rid of loop and check on every call.

This graph should be updated with custom addListener / removeListener that overloads default methods.

For example DAWG graph structure. (Found js implementation as PTrie from https://github.com/mckoss/dawg).

Should be benchmarked anyway, because current DAWG implementation may be slower than just for loop & regex check every time.

from tseep.

Morglod avatar Morglod commented on May 25, 2024 1

As another question, is it also possible to order the execution of events, like async support or something like that?

If I understand you correctly, you want to wait for async listener to complete and only after that call next listener when emitting.
First of all it will significantly impact performance, so may be will be faster use classic event emitter.

I did not test it & did not benchmark it yet, but TaskCollection in tseep supports it by passing true to last constructor argument of TaskCollection.

You also should fork this package and update addListener and prependListener

TaskCollection is the thing that unrolls call loop so it calls array of functions as single function without loop.
Code generation for loop unroll is here

from tseep.

mustafa519 avatar mustafa519 commented on May 25, 2024 1

Oh, you literally implemented the logic in the issue already. I do appreciate that you shared detailed above, and so its types also. I'll try to add that logic by my own additions, thanks!

I think, I am not good enough to implement something like DAWG. Still it helped what you mean, even if I'd go for something simple like you mentioned regex etc.

IMHO, multi-level wildcard is kinda necessary in an emitter. Like:

// For instance we have three type of db that we watch
// db:mysql:error
// db:postgres:error
// db:redis:error
emitter.on('db:*:error', (e) =>
{
  writeErrorLog(e, 'db');
  fatal(e);
});

// or
emitter.on('db:*:init', (dbName) =>
{
  hasInitialized.dbs[dbName] = true;
});

// or a websocket event impl.
// ws:room:user --- 1...n (room id)
// ws:typing --- 1..n (user id)
// sse:notification:profile --- 1..n (user id)
// sse:notification:mail --- 1..n (user id)

emitter.on('sse:notification:*', ([firstWildcardParam], ...args) =>
{
  if (firstWildcardParam === 'mail')
  {
    const { sender, to, body, attachments ) = args[0];
    addQueue('smtp', { sender, to, body, attachments });
  }
});

I'm particularly excited about the prospect of leveraging this high-performance library for SSE and ws events.

I'll patiently await your implementation of wildcard support, or I may explore implementing it myself by forking the repository when the need arises by referencing your advice that you shared above in this issue.

Thank you for your prompt and detailed response.

from tseep.

mustafa519 avatar mustafa519 commented on May 25, 2024 1

Yeah, in this library if I inherit the event listener I can check in another one which is going to be optimized by default.

I haven't thought this. You led me to question on myself why I made the things more complex than it requires, lol.

I hope I'll present your art to the community when I release what I am building.

Thank you for the support.

from tseep.

Morglod avatar Morglod commented on May 25, 2024 1

Waiting for results! Wish you a good luck 🙌🏻

from tseep.

Related Issues (4)

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.