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

@c9up/quasar

v0.1.2

Published

Quasar — Redis connections for the Ream framework: named connections, pub/sub, health checks

Downloads

947

Readme

@c9up/quasar

Redis connections for the Ream framework — named connections, pub/sub, health checks, clean shutdown.

A quasar is powered by a black hole feeding on the matter around it: this one feeds the app its data. Like every package in the cohort it is named for what it is, not for the technology it speaks — which is Redis.

This package owns the connection, and nothing else. The packages that store things in Redis — @c9up/echo (cache), @c9up/bay (queue), @c9up/warden (token blacklist) — keep taking a client through a structural contract, so they stay agnostic and this package stays optional.

Install

pnpm add @c9up/quasar

Configure

// config/redis.ts
import { defineConfig } from '@c9up/quasar'
import env from '#start/env'

export default defineConfig({
  connection: 'main',
  connections: {
    main: { url: env.get('REDIS_URL') },
    cache: { host: env.get('REDIS_HOST'), port: 6379, db: 1 },
    cluster: { clusters: [{ host: 'node-1', port: 7000 }, { host: 'node-2', port: 7001 }] },
  },
})

defineConfig refuses a default connection that is not declared, and an empty connection list — a typo there would otherwise surface as a connection to some default localhost.

The config key and the container token stay redis — the role, matching @c9up/echo binding cache and @c9up/bay binding queue.

The config key and the container token stay redis — the role, the same way @c9up/echo binds cache and @c9up/bay binds queue.

Register the provider in start/providers.ts (or your app's provider list):

import QuasarProvider from '@c9up/quasar/provider'

It binds the manager as 'redis' in the container and seats it on the service accessor. register opens no socket: connections are built on first use.

Use

import redis from '@c9up/quasar/services/main'

await redis.connection().set('user:42', payload, 'EX', 60)
await redis.connection('cache').get('user:42')

Every ioredis command is callable straight on a connection and on the manager, where it runs on the default connection:

await redis.set('user:42', payload, 'EX', 60)

The raw client stays reachable as connection.ioConnection for anything not wrapped here. A connection also reports its state the way Adonis does: connectionName, status, subscriberStatus, lastError, isConnecting() / isReady() / isClosed().

LUA scripts go through defineCommand / runCommand; a script defined on the manager reaches every open connection and is remembered for the ones opened later.

Pub/sub

await redis.subscribe('orders', (message, channel) => { /* … */ })
await redis.psubscribe('user:*', (message, channel, pattern) => { /* … */ })
await redis.publish('orders', JSON.stringify(order))

Redis puts a subscribed client into a mode where it accepts nothing but subscribe/unsubscribe, so a connection that both publishes and listens needs two sockets. The second one opens lazily, on the first subscribe, and never at all for a connection that only runs commands — meanwhile ordinary commands keep working on the first.

Subscribing twice to one channel stacks the handlers — both are called, as in Adonis. Pass the handler back to unsubscribe to drop just that one; the socket stays subscribed while others remain.

A failed subscription does not reject: Adonis' subscribe returns void, so code written against it never awaits the call, and a rejection nobody handles would end the process. Failure arrives through onError, the subscription:error event, and the connection logger.

The subscriber socket's lifecycle is re-emitted on the connection under Adonis' names — subscriber:ready, subscriber:error, and so on — because that socket is internal and opened lazily, so nothing outside could listen to it otherwise.

Health

import { QuasarCheck, QuasarMemoryUsageCheck } from '@c9up/quasar'

const ping = await new QuasarCheck(redis.connection()).run()
const memory = await new QuasarMemoryUsageCheck(redis.connection())
  .warnWhenExceeds(400_000_000)
  .failWhenExceeds(800_000_000)
  .run()

Both return { status: 'ok' | 'warning' | 'error', message } rather than throwing — a health endpoint reports, it does not crash.

Shutdown

Following Adonis exactly: quit() and disconnect() act on one connection — the default one when no name is given — and quitAll() / disconnectAll() act on every open one.

QuasarProvider.shutdown() calls quitAll(). Without it a stopped process keeps its sockets and ioredis' reconnection timer keeps the event loop alive, so the server looks hung instead of exiting.

Tests

The suite runs against a real server on REDIS_TEST_URL (default redis://127.0.0.1:6379, db 15) — a mock would prove nothing about the part that actually bites. With no server answering, the live tests skip rather than fail.