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

pubsub-client-ddp

v0.0.7

Published

A promised based client to communicate with any DDP server

Readme

@ddp/client

Do not use this library yet. Its work in progress. Feel free to test it and provide feedback :) The publication, call and apply methods have not yet been finished too and the package has not yet been published to NPM, because the name will likely change.

A modern isomorphic DDP client with optional Promise based API for easy pub/sub integration on any client.

Features

  • Retries on first attempt
  • Auto reconnect with backoff policy on disconnect
  • Event emitter for any plugins or 3th party libraries
  • Optional Promise based API for synchronous flows
  • Typescript support

Getting Started

npm i @ddp/client

or

yarn @ddp/client

Initialize the client and start subscribing!

import { Client } from '@ddp/client';

const URL = 'ws://localhost:3001/websocket';

const DDP = new Client(URL) // Starts connection

DDP.subscribe('{publication}', params) // Subscribes to publication
DDP.call('{method}', params) // Calls a DDP method on the server

Using promises

(async () => {
  const DDP = new Client(URL)

  // Resolves when the socket has been established and the DDP connect message was sent
  await DDP.connected() 

  // Subscriptions return a subId, but are not promised based to allow non-blocking 
  // scenarios. During SSR, you might want to wait for the subscription to go into a 
  // "ready" state, meaning the initial data has been sent back to the client.
  // 
  // Adding `.ready()` returns a promise with the subId. It resolves when the subscription is ready
  const subId = await DDP.subscribe('{subscription}', params).ready()

  // Similar to the subscription's `.ready()`, `.done()` could be used for methods 
  // to return results synchroneously similar to how for example the 
  // [Axios](https://github.com/axios/axios) library handles normal http requests
  const result = await DDP.call('{method}', params).done()
})()

Listening to events

DDP.on('error', (error) => handler(error))
DDP.on('disconnected', handler)
DDP.on('reconnecting', handler)
DDP.on('retry', handler)
DDP.on('connected', ({ sessionId }) => handler(sessionId))

The events are listed in the typescript EventName enum:

import { EventName } from '@ddp/client/enums';

DDP.on(EventName.Connected, handler)

Example for SSR scenarios:

const getArticles = async (DDP, params) => {
  
  const articles = []

  DDP.on(`articles.added`, ({ id, fields }) => {
    articles.push({ id, ...fields })
  })

  await DDP.subscribe('articles', params).ready()

  return articles
}

app.route('*', async (req, res) => {
  // Start a connection per request. Because a DDP connection contains 
  // a session token per client / user
  const DDP = new Client(URL) 

  const articles = await getArticles(DDP, req.query)

  DDP.disconnect() // Close connection

  // ... hydration code for your specific UI library or framework
})