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

@monlite/realtime

v0.3.0

Published

Networked realtime for @monlite/core: stream live queries and documents to remote clients over SSE, backed by the change feed.

Readme

@monlite/realtime

Networked realtime for @monlite/core — stream live queries and documents to remote clients (browser, mobile, other services) over Server-Sent Events, backed by the change feed. Zero extra dependencies (built on node:http + fetch).

npm install @monlite/realtime

The database stays embedded in your service; this package puts a realtime API in front of it.

Server

import { createDb } from "@monlite/core";
import { realtime } from "@monlite/realtime";

const db = createDb("./app.db", { changefeed: true }); // change feed required

// Single database:
realtime({ db }).listen(8080);

// Or per-tenant + auth (resolve which db from the request):
realtime({
  authorize: (req) => {
    const tenant = verify(req.headers.authorization); // your auth
    return tenant ? { db: dbForTenant(tenant) } : null; // null → 401
  },
}).listen(8080);

Attach to an existing server/framework instead of listen():

const rt = realtime({ db });
http.createServer((req, res) => {
  if (req.url?.startsWith("/realtime")) return rt.handler(req, res);
  // ... your other routes
});

Client (browser or Node ≥ 18)

import { connectRealtime } from "@monlite/realtime/client";

const live = connectRealtime("https://api.example.com", { token });

// Live query — fires with the snapshot, then on every change
const stop = live
  .collection("orders")
  .where({ status: "open" })
  .orderBy({ createdAt: "desc" })
  .onSnapshot(({ results, added, removed, changed, moved }) => render(results));

// Single document (null on delete)
const stopDoc = live.doc("orders", "o-123", (doc) => render(doc));

// Only re-emit when a specific field changes
live.collection("orders").fields(["status"]).onSnapshot(onChange);

stop(); // unsubscribe
live.close(); // unsubscribe everything

Client options: { token, path, reconnectMs, fetch, onError }. onError (default console.error) receives any server-sent { error } frame — e.g. a watch that failed server-side — so it is never mis-delivered as a snapshot or a null document.

How it works

  • One SSE stream per subscription; the query travels in the URL.
  • The server runs collection.watch() / watchDoc() on the authorized database and pushes each LiveEvent (init snapshot, then added/removed/changed/moved deltas) down the stream.
  • The client auto-reconnects with backoff; on reconnect it receives a fresh snapshot (no missed state). Because writes flow through the change feed, changes from other processes and from @monlite/sync are delivered too.

Notes

  • Auth & multi-tenancy are your authorize hook's job — it maps a request to a { db }.
  • CORS is * by default; set cors to a specific origin (or false) in production.
  • Pairs naturally with the embedded, one-.db-file-per-tenant model.