# Overview

## `EventEmitter` comparison

Let us consider this example, use of `EventEmitter`:

```typescript
import { EventEmitter } from "events";

const eventEmitter = new EventEmitter();

eventEmitter.on("text", text => console.log(text));
eventEmitter.once("time", time => console.log(time));

eventEmitter.emit("text", "hi!"); //Prints "hi!"
eventEmitter.emit("time", 123); //Prints "123"
eventEmitter.emit("time", 1234); //Prints nothing ( once )
```

In EVT the recommended approach is to give every event it's `Evt` instance. Translation of the example:

```typescript
import { Evt } from "evt";
//Or import { Evt } from "https://evt.land/x/evt/mod.ts" on deno

const evtText = Evt.create<string>();
const evtTime = Evt.create<number>();

evtText.attach(text => console.log(text));
evtTime.attachOnce(time => console.log(time));

evtText.post("hi!");
evtTime.post(123);
evtTime.post(1234);
```

However, the traditional approach that consists of gathering all the events in a single bus is also an option.

Note: Due to [a current TypeScript limitation](https://github.com/microsoft/TypeScript/issues/36735) the `.attach()` methods need to be prefixed with `$` when used with fλ ( `to` in this case) operators but `evt.$attach*()` are actually just aliases to the corresponding `evt.attach*()` methods.

```typescript
import { Evt, to } from "evt";

const evt = Evt.create<
    [ "text",  string ] | 
    [ "time",  number ]
>();

evt.$attach(to("text"), text => console.log(text));
evt.$attachOnce(to("time"), time => console.log(time));

evt.post(["text", "hi!"]);
evt.post(["time", 123]);
evt.post(["time", 1234]);
```

[**Run the example**](https://stackblitz.com/edit/evt-honvv3?embed=1\&file=index.ts\&hideExplorer=1)

## RxJS comparison

### "Get started" examples.

Here is a translations of [the examples provided as an overview](https://rxjs-dev.firebaseapp.com/guide/overview#values) on the RxJS website.

```typescript
import { fromEvent } from "rxjs";
import { throttleTime, map, scan } from "rxjs/operators";

fromEvent(document, "click")
  .pipe(
      throttleTime(1000),
      map(event => event.clientX), // (TS: clientX does not exsist on type Event)
      scan((count, clientX) => count + clientX, 0)
  )
  .subscribe(count => console.log(count))
  ;

/* ------------------------------ */

import { Evt, throttleTime } from "evt";

Evt.from(document, "click")
    .pipe(
        throttleTime(1000),
        event => [ event.clientX ],
        [(clientX, count) => [ count + clientX ], 0]
    )
    .attach(count => console.log(count))
    ;
```

\*\*\*\*[**Run the example**](https://stackblitz.com/edit/evt-q772em?embed=1\&file=index.ts\&hideExplorer=1)

### RxJS operators vs EVT operator

Unlike [RxJS operators](https://rxjs-dev.firebaseapp.com/guide/operators) that return `Observable` EVT operators are function build using native language features, no by composing other pre-existing operators or instantiating any particular class.

Consider that we have an emitter for this data type:

```typescript
type Data = {
    type: "TEXT";
    text: string;
} | {
    type: "AGE";
    age: number;
};
```

We want to get a `Promise<string>` that resolves with the next text event.

```typescript
import { Subject } from "rxjs";
import { filter, first, map } from "rxjs/operators";

const subject = new Subject<Data>();

const prText = subject
    .pipe(
        filter(
            (data): data is Extract<Data, { type: "TEXT" }> => 
                data.type === "TEXT"
        ),
        first(),
        map(data => data.text) 
    )
    .toPromise()
    ;

/* ---------------------------------------------------------------- */

import { Evt } from "evt";

const evt = new Evt<Data>();

const prText = evt.waitFor(
    data => data.type !== "TEXT" ? 
        null : [data.text] 
);
```

\*\*\*\*[**Run the example**](https://stackblitz.com/edit/evt-795plc?embed=1\&file=index.ts\&hideExplorer=1)\*\*\*\*

Let us consider another example involving state encapsulation. Here we want to accumulate all texts events until `"STOP"`

```typescript
import { Subject } from "rxjs";
import { map, filter, takeWhile, scan } from "rxjs/operators";

const subject = new Subject<Data>();

subject
    .pipe(
        filter(
            (data): data is Extract<Data, { type: "TEXT" }> => 
                data.type === "TEXT"
        ), 
        map(data=> data.text),
        takeWhile(text => text !== "STOP"),
        scan((prev, text) => `${prev} ${text}`, "=>")
    )
    .subscribe(str => console.log(str))
    ;

/* ---------------------------------------------------------------- */

import { Evt } from "evt";

const evtData = new Evt<Data>();

evtData.$attach(
    [
        (data, prev) =>
            data.type !== "TEXT" ?
                null :
                data.text === "STOP" ?
                    "DETACH" :
                    [`${prev} ${data.text}`]
        ,
        "=>"
    ], //<= Stateful fλ operator 
    str => console.log(str)
);
```

\*\*\*\*[**Run the example**](https://stackblitz.com/edit/evt-xuutfw?embed=1\&file=index.ts\&hideExplorer=1)\*\*\*\*

## Where to start

The API reference documentation is full of runnable examples that should get you started in no time.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.evt.land/v1/overview.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
