@x5e/gink
Version:
an eventually consistent database
110 lines • 4.59 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.CommandLineInterface = void 0;
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");
const Directory_1 = require("./Directory");
const Box_1 = require("./Box");
const Sequence_1 = require("./Sequence");
const KeySet_1 = require("./KeySet");
const Accumulator_1 = require("./Accumulator");
/**
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) {
// This makes debugging through integration tests way easier.
globalThis.ensure = utils_1.ensure;
this.logger = args.verbose ? utils_1.logToStdErr : utils_1.noOp;
this.authToken = args.auth_token;
this.reconnectOnClose = args.reconnect;
this.targets = args.connect_to ?? [];
const identity = args.identity ?? (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_file) {
const is_exclusive = args.exclusive ? "exclusive" : "not exclusive";
this.logger(`using data file=${args.data_file} (${is_exclusive})`);
this.store = new LogBackedStore_1.LogBackedStore(args.data_file, args.exclusive);
}
else {
this.logger(`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: this.logger,
authFunc: authFunc,
};
this.instance = new SimpleServer_1.SimpleServer({
store: this.store,
identity: identity,
...common,
});
}
else {
// port not set so don't listen for incoming connections
this.instance = new Database_1.Database({
store: this.store,
identity,
logger: this.logger,
});
}
}
async run() {
if (this.instance) {
await this.instance.ready;
globalThis.isAlive = utils_1.isAlive;
globalThis.database = this.instance;
globalThis.root = Directory_1.Directory.get(this.instance);
globalThis.Accumulator = Accumulator_1.Accumulator;
globalThis.Sequence = Sequence_1.Sequence;
globalThis.Box = Box_1.Box;
globalThis.KeySet = KeySet_1.KeySet;
globalThis.Directory = Directory_1.Directory;
for (const target of this.targets) {
this.logger(`connecting to: ${target}`);
await this.instance.connectTo(target, {
reconnectOnClose: this.reconnectOnClose,
authToken: this.authToken,
onError: (e) => {
this.logger(`Failed connection to ${target}. Bad Auth token?\n` +
e);
},
}).ready;
this.logger(`connected!`);
}
}
this.replServer = (0, node_repl_1.start)({ prompt: "node+gink> ", useGlobal: true });
this.replServer.on("exit", () => {
process.exit(0);
});
}
}
exports.CommandLineInterface = CommandLineInterface;
//# sourceMappingURL=CommandLineInterface.js.map