npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@api-platform/mercure

v2.0.0

Published

Mercure handler

Downloads

273

Readme

@api-platform/mercure

@api-platform/mercure is an EventSource wrapper that discovers a Mercure Hub according to the Link headers and handles subscriptions for you.

import mercure, { close } from "@api-platform/mercure";

const res = await mercure('https://localhost/authors/1', {
    onUpdate: (author) => console.log(author)
})

const author = res.then(res => res.json())

// Close if you need to 
history.onpushstate = function(e) {
    close('https://localhost/authors/1')
}

Assuming /authors/1 returned:

Link: <https://localhost/authors/1>; rel="self"
Link: <https://localhost/.well-known/mercure>; rel="mercure"

A new EventSource is created by subscribing to the topic https://localhost/authors/1 on the Hub https://localhost/.well-known/mercure.

Installation

npm install @api-platform/mercure

Usage

Use mercure like fetch:

import mercure, { close } from "@api-platform/mercure";

const res = await mercure('https://localhost/authors/1', {
    onUpdate: (author) => console.log(author)
})

const author = res.then(res => res.json())

Available options:

  • onError on EventSource error callback
  • EventSource to provide your own EventSource constructor
  • fetchFn to provide your own fetch function, it needs to return a response so that we can read headers
  • parse to read the payload yourself, JSON.parse by default. A parse error goes to onError
  • rawEvent to receive the whole MessageEvent instead of the payload

This can be used in conjunction with @api-platform/ld as the fetchFn.

Subscribing to a family of topics

A hub takes matchers rather than resources, and subscribe returns the function that ends the subscription:

import mercure, { hub } from "@api-platform/mercure";

const authors = hub('https://localhost/.well-known/mercure')

const unsubscribe = authors.subscribe({type: 'urlpattern', value: '/authors/:id'}, {
    onUpdate: (author) => console.log(author)
})

Every resource you then fetch with mercure() that this pattern covers joins that subscription instead of opening one of its own. The family belongs to the caller that asked for it: close(topic) on a covered resource removes that callback alone, and the subscription ends when you call the returned function.

The hub matches the pattern, so you also receive updates for topics you never fetched. URL Patterns support named groups (:id), wildcards (*), regular expression constraints and optional segments.

hub takes the connection options, headers, withCredentials and EventSource, because they belong to the stream and not to one subscription. subscribe(hubUrl, matcher, options) is the same call in one step.

Discovery

The rel="mercure" Link header can carry target attributes, and the client honours two of them. last-event-id is the identifier of the last event the publisher had dispatched when it generated the resource: it goes to the hub as a last_event_id query parameter, so an update published between that moment and the subscription is not lost. type is the Server-Sent Events event type the updates carry, and the client listens for it in addition to the default one.

One connection per hub

Resources served by the same hub share one connection. An SSE frame does not name a topic, so every callback registered on that hub receives every update, and the payload is what tells them apart. With JSON-LD, dispatch on @id.

The connection uses the options of the call that opened it. A later call on the same hub adds its callbacks, but it does not change the credentials, the headers or the EventSource implementation of a stream that already runs.

Examples

See our Tanstack query example or the source code of our home page.