Migrate to Deno (#86)

Big bang migration to Deno 🤯
This commit is contained in:
Zef Hemel
2022-10-10 14:50:21 +02:00
committed by GitHub
parent 78f83c70d8
commit 561aa6891f
287 changed files with 4577 additions and 25087 deletions
+163
View File
@@ -0,0 +1,163 @@
#!/usr/bin/env deno
import { Manifest } from "../types.ts";
import { YAML } from "../../common/deps.ts";
import {
compile,
CompileOptions,
esbuild,
sandboxCompileModule,
} from "../compile.ts";
import { path } from "../../server/deps.ts";
import * as flags from "https://deno.land/std@0.158.0/flags/mod.ts";
import { bundleAssets } from "../../plugos/asset_bundle.ts";
export async function bundle(
manifestPath: string,
options: CompileOptions = {},
): Promise<Manifest<any>> {
const rootPath = path.dirname(manifestPath);
const manifest = YAML.parse(
await Deno.readTextFile(manifestPath),
) as Manifest<any>;
if (!manifest.name) {
throw new Error(`Missing 'name' in ${manifestPath}`);
}
const allModulesToExclude = options.excludeModules
? options.excludeModules.slice()
: [];
// Dependencies
for (let [name, moduleSpec] of Object.entries(manifest.dependencies || {})) {
manifest.dependencies![name] = await sandboxCompileModule(moduleSpec);
allModulesToExclude.push(name);
}
// Assets
const assetsBundle = await bundleAssets(
rootPath,
manifest.assets as string[] || [],
);
manifest.assets = assetsBundle;
// Functions
for (let [name, def] of Object.entries(manifest.functions || {})) {
let jsFunctionName = "default",
filePath = path.join(rootPath, def.path!);
if (filePath.indexOf(":") !== -1) {
[filePath, jsFunctionName] = filePath.split(":");
}
def.code = await compile(
filePath,
jsFunctionName,
{
...options,
excludeModules: allModulesToExclude,
},
);
delete def.path;
}
return manifest;
}
async function buildManifest(
manifestPath: string,
distPath: string,
options: CompileOptions = {},
) {
const generatedManifest = await bundle(manifestPath, options);
const outFile = manifestPath.substring(
0,
manifestPath.length - path.extname(manifestPath).length,
) + ".json";
const outPath = path.join(distPath, path.basename(outFile));
console.log("Emitting bundle to", outPath);
await Deno.writeTextFile(outPath, JSON.stringify(generatedManifest, null, 2));
return { generatedManifest, outPath };
}
async function bundleRun(
manifestFiles: string[],
dist: string,
watch: boolean,
options: CompileOptions = {},
) {
// console.log("Args", arguments);
let building = false;
async function buildAll() {
if (building) {
return;
}
console.log("Building", manifestFiles);
building = true;
Deno.mkdirSync(dist, { recursive: true });
for (const plugManifestPath of manifestFiles) {
const manifestPath = plugManifestPath as string;
try {
await buildManifest(
manifestPath,
dist,
options,
);
} catch (e) {
console.error(`Error building ${manifestPath}:`, e);
}
}
console.log("Done.");
building = false;
}
await buildAll();
if (watch) {
const watcher = Deno.watchFs(manifestFiles.map((p) => path.dirname(p)));
for await (const event of watcher) {
if (event.paths.length > 0) {
if (event.paths[0].endsWith(".json")) {
continue;
}
}
console.log("Change detected, rebuilding...");
buildAll();
}
}
}
if (import.meta.main) {
const args = flags.parse(Deno.args, {
boolean: ["debug", "watch"],
string: ["dist", "exclude", "importmap"],
alias: { w: "watch" },
// collect: ["exclude"],
});
if (args._.length === 0) {
console.log(
"Usage: plugos-bundle [--debug] [--dist <path>] [--importmap import_map.json] [--exclude=package1,package2] <manifest.plug.yaml> <manifest2.plug.yaml> ...",
);
Deno.exit(1);
}
if (!args.dist) {
args.dist = path.resolve(".");
}
await bundleRun(
args._ as string[],
args.dist,
args.watch,
{
debug: args.debug,
excludeModules: args.exclude ? args.exclude.split(",") : undefined,
importMap: args.importmap
? new URL(args.importmap, `file://${Deno.cwd()}/`)
: undefined,
},
);
esbuild.stop();
}
+60
View File
@@ -0,0 +1,60 @@
#!/usr/bin/env node
import express from "express";
import yargs from "yargs";
import { hideBin } from "yargs/helpers";
import { DiskPlugLoader } from "../plug_loader";
import { CronHookT, NodeCronHook } from "../hooks/node_cron.ts";
import shellSyscalls from "../syscalls/shell.node.ts";
import { System } from "../system.ts";
import { EndpointHook, EndpointHookT } from "../hooks/endpoint.ts";
import { safeRun } from "../util.ts";
import knex from "knex";
import { ensureTable, storeSyscalls } from "../syscalls/store.knex_node";
import { EventHook, EventHookT } from "../hooks/event.ts";
import { eventSyscalls } from "../syscalls/event.ts";
let args = yargs(hideBin(process.argv))
.option("port", {
type: "number",
default: 1337,
})
.parse();
if (!args._.length) {
console.error("Usage: plugos-server <path-to-plugs>");
process.exit(1);
}
const plugPath = args._[0] as string;
const app = express();
type ServerHook = EndpointHookT & CronHookT & EventHookT;
const system = new System<ServerHook>("server");
safeRun(async () => {
const db = knex({
client: "better-sqlite3",
connection: {
filename: "plugos.db",
},
useNullAsDefault: true,
});
await ensureTable(db, "item");
let plugLoader = new DiskPlugLoader(system, plugPath);
await plugLoader.loadPlugs();
plugLoader.watcher();
system.addHook(new NodeCronHook());
let eventHook = new EventHook();
system.addHook(eventHook);
system.registerSyscalls([], eventSyscalls(eventHook));
system.addHook(new EndpointHook(app, ""));
system.registerSyscalls([], shellSyscalls("."));
system.registerSyscalls([], storeSyscalls(db, "item"));
app.listen(args.port, () => {
console.log(`Plugbox server listening on port ${args.port}`);
});
});