marsdb-sync-client
v0.2.12
Published
Standalone Meteor DDP client based on MarsDB
Downloads
72
Maintainers
Readme
MarsDB DDP Client
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