<commit_before># ts-events

A library for sending spontaneous events similar to Qt signal/slot or C# events. It replaces EventEmitter, and instead makes each event into a member which is its own little emitter.

# Features

* Each event is a member, and its own little event emitter. Because of this, you have a place for comments to document them. And adding handlers is no longer on string basis.
* For TypeScript users: made in TypeScript and type-safe. Typings are in ts-events.d.ts
* Synchronous, a-synchronous and queued events
* For a-synchronous events, you decide whether to use setImmediate(), setTimeout(, 0) or process.nextTick()
* Recursion-safe: sending events from event handlers is possible, endless loops are detected
* Attaching and detaching event handlers has clear semantics
* Attach handlers bound to a certain object, i.e. no need for .bind(this)
* Detach one handler, all handlers, or all handlers bound to a certain object

# Documentation

For class documentation, see ./doc/index.html

# Usage

## Event types

ts-event supports three event types: Synchronous, A-synchronous and Queued. Here is a comparison:

|Event Type|Handler Invocation|Condensable?|Comment|
| ------------- | ------------- | ------------- |
|Synchronous|directly, within the call to post()| no |
|A-synchronous|in the next Node.JS cycle| yes |
|Queued|when you flush the queue manually| yes |

In the table above, "condensable" means that you can choose to condense multiple sent events into one: e.g. for an a-synchronous event, you can opt that if it is sent more than once in a Node.JS cycle, the event handlers are invoked only once.

## Replacing EventEmitter

If you want EventEmitter-style events, then use SyncEvent. The handlers of SyncEvents are called directly when you emit the event.

JavaScript:

```javascript
var tsevents = require("../index");
var SyncEvent = tsevents.SyncEvent;

var Counter = (function () {
    function Counter() {
        /**
         * This event is called whenever the counter changes
         * @param n The counter value
         */
        this.evtChanged = new SyncEvent();
        /**
         * The counter value
         */
        this.n = 0;
    }
    /**
     * Increment counter by 1
     */
    Counter.prototype.inc = function () {
        this.n++;
        this.evtChanged.post(this.n);
    };
    return Counter;
})();

var ctr = new Counter();

// Attach a handler to the event
// Do this instead of ctr.on("changed", ...)
ctr.evtChanged.attach(function (n) {
    console.log("The counter changed to: " + n.toString(10));
});

ctr.inc();
// Here, the event handler is already called and you see a log line on the console
```

TypeScript:
```javascript
class Counter {
    /**
     * This event is called whenever the counter changes
     * @param n The counter value
     */
    public evtChanged: SyncEvent<number> = new SyncEvent<number>();
    /**
     * The counter value
     */
    public n: number = 0;
    /**
     * Increment counter by 1
     */
    public inc(): void {
        this.n++;
        this.evtChanged.post(this.n);
    }
}

var ctr = new Counter();

ctr.evtChanged.attach((n: number): void => {
    console.log("The counter changed to: " + n.toString(10));
});

ctr.inc();
// Here, the event handler is already called and you see a log line on the console
```<commit_msg>Minor documentation update (example more clear).<commit_after># ts-events

A library for sending spontaneous events similar to Qt signal/slot or C# events. It replaces EventEmitter, and instead makes each event into a member which is its own little emitter.

# Features

* Each event is a member, and its own little event emitter. Because of this, you have a place for comments to document them. And adding handlers is no longer on string basis.
* For TypeScript users: made in TypeScript and type-safe. Typings are in ts-events.d.ts
* Synchronous, a-synchronous and queued events
* For a-synchronous events, you decide whether to use setImmediate(), setTimeout(, 0) or process.nextTick()
* Recursion-safe: sending events from event handlers is possible, endless loops are detected
* Attaching and detaching event handlers has clear semantics
* Attach handlers bound to a certain object, i.e. no need for .bind(this)
* Detach one handler, all handlers, or all handlers bound to a certain object

# Documentation

For class documentation, see ./doc/index.html

# Usage

## Event types

ts-event supports three event types: Synchronous, A-synchronous and Queued. Here is a comparison:

|Event Type|Handler Invocation|Condensable?|Comment|
| ------------- | ------------- | ------------- |
|Synchronous|directly, within the call to post()| no |
|A-synchronous|in the next Node.JS cycle| yes |
|Queued|when you flush the queue manually| yes |

In the table above, "condensable" means that you can choose to condense multiple sent events into one: e.g. for an a-synchronous event, you can opt that if it is sent more than once in a Node.JS cycle, the event handlers are invoked only once.

## Replacing EventEmitter

If you want EventEmitter-style events, then use SyncEvent. The handlers of SyncEvents are called directly when you emit the event.


```javascript
var tsevents = require("../index");
var SyncEvent = tsevents.SyncEvent;

var myEvent = new SyncEvent();

myEvent.attach(function(s) {
    console.log(s);
});

myEvent.post("hi!");
// at this point, "hi!" was already printed on the console

```

Typically you use events as members in a class, instead of extending EventEmitter:

```javascript
var tsevents = require("../index");
var SyncEvent = tsevents.SyncEvent;

function Counter() {
    /**
     * This event is called whenever the counter changes
     * @param n The counter value
     */
    this.evtChanged = new SyncEvent();
    /**
     * The counter value
     */
    this.n = 0;
}
/**
 * Increment counter by 1
 */
Counter.prototype.inc = function () {
    this.n++;
    this.evtChanged.post(this.n);
};

var ctr = new Counter();

// Attach a handler to the event
// Do this instead of ctr.on("changed", ...)
ctr.evtChanged.attach(function (n) {
    console.log("The counter changed to: " + n.toString(10));
});

ctr.inc();
// Here, the event handler is already called and you see a log line on the console
```

As you can see, each event is its own little emitter.


For TypeScript users:

```javascript
class Counter {
    /**
     * This event is called whenever the counter changes
     * @param n The counter value
     */
    public evtChanged: SyncEvent<number> = new SyncEvent<number>();
    /**
     * The counter value
     */
    public n: number = 0;
    /**
     * Increment counter by 1
     */
    public inc(): void {
        this.n++;
        this.evtChanged.post(this.n);
    }
}

var ctr = new Counter();

ctr.evtChanged.attach((n: number): void => {
    console.log("The counter changed to: " + n.toString(10));
});

ctr.inc();
// Here, the event handler is already called and you see a log line on the console
```
{'fraction_non_alphanumeric': 0.11082547843473294, 'fraction_numerical': 0.002570694087403599, 'mean_word_length': 3.1560830860534126, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2155664', 'n_tokens_mistral': 2042, 'n_tokens_neox': 1987, 'n_words': 851}