MarsDB
MarsDB is a lightweight client-side database.
It based on a Meteor’s minimongo
mathing/modifying implementation. It carefully written on ES6
, usess modular lodash
, have a Promise
based interface and may be backed with any storage implementation (LevelUP, LocalStorage, IndexDB, etc). It also supports observable
cursors.
MarsDB supports any kind of find/update/remove operations that Meteor’s minimongo does. So, go to the Meteor docs for supported query/modifier operations.
You can use it in any JS environment (Browser, Electron, NW.js, Node.js).
Features
- Promise based API
- Carefully written on ES6
- Supports many of MongoDB query/modify operations – thanks to Meteor’s minimongo
- Flexible pipeline – map, reduce, custom sorting function, filtering. All with a sexy JS interface (no ugly mongo’s aggregation language)
- Joinable cursor – joining one object with another can’t be simplier
- Persistence API – all collections can be stored (and restored) with any kind of storage (in-memory, LocalStorage, LevelUP, etc)
- Live queries - just like in Meteor, but with simplier interface
Examples
Using with Angular 1.x
Include marsdb.angular.js
after marsdb.min.js
and angular.js
in your <head>
. Then add a MarsDB
dependency in your module. That's it. Now you can use $collection
factory. For example:
angular.module(‘app’, [‘MarsDB’])
.controller(function($scope, $collection) {
const posts = $collection(‘posts’);
posts.find({authorId: 123}).observe((docs) => {
$scope.posts = docs;
}, $scope).then(() => {
$scope.loaded = true;
});
});
You also can use MarsDB within browserify environment. Just require(‘marsdb/dist/angular’)
and MarsDB module will be added to the angular. Angular must be defined in a window
or must be available as a module require(‘angular’)
.
Create a collection
import Collection from ‘marsdb’;
import LocalStorageManager from 'marsdb/lib/LocalStorageManager';
Collection.defaultStorageManager(LocalStorageManager);
Collection.defaultIdGenerator(() => {
return {
value: Math.random(),
seed: 0,
};
});
const users = new Collection(‘users’);
Find a documents
const posts = new Collection(‘posts’);
posts.find({author: ‘Bob’})
.sort([‘createdAt’])
.then(docs => {
});
Find with pipeline (map, reduce, filter)
An order of pipeline methods invokation is important. Next pipeline operation gives as argument a result of a previous operation.
const posts = new Collection(‘posts’);
posts.find()
.limit(10)
.sortFunc((a, b) => a - b + 10)
.filter(doc => Matsh.sqrt(doc.comment.length) > 1.5)
.map(doc => doc.comments.length)
.reduce((acum, val) => acum + val)
.then(result => {
});
Find with observing changes
Observable cursor returned only by a find
method of a collection. Updates of the cursor is batched and debounced (default batch size is 20
and debounce time is 1000 / 15
ms). You can change the paramters by batchSize
and debounce
methods of an observable cursor (methods is chained).
const posts = new Collection(‘posts’);
const stopper = posts.find({tags: {$in: [‘marsdb’, ‘is’, ‘awesome’]}})
.observe(docs => {
stopper.stop();
}).then(docs => {
});
Find with joins
Joined objects is not obervable yet.
const users = new Collection(‘users’);
const posts = new Collection(‘posts’);
posts.find()
.join(doc => {
return users.findOne(doc.authorId).then(user => {
doc.authorObj = user;
return doc;
});
})
.join(doc => {
doc.another = _cached_data_by_post[doc._id];
return doc;
});
Inserting
const posts = new Collection(‘posts’);
posts.insert({text: ‘MarsDB is awesome’}).then(docId => {
})
posts.insertAll(
{text: ‘MarsDB’},
{text: ‘is’},
{text: ‘awesome’}
).then(docsIds => {
});
Updating
const posts = new Collection(‘posts’);
posts.update(
{authorId: {$in: [1, 2, 3]}},
{$set: {text: ‘noop’}}
).then(result => {
console.log(result.modified)
console.log(result.updated)
console.log(result.original)
});
Removing
const posts = new Collection(‘posts’);
posts.remove({authorId: {$in: [1,2,3]}})
.then(removedDocs => {
});
Roadmap
- Keep track of multiple remove/update documents in selector (allow only if opations.multi passed)
- Upsert updating
- Indexes support for some kind of simple requests {a: '^b'}, {a: {$lt: 9}}
- Some set of backends
- 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