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

viewdb

v0.8.0

Published

ViewDB ======

Downloads

5,989

Readme

ViewDB

ViewDB is an database facade for JavaScript. It can be configured with a custom Store in order to provide support for different persistence sources, such as MongoDB or IndexedDB, but comes with a default in-memory Store for easy testing.

Purpose

Provide a MongoDB like syntax for managing documents while providing customization for where to store the data.

Installation

npm install viewdb

Usage Example

In-Memory Database

Create a ViewDB instance keeping data in memory.

import ViewDB from 'viewdb';
import { processUsers, User, usersData } from './users';

const viewDB = new ViewDB();
const userCollection = viewDB.collection('user');
userCollection.insert(usersData, () => {
  userCollection.find({ name: 'Jeff' }, (err, users) => {
    if (err ?? users.length === 0) {
      return;
    }

    processUsers(users);
  });
});

Components

ViewDB

The database facade that manages a persistence Store. Manages Collections through the Store.

Methods

open
// Use a MongoDB Store for persistence
const viewDB = new ViewDB(mongoDBStore);
// Make sure the Store is open and ready to use
await viewDB.open();
collection

Get a Collection from the provided Store. Will create and return a new Collection if one doesn't already exist.

const userCollection = viewDB.collection('user');
userCollection.find({ name: 'Jeff' }, (err, users) => {
  if (err ?? users.length === 0) {
    return;
  }

  processUsers(users);
});

Plugins

ViewDB can be extended by plugins to intercept data manipulation. Two plugins are included in this repository:

TimeStampPlugin

Intercepts the save, insert & findAndModify Collection methods with timestamps for creation and latest update. The time inserted is a unix timestamp in milliseconds. It provides the following changes.

When inserting documents without providing a skipTimestamp option, the inserted documents will get a createDateTime and a changeDateTime property will be added to the documents.

When saving documents without providing a skipTimestamp option, the inserted documents will get an updated changeDateTime and a changeDateTime value. If there is no createDateTime property on the document, it will be added as well.

When finding and modifying an existing document, the changeDateTime value will be update to the current time.

const viewDB = new ViewDB();

// Apply the plugin to the ViewDB Store
new TimeStampPlugin(viewDB);

const collection = viewDB.collection('user');

// User data for Jeff will get `createDateTime` and `changeDateTime` properties
await collection.insert({ name: 'Jeff' });
VersioningPlugin

Intercepts the save, insert & findAndModify Collection methods with an incremented version, unless the skipVersioning option is passed and set to true.

Note that when finding and modifying existing documents, if version is explicitly set in the update query, that value will be replaced with the incremented version.

const viewDB = new ViewDB();

// Apply the plugin to the ViewDB Store
new VersioningPlugin(viewDB);

const collection = viewDB.collection('user');

// User data for Jeff will get a `version` property
await collection.insert({ name: 'Jeff' });

Store

Responsible for retrieving a Collection of documents. If the store needs some setup to be ready, it shall provide an open method for that.

Used through the ViewDB methods.

Methods

open

Optional method on the Store, to prepare the Store for usage.

await store.open();
collection

Returns a named Collection, kept in the Store for multiple retrievals.

const userCollection = store.collection('user');

// Same instance of the collection retrieved above
const userCollectionRetrievedLater = store.collection('user');

InMemoryStore

A basic implementation of a Store, which keeps a record of the in memory collections by name in memory. Used if no Store is provided as an argument to the ViewDB constructor.

Collection

Responsible for managing the data.

Methods

count

Retrieve the current amount of documents in the collection.

collection.count((err, count) => {
});
createIndex

Creates an index to be used when looking up data.

collection.createIndex({ 'contactMeans.identifier': 1 }, null, (err, result) => {
});
drop

Clear all data in the collection.

// Whether the collection was successfully dropped
const isSuccess = collection.drop();
ensureIndex

Creates an index for the collection unless it already exists.

collection.ensureIndex({ 'contactMeans.identifier': 1 }, null, (err, result) => {
});
find

Returns a Cursor for the list of documents from the collection matching the query.

await cursor = collection.find({});
findAndModify

Retrieve a list of documents from the collection matching the query, and update the resulting documents based on the update query.

collection.findAndModify(query, null, update, options, (err, res) => {
});
insert

Insert new documents into the collection.

collection.insert(newDocs, (err, insertedDocs) => {
});
remove

Remove documents matching the query from the collection.

collection.remove({ name: 'Jeff' }, null, (err, result) => {
});
save

Replace the documents in the collection matching the provided documents by _id.

collection.save(updatedDocs, (err, savedDocs) => {
});

InMemoryCollection

A basic implementation of a Collection managing the data in memory.

Cursor

A result set of the queried Collection. Contains methods to operate on the result set.

Used through the Collection.find method, but a Cursor can be constructed manually.

const collection = viewDB.collection('user');
const queryObj = { query: {} };
const cursorOptions = null;
const getDocuments = (query, callback) => {
  // Logic for retreving documents based on query and passing them to the callback
};

const cursor = new Cursor(collection, queryObj, cursorOptions, getDocuments);

Methods

count

Get the amount of matches for the Cursor.

cursor.count((err, count) => {
});
forEach

Iterate through the matched documents and run the callback for each document.

cursor.forEach((doc) => {
});
limit

Limit the amount of documents to be retrieved.

// Get maximum 5 documents
cursor.limit(5).toArray((err, docs) => {
});
observe

Retrieves an Observer listening for changes for the documents matched in the Cursor.

const observeOptions = {
  added: (user, index) => {
    // Called when a user matching the cursor has been inserted to the collection
  },
  changed: (currentUser, newUser, index) => {
    // Called when a user matching the cursor has been updated in the collection
  },
  moved: (user, oldIndex, newIndex) => {
    // Called when a user matching the cursor has been moved to another position
  },
  removed: (user, index) => {
    // Called when a user matching the cursor has been removed from the collection
  }
};

const observer = cursor.observe(observeOptions);
skip

Amounts of documents in the Cursor that should be skipped.

// Get documents starting from the 6th match
cursor.skip(5).toArray((err, docs) => {
});
sort

Sort the resulting documents based on a query.

// Get documents sorted by creation time in descending order
cursor.sort({ createDateTime: -1 }).toArray((err, docs) => {
});
toArray

Retrieve the list of documents matching the query.

cursor.toArray((err, docs) => {
});

Observer

Observe changes to documents for a Cursor. With provide information about initial data, added, changed, moved & removed data.

Used through the Collection.observe method, but an Observer can be constructed manually.

const observer = new Observe(query, cursorOptions, collection, observerOptions);

Methods

stop

Stop listening to changes matching the query.

const observer = collection.find({}).observe(observeOptions);
observer.stop();

Merger

Check the provided data and provide information about how the values have changed.