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 🙏

© 2024 – Pkg Stats / Ryan Hefner

mercurius-hit-map

v2.0.0

Published

Find out which GQL resolvers are used

Downloads

138

Readme

mercurius-hit-map

Build Status npm JavaScript Style Guide

Find out which resolvers are used.

Versioning a GraphQL API is a hard task. You have to be sure that no one is using a resolver that you are going to remove and you have deprecated 42 months ago.

To know it you can dig into your logs and find out which resolvers are used, hoping all your team members have enabled the logs OR you can use this plugin that does it for you.

Install

npm install mercurius-hit-map

Compatibility

| Plugin version | Fastify version | | ------------- |:---------------:| | ^2.0.0 | ^5.0.0 | | ^1.0.0 | ^4.0.0 |

Usage

Spin up your GQL server as you do usally and add the plugin. It will add an async function getHitMap() decorator to the Fastify instance.

const app = Fastify()
app.register(mercurius, {
  schema,
  resolvers,
  subscription // it is supported too!
})

app.register(require('mercurius-hit-map'))

app.get('/hit', async () => {
  const hitMap = await app.getHitMap()
  return hitMap
})

Now you can:

  • call the /hit your server's endpoint and get the hit map
  • configure a cron job to call the endpoint and store the hit map in a database
  • configure an interval to log the hit map
  • anything you want that gives you the hit map!

The hit map is a JSON object that maps the application's GQL Schema with the number of times that resolver has been called.

By default the hit map is an in-memory object that is reset every time you restart the server.

Given the following schema:

  type User {
    nick: String
    name: String
  }

  type Query {
    hello: User
  }

  type Mutation {
    updateName(name: String): User
  }

  type Subscription {
    userChanges: User
  }

The hit map will looks like:

{
  "Query": {
    "hello": 4
  },
  "Mutation": {
    "updateName": 1
  },
  "Subscription": {
    "userChanges": 1
  },
  "User": {
    "nick": 1,
    "name": 5
  }
}

Options

The plugin accepts an options object as second parameter.

store

To store the hit map in a custom datasource you can set the store option. It must be a factory function that accepts an EventEmitter as argument and returns an object with the readHits property.

The event emitter is used to notify two events:

  • wrap: it is emitted when the application is starting. If you throw an error in the listener the application will not start.
  • hit: it is emitted every time a resolver is called. If you throw an error in the listener, it will be log as a WARN. The resolver will be executed as usual.

If you set an async function as listener, the function will be not awaited. In this case any you must handle the error in the listener itself.

Each event gets an object as argument with the following properties:

{
  typeName: 'Query', // the Type object name
  fieldName: 'hello' // the Type object's field name
}

The following code shows the basic structure of the store object:

app.register(require('mercurius-hit-map'), {
  store: function customFactory (eventEmitter) {
  
    // sync function example
    eventEmitter.on('wrap', (item) => {
      // prepare the item to be stored
    })

    // async function example
    eventEmitter.on('hit', async (item) => {
      try {
        // increment the counter
      } catch (error) {
        // ops, something went wrong
      }
    })

    return {
      readHits: async function () {
        // return the hit map
      },
    }
  }
})

License

Copyright Manuel Spigolon, Licensed under MIT.