@x5e/gink
Version:
an eventually consistent database
89 lines • 3.89 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.SimpleServer = void 0;
const Database_1 = require("./Database");
const Peer_1 = require("./Peer");
const buffer_1 = require("buffer");
const Listener_1 = require("./Listener");
const utils_1 = require("./utils");
/**
* A server that connects all inbound websocket connections to a single database instance.
*/
class SimpleServer extends Database_1.Database {
constructor(store, args) {
super(store, args.identity, args.logger || (() => null));
this.listener = new Listener_1.Listener(Object.assign({ requestHandler: this.onRequest.bind(this), requestListener: this.requestListener.bind(this), index: "/static/dashboard/dashboard.html" }, args));
this.connections = new Map();
this.authFunc = args.authFunc || (() => true);
this.ready = Promise.all([this.ready, this.listener.ready]).then(() => args.logger(`SimpleServer.ready`));
}
async onRequest(request) {
await this.ready;
const thisServer = this; // pass into closures
let protocol = null;
let token = null;
if (request.requestedProtocols.length) {
for (const protocol of request.requestedProtocols) {
if (protocol.match(/0x.*/)) {
token = (0, utils_1.decodeToken)(protocol);
}
}
if (request.requestedProtocols.includes(Database_1.Database.PROTOCOL))
protocol = Database_1.Database.PROTOCOL;
else
return request.reject(400, "bad protocol");
}
if (!this.authFunc(token)) {
return request.reject(401, "authentication failed");
}
const connection = request.accept(protocol, request.origin);
this.logger(`Connection accepted.`);
const sendFunc = (data) => {
connection.sendBytes(buffer_1.Buffer.from(data));
};
const closeFunc = () => {
connection.close();
};
const connectionId = this.createConnectionId();
this.connections.set(connectionId, connection);
const peer = new Peer_1.Peer(sendFunc, closeFunc);
this.peers.set(connectionId, peer);
connection.on("close", function (_reasonCode, _description) {
thisServer.peers.delete(connectionId);
thisServer.connections.delete(connectionId);
thisServer.logger(" Peer " + connection.remoteAddress + " disconnected.");
});
connection.on("message", this.onMessage.bind(this, connectionId));
sendFunc(this.iHave.getGreetingMessageBytes());
}
onMessage(connectionId, webSocketMessage) {
if (webSocketMessage.type === "utf8") {
this.logger("Received Text Message: " + webSocketMessage.utf8Data);
}
else if (webSocketMessage.type === "binary") {
this.logger("Server received binary message of " +
webSocketMessage.binaryData.length +
" bytes.");
this.receiveMessage(webSocketMessage.binaryData, connectionId).catch((reason) => this.logger(reason));
}
}
requestListener(request, response) {
const connectTo = this.connectTo.bind(this);
if (request.url.startsWith("/api/connections")) {
if (request.method === "GET") {
let connections = Object.fromEntries(this.connections);
response.end(JSON.stringify(connections));
}
if (request.method === "POST") {
request.addListener("data", async function (chunk) {
await connectTo(chunk);
});
}
}
else {
this.listener.requestListener(request, response);
}
}
}
exports.SimpleServer = SimpleServer;
//# sourceMappingURL=SimpleServer.js.map