marsdb-sync-client

0.2.12 • Public • Published

MarsDB DDP Client

Build Status npm version Coverage Status Dependency Status

It's a Meteor compatible DDP client, based on MarsDB. It supports methods, pub/sub and collection operations. It is very similar to Meteor, but it also have some killer features...

Features

  • Cache collections – with LocalForage, for example
  • Auto subcribe/unsubscribe - see examples
  • Smart subscriptions – any subscription will be stopped only after 15 sec delay.
  • Framework agnostic
  • Works in any JS environment – browser, Node.JS, Electron, NW.js, Cordova

WARNING

It's only a concept until 1.0. Use it for your own risk.

Examples

Basic example

The repository comes with a simple example. To try it out:

git clone https://github.com/c58/marsdb-sync-client.git
cd marsdb-sync-client/example && npm install
npm start

Then, just point your browser at http://localhost:3000.

Usage with Meteor server and LocalForage

marsdb-sync-client is a DDP client, so it should work well with Meteor server. But it have an extension for syncing local cache with a server side. The extension is implemented by marsdb-sync-server and is follow:

  • Each collection have additional server method called /${myCollection}/sync
  • This method invoked by MarsSync client on init stage for each collection
  • Method invoked with one argument: list of all available document ids in a local cache
  • Method must return a sublist of given ids that is NOT presented in a server anymore (deleted ids).

You should implement it by yourself for each collection in Meteor's server-side code. In the future it might be a package for Meteor (it would be great if you implement it).

Example of a sync method for some collection:

// /server/collections/Posts.js
Posts = new Meteor.Collection('posts');
 
Meteor.methods({
  '/posts/sync': function(remoteIds) {
    const existingDocs = Posts.find({_id: {$in: remoteIds}}, {fields: {_id: 1}}).fetch();
    const existingIdsSet = new Set(existingDocs.map(doc => doc._id));
    return remoteIds.filter(id => !existingIdsSet.has(id));
  }
});

Configure a client

import Collection from 'marsdb';
import * as MarsSync from 'marsdb-sync-client';
 
// Setup marsdb-sync-client
MarsSync.configure({ url: 'ws://localhost:3000' });
 
// User your collections
const posts = new Collection('posts');
const observer = posts.find(
  {author: 'me'},
  {sub: ['postsByAuthor', 'me']}
).observe((posts) => {
  // Subscribe to "postsByAuthor" publisher and update any time when
  // some documents added (but with debounce)
});
 
// When you stop all observers of a cursor
// subscription will be automatically stopped
// (after 15 sec for optimal client/server communication)
observer.stop();

Wait for subscription ready

// Sometimes you need to show a result only when
// all documents of a subscription received.
// There is special options "waitReady" for this.
const posts = new Collection('posts');
posts.find(
  {author: 'me'},
  {sub: ['postsByAuthor', 'me'], waitReady: true}
).observe((posts) => {
  // Subscribe to "postsByAuthor" publisher and wait until
  // subscription ready (observer called only when sub ready)
});

Decide when to use cache

// Cache is good, but sometimes you need to decide when to use
// cache, and when to wait new data from the server...
const posts = new Collection('posts');
posts.find(
  {author: 'me'},
  {sub: ['postsByAuthor', 'me'], tryCache: true}
).observe((posts) => {
  // Subscribe to "postsByAuthor" publisher and try
  // to get posts from cache. If "tryCache" is true, then
  // cache is used when it's not empty array or not empty object.
  // In other cases it will wait subscription ready.
});
 
posts.find(
  {author: 'not_me'},
  {sub: ['postsByAuthor', 'not_me'], tryCache: (posts) => true}
).observe((posts) => {
  // Subscribe to "postsByAuthor" publisher and try
  // to get posts from cache. If "tryCache" is a function, then
  // the function will be called with cache result. If function returns
  // true, then cache will be used.
});

Methods and subscriptions

import * as MarsSync from 'marsdb-sync-client';
 
MarsSync.call('myMethod', 1, 2, 3).result().then((res) => {
  // Result of the method in "res"
}).updated().then(() => {
  // Invoked when "updated" message received.
});
 
// Similar for "apply"
MarsSync.apply('myMethod', [1, 2, 3])
 
// You can also subscribe just like in Meteor
const sub = MarsSync.subscribe('myPublisher', 1, 2, '3th arg');
sub.ready().then(() => {
  // When ready
}).stopped().then(() => {
  // When stopped
});
// Stop the subscription
sub.stop();

Roadmap

  • More examples of usage and tests
  • Documentation

Contributing

I'm waiting for your pull requests and issues. Don't forget to execute gulp lint before requesting. Accepted only requests without errors.

License

See License

Versions

Current Tags

  • Version
    Downloads (Last 7 Days)
    • Tag
  • 0.2.12
    8
    • latest

Version History

Package Sidebar

Install

npm i marsdb-sync-client

Weekly Downloads

8

Version

0.2.12

License

MIT

Last publish

Collaborators

  • a.artemev