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

@runhare/node

v0.2.5

Published

Node helper functions for RunHare platform.

Readme

@runhare/node

Node helper functions for RunHare platform.

To use RunHare SDK you will need two elements:

  • Namespace
  • Send Keys: Are used to secure sending and receiving events from RunHare's platform.

Sending Events

To send a Background Task Event you will create a Client and use it to fire the event with the associated payload.

import { createClient } from '@runhare/node'

interface SendEmail {
  to: string
  subject: string
  content: string
}

interface DemoEvents {
  'send-email': SendEmail
}

const client = createClient<DemoEvents>('la329bg', process.env.SENDKEY, 'demo')

client
  .sendEvent('send-email', {
    to: '[email protected]',
    subject: 'Hello from SDK',
    content: 'Yes, this works'
  })
  .then(response => {
    console.log(response)
  })

TypeScript support

Event types in RunHare are checked against a registered schema. On the RunHare Console you can export TypeScript type definitions for all Event types your Namespace uses.

Using this type definitions you can have autocomplete hints of the properties different payloads requires.

API Reference

Exported types

export declare type RunHareEventPriority = 'normal' | 'high'

export declare type RunHareEventStatus = 'queued' | 'prequed'

export interface RunHareResponse<EventTypes> {
  status: RunHareEventStatus
  message: keyof EventTypes
  priority: RunHareEventPriority
}

RunHare Client.

export declare const createClient: <EventTypes>(
  namespace: string,
  sendKey?: string | undefined,
  origin?: string | undefined
) => {
  sendEvent: <K extends keyof EventTypes>(
    event: K,
    message: EventTypes[K],
    priority?: RunHareEventPriority,
    signal?: boolean | undefined
  ) => Promise<RunHareResponse<EventTypes>>
}

createClient<T>(namespace, sendKey?, origin?)

  • namespace : Unique Namespace name
  • sendKey : Send secret used to sign requests
  • origin : Helps identify which process sent the request. Will be received as a X-RunHare-Origin header on the consumer

client.sendEvent(event, message, priority?, signal?) -> Response

  • event : Event identifier as defined on RunHare's console.
  • message : Event Payload, must pass Event schema
  • priority : "normal" | "high" (default "normal")
  • signal : true | false (default false) Signal events return a pre-queued state meaning they are faster to respond but no direct garantee of being queued.

Response

  • status : "queued" | "pre-queued"
  • event : Event identifier as defined on RunHare's console.
  • priority : "normal" | "high"

Consuming Events

RunHare sends events to registered HTTP endpoints (POST, GET) where your consumer functions receive the payloads according to the event types they are registered. As such, consumers live inside a HTTP server handler, preferably using a framework.

HTTP handlers should respond to 2 methods:

  • POST to receive event messages
  • GET to query about consumer health and metadata (SDK related)
interface SendEmail {
  to: string
  subject: string
  content: string
}

interface DemoEvents {
  'send-email': SendEmail
}

const consumer = createConsumer<DemoEvents>(process.env.SENDKEY)

const sendEmailHandler = consumer.createHandler(
  ['send-email'],
  async (
    event,
    payload: SendEmail,
    headers: any
  ): Promise<ConsumerResponse> => {
    await EmailClient.sendEmail(payload)
    return { result: 'sucess' }
  }
)

const payload = {
  to: '[email protected]',
  subject: 'Hello',
  world: 'World'
}

const signature = signPayload(payload, process.env.SENDKEY)

const response = await handler(payload, {
  ...signature.headers,
  'x-runhare-event': 'dothis'
})

We provide wrappers for ExpressJS and NextJS.

ExpressJS

const express = require('express')
const consumer = require('@runhare/express')

const sendEmailHandler = async (event, payload, headers) => {
  await EmailClient.sendEmail(payload)
  return { result: 'sucess' }
}

app.use(
  '/send-email',
  consumer(['send-email'], process.env.SENDKEY, sendEmailHandler)
)

app.listen(3000, () => {
  console.log(`Email consumer listening at http://localhost:${port}`)
})

NextJs

// 'src/pages/api/send-email.ts'
import consumer from '@runhare/next'

interface SendEmail {
  to: string
  subject: string
  content: string
}

interface DemoEvents {
  'send-email': SendEmail
}

export default consumer([
  'send-email',
  process.env.SENDKEY,
  async (
    event,
    payload: SendEmail,
    headers: any
  ): Promise<ConsumerResponse> => {
    await EmailClient.sendEmail(payload)
    return { result: 'sucess' }
  }
])

API Reference

Exported types

export interface ConsumerOptions {
  rejectUnregisteredMessages?: boolean
}
export interface EventSuccess {
  result: 'sucess'
}
export interface EventFailed {
  result: 'fail'
  error: string
}
export declare type ConsumerResponse = EventSuccess | EventFailed
export declare const createConsumer: <EventTypes>(
  sendKey?: string | undefined,
  options?: ConsumerOptions | undefined
) => {
  createHandler: <K extends keyof EventTypes>(
    events: K[],
    consumer: (
      event: K,
      payload: EventTypes[K],
      headers?: PayloadHeaders | undefined
    ) => Promise<ConsumerResponse>
  ) => (
    payload: EventTypes[K],
    headers?: PayloadHeaders | undefined
  ) => Promise<ConsumerResponse>
}

createConsumer<T>(sendKey?, options?)

  • sendKey : Shared secret used to verify messages signatures.
  • options.rejectUnregisteredMessages : If set, messages received not in the subscription list will be marked as failed (potentially retrying them)

createHandler(events, consumer) -> handler(event, payload, headers)

  • events : Array of subscribed event types
  • consumer : Asynchronous Consumer function

Returns Handler function

  • event : Received event
  • payload : Clean payload
  • headers : Request headers