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

graphql-firebase-subscriptions

v2.5.0

Published

Broadcast graphql messages via firebase realtime database, optional local cache for performance

Downloads

327

Readme

GraphQL Subscriptions through Firebase Realtime Database

JavaScript Style Guide QA Publish to NPM and GCR codecov

This is a GraphQL Subscriptions implementation that uses Firebase Realtime Database as a message broker.

Comparison

Depending on your use-case this may or may not be the tool for you, this implementation is not meant as a way to listen to state updates on persisted data, for that you should probably look at graphql-firestore-subscriptions. This implementation is closer to an alternative to Google PubSub. Now you may wonder, "why not use PuSub then?" well, basically I had concerns that the PubSub documentation stated the performance on low message volumes might not be great on PubSub since the priority was low latency at high load, some graphs I saw showed seconds of latency for the types of volumes I was looking at, whereas I've experienced a more consistent performance from RTDB, but it doesn't go lower with scale like PubSub does. For using PubSub, there's graphql-google-pubsub.

Now Firebase RTDB isn't without latency, not at all! And to alleviate this, this library also provides an optional "local cache", this is really useful if you're running on something like Google Cloud Run where you have multiple instances serving requests. Turning this on will make the library work on an "at-least-once" delivery principle. If something happens (most likely a mutation) on the same instance a subscriber is connected to it will use an internal in-memory EventEmitter and "instantly" forward the message. It will also publish the message to Firestore RTDB and keep the node ID in a short-lived local cache, when the message later arrives, and assuming its ID hasn't expired from the cache, it will simply be ignored and not re-emitted to subscribers connected to the instance that originally received the message.

Usage

By default, the ref /graphql-firebase-subscriptions in your database will be used as the root for messages.

import { PubSub } from 'graphql-firebase-subscriptions'

enum Topic {
  NEW_COMMENT = 'new-comment'
}

const pubSub = new PubSub()

const Resolvers = {
  Subscription: {
    newComment: {
      subscribe: () => pubSub.asyncIterator(Topic.NEW_COMMENT)
    }
  },
  Mutation: {
    async addComment (_, args, ctx) {
      const comment = await ctx.dataSources.comments.createOne(args.postId, args.comment)
      await pubSub.publish(Topic.NEW_COMMENT, { postId: args.postId, commentId: comment.id })

      return comment
    }
  }
}

Local Cache

Enabling the local cache for speed up is as simple as a boolean

import { PubSub } from 'graphql-firebase-subscriptions'

const pubSub = new PubSub({ localCache: true })

Only New

This flag allows receiving only messages which were published after client subscription to some topic. Default behaviour is to receive all messages which were published and not deleted (see Cleanup section).

import { PubSub } from 'graphql-firebase-subscriptions'

const pubSub = new PubSub({ onlyNew: true })

When creating an asyncIterator you can override this option

import { PubSub } from 'graphql-firebase-subscriptions'

const pubSub = new PubSub({ onlyNew: false })

const iterator = pubSub.asyncIterator(['TOPIC'], { onlyNew: true })

Alternative base ref

You can use an alternative base ref for the message brokerage, useful if you want separate instances with the same topics.

import { PubSub } from 'graphql-firebase-subscriptions'
import { getDatabase } from 'firebase-admin/database'

const pubSub = new PubSub({
  ref: getDatabase().ref('/path/to/base/ref')
})

Cleanup

This library requires you to clean up old messages, else it will just keep adding messages to the topics forever. This could slow down message delivery, and it'll waste storage and cost.

To help with this task, the library provides a Firebase Function that works on a Google Cloud Scheduler Trigger. Note that per Firebase's own documentation a cloud scheduler job costs about USD 0.10 per month and requires you to be on the Blaze plan for firebase.

To use it, just generate a handler and re-export it

import getDeletionRoutineFunction from 'graphql-firebase-subscriptions/firebase-functions'

enum Topics {
  NEW_COMMENT = 'new-comment'
}

export const pubSubDeletionRoutine = getDeletionRoutineFunction({
  topics: Topics,

  // -------OPTIONAL-------
  // You can overwrite the base ref, if you've done so when using the PubSub
  ref: getDatabase.ref('/graphql-firebase-subscriptions'),
  // you can override the schedule for the function, by default it runs every
  // 10 minutes
  schedule: 'every 10 minutes',
  // and you can override the maximum time a message should be stored,
  // the default is to delete messages older than 10 minutes
  maxAge: 600_000
})