@ortoo/angular-resource
Version:
Magical CRUD resource management for angular
143 lines • 15.5 kB
JavaScript
// tslint:disable only-arrow-functions
import { cloneDeep } from 'lodash';
import { isObject } from 'lodash';
import * as Datastore from 'nedb/browser-version/out/nedb';
const me = self;
me.onmessage = handleMessage;
const _DB_MAP = {};
class Database {
constructor() {
this.db = new Datastore();
this.RES_TO_DB_ID_MAP = {};
// Stick an index on __id - our id field.
this.db.ensureIndex({ fieldName: '__id' }, function (err) {
if (err) {
throw err;
}
});
}
remove(id, callback) {
let dbid = this.RES_TO_DB_ID_MAP[id];
if (dbid) {
delete this.RES_TO_DB_ID_MAP[id];
this.db.remove({ _id: dbid }, { multi: true }, function (err) {
callback(err);
});
}
else {
callback(new Error(`No object to remove with id ${id}`));
}
}
update(doc, callback) {
// We need to transform the resource by replacing the _id field (nedb uses its own id in that
// place). Instead call it __id
doc.__id = doc._id;
doc.__$id = doc.$id;
delete doc._id;
delete doc.$id;
let dbid = this.RES_TO_DB_ID_MAP[doc.__$id];
if (dbid) {
this.db.update({ _id: dbid }, doc, {}, function (err) {
callback(err);
});
}
else {
this.db.insert(doc, (err, newDoc) => {
if (err) {
return callback(err);
}
this.RES_TO_DB_ID_MAP[doc.__$id] = newDoc._id;
callback();
});
}
}
query(qry, callback) {
let find = createDbFind(qry.find);
let limit = qry.limit;
let skip = qry.skip;
let sort = qry.sort;
let cur = this.db.find(find);
if (sort) {
cur = cur.sort(sort);
}
if (skip) {
cur = cur.skip(skip);
}
if (limit) {
// We go + 1 so we can tell if there are any more results
cur = cur.limit(limit + 1);
}
cur.exec(function (err, docs) {
// Now go from our docs to the ids
let ids = docs.map(function (doc) {
return doc.__$id;
});
callback(err, ids);
});
}
}
// Convert any _id searches to __id (which is where our id moved to)
function _createDbFind(qry) {
if (Array.isArray(qry)) {
qry.forEach(function (val) {
_createDbFind(val);
});
}
else if (isObject(qry)) {
for (let key of Object.keys(qry)) {
let val = qry[key];
// Convert the _id to __id searches
if (key === '_id') {
qry.__id = val;
delete qry._id;
}
_createDbFind(val);
}
}
}
function createDbFind(qry) {
// Converts the query into the form required for a db search. First clone the object
qry = cloneDeep(qry);
_createDbFind(qry);
return qry;
}
function createCallback(id) {
return function callback(err, resp) {
me.postMessage({
id,
data: resp,
error: err && err.message,
});
};
}
function getDatabase(dbid) {
let db = _DB_MAP[dbid];
if (!db) {
db = new Database();
_DB_MAP[dbid] = db;
}
return db;
}
function handleMessage(event) {
let data = event.data;
let dbid = data.dbid;
let id = data.id;
let args = data.args;
let cb = createCallback(id);
let db = getDatabase(dbid);
switch (data.fnName) {
case 'update':
db.update(args[0], cb);
break;
case 'remove':
db.remove(args[0], cb);
break;
case 'query':
db.query(args[0], cb);
break;
default:
cb(new Error(`No such method ${data.fnName}`));
break;
}
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid29ya2VyLmpzIiwic291cmNlUm9vdCI6Ii9Ab3J0b28vYW5ndWxhci1yZXNvdXJjZS9kYnMvd2Vid29ya2VyLyIsInNvdXJjZXMiOlsid29ya2VyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLHNDQUFzQztBQUN0QyxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sUUFBUSxDQUFDO0FBQ25DLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxRQUFRLENBQUM7QUFFbEMsT0FBTyxLQUFLLFNBQVMsTUFBTSwrQkFBK0IsQ0FBQztBQUUzRCxNQUFNLEVBQUUsR0FBRyxJQUFrQyxDQUFDO0FBRTlDLEVBQUUsQ0FBQyxTQUFTLEdBQUcsYUFBYSxDQUFDO0FBRTdCLE1BQU0sT0FBTyxHQUErQixFQUFFLENBQUM7QUFJL0M7SUFJRTtRQUNFLElBQUksQ0FBQyxFQUFFLEdBQUcsSUFBSSxTQUFTLEVBQUUsQ0FBQztRQUUxQixJQUFJLENBQUMsZ0JBQWdCLEdBQUcsRUFBRSxDQUFDO1FBRTNCLHlDQUF5QztRQUN6QyxJQUFJLENBQUMsRUFBRSxDQUFDLFdBQVcsQ0FBQyxFQUFFLFNBQVMsRUFBRSxNQUFNLEVBQUUsRUFBRSxVQUFVLEdBQUc7WUFDdEQsRUFBRSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztnQkFDUixNQUFNLEdBQUcsQ0FBQztZQUNaLENBQUM7UUFDSCxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFTSxNQUFNLENBQUMsRUFBVSxFQUFFLFFBQWtCO1FBQzFDLElBQUksSUFBSSxHQUFHLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUNyQyxFQUFFLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO1lBQ1QsT0FBTyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsRUFBRSxDQUFDLENBQUM7WUFDakMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxNQUFNLENBQUMsRUFBQyxHQUFHLEVBQUUsSUFBSSxFQUFDLEVBQUUsRUFBQyxL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QztRQUNSO1lBQ0UsRUFBRSxDQUFDLElBQUksS0FBSyxDQUFDLGtCQUFrQixJQUFJLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQyxDQUFDO1lBQy9DLEtBQUssQ0FBQztJQUNWLENBQUM7QUFDSCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLy8gdHNsaW50OmRpc2FibGUgb25seS1hcnJvdy1mdW5jdGlvbnNcbmltcG9ydCB7IGNsb25lRGVlcCB9IGZyb20gJ2xvZGFzaCc7XG5pbXBvcnQgeyBpc09iamVjdCB9IGZyb20gJ2xvZGFzaCc7XG5cbmltcG9ydCAqIGFzIERhdGFzdG9yZSBmcm9tICduZWRiL2Jyb3dzZXItdmVyc2lvbi9vdXQvbmVkYic7XG5cbmNvbnN0IG1lID0gc2VsZiBhcyBEZWRpY2F0ZWRXb3JrZXJHbG9iYWxTY29wZTtcblxubWUub25tZXNzYWdlID0gaGFuZGxlTWVzc2FnZTtcblxuY29uc3QgX0RCX01BUDoge1tkYmlkOiBzdHJpbmddOiBEYXRhYmFzZX0gPSB7fTtcblxuZGVjbGFyZSB0eXBlIENhbGxiYWNrID0gKGVycj86IEVycm9yLCB2YWw/OiBhbnkpID0+IHZvaWQ7XG5cbmNsYXNzIERhdGFiYXNlIHtcbiAgcHJpdmF0ZSBkYjogRGF0YXN0b3JlO1xuICBwcml2YXRlIFJFU19UT19EQl9JRF9NQVA6IHtbaWQ6IHN0cmluZ106IHN0cmluZ307XG5cbiAgY29uc3RydWN0b3IoKSB7XG4gICAgdGhpcy5kYiA9IG5ldyBEYXRhc3RvcmUoKTtcblxuICAgIHRoaXMuUkVTX1RPX0RCX0lEX01BUCA9IHt9O1xuXG4gICAgLy8gU3RpY2sgYW4gaW5kZXggb24gX19pZCAtIG91ciBpZCBmaWVsZC5cbiAgICB0aGlzLmRiLmVuc3VyZUluZGV4KHsgZmllbGROYW1lOiAnX19pZCcgfSwgZnVuY3Rpb24gKGVycikge1xuICAgICAgaWYgKGVycikge1xuICAgICAgICB0aHJvdyBlcnI7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICBwdWJsaWMgcmVtb3ZlKGlkOiBzdHJpbmcsIGNhbGxiYWNrOiBDYWxsYmFjaykge1xuICAgIGxldCBkYmlkID0gdGhpcy5SRVNfVE9fREJfSURfTUFQW2lkXTtcbiAgICBpZiAoZGJpZCkge1xuICAgICAgZGVsZXRlIHRoaXMuUkVTX1RPX0RCX0lEX01BUFtpZF07XG4gICAgICB0aGlzLmRiLnJlbW92ZSh7X2lkOiBkYmlkfSwge211bHRpOiB0cnVlfSwgZnVuY3Rpb24oZXJyKSB7XG4gICAgICAgIGNhbGxiYWNrKGVycik7XG4gICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgY2FsbGJhY2sobmV3IEVycm9yKGBObyBvYmplY3QgdG8gcmVtb3ZlIHdpdGggaWQgJHtpZH1gKSk7XG4gICAgfVxuICB9XG5cbiAgcHVibGljIHVwZGF0ZShkb2M6IGFueSwgY2FsbGJhY2s6IENhbGxiYWNrKSB7XG4gICAgLy8gV2UgbmVlZCB0byB0cmFuc2Zvcm0gdGhlIHJlc291cmNlIGJ5IHJlcGxhY2luZyB0aGUgX2lkIGZpZWxkIChuZWRiIHVzZXMgaXRzIG93biBpZCBpbiB0aGF0XG4gICAgLy8gcGxhY2UpLiBJbnN0ZWFkIGNhbGwgaXQgX19pZFxuICAgIGRvYy5fX2lkID0gZG9jLl9pZDtcbiAgICBkb2MuX18kaWQgPSBkb2MuJGlkO1xuICAgIGRlbGV0ZSBkb2MuX2lkO1xuICAgIGRlbGV0ZSBkb2MuJGlkO1xuICAgIGxldCBkYmlkID0gdGhpcy5SRVNfVE9fREJfSURfTUFQW2RvYy5fXyRpZF07XG4gICAgaWYgKGRiaWQpIHtcbiAgICAgIHRoaXMuZGIudXBkYXRlKHtfaWQ6IGRiaWR9LCBkb2MsIHt9LCBmdW5jdGlvbihlcnIpIHtcbiAgICAgICAgY2FsbGJhY2soZXJyKTtcbiAgICAgIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmRiLmluc2VydChkb2MsIChlcnIsIG5ld0RvYykgPT4ge1xuICAgICAgICBpZiAoZXJyKSB7XG4gICAgICAgICAgcmV0dXJuIGNhbGxiYWNrKGVycik7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLlJFU19UT19EQl9JRF9NQVBbZG9jLl9fJGlkXSA9IG5ld0RvYy5faWQ7XG4gICAgICAgIGNhbGxiYWNrKCk7XG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICBwdWJsaWMgcXVlcnkocXJ5OiBhbnksIGNhbGxiYWNrOiBDYWxsYmFjaykge1xuICAgIGxldCBmaW5kID0gY3JlYXRlRGJGaW5kKHFyeS5maW5kKTtcbiAgICBsZXQgbGltaXQgPSBxcnkubGltaXQ7XG4gICAgbGV0IHNraXAgPSBxcnkuc2tpcDtcbiAgICBsZXQgc29ydCA9IHFyeS5zb3J0O1xuXG4gICAgbGV0IGN1ciA9IHRoaXMuZGIuZmluZChmaW5kKTtcblxuICAgIGlmIChzb3J0KSB7XG4gICAgICBjdXIgPSBjdXIuc29ydChzb3J0KTtcbiAgICB9XG4gICAgaWYgKHNraXApIHtcbiAgICAgIGN1ciA9IGN1ci5za2lwKHNraXApO1xuICAgIH1cbiAgICBpZiAobGltaXQpIHtcbiAgICAgIC8vIFdlIGdvICsgMSBzbyB3ZSBjYW4gdGVsbCBpZiB0aGVyZSBhcmUgYW55IG1vcmUgcmVzdWx0c1xuICAgICAgY3VyID0gY3VyLmxpbWl0KGxpbWl0ICsgMSk7XG4gICAgfVxuXG4gICAgY3VyLmV4ZWMoZnVuY3Rpb24oZXJyLCBkb2NzOiBhbnlbXSkge1xuICAgICAgLy8gTm93IGdvIGZyb20gb3VyIGRvY3MgdG8gdGhlIGlkc1xuICAgICAgbGV0IGlkcyA9IGRvY3MubWFwKGZ1bmN0aW9uKGRvYzogYW55KSB7XG4gICAgICAgIHJldHVybiBkb2MuX18kaWQgYXMgc3RyaW5nO1xuICAgICAgfSk7XG4gICAgICBjYWxsYmFjayhlcnIsIGlkcyk7XG4gICAgfSk7XG4gIH1cbn1cblxuLy8gQ29udmVydCBhbnkgX2lkIHNlYXJjaGVzIHRvIF9faWQgKHdoaWNoIGlzIHdoZXJlIG91ciBpZCBtb3ZlZCB0bylcbmZ1bmN0aW9uIF9jcmVhdGVEYkZpbmQocXJ5OiBhbnkpIHtcbiAgaWYgKEFycmF5LmlzQXJyYXkocXJ5KSkge1xuICAgIHFyeS5mb3JFYWNoKGZ1bmN0aW9uKHZhbCkge1xuICAgICAgX2NyZWF0ZURiRmluZCh2YWwpO1xuICAgIH0pO1xuICB9IGVsc2UgaWYgKGlzT2JqZWN0KHFyeSkpIHtcbiAgICBmb3IgKGxldCBrZXkgb2YgT2JqZWN0LmtleXMocXJ5KSkge1xuICAgICAgbGV0IHZhbCA9IHFyeVtrZXldO1xuXG4gICAgICAvLyBDb252ZXJ0IHRoZSBfaWQgdG8gX19pZCBzZWFyY2hlc1xuICAgICAgaWYgKGtleSA9PT0gJ19pZCcpIHtcbiAgICAgICAgcXJ5Ll9faWQgPSB2YWw7XG4gICAgICAgIGRlbGV0ZSBxcnkuX2lkO1xuICAgICAgfVxuXG4gICAgICBfY3JlYXRlRGJGaW5kKHZhbCk7XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIGNyZWF0ZURiRmluZChxcnk6IGFueSkge1xuICAvLyBDb252ZXJ0cyB0aGUgcXVlcnkgaW50byB0aGUgZm9ybSByZXF1aXJlZCBmb3IgYSBkYiBzZWFyY2guIEZpcnN0IGNsb25lIHRoZSBvYmplY3RcbiAgcXJ5ID0gY2xvbmVEZWVwKHFyeSk7XG4gIF9jcmVhdGVEYkZpbmQocXJ5KTtcbiAgcmV0dXJuIHFyeTtcbn1cblxuZnVuY3Rpb24gY3JlYXRlQ2FsbGJhY2soaWQ6IHN0cmluZykge1xuICByZXR1cm4gZnVuY3Rpb24gY2FsbGJhY2soZXJyPzogRXJyb3IsIHJlc3A/OiBhbnkpIHtcbiAgICBtZS5wb3N0TWVzc2FnZSh7XG4gICAgICBpZCxcbiAgICAgIGRhdGE6IHJlc3AsXG4gICAgICBlcnJvcjogZXJyICYmIGVyci5tZXNzYWdlLFxuICAgIH0pO1xuICB9O1xufVxuXG5mdW5jdGlvbiBnZXREYXRhYmFzZShkYmlkOiBzdHJpbmcpIHtcbiAgbGV0IGRiID0gX0RCX01BUFtkYmlkXTtcblxuICBpZiAoIWRiKSB7XG4gICAgZGIgPSBuZXcgRGF0YWJhc2UoKTtcbiAgICBfREJfTUFQW2RiaWRdID0gZGI7XG4gIH1cblxuICByZXR1cm4gZGI7XG59XG5cbmZ1bmN0aW9uIGhhbmRsZU1lc3NhZ2UoZXZlbnQ6IE1lc3NhZ2VFdmVudCkge1xuICBsZXQgZGF0YSA9IGV2ZW50LmRhdGE7XG4gIGxldCBkYmlkID0gZGF0YS5kYmlkO1xuICBsZXQgaWQgPSBkYXRhLmlkO1xuICBsZXQgYXJncyA9IGRhdGEuYXJncztcbiAgbGV0IGNiID0gY3JlYXRlQ2FsbGJhY2soaWQpO1xuICBsZXQgZGIgPSBnZXREYXRhYmFzZShkYmlkKTtcblxuICBzd2l0Y2ggKGRhdGEuZm5OYW1lKSB7XG4gICAgY2FzZSAndXBkYXRlJzpcbiAgICAgIGRiLnVwZGF0ZShhcmdzWzBdLCBjYik7XG4gICAgICBicmVhaztcbiAgICBjYXNlICdyZW1vdmUnOlxuICAgICAgZGIucmVtb3ZlKGFyZ3NbMF0sIGNiKTtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgJ3F1ZXJ5JzpcbiAgICAgIGRiLnF1ZXJ5KGFyZ3NbMF0sIGNiKTtcbiAgICAgIGJyZWFrO1xuICAgIGRlZmF1bHQ6XG4gICAgICBjYihuZXcgRXJyb3IoYE5vIHN1Y2ggbWV0aG9kICR7ZGF0YS5mbk5hbWV9YCkpO1xuICAgICAgYnJlYWs7XG4gIH1cbn1cbiJdfQ==