@real-db/server
Version:
The library for syncing data changes to multiple devices from your database
167 lines (166 loc) • 7.07 kB
JavaScript
;
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
result["default"] = mod;
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
var room_1 = require("./room");
var adapter_1 = require("./adapter");
var enums_1 = require("../shared/enums");
var lodash_1 = require("lodash");
var IO = __importStar(require("socket.io"));
var utilService = __importStar(require("../services"));
/**
* The main Realtime Database class
*/
var RealDBCore = /** @class */ (function () {
function RealDBCore(config) {
var _this = this;
this._rooms = {};
this._globalAuths = [this.defaultAuth];
// sets default values if not specified in config object
this._config = lodash_1.assign({}, {
// default props will be here
}, config);
// initializes io for connections
this._io = IO.default(this._config.httpServer);
this._io.on('connection', function (socket) {
// list of room ids for events fired already to prevent duplication
var roomIds = [];
// we allow each socket to listen to each roomId when they connect to server
lodash_1.keys(_this._rooms).forEach(function (roomId) {
// listens for each room syncs
socket.on(roomId, function (payload) {
if (roomIds.indexOf(roomId) >= 0) {
_this._rooms[roomId].updateSocketData(socket.id, payload);
}
else {
roomIds.push(roomId);
_this._rooms[roomId].addSocketToRoom(socket, payload);
}
});
});
// manually trigger the global auth function
// @TODO we need to get payload from the connection data
_this.globalAuthTriggerHandler({}, socket.id);
// listen for global auth triggers
socket.on('_REAL_DB_GLOBAL_AUTH_', function (payload) {
_this.globalAuthTriggerHandler(payload, socket.id);
});
});
// applies selected adapter event triggers for write operations
this.applyAdapterTriggers();
}
/**
* Sets global middlewares for any connected clients
* @param auths List of authentication functions to be applied at global level
*/
RealDBCore.prototype.setMiddlewares = function () {
var auths = [];
for (var _i = 0; _i < arguments.length; _i++) {
auths[_i] = arguments[_i];
}
if (auths.length > 0) {
this._globalAuths = auths;
}
};
/**
* Configures each room with id like route setup
* @param roomId unique id for each room
* @param options config options for the room created
* @param auths list of authentication functions that return promise<boolean>
*/
RealDBCore.prototype.route = function (roomId, options) {
var auths = [];
for (var _i = 2; _i < arguments.length; _i++) {
auths[_i - 2] = arguments[_i];
}
// checks if room id already exists
if (this._rooms[roomId]) {
throw Error("Room '" + roomId + "' already exist");
}
// we need to test if the query template is valid and it matches the query params
// try {
// const testQuery = utilService.generateQueryFromTemplate(
// options.template,
// utilService.generateTestQueryParamValues(options.queryParams)
// );
// console.log(testQuery);
// } catch (e) {
// throw Error(e ||
// `Error while configuring route '${roomId}'.
// Invalid or unmatchable template and queryParams`
// );
// }
// uses default auth function if not supplied
if (auths.length === 0) {
auths = [this.defaultAuth];
}
// create the room
var newRoom = new room_1.RealDBRoom(roomId, options, auths, this._adapter);
// adds new room to list of rooms
this._rooms[roomId] = newRoom;
};
/**
* Applies global auth middlewares and sets each room status for socket
* @param payload payload from client
* @param socketId socket id
*/
RealDBCore.prototype.globalAuthTriggerHandler = function (payload, socketId) {
var _this = this;
utilService.resolveAuths(this._globalAuths, lodash_1.cloneDeep(payload), function (status) {
// iterate through each room for this socket and trigger authStateChanged callbacks
lodash_1.keys(_this._rooms).forEach(function (roomId) {
_this._rooms[roomId].setGlobalAuthState(status, socketId);
});
});
};
/**
* Sends affected document to only rooms of the affected collection
* @param col collection name
* @param doc affected document
* @param operationType write operation type
*/
RealDBCore.prototype.filterRoomsForTrigger = function (col, doc, op) {
var _this = this;
lodash_1.keys(this._rooms).forEach(function (roomId) {
if (_this._rooms[roomId].collectionName === col) {
_this._rooms[roomId].broadcastChangesToRoom(doc, op);
}
});
};
/**
* Applies selected adapter event triggers for write operations
*/
RealDBCore.prototype.applyAdapterTriggers = function () {
var _this = this;
// create new instance of adapter
this._adapter = adapter_1.getRealDBAdapter(this._config.adapterId, this._config.dbUrl);
// triggered whenever a new document is created
this._adapter.onCreate(function (col, doc) {
_this.filterRoomsForTrigger(col, doc, enums_1.WriteOperationTypes.CREATE);
});
// triggered when a document is updated
this._adapter.onUpdate(function (col, doc) {
_this.filterRoomsForTrigger(col, doc, enums_1.WriteOperationTypes.UPDATE);
});
// triggered when a document is deleted
this._adapter.onDelete(function (col, doc) {
_this.filterRoomsForTrigger(col, doc, enums_1.WriteOperationTypes.DELETE);
});
};
/**
* Default auth implementation used if auth middleware is not specified
* @param payload client payload
* @param authChangedFn auth state change trigger callback
*/
RealDBCore.prototype.defaultAuth = function (payload, authChangedFn) {
console.log('Auth middleware not provided. Using no-auth trigger...');
authChangedFn(true);
};
return RealDBCore;
}());
exports.RealDBCore = RealDBCore;