# event-source-hook

> Easily intercept, modify, and simulate EventSource server-sent events.

Latest version **2.1.1** (published 2022-08-19) · ISC license · 0 weekly downloads

## Install

```sh
npm install event-source-hook
pnpm add event-source-hook
yarn add event-source-hook
bun add event-source-hook
```

## Health

**Score 25/100 (F)** — status: abandoned.

Positive: has types; no vulnerabilities; high quality score.

Warnings: low downloads; no esm support.

Negative: abandoned; low maintenance score.

## Facts

| | |
|---|---|
| Version | 2.1.1 |
| Published | 2022-08-19 |
| First published | 2022-07-15 |
| Weekly downloads | 0 |
| License | ISC |
| TypeScript types | bundled |
| Module format | CommonJS |
| Dependencies | 0 |
| Unpacked size | 28.4 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| GitHub stars | 1 |
| Author | Akwd22 - Eddy D. |
| Maintainers | akwd22 |
| Keywords | eventsource, hook, intercept, capture, sniff, spy, modify, edit, simulate, server, sent, message, events, sse, interceptor, capturer, sniffer, messages |

## Links

- npm: https://www.npmjs.com/package/event-source-hook
- Repository: https://github.com/Akwd22/event-source-hook
- Homepage: https://github.com/Akwd22/event-source-hook#readme
- Issues: https://github.com/Akwd22/event-source-hook/issues
- npm.io page: https://npm.io/package/event-source-hook

## Alternatives

- [ext-list](https://npm.io/package/ext-list.md) — 6.3M weekly downloads
- [@lexical/selection](https://npm.io/package/@lexical/selection.md) — 3.8M weekly downloads
- [@lexical/text](https://npm.io/package/@lexical/text.md) — 3.6M weekly downloads
- [@lexical/clipboard](https://npm.io/package/@lexical/clipboard.md) — 3.0M weekly downloads
- [@tiptap/extension-mention](https://npm.io/package/@tiptap/extension-mention.md) — 3.0M weekly downloads

## Recent versions

- 2.1.1 (latest) — 2022-08-19
- 2.1.0 — 2022-08-19
- 2.0.0 — 2022-08-16
- 1.0.1 — 2022-07-15
- 1.0.0 — 2022-07-15

## README

<div id="top"></div>

<!-- PROJECT TITLE -->
<br />
<div align="center">
  <h3 align="center">Event Source Hook</h3>
  
A library to easily intercept, modify, and simulate [EventSource](https://developer.mozilla.org/en-US/docs/Web/API/EventSource) server-sent events.

![build pass](https://img.shields.io/github/workflow/status/Akwd22/event-source-hook/Node.js%20CI)
![latest release](https://img.shields.io/npm/v/event-source-hook?label=release)
![types included](https://img.shields.io/npm/types/event-source-hook)
![total downloads](https://img.shields.io/npm/dt/event-source-hook)

</div>

<!-- TABLE OF CONTENTS -->
<details>
  <summary>Table of Contents</summary>
  <ol>
    <li><a href="#features">Features</a></li>
    <li><a href="#installation">Installation</a></li>
    <li><a href="#usage">Usage</a></li>
    <li><a href="#documentation">Documentation</a></li>
  </ol>
</details>

<!-- FEATURES -->

## Features

- [x] Intercept new connections
  - [x] Change connection URL
- [x] Intercept incoming events
  - [x] Modify events (data, origin, id, etc.)
  - [x] Block events
- [x] Simulate incoming events

<p align="right">(<a href="#top">back to top</a>)</p>

<!-- INSTALLATION -->

## Installation

**Install with npm**:

```sh
npm install --save event-source-hook
```

**Install in a browser**:

- download file [`browser/eshook.js`](https://github.com/Akwd22/event-source-hook/tree/main/browser) or [`browser/eshook.min.js`](https://github.com/Akwd22/event-source-hook/tree/main/browser)
- import it on your web page

_Note: these scripts are polyfilled, so it should run on every browser supporting `EventSource` API._

<p align="right">(<a href="#top">back to top</a>)</p>

<!-- USAGE -->

## Usage

⚠️ You must **load** and **enable** the library **first**, to be able to spoof native `EventSource` before other libraries or code instantiate it.

### 1. Enable the library after importing it

This applies the patch to the native `EventSource` constructor.

<details>
  <summary>View code</summary>
  <p>

**In Node**:

```js
import ESHook from "event-source-hook";
ESHook.enable();
```

**In a browser**:

```js
// In a browser, the library object is exposed globally.
ESHook.enable();
```

  </p>
</details>

### 2. Intercept new connections

Attach a hook function to listen each new opening connection. You can save `EventSource` instances for later use if you wish.

<details>
  <summary>View code</summary>
  <p>

```js
const connections = [];

ESHook.createHook = (eventSource) => {
  console.log("New connection:", eventSource);
  connections.push(eventSource);
};
```

  </p>
</details>

### 3. Change a connection URL

Attach a hook function to change a connection URL just before a new connection is established.

<details>
  <summary>View code</summary>
  <p>

```js
ESHook.urlHook = (url) => {
  if (url === "http://a-url") {
    url = "http://new-url";
  }

  return url;
};
```

  </p>
</details>

### 4. Simulate an event

You can simulate an incoming `MessageEvent`. It will be handled as if it were an genuine event received from the server.  
It is required to specify on which connection you want to simulate the event.

<details>
  <summary>View code</summary>
  <p>

```js
// Connection where the event should be received.
const eventSource = connections[0];
// Event type: can be anything.
const type = "message";
// Event options.
// See: https://developer.mozilla.org/en-US/docs/Web/API/MessageEvent/MessageEvent#options
const options = {
  data: { foo: "bar" },
  lastEventId: "id",
};

ESHook.simulate(eventSource, type, options);
```

_Note: the `simulated` property is set to `true` on the `MessageEvent` object. Thus, it is possible to detect the simulated event like in section 4 just below._

  </p>
</details>

### 5. Intercept, then modify or block an event

Attach a hook function to listen for incoming `MessageEvent` just before the native `EventSource` receives them.  
_Note: the hook function can be synchronous or asynchronous (see, below examples)._

You can modify all event object's properties (such as `data`, `lastEventId`) as it is mutable.

<details>
  <summary>View code (synchronous)</summary>
  <p>

Return the (modified) event or `null` to block the event.

```js
EventSourceHook.eventHook = (type, event, eventSource) => {
  // Block incoming events with type `message`.
  if (type === "message") {
    return null;
  }

  // Modify incoming events data from URL `https://test`.
  if (eventSource.url === "https://test") {
    const data = JSON.parse(event.data);
    data.foo = "new value";
    event.data = JSON.stringify(data);

    return event;
  }

  // Detect simulated events.
  if (event.simulated) {
    console.log("This event was simulated by the library.");
  }

  // Leave the other events as they are.
  return event;
};
```

  </p>
</details>

<details>
  <summary>View code (asynchronous)</summary>
  <p>

To make the hook function asynchronous, include the optional `result` callback parameter, and call it to return the (modified) event or `null` to block the event.

**Example with a promise**:

```js
EventSourceHook.eventHook = (type, event, eventSource, result) => {
  // Block incoming events with type `message`.
  if (type === "message") {
    result(null);
    return;
  }

  // Modify incoming events data from URL `http://test`.
  if (eventSource.url === "https://test") {
    fetchData().then((data) => {
      event.data = JSON.stringify(data);
      result(event);
    });

    return;
  }

  // Leave the other events as they are.
  result(event);
};
```

**Example with async/await**:

```js
EventSourceHook.eventHook = async (type, event, eventSource, result) => {
  const thing = await something();

  if (thing) {
    event.data = thing;
    result(event);
  } else {
    result(null);
  }
};
```

  </p>
</details>

### Reset hooks

You can disable hooks by setting `null`.

<details>
  <summary>View code</summary>
  <p>

```js
ESHook.urlHook = null;
ESHook.createHook = null;
ESHook.eventHook = null;
...
```

  </p>
</details>

<p align="right">(<a href="#top">back to top</a>)</p>

<!-- DOCUMENTATION -->

## Documentation

View [API docs](<https://github.com/Akwd22/event-source-hook/wiki/API-Documentation-(v2.1.0)>).

<p align="right">(<a href="#top">back to top</a>)</p>

---
_Source: https://npm.io/package/event-source-hook · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
