Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

EventEmitter to evt sample. #32

Open
UrielCh opened this issue Jul 16, 2022 · 8 comments
Open

EventEmitter to evt sample. #32

UrielCh opened this issue Jul 16, 2022 · 8 comments

Comments

@UrielCh
Copy link

UrielCh commented Jul 16, 2022

Hi,

can you provide conversion list from EventEmitter to Evt ?

should we extend Evt in ours class ?
is this.emit(type, parma) should be replace by a this.evt.push([type, param])
is obj.on('event', (params) => {do stuff}) become evtText.attach???
is obj.once('event', (params) => {do stuff}) become evtText.attachOnce???
and where is the detach ?

@garronej
Copy link
Owner

garronej commented Jul 16, 2022

Hi @UrielCh ,

should we extend Evt in ours class

You can if you want, here is the doc: https://docs.evt.land/extending_evt

is this.emit(type, parma) should be replace by a this.evt.push([type, param])

It depends,
If you want to have only one Evt instance that is a single bus for all your event type (like with EventEmitter) you can do:

import { Evt } from "evt";

//Equivalent of const eeSocket = new EventEmitter();
const evtSocket = Evt.create<
    | { type: "connect"; } 
    | { type: "disconnect"; data: { cause: "remote" | "local" }; }
    | { type: "error"; data: Error }
>();

//Equivalent of eeSocket.emit("disconnect", { "cause": "local" });
evtSocket.post({ "type": "disconnect", "data": { "cause": "local" });

//Equivalent of eeSocket.on("disconnect", data => { /* ... */ });
evtSocket.$attach(
       event => event.type !== "disconnect" ? [ event.data ] : null,
       data => { /*...*/ }
); 


//Equivalent of eeSocket.once("disconnect", data => { /* ... */ });
evtSocket.$attachOnce(
       event => event.type !== "disconnect" ? [ event.data ] : null,
       data => { /*...*/ }
); 

Or, if you think the above example is too verbose:

import { Evt, to } from "evt";

//Equivalent of const eeSocket = new EventEmitter();
const evtSocket = Evt.create<
    | [ "connect", void ]
    | [ "disconnect", { cause: "remote" | "local" } ]
    | ["error", Error ]
>();

//Equivalent of eeSocket.emit("disconnect", { "cause": "local" });
evtSocket.post([ "disconnect", { "cause": "local" }]);

//Equivalent of eeSocket.on("disconnect", data => { /* ... */ });
evtSocket.$attach(
       to("disconnect"),
       data => { /*...*/ }
); 


//Equivalent of eeSocket.once("disconnect", data => { /* ... */ });
evtSocket.$attachOnce(
       to("disconnect"),
       data => { /*...*/ }
); 

But Evt really shines when you have one instance of Evt by event type:

const evtConnect = Evt.create();
const evtDisconnect= Evt.create<{ cause: "local" | "remote"; }>();
const evtError = Evt.create<Error>();

//Equivalent of eeSocket.on("disconnect", data => { /* ... */ });
evtDisconnect.attach(
       data => { /*...*/ }
); 

//Equivalent of eeSocket.once("disconnect", data => { /* ... */ });
evtDisconnect.attachOnce(
       data => { /*...*/ }
); 

where is the detach

If you want a direct equivalent you can refer to this section of the doc

However, the recommended way to detach handlers is to use Ctx: example:

import { Evt } from "evt";

const ctx = Evt.newCtx();

evtSocket.$attach(
       event => event.type !== "disconnect" ? [ event.data ] : null,
       ctx,
       data => { /*...*/ }
); 


//Equivalent of eeSocket.once("disconnect", data => { /* ... */ });
evtSocket.$attachOnce(
       event => event.type !== "disconnect" ? [ event.data ] : null,
       ctx,
       data => { /*...*/ }
); 

// Detaches all handlers attached using ctx.
ctx.done();
evtSocket.$attach(
       to("disconnect"),
      ctx,
       data => { /*...*/ }
); 

evtSocket.$attachOnce(
       to("disconnect"),
       ctx,
       data => { /*...*/ }
); 
evtDisconnect.attach(
      ctx,
      data => { /*...*/ }
); 

evtDisconnect.attachOnce(
       ctx,
       data => { /*...*/ }
); 

Hope it helps.

You can have a look at the playground: https://stackblitz.com/edit/evt-playground?embed=1&file=index.ts&hideExplorer=1

@UrielCh
Copy link
Author

UrielCh commented Jul 16, 2022

in my case I have a single event bus per class.

so with evt, evtSocket.$attach will receves all event type, and will have to filter the correct type ?

for the event definition I'm already to my 3th implementation,
the first one was an:

interface {
  on("event1", (params: type) => void),
  off("event1", (params: type) => void),
  once("event1", (params: type) => void),
  on("event2", (params: type) => void),
  off("event2", (params: type) => void),
  once("event2", (params: type) => void),
}

the second one: see

export interface ProtocolEventsApi {
    "Accessibility.loadComplete" (params: Protocol.Accessibility.LoadCompleteEvent, sessionId?: string): void;
    "Accessibility.nodesUpdated" (params: Protocol.Accessibility.NodesUpdatedEvent, sessionId?: string): void;
    "Animation.animationCanceled" (params: Protocol.Animation.AnimationCanceledEvent, sessionId?: string): void;
...
}

the 3th one see:

export type ProtocolEventsApi = {
  "Accessibility.loadComplete": [ params: Protocol.Accessibility.LoadCompleteEvent, sessionId?: string ];
  "Accessibility.nodesUpdated": [ params: Protocol.Accessibility.NodesUpdatedEvent, sessionId?: string ];
  "Animation.animationCanceled": [ params: Protocol.Animation.AnimationCanceledEvent, sessionId?: string ];

And now I should change to a 4th... that will be somthink like:

export type ProtocolEventsApi  =
  | { type: "Accessibility.loadComplete"; data: [ params: Protocol.Accessibility.LoadCompleteEvent, sessionId?: string ] } 
  | { type: "Accessibility.nodesUpdated"; data:  [ params: Protocol.Accessibility.NodesUpdatedEvent, sessionId?: string ] }
  | { type: "Animation.animationCanceled"; data:  [ params: Protocol.Animation.AnimationCanceledEvent, sessionId?: string ] }

or

export type ProtocolEventsApi  =
  | { type: "Accessibility.loadComplete"; data: { params: Protocol.Accessibility.LoadCompleteEvent, sessionId?: string } }
  | { type: "Accessibility.nodesUpdated"; data:  { params: Protocol.Accessibility.NodesUpdatedEvent, sessionId?: string } }
  | { type: "Animation.animationCanceled"; data:  { params: Protocol.Animation.AnimationCanceledEvent, sessionId?: string } }

or

export type ProtocolEventsApi  =
  | { type: "Accessibility.loadComplete"; data: Protocol.Accessibility.LoadCompleteEvent, data2: string }
  | { type: "Accessibility.nodesUpdated"; data: Protocol.Accessibility.NodesUpdatedEvent, data2: string }
  | { type: "Animation.animationCanceled"; data:  Protocol.Animation.AnimationCanceledEvent, data2: string }

Switching from the 1st to the second, was ok, it removed the needs to duplicate all on, one, off, addlistener....
Switching from the 2nd to the 3th, removed the boilerplate :void

but switching to your implementation, mean adding 3 times mode boilerplate

And you should check http://semasim.com which is different from http://www.semasim.com...

et puis entre francophone dans le Typescript et la telephonie, on devrait pouvoir trouvez des interets commun.

@UrielCh
Copy link
Author

UrielCh commented Jul 16, 2022

in this page the syntax is more compact

export type ProtocolEventsApi  =
  | [ "Accessibility.loadComplete", Protocol.Accessibility.LoadCompleteEvent, string ]
  | [ "Accessibility.nodesUpdated", Protocol.Accessibility.NodesUpdatedEvent, string ]
  | [ "Animation.animationCanceled", Protocol.Animation.AnimationCanceledEvent, string ]

like this, the type declaration have the same size, but I'm not able to use this structure to type my params.

I can not do something like

function doNodesUpdated(typeof ProtocolEventsApi["Accessibility.nodesUpdated"]) {
// code
}

@garronej
Copy link
Owner

garronej commented Jul 16, 2022

Hi @UrielCh,

It would look something like this:

type ExtractArgs<key extends ProtocolEventsApi[0]> = [
    Extract< ProtocolEventsApi,[key, any, any]>[1],
    Extract< ProtocolEventsApi,[key, any, any]>[2],
];

function doNodesUpdated(...args: ExtractArgs<"Accessibility.nodesUpdated">) {
    // code
}

And you should check http://semasim.com/ which is different from http://www.semasim.com/...

Thanks for reporting this! Where did you find the faulty URL?

@UrielCh
Copy link
Author

UrielCh commented Jul 17, 2022

There is no faulty URL, but do not expect the URL given from a presentation not to be shortened by part of the audience.

nice ExtractArgs.

So this tuple approach is valid.

and since I do not want do make to mush change to the nodejs version, I will proxy the evt logic in some

  • on
  • once
  • off
  • [eventname] this is promise version of once.

Can you give me a project that use evt in deno and denoify to release a npm flavor ?

@garronej
Copy link
Owner

There is no faulty URL, but do not expect the URL given from a presentation not to be shortened by part of the audience.

Ah yes I see! Thanks for bringing it up!

Can you give me a project that use evt in deno and denoify to release a npm flavor ?

Denoify is for transpiling node to deno, not the other way around.
If you are writing your code for Deno, denoify won't let you publish on NPM.

The simplest example, that I use myself as reference whenever I want to publish on both NPM and Deno.land/x is tsafe.
You can copy paste the CI setup, it's completely portable.

You can also start from the setup of EVT itself. Note that EVT has three dependencies:
image

But they are transparently replaced by their deno build while transpiling because tsafe, run-exclusive and minimall-polyfill are all denoified packages:

image

This means that if your project uses EVT you'll just have to run npx denoify and voilà, everything will be transpiled sucesfully. Denoify will be able to find the deno distribution of EVT itself.

Now if your project have other dependencies, in this repo I sums up the differents approach you can implement to deal with dependencies that are not automatically denoifiable.

@garronej
Copy link
Owner

FYI @UrielCh, I updated the EventEmitter to Evt migration guide: https://docs.evt.land/migrating_from_events

@UrielCh
Copy link
Author

UrielCh commented Jul 19, 2022

Hi,

My migration is on hold due to issue

node_deno_shims looks not very active.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants