Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/romainlanz/adonis-mercure

Mercure Provider - Real-time Made Easy
https://github.com/romainlanz/adonis-mercure

adonisjs mercure real-time server-sent-events

Last synced: 2 months ago
JSON representation

Mercure Provider - Real-time Made Easy

Awesome Lists containing this project

README

        


@setten/mercure


Download
Version
License

`@setten/mercure` is a [Mercure](https://mercure.rocks) client for [AdonisJS](https://adonisjs.com/).

Mercure allows you to use [Server Sent Events](https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events) to push data to your clients using Http.

> **Note**
>
> You must have a [Mercure Hub instance running](https://mercure.rocks/docs/hub/install).
---

## Getting Started

This package is available in the npm registry.

```bash
npm install @setten/mercure
```

Next, configure the package by running the following command.

```bash
node ace configure @setten/mercure
```

and... Voilà!

### Configuration

You have to configure the package before you can use it.
The configuration is stored in the `config/mercure.ts` file.

* `endpoint`: The endpoint of the Mercure Hub.
* `adminToken`: The JWT created to authenticate as an admin of the Mercure Hub.
* `jwt.alg`: The algorithm used to sign the JWT - should correlate to Mercure Hub configuration.
* `jwt.secret`: The secret used to sign the JWT - should correlate to Mercure Hub configuration.

Note that the `adminToken` must be generated using the same `alg` and `secret` used in the Mercure Hub with the following payload.

```json
{
"mercure": {
"publish": [
"*"
]
}
}
```

For example, given the secret of `ChangeMe` and the algorithm of `HS256`, the JWT would be:

```
eyJhbGciOiJIUzI1NiJ9.eyJtZXJjdXJlIjp7InB1Ymxpc2giOlsiKiJdfX0.mx2ROlYlE1rp7udoDy-WCdnpLdPuKWzDxoBJXGMK4OE
```

## Usage

The Mercure Provider gives you access to two classes.

* `Update`: This class is used to publish updates to the hub.
* `Token`: This class is used to generate a token for authentication.

You can easily send an update to the hub using the `Update.send` method.

```ts
import { Update } from '@ioc:Setten/Mercure';

Update.send('/users/1', { ... });
```

The `send` method takes three arguments.

* `topic`: The topic to publish the update to.
* `data`: The data to publish.
* `isPrivate`: Whether the update is private or not.

More information on the topic and data arguments can be found in the [Mercure documentation](https://mercure.rocks/spec#publication).

### Frontend

The frontend can listen to changes using the standard [`EventSource` web interface](https://developer.mozilla.org/en-US/docs/Web/API/EventSource).

```js
const url = new URL(/* Mercure Endpoint */)
url.searchParams.append('topic', '/users/1')

const eventSource = new EventSource(url)
eventSource.onmessage = (event) => {
console.log(event.data)
}
```

More information on the topic can be found in the [Mercure documentation](https://mercure.rocks/docs/getting-started).

### Authentication

You may want to send private messages. To do so, you need to set the update as private using the third argument of the `Update.send` method, and authenticate the client using a JWT stored in a cookie.

You can generate the JWT using the `Token` class.

```ts
import { Token } from '@ioc:Setten/Mercure';

// Generating the token allowing the user to listen on private events
// send to `/users/1`.
const token = await Token.generate({
subscribe: ['/users/1'],
})

// Adding the token in a cookie name `mercureAuthorization`.
response.append(
'set-cookie',
`mercureAuthorization=${token}; Domain=.setten.io; Path=/.well-known/mercure; HttpOnly`
)
```

The cookie must be named `mercureAuthorization` and must be not encoded by AdonisJS (you cannot use `response.cookie()` at the moment for that reason).

Note that the Mercure Hub must run on the same domain as the client since cookies cannot be shared cross-domain.

Once done, you have to change your client's connection to use cookies.

```js
const eventSource = new EventSource(url, { withCredentials: true })
```

More information on the topic can be found in the [Mercure documentation](https://mercure.rocks/spec#authorization).