Browse Source

Asyncify everything so that we can do dependency injection

master
Starbeamrainbowlabs 2 years ago
parent
commit
bd08aae1da
  1. 1
      .gitignore
  2. 72
      server/bootstrap/cli.mjs
  3. 63
      server/bootstrap/container.mjs
  4. 4
      server/bootstrap/database_init.mjs
  5. 6
      server/help.mjs
  6. 78
      server/index.mjs

1
.gitignore

@ -1,4 +1,5 @@
example-message.json
*.sqlite
*.pcapng
*.png
*.stl

72
server/bootstrap/cli.mjs

@ -0,0 +1,72 @@
"use strict";
import show_help from '../help.mjs';
import { decode_payload } from '../ttn-app-server/DecodePayload.mjs';
export default async function(c) {
let { ansi: a, log: l, settings } = c.cradle;
// 2: CLI Argument Parsing
let args = process.argv.slice(2); // Slice out the node binary name and the filename
let extras = [];
for(let i = 0; i < args.length; i++) {
if(!args[i].startsWith("-")) {
extras.push(args[i]);
continue;
}
switch(args[i]) {
case "--help":
case "-h":
show_help(c.cradle);
process.exit();
break;
case "--version":
case "-v":
console.log(program.version);
break;
// Add more arguments here
}
}
// 3: Environment Variable Parsing
// process.env.XYZ
// 4: Run
if(extras.length < 1) {
console.error(`${a.fred}${a.hicol}Error: No subcommand specified.${a.reset}`);
show_help(c.cradle);
process.exit();
}
l.log(`${a.fgreen}${a.hicol}*** LoRaWAN Signal Mapper ***${a.reset}`);
switch(extras[0]) {
case "ttn-app-server":
l.log(`${a.fgreen}${a.hicol}Starting The Things Network application server${a.reset}`);
let app_server = c.resolve("TTNAppServer");
await app_server.run();
break;
case "decode-test":
l.log(`${a.fgreen}${a.hicol}Decoding message${a.reset}`);
if(process.argv.length < 4) {
l.error("No message specified. Specify the message to decode in single quotes directly after 'decode-test'.");
process.exit(1);
}
l.log("Input: ", process.argv[3]);
l.log("Output: ", decode_payload(process.argv[3]));
break;
default:
console.error(`${a.fred}${a.hicol}Error: Subcommand '${extras[0]}' not recognised.${a.reset}`);
console.error( `${a.fred}Perhaps you mistyped it, or it hasn't been implemented yet?`);
process.exit(1);
break;
}
}

63
server/bootstrap/container.mjs

@ -1,5 +1,9 @@
"use strict";
import { promises as fs } from 'fs';
import path from 'path';
import { fileURLToPath } from 'url';
import a from 'awilix';
import Ansi from '../Helpers/Ansi.mjs';
@ -10,22 +14,47 @@ import MessageHandler from '../ttn-app-server/MessageHandler.mjs';
import settings from './settings.mjs';
import database_init from '../bootstrap/database_init.mjs';
const c = a.createContainer({
injectionMode: a.InjectionMode.PROXY
});
c.register({
settings: a.asValue(settings),
ansi: a.asClass(Ansi).singleton(),
log: a.asClass(Log).singleton(),
database: a.asFunction(database_init).singleton(),
TTNAppServer: a.asClass(TTNAppServer),
MessageHandler: a.asClass(MessageHandler)
});
const root_dir = path.dirname(path.dirname(fileURLToPath(import.meta.url)));
c.loadModules("../Repos.SQLite/*.mjs", {
register: a.asClass,
lifetime: a.Lifetime.SINGLETON
});
export default async function setup() {
const c = a.createContainer({
injectionMode: a.InjectionMode.PROXY
});
export default c;
c.register({
root_dir: a.asValue(root_dir),
settings: a.asValue(settings),
ansi: a.asClass(Ansi).singleton(),
log: a.asClass(Log).singleton(),
database: a.asFunction(database_init).singleton(),
TTNAppServer: a.asClass(TTNAppServer),
MessageHandler: a.asClass(MessageHandler)
});
let repo_filenames = await fs.readdir(path.join(root_dir, "./Repos.SQLite"));
for(let repo_filename of repo_filenames) {
let class_root = await import(path.join(root_dir, `./Repos.SQLite/${repo_filename}`)),
class_name = class_root.default.prototype.constructor.name;
c.register(
class_name,
a.asClass(class_root.default).singleton(),
);
}
// console.log(c.registrations);
// c.loadModules([
// "./Repos.SQLite/*.mjs"
// // "./Repos.SQLite/ReadingRepo.mjs"
// ], {
// cwd: root_dir,
// resolverOptions: {
// register: a.asClass,
// lifetime: a.Lifetime.SINGLETON
// }
// });
return c;
}

4
server/bootstrap/database_init.mjs

@ -5,9 +5,9 @@ import Database from 'better-sqlite3';
var db = null;
async function init({ settings: { database: { filename, options } } }) {
function init({ settings: { database: { filename, options } } }) {
db = new Database(filename, options);
db.exec(await fs.promises.readFile("../db_template.sql", "utf8"));
db.exec(fs.readFileSync("../db_template.sql", "utf8"));
return db;
}

6
server/help.mjs

@ -1,10 +1,6 @@
import path from 'path';
import c from './bootstrap/container.mjs';
const a = c.resolve("ansi");
export default function(settings) {
export default function({ settings, ansi : a }) {
console.log(`${settings.program_name}, ${settings.version}
${a.locol}By Starbeamrainbowlabs${a.reset}

78
server/index.mjs

@ -2,74 +2,16 @@
"use strict";
// 1: Setup & Imports
import c from './bootstrap/container.mjs';
import show_help from './help.mjs';
import { decode_payload } from './ttn-app-server/DecodePayload.mjs';
const settings = c.resolve("settings");
const a = c.resolve("ansi");
const l = c.resolve("log");
// 2: CLI Argument Parsing
let args = process.argv.slice(2); // Slice out the node binary name and the filename
let extras = [];
for(let i = 0; i < args.length; i++) {
if(!args[i].startsWith("-")) {
extras.push(args[i]);
continue;
import setup from './bootstrap/container.mjs';
import cli from './bootstrap/cli.mjs';
async function run() {
try {
let c = await setup();
await cli(c);
} catch(error) {
console.error(error);
}
switch(args[i]) {
case "--help":
case "-h":
show_help(settings);
process.exit();
break;
case "--version":
case "-v":
console.log(program.version);
break;
// Add more arguments here
}
}
// 3: Environment Variable Parsing
// process.env.XYZ
// 4: Run
if(extras.length < 1) {
console.error(`${a.fred}${a.hicol}Error: No subcommand specified.${a.reset}`);
show_help(settings);
process.exit();
}
l.log(`${a.fgreen}${a.hicol}*** LoRaWAN Signal Mapper ***${a.reset}`);
switch(extras[0]) {
case "ttn-app-server":
l.log(`${a.fgreen}${a.hicol}Starting The Things Network application server${a.reset}`);
let app_server = c.resolve("TTNAppServer");
app_server.run();
break;
case "decode-test":
l.log(`${a.fgreen}${a.hicol}Decoding message${a.reset}`);
if(process.argv.length < 4) {
l.error("No message specified. Specify the message to decode in single quotes directly after 'decode-test'.");
process.exit(1);
}
l.log("Input: ", process.argv[3]);
l.log("Output: ", decode_payload(process.argv[3]));
break;
default:
console.error(`${a.fred}${a.hicol}Error: Subcommand '${extras[0]}' not recognised.${a.reset}`);
console.error( `${a.fred}Perhaps you mistyped it, or it hasn't been implemented yet?`);
process.exit(1);
break;
}
run();

Loading…
Cancel
Save