@pamlight/admin
Version:
The library for syncing data changes to multiple devices from your database
186 lines (185 loc) • 7.63 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
var shared_1 = require("../shared");
var lodash_1 = require("lodash");
var services_1 = require("../services");
var socket_1 = require("./socket");
var PamlightAdmin = /** @class */ (function () {
function PamlightAdmin(credentials) {
this._readRoutesMap = {};
this._writeRoutesMap = {};
this.client = new socket_1.ServerSocketIOClient(credentials);
this._settings = {};
this.setupRoutesModel();
}
PamlightAdmin.prototype.enableDevMode = function () {
this.client.enableDevMode();
};
PamlightAdmin.prototype.configure = function (key, val) {
this._settings[key] = val;
};
PamlightAdmin.prototype.route = function (route) {
if (route.type === shared_1.RouteTypes.READ) {
this.reads.route(route);
}
else if (route.type === shared_1.RouteTypes.WRITE) {
this.writes.route(route);
}
else {
throw Error("Invalid route type " + JSON.stringify(route));
}
};
PamlightAdmin.prototype.routes = function () {
var _this = this;
var rs = [];
for (var _i = 0; _i < arguments.length; _i++) {
rs[_i] = arguments[_i];
}
rs.forEach(function (r) { return _this.route(r); });
};
PamlightAdmin.prototype.start = function () {
var _this = this;
return new Promise(function (resolve, reject) {
if (_this.appStarted) {
reject(new Error('Pamlight app instance run method called more than once'));
}
else {
_this.appStarted = true;
if (lodash_1.keys(_this._readRoutesMap).length === 0) {
console.warn('Starting pamlight app without any read route configured');
}
if (lodash_1.keys(_this._writeRoutesMap).length === 0) {
console.warn('Starting pamlight app without any write route configured');
}
var routeErr = _this.checkWriteRoutes();
if (routeErr) {
reject(new Error(routeErr));
}
else {
_this.client.ensureConnection().then(function () {
return _this.client.toggleAppState(true, lodash_1.values(_this._readRoutesMap), lodash_1.values(_this._writeRoutesMap));
}).then(function () {
resolve();
}).catch(function (err) {
reject(err.error || err);
});
}
}
});
};
PamlightAdmin.prototype.stop = function () {
var _this = this;
return new Promise(function (resolve, reject) {
_this.appStarted = false;
_this.client.ensureConnection()
.then(function () { return _this.client.toggleAppState(false); })
.then(function () {
resolve();
}).catch(function (err) {
reject(err.error || err);
});
});
};
/* Private members */
PamlightAdmin.prototype.validateRouteID = function (routeId) {
if (/\W/.test(routeId)) {
return "Unacceptable routeId in " + routeId;
}
return null;
};
PamlightAdmin.prototype.configureReadRoute = function (config) {
if (!config.routeId) {
throw Error("Route ID is a required property for read configuration");
}
var routeErr = this.validateRouteID(config.routeId);
if (routeErr) {
throw Error(routeErr);
}
if (this._readRoutesMap[config.routeId]) {
throw Error("Route ID: " + config.routeId + " already configured for read operation");
}
// adds default values to config
config = Object.assign({}, {
queryFn: function () {
return {};
},
skip: 0,
projection: {}
}, config);
// _id must not be false or -1 if projection is applied because
// _id is currently the only way to identify unique document on the client
var projection = config.projection;
if (projection && (projection._id === false || projection._id === -1)) {
throw Error("Error at " + config.routeId + " config. Query result projection must not exclude primary key.");
}
// sets default sort if skip and/or limit operators are applied
// if ((config.skip || config.limit) && !config.sort) {
// config.sort = getDefaultPrimaryIndex();
// }
// indexable queries cannot be used on single document queries
if (services_1.isIndexRequired(config) && config.isSingleDocument) {
throw Error("Indexable query options (sort) cannot be applied to single document query");
}
this._readRoutesMap[config.routeId] = config;
};
PamlightAdmin.prototype.configureWriteRoute = function (config) {
if (!config.routeId) {
throw Error("Route ID is a required property for write configuration");
}
var routeErr = this.validateRouteID(config.routeId);
if (routeErr) {
throw Error(routeErr);
}
if (this._writeRoutesMap[config.routeId]) {
throw Error("Route ID: " + config.routeId + " already configured for write operation");
}
// adds default values to config
config.triggers = config.triggers || [];
if (!config.docFn) {
config.docFn = function (queryData, updateData) {
return Promise.resolve({ query: queryData, payload: updateData });
};
}
this._writeRoutesMap[config.routeId] = config;
};
PamlightAdmin.prototype.setupRoutesModel = function () {
var _this = this;
this.reads = {
route: function (config) {
_this.configureReadRoute(config);
},
routes: function (configs) {
for (var _i = 0, configs_1 = configs; _i < configs_1.length; _i++) {
var config = configs_1[_i];
_this.configureReadRoute(config);
}
}
};
this.writes = {
route: function (config) {
_this.configureWriteRoute(config);
},
routes: function (configs) {
for (var _i = 0, configs_2 = configs; _i < configs_2.length; _i++) {
var config = configs_2[_i];
_this.configureWriteRoute(config);
}
}
};
};
PamlightAdmin.prototype.checkWriteRoutes = function () {
var routes = lodash_1.values(this._writeRoutesMap);
for (var _i = 0, routes_1 = routes; _i < routes_1.length; _i++) {
var route = routes_1[_i];
for (var _a = 0, _b = route.triggers; _a < _b.length; _a++) {
var triggeredId = _b[_a];
if (!this._writeRoutesMap[triggeredId]) {
return "'" + triggeredId + "' is not a valid routeId as trigger for '" + route.routeId + "'";
}
}
}
return null;
};
return PamlightAdmin;
}());
exports.PamlightAdmin = PamlightAdmin;