UNPKG

@cocalc/project

Version:
149 lines 5.74 kB
"use strict"; /* * This file is part of CoCalc: Copyright © 2020 Sagemath, Inc. * License: AGPLv3 s.t. "Commons Clause" – see LICENSE.md for details */ Object.defineProperty(exports, "__esModule", { value: true }); exports.lean = exports.lean_channel = void 0; /* LEAN server */ const lean_files = {}; const lean_1 = require("./lean"); const global_packages_1 = require("./global-packages"); const underscore_1 = require("underscore"); let the_lean_server = undefined; function init_lean_server(client, logger) { the_lean_server = (0, lean_1.lean_server)(client); the_lean_server.on("tasks", function (path, tasks) { logger.debug("lean_server:websocket:tasks -- ", path, tasks); const lean_file = lean_files[`lean:${path}`]; if (lean_file !== undefined && !(0, underscore_1.isEqual)(lean_file.tasks, tasks)) { lean_file.tasks = tasks; lean_file.channel.write({ tasks }); } }); the_lean_server.on("sync", function (path, hash) { logger.debug("lean_server:websocket:sync -- ", path, hash); const lean_file = lean_files[`lean:${path}`]; if (lean_file !== undefined && !(0, underscore_1.isEqual)(lean_file.sync, hash)) { const sync = { hash: hash, time: new Date().valueOf() }; lean_file.sync = sync; lean_file.channel.write({ sync }); } }); the_lean_server.on("messages", function (path, messages) { logger.debug("lean_server:websocket:messages -- ", path, messages); const lean_file = lean_files[`lean:${path}`]; if (lean_file !== undefined && !(0, underscore_1.isEqual)(lean_file.messages, messages)) { lean_file.messages = messages; lean_file.channel.write({ messages }); } }); } async function lean_channel(client, primus, logger, path) { if (the_lean_server === undefined) { await (0, global_packages_1.init_global_packages)(); init_lean_server(client, logger); if (the_lean_server === undefined) { // just to satisfy typescript. throw Error("lean server not defined"); } } the_lean_server.register(path); // TODO: delete lean_files[name] under some condition. const name = `lean:${path}`; if (lean_files[name] !== undefined) { return name; } const channel = primus.channel(name); lean_files[name] = { channel, messages: [], }; channel.on("connection", function (spark) { // make sure lean server cares: if (the_lean_server === undefined) { // just to satisfy typescript. throw Error("lean server not defined"); } the_lean_server.register(path); const lean_file = lean_files[name]; if (lean_file === undefined) { return; } // Now handle the connection logger.debug("lean channel", `new connection from ${spark.address.ip} -- ${spark.id}`); spark.write({ messages: lean_file.messages, sync: lean_file.sync, tasks: lean_file.tasks, }); spark.on("end", function () { }); }); return name; } exports.lean_channel = lean_channel; function assert_type(name, x, type) { if (typeof x != type) { throw Error(`${name} must have type ${type}`); } } async function lean(client, _, logger, opts) { if (the_lean_server === undefined) { init_lean_server(client, logger); if (the_lean_server === undefined) { // just to satisfy typescript. throw Error("lean server not defined"); } } if (opts == null || typeof opts.cmd != "string") { throw Error("opts must be an object with cmd field a string"); } // control message logger.debug("lean command", JSON.stringify(opts)); switch (opts.cmd) { case "info": assert_type("path", opts.path, "string"); assert_type("line", opts.line, "number"); assert_type("column", opts.column, "number"); const r = (await the_lean_server.info(opts.path, opts.line, opts.column)) .record; return r ? r : {}; // get server version case "version": return await the_lean_server.version(); // kill the LEAN server. // this can help with, e.g., updating the LEAN_PATH case "kill": return the_lean_server.kill(); case "restart": return await the_lean_server.restart(); case "complete": assert_type("path", opts.path, "string"); assert_type("line", opts.line, "number"); assert_type("column", opts.column, "number"); const complete = await the_lean_server.complete(opts.path, opts.line, opts.column, opts.skipCompletions); if (complete == null || complete.completions == null) { return []; } // delete the source fields -- they are LARGE and not used at all in the UI. for (const c of complete.completions) { delete c.source; // cast because of mistake in upstream type def. sigh. } /* complete.completions.sort(function(a, b): number { if (a.text == null || b.text == null) { // satisfy typescript null checks; shouldn't happen. return 0; } return cmp(a.text.toLowerCase(), b.text.toLowerCase()); }); */ return complete.completions; default: throw Error(`unknown cmd ${opts.cmd}`); } } exports.lean = lean; //# sourceMappingURL=server.js.map