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

motion-rxdb

v5.2.0

Published

Offline-first database with Reactive, Sync, Schema, Promises, Mongo-Query, Encryption, LevelDown

Downloads

11

Readme

| Announcement | | :--: | |                 Version 4.0.0 is now released, read the CHANGELOG                |


Features

  • Multiplatform support for browsers, nodejs, electron, cordova, react-native and every other javascript-runtime
  • Reactive data-handling based on rxjs
  • Replication between client and server-data, compatible with pouchdbPouchDB, couchdbCouchDB and cloudantIBM Cloudant
  • Schema-based with the easy-to-learn standard of jsonschema
  • Mango-Query exactly like you know from mongoDB and mongoose
  • Encryption of single data-fields to protect your users data
  • Import/Export of the database-state (json), awesome for coding with TDD
  • Multi-Window to synchronise data between different browser-windows or nodejs-processes
  • ORM-capabilities to easily handle data-code-relations

Platform-support

RxDB is made so that you can use exactly the same code at

  • Chrome Firefox Safari Edge Internet Explorer 11 browsers
  • NodeJS NodeJS
  • electron Electron
  • react-native React-Native
  • cordova Cordova/Phonegap
  • nativescript Nativescript

We optimized, double-checked and made boilerplates so you can directly start to use RxDB with frameworks like

  • react react
  • angular angular/ng2
  • ionic ionic2
  • vuejs vuejs

Quickstart

Installation:

npm install rxdb --save

# peerDependencies
npm install rxjs babel-polyfill --save

Import/Require:

import 'babel-polyfill'; //only needed when you dont have polyfills
import * as RxDB from 'rxdb';
const db = await RxDB.create({
    name: 'heroesdb',
    adapter: 'websql',
    password: 'myLongAndStupidPassword', // optional
    multiInstance: true                  // default: true
  });                                                       // create database

await db.collection({name: 'heroes', schema: mySchema});    // create collection
db.heroes.insert({ name: 'Bob' });                          // insert document
require('babel-polyfill'); //only needed when you dont have polyfills
var RxDB = require('rxdb');
RxDB.create({
    name: 'heroesdb',
    adapter: 'websql',
    password: 'myLongAndStupidPassword', // optional
    multiInstance: true                  // default: true
  })                                                                              // create database
  .then(function(db) {return db.collection({name: 'heroes', schema: mySchema});}) // create collection
  .then(function(collection) {collection.insert({name: 'Bob'});})                 // insert document

Feature-Showroom (click to toggle)

To find data in your collection, you can use chained mango-queries, which you maybe know from mongoDB or mongoose.

myCollection
  .find()
  .where('name').ne('Alice')
  .where('age').gt(18).lt(67)
  .limit(10)
  .sort('-age')
  .exec().then( docs => {
    console.dir(docs);
  });

RxDB implements rxjs to make your data reactive. This makes it easy to always show the real-time database-state in the dom without manually re-submitting your queries.

db.heroes
  .find()
  .sort('name')
  .$ // <- returns observable of query
  .subscribe( docs => {
    myDomElement.innerHTML = docs
      .map(doc => '<li>' + doc.name + '</li>')
      .join();
  });

reactive.gif

When two instances of RxDB use the same storage-engine, their state and action-stream will be broadcasted. This means with two browser-windows the change of window #1 will automatically affect window #2. This works completely serverless.

multiwindow.gif

Because RxDB relies on glorious PouchDB, it is easy to replicate the data between devices and servers. And yes, the changeEvents are also synced.

sync.gif

Schemas are defined via jsonschema and are used to describe your data.

const mySchema = {
    title: "hero schema",
    version: 0,                 // <- incremental version-number
    description: "describes a simple hero",
    type: "object",
    properties: {
        name: {
            type: "string",
            primary: true       // <- this means: unique, required, string and will be used as '_id'
        },
        secret: {
            type: "string",
            encrypted: true     // <- this means that the value of this field is stored encrypted
        },
        skills: {
            type: "array",
            maxItems: 5,
            uniqueItems: true,
            item: {
                type: "object",
                properties: {
                    name: {
                        type: "string"
                    },
                    damage: {
                        type: "number"
                    }
                }
            }
        }
    },
    required: ["color"]
};

By setting a schema-field to encrypted: true, the value of this field will be stored in encryption-mode and can't be read without the password. Of course you can also encrypt nested objects. Example:

"secret": {
  "type": "string",
  "encrypted": true
}

The underlaying pouchdb can use different adapters as storage engine. So you can use RxDB in different environments by just switching the adapter. For example you can use websql in the browser, localstorage in mobile-browsers and a leveldown-adapter in nodejs.

// this requires the localstorage-adapter
RxDB.plugin(require('rxdb-adapter-localstorage'));
// this creates a database with the localstorage-adapter
const db = await RxDB.create('heroesDB', 'localstorage');

Some adapters you can use:

RxDB lets you import and export the whole database or single collections into json-objects. This is helpful to trace bugs in your application or to move to a given state in your tests.


// export a single collection
const jsonCol = await myCollection.dump();

// export the whole database
const jsonDB = await myDatabase.dump();

// import the dump to the collection
await emptyCollection.importDump(json);


// import the dump to the database
await emptyDatabase.importDump(json);

Imagine your website needs to get a piece of data from the server once every minute. To accomplish this task you create a websocket or pull-interval. If your user now opens the site in 5 tabs parallel, it will run the interval or create the socket 5 times. This is a waste of resources which can be solved by RxDB's LeaderElection.

myRxDatabase.waitForLeadership()
  .then(() => {
      // this will only run when the instance becomes leader.
      mySocket = createWebSocket();
  });

In this example the leader is marked with the crown ♛

reactive.gif

Depending on which adapter and in which environment you use RxDB, client-side storage is limited in some way or the other. To save disc-space, RxDB has an internal schema-based key-compression to minimize the size of saved documents.

Example:


// when you save an object with big keys
await myCollection.insert({
  firstName: 'foo'
  lastName:  'bar'
  stupidLongKey: 5
});

// RxDB will internally transform it to
{
  '|a': 'foo'
  '|b':  'bar'
  '|c': 5
}

// so instead of 46 chars, the compressed-version has only 28
// the compression works internally, so you can of course still access values via the original key.names
console.log(myDoc.firstName);
// 'foo'

Use-Case-Example

Imagine you have a very big collection with many user-documents. At your page you want to display a toplist with users which have the most points and are currently logged in. You create a query and subscribe to it.

const query = usersCollection.find().where('loggedIn').eq(true).sort('points');
query.$.subscribe(users => {
    document.querySelector('body').innerHTML = users
        .reduce((prev, cur) => prev + cur.username+ '<br/>', '');
});

As you may detect, the query can take very long time to run, because you have thousands of users in the collection. When a user now loggs of, the whole query will re-run over the database which takes again very long.

anyUser.loggedIn = false;
await anyUser.save();

But not with the QueryChangeDetection enabled. Now, when one user loggs of, it will calculate the new results from the current results plus the RxChangeEvent. This often can be done in-memory without making IO-requests to the storage-engine. The QueryChangeDetection not only works on subscribed queries, but also when you do multiple .exec()'s on the same query.

Browser support

All major evergreen browsers and IE11 are supported. Tests automatically run against Firefox and Chrome, and manually in a VirtualBox for IE11 and Edge.

As RxDB heavily relies on PouchDB, see their browser support for more information. Also do keep in mind that different browsers have different storage limits, especially on mobile devices.

Getting started

Get started now by reading the docs or exploring the example-projects.

Contribute

Check out how you can contribute to this project.

Follow up

  • Follow RxDB on twitter to not miss the latest enhancements.
  • Join the chat on gitter for discussion.
  • Support RxDB at patreon

Thank you

A big Thank you to every patreon-supporter and every contributor of this project.