@x5e/gink
Version:
an eventually consistent database
106 lines • 4.79 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.CommandLineInterface = void 0;
const RoutingServer_1 = require("./RoutingServer");
const LogBackedStore_1 = require("./LogBackedStore");
const Database_1 = require("./Database");
const SimpleServer_1 = require("./SimpleServer");
const utils_1 = require("./utils");
const IndexedDbStore_1 = require("./IndexedDbStore");
const node_repl_1 = require("node:repl");
/**
Intended to manage server side running of Gink.
Basically it takes some settings in the form of
arguments plus a list of peers to
connect to then starts up the Gink Instance,
or Gink Server if port listening is specified.
*/
class CommandLineInterface {
constructor(args) {
var _a, _b;
(0, utils_1.logToStdErr)("starting...");
// This makes debugging through integration tests way easier.
globalThis.ensure = utils_1.ensure;
let logger = utils_1.logToStdErr;
this.authToken = args.auth_token;
this.retryOnDisconnect = args.reconnect;
this.targets = (_a = args.connect_to) !== null && _a !== void 0 ? _a : [];
const identity = (_b = args.identity) !== null && _b !== void 0 ? _b : (0, utils_1.getIdentity)();
(0, utils_1.ensure)(identity);
let authFunc = null;
if (this.authToken) {
authFunc = (token) => {
// Expecting token to have already been decoded from hex.
if (!token)
return false;
// Purposely using includes here since the token will have been
// decoded and may contain '\x00' as a prefix.
(0, utils_1.ensure)(token.includes("token "));
let key = this.authToken.toLowerCase();
token = token.toLowerCase().split("token ")[1].trimStart();
return token === key;
};
}
if (args.data_root) {
(0, utils_1.logToStdErr)(`using data root ${args.data_root}`);
(0, utils_1.ensure)(args.listen_on, "must provide port for routing server to listen on hint: -l [port]");
}
else if (args.data_file) {
(0, utils_1.logToStdErr)(`using data file=${args.data_file}`);
this.store = new LogBackedStore_1.LogBackedStore(args.data_file);
}
else {
(0, utils_1.logToStdErr)(`using in-memory database`);
this.store = new IndexedDbStore_1.IndexedDbStore((0, utils_1.generateTimestamp)().toString());
}
if (args.listen_on) {
const common = {
port: args.listen_on,
sslKeyFilePath: args.ssl_key,
sslCertFilePath: args.ssl_cert,
staticContentRoot: args.static_path,
logger: logger,
authFunc: authFunc,
};
if (args.data_root) {
this.routingServer = new RoutingServer_1.RoutingServer(Object.assign({ identity: identity, dataFilesRoot: args.data_root }, common));
}
else {
this.instance = new SimpleServer_1.SimpleServer(this.store, Object.assign({ identity: identity }, common));
}
}
else {
// port not set so don't listen for incoming connections
this.instance = new Database_1.Database(this.store, identity, logger);
}
}
async run() {
var _a;
if (this.instance) {
await this.instance.ready;
globalThis.database = this.instance;
globalThis.root = this.instance.getGlobalDirectory();
this.instance.addListener(async (bundle) => (0, utils_1.logToStdErr)(`received bundle: ${JSON.stringify(bundle.info, ["medallion", "timestamp", "comment"])}`));
for (const target of this.targets) {
(0, utils_1.logToStdErr)(`connecting to: ${target}`);
try {
await this.instance.connectTo(target, {
onClose: utils_1.logToStdErr,
retryOnDisconnect: this.retryOnDisconnect,
authToken: this.authToken,
});
(0, utils_1.logToStdErr)(`connected!`);
}
catch (e) {
(0, utils_1.logToStdErr)(`Failed connection to ${target}. Bad Auth token?\n` + e);
}
}
}
else {
await ((_a = this.routingServer) === null || _a === void 0 ? void 0 : _a.ready);
}
this.replServer = (0, node_repl_1.start)({ prompt: "node+gink> ", useGlobal: true });
}
}
exports.CommandLineInterface = CommandLineInterface;
//# sourceMappingURL=CommandLineInterface.js.map