diff --git a/.system b/.system
index c86bac2..76bd100 100644
--- a/.system
+++ b/.system
@@ -1,21 +1,17 @@
{
"handoff": "",
"instances": {
- "72C17CDFC5F943E0A41155D892419843": {
+ "50C60F4EF04D41B38A2EB573788829DA": {
"config": {},
"module": "systemd"
},
- "D2A1E19739BB4CC08DD7192164CD4D67": {
- "config": {},
- "module": "sshd"
- },
- "768C13637962402D803215C97D8F04CD": {
- "config": {},
- "module": "systemd"
- },
- "0CEB261DB70A4A51BC80E15D782D8D98": {
+ "C34D0DE00AB3454195E9249BF3596610": {
"config": {},
"module": "sshd"
}
+ },
+ "aliases": {
+ "systemd": "50C60F4EF04D41B38A2EB573788829DA",
+ "sshd": "C34D0DE00AB3454195E9249BF3596610"
}
}
\ No newline at end of file
diff --git a/loader.mjs b/loader.mjs
index 1604afa..2e5a2b9 100644
--- a/loader.mjs
+++ b/loader.mjs
@@ -16,6 +16,7 @@ let echo = true;
export async function resolve(specifier, context, defaultResolver) {
if(echo === false) {
} else if(imports === 0) {
+ console.log(chalk.black.bgAnsi256(204)(' Welcome to Vogue System Runtime '));
console.log(chalk.green('#'), chalk.ansi256(242)('@kernel'))
} else {
console.log(chalk.green('#'), chalk.ansi256(242)(specifier));
@@ -26,13 +27,20 @@ export async function resolve(specifier, context, defaultResolver) {
}
const maps = {
- 'file:///boot': pathResolve(__dirname, 'src', 'index.ts'),
- '@kernel:base': pathResolve(__dirname, 'src', 'index.ts'),
- '@kernel:log-hook': pathResolve(__dirname, 'src', 'logHook.ts'),
+ 'file:///boot': pathResolve(__dirname, 'src', 'index.ts'),
+
+ '@kernel:base': pathResolve(__dirname, 'src', 'index.ts'),
+ '@kernel:log-hook': pathResolve(__dirname, 'src', 'logHook.ts'),
+
'@commands:executor': pathResolve(__dirname, 'src', 'commands', 'executor.ts'),
- '@builtin:systemd': pathResolve(__dirname, 'src', 'modules', 'systemd.ts'),
- '@builtin:sshd': pathResolve(__dirname, 'src', 'modules', 'sshd.ts'),
- '@echo off': pathResolve(__dirname, 'src', 'noop.ts')
+ '@commands:create': pathResolve(__dirname, 'src', 'commands', 'create.ts'),
+ '@commands:ls': pathResolve(__dirname, 'src', 'commands', 'ls.ts'),
+ '@commands:save': pathResolve(__dirname, 'src', 'commands', 'save.ts'),
+
+ '@builtin:systemd': pathResolve(__dirname, 'src', 'modules', 'systemd.ts'),
+ '@builtin:sshd': pathResolve(__dirname, 'src', 'modules', 'sshd.ts'),
+
+ '@echo off': pathResolve(__dirname, 'src', 'noop.ts')
};
const matches = Object.keys(maps).filter(map => specifier.startsWith(map));
diff --git a/package.json b/package.json
index a7cd3b3..b6d4bc5 100644
--- a/package.json
+++ b/package.json
@@ -5,13 +5,15 @@
"license": "MIT",
"type": "module",
"scripts": {
- "start": "(clear || cls) && node --no-warnings --loader ./loader.mjs /boot",
+ "start": "(clear || cls) && node --no-warnings --unhandled-rejections=strict --loader ./loader.mjs /boot",
"tsc": "tsc"
},
"dependencies": {
+ "@types/md5": "^2.3.1",
"@types/node": "^16.11.12",
"@types/uuid": "^8.3.3",
"chalk": "^5.0.0",
+ "md5": "^2.3.0",
"serverline": "^1.5.0",
"ssh2": "^1.5.0",
"telnet": "^0.0.1",
diff --git a/src/commands/create.ts b/src/commands/create.ts
index e757de7..ac91ab3 100644
--- a/src/commands/create.ts
+++ b/src/commands/create.ts
@@ -1,7 +1,33 @@
-import createExecutor from "./executor.js";
+import { system, autoColorString } from '@kernel:base';
+import * as uuid from 'uuid';
-export const create = createExecutor({
- pawn() {
-
+export default async function create(module: string, name: string, id: string) {
+ if(!module || typeof module !== 'string' || module.trim() === '') {
+ throw new Error('INVALID_MODULE_NAME');
}
-})
\ No newline at end of file
+ if(name && (typeof name !== 'string' || name.trim() === '')) {
+ throw new Error('IVALID_MODULE_ALIAS');
+ }
+ name ??= module;
+ if(system.aliases.has(name)) {
+ if(name === module) {
+ throw new Error('DEFAULT_MODULE_ALREADY_EXISTS');
+ } else {
+ throw new Error('MODULE_ALIAS_TAKEN');
+ }
+ }
+ const imported = (await import('@builtin:' + module));
+ const functions = 'default' in imported ? imported.default : imported;
+ id ??= uuid.v4().replace(/-/g, '').toUpperCase();
+ system.instances.set(id, {
+ config: {},
+ ram: {},
+ module: module,
+ functions
+ });
+ if(name) {
+ system.aliases.set(name, id);
+ }
+ console.log('Created instance of', autoColorString(module))
+ return id;
+}
\ No newline at end of file
diff --git a/src/commands/ls.ts b/src/commands/ls.ts
new file mode 100644
index 0000000..f3229f3
--- /dev/null
+++ b/src/commands/ls.ts
@@ -0,0 +1,15 @@
+import { system, autoColorString } from '@kernel:base';
+import chalk from 'chalk';
+
+export default function ls(flags: any) {
+ // if(flags) console.log(flags)
+
+ console.log('Instances', chalk.ansi256(242)('(' + system.instances.size + ')'));
+ for(const [k, v] of system.instances) {
+ console.log(
+ ' '
+ + autoColorString(k.substring(0, 4))
+ + ':', JSON.stringify(v.config, null, 2).replace('\n', ' ').trim()
+ );
+ }
+}
\ No newline at end of file
diff --git a/src/commands/save.ts b/src/commands/save.ts
new file mode 100644
index 0000000..5e97c1f
--- /dev/null
+++ b/src/commands/save.ts
@@ -0,0 +1,26 @@
+import { system } from '@kernel:base';
+import { resolve } from 'path';
+import { writeFileSync } from 'fs';
+
+export default function save() {
+ const timeStart = new Date().getTime();
+ const obj: any = {
+ handoff: system.handoff,
+ instances: {},
+ aliases: {}
+ };
+ for(const [id, info] of system.instances.entries()) {
+ obj.instances[id] = {
+ config: info.config,
+ module: info.module
+ }
+ }
+ for(const [alias, id] of system.aliases.entries()) {
+ obj.aliases[alias] = id;
+ }
+ const systemString = JSON.stringify(obj, null, 2);
+ const fullPath = resolve('.system');
+ writeFileSync(fullPath, systemString);
+ const elapsed = new Date().getTime() - timeStart;
+ console.log('System saved to ' + fullPath + ' in ' + elapsed + ' ms')
+}
\ No newline at end of file
diff --git a/src/externals.d.ts b/src/externals.d.ts
index a8ebaa8..847853f 100644
--- a/src/externals.d.ts
+++ b/src/externals.d.ts
@@ -2,6 +2,9 @@ declare module "serverline";
declare module "telnet";
declare module "@kernel:base";
declare module "@commands:executor";
+declare module "@commands:create";
+declare module "@commands:ls";
+declare module "@commands:save";
declare module "@builtin:systemd";
declare module "@builtin:sshd";
declare module "@echo off";
\ No newline at end of file
diff --git a/src/index.ts b/src/index.ts
index c291a99..75de3d7 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -1,14 +1,16 @@
///
-// console.clear();
-
import '@kernel:log-hook';
import createExecutor from '@commands:executor';
+import create from '@commands:create';
+import ls from '@commands:ls';
+import save from '@commands:save';
import * as uuid from 'uuid';
import serverline from 'serverline';
import { existsSync, readFileSync, writeFileSync } from 'fs';
import { resolve } from 'path'
import chalk from 'chalk';
+import md5 from 'md5';
const args = process.argv.slice(2);
const [ startupFile ] = args;
@@ -20,9 +22,22 @@ type Instance = {
functions: any;
};
-const system = {
+export const system = {
instances: new Map(),
- handoff: ''
+ handoff: '',
+ aliases: new Map()
+}
+
+function checkpoint(string: string) {
+ console.log(chalk.black.bgAnsi256(204)(' ' + string + ' '));
+}
+
+export function autoColorString(string: string) {
+ let colorCode = 0;
+ for(const char of md5(string)) colorCode += char.charCodeAt(0);
+ colorCode %= 6 ** 3;
+ colorCode += 16;
+ return chalk.ansi256(colorCode)(string);
}
export const exec = async (s: string, echo = true) => {
@@ -30,71 +45,18 @@ export const exec = async (s: string, echo = true) => {
await executor(...(s.split(' ')));
};
-serverline.init({
- prompt: chalk.cyan('λ ')
-});
-
-const kernel = {
- async create(module: string, name: string) {
- // TODO assert module.
- try {
- const imported = (await import('@builtin:' + module));
- const functions = 'default' in imported ? imported.default : imported;
- const id = name ?? uuid.v4().replace(/-/g, '').toUpperCase();
- system.instances.set(id, {
- config: {},
- ram: {},
- module: module,
- functions
- });
- return id;
- } catch(e) {
- console.log(e);
- e.trace();
- }
- },
+export const kernel = {
+ create: create,
quit() {
console.log('Shutting down');
- serverline.close();
setTimeout(() => process.exit(0), 0);
},
- ls(flags: any) {
- if(flags) console.log(flags)
-
- console.log('Instances', chalk.ansi256(242)('(' + system.instances.size + ')'));
- for(const [k, v] of system.instances) {
- let colorCode = 0;
- for(const char of k) colorCode += char.charCodeAt(0);
- colorCode %= 6 ** 3;
- colorCode += 16;
- console.log(
- ' '
- + chalk.ansi256(colorCode)(k.substring(0, 8))
- + ':', JSON.stringify(v.config, null, 2).replace('\n', ' ').trim()
- );
- }
- },
- save() {
- const timeStart = new Date().getTime();
- const obj: any = {
- handoff: system.handoff,
- instances: {}
- };
- for(const [id, info] of system.instances.entries()) {
- obj.instances[id] = {
- config: info.config,
- module: info.module
- }
- }
- const systemString = JSON.stringify(obj, null, 2);
- const fullPath = resolve('.system');
- writeFileSync(fullPath, systemString);
- const elapsed = new Date().getTime() - timeStart;
- console.log('System saved to ' + fullPath + ' in ' + elapsed + ' ms')
- },
+ ls: ls,
+ save: save,
reset() {
system.handoff = '';
system.instances = new Map();
+ system.aliases = new Map();
console.log('System has been reset.');
},
exec: exec,
@@ -112,35 +74,44 @@ const kernel = {
const executor = createExecutor(kernel);
-serverline.on('line', (a: string) => {
- if(a.trim() === "") return;
- exec(a, false);
-})
-
-serverline.on('SIGINT', () => {
- exec('quit');
-});
-
-
-
(async () => {
if(existsSync('.system')) {
const state: any = JSON.parse(readFileSync('.system').toString());
system.handoff = state.handoff;
for(const [id, info] of Object.entries(state.instances)) {
- await kernel.create(info.module, id);
+ const [alias] =
+ Object.entries(state.aliases)
+ .find(([,tryId]) => tryId === id)
+ ?? [undefined];
+ await kernel.create(info.module, alias, id);
system.instances.get(id).config = info.config;
}
+ checkpoint('System State Restored');
}
if(startupFile) {
await exec('script ' + startupFile);
- console.log(chalk.green('Script finished, exitting...'));
+ checkpoint('Script Finished');
await exec('quit');
+ } else {
}
-})()
+ serverline.init({
+ prompt: chalk.cyan('λ ')
+ });
+ serverline.setCompletion(Object.keys(kernel));
+ serverline.on('line', (a: string) => {
+ if(a.trim() === "") return;
+ exec(a, false);
+ });
+
+ serverline.on('SIGINT', () => {
+ exec('quit');
+ });
+
+})().catch((e: Error) => {
+ console.error(e);
+});
+checkpoint('Kernel Loaded');
import '@echo off';
-
-serverline.setCompletion(Object.keys(kernel))
\ No newline at end of file
diff --git a/tsconfig.json b/tsconfig.json
index bef4e22..bfc7fb6 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -6,7 +6,8 @@
"moduleResolution": "Node",
"baseUrl": "./src",
"outDir": "./dist",
- "declaration": true
+ "declaration": true,
+ "allowSyntheticDefaultImports": true
},
"paths": {
"@commands:executor": [""]
diff --git a/vsh/install.vsh b/vsh/install.vsh
index dca1810..5d7683f 100644
--- a/vsh/install.vsh
+++ b/vsh/install.vsh
@@ -1,3 +1,4 @@
+reset
create systemd
create sshd
invoke systemd add sshd invoke sshd start
diff --git a/yarn.lock b/yarn.lock
index 62719cd..4bb3718 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -39,7 +39,14 @@
resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee"
integrity sha1-7ihweulOEdK4J7y+UnC86n8+ce4=
-"@types/node@^16.11.12":
+"@types/md5@^2.3.1":
+ version "2.3.1"
+ resolved "https://registry.yarnpkg.com/@types/md5/-/md5-2.3.1.tgz#010bcf3bb50a2cff3a574cb1c0b4051a9c67d6bc"
+ integrity sha512-OK3oe+ALIoPSo262lnhAYwpqFNXbiwH2a+0+Z5YBnkQEwWD8fk5+PIeRhYA48PzvX9I4SGNpWy+9bLj8qz92RQ==
+ dependencies:
+ "@types/node" "*"
+
+"@types/node@*", "@types/node@^16.11.12":
version "16.11.12"
resolved "https://registry.yarnpkg.com/@types/node/-/node-16.11.12.tgz#ac7fb693ac587ee182c3780c26eb65546a1a3c10"
integrity sha512-+2Iggwg7PxoO5Kyhvsq9VarmPbIelXP070HMImEpbtGCoyWNINQj4wzjbQCXzdHTRXnqufutJb5KAURZANNBAw==
@@ -103,6 +110,11 @@ chalk@^5.0.0:
resolved "https://registry.yarnpkg.com/chalk/-/chalk-5.0.0.tgz#bd96c6bb8e02b96e08c0c3ee2a9d90e050c7b832"
integrity sha512-/duVOqst+luxCQRKEo4bNxinsOQtMP80ZYm7mMqzuh5PociNL0PvmHFvREJ9ueYL2TxlHjBcmLCdmocx9Vg+IQ==
+charenc@0.0.2:
+ version "0.0.2"
+ resolved "https://registry.yarnpkg.com/charenc/-/charenc-0.0.2.tgz#c0a1d2f3a7092e03774bfa83f14c0fc5790a8667"
+ integrity sha1-wKHS86cJLgN3S/qD8UwPxXkKhmc=
+
cpu-features@0.0.2:
version "0.0.2"
resolved "https://registry.yarnpkg.com/cpu-features/-/cpu-features-0.0.2.tgz#9f636156f1155fd04bdbaa028bb3c2fbef3cea7a"
@@ -115,6 +127,11 @@ create-require@^1.1.0:
resolved "https://registry.yarnpkg.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333"
integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==
+crypt@0.0.2:
+ version "0.0.2"
+ resolved "https://registry.yarnpkg.com/crypt/-/crypt-0.0.2.tgz#88d7ff7ec0dfb86f713dc87bbb42d044d3e6c41b"
+ integrity sha1-iNf/fsDfuG9xPch7u0LQRNPmxBs=
+
debug@*:
version "4.3.3"
resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.3.tgz#04266e0b70a98d4462e6e288e38259213332b664"
@@ -127,6 +144,11 @@ diff@^4.0.1:
resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d"
integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==
+is-buffer@~1.1.6:
+ version "1.1.6"
+ resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be"
+ integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==
+
json5@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.1.tgz#779fb0018604fa854eacbf6252180d83543e3dbe"
@@ -139,6 +161,15 @@ make-error@^1.1.1:
resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2"
integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==
+md5@^2.3.0:
+ version "2.3.0"
+ resolved "https://registry.yarnpkg.com/md5/-/md5-2.3.0.tgz#c3da9a6aae3a30b46b7b0c349b87b110dc3bda4f"
+ integrity sha512-T1GITYmFaKuO91vxyoQMFETst+O71VUPEU3ze5GNzDm0OWdP8v1ziTaAEPUr/3kLsY3Sftgz242A1SetQiDL7g==
+ dependencies:
+ charenc "0.0.2"
+ crypt "0.0.2"
+ is-buffer "~1.1.6"
+
minimist@^1.2.0:
version "1.2.5"
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602"