// Backend imports import { ArrayFuncs } from '../../common/etc.js'; import { CoqWorker, backend } from '../../../backend'; // Frontend imports (not so clear for the package manager import JSZip from 'jszip'; import $ from 'jquery'; interface BundleInfo { row : string; } export class PackageManager { /** * Creates the packages UI and loading manager. * * @param {Element} panel_dom
element to hold the package entries * @param {object} packages an object containing package URLs and lists of * names in the format * `{'base_uri1', ['pkg_name1', 'pkg_name2', ...], 'base_uri2': ...}`. * @param {object} pkg_path_aliases mnemonic for specific base URIs * @param {CoqWorker} coq reference to the `CoqWorker` instance to send * load requests to */ backend : backend; panel : any; bundles : Map; loaded_pkgs: string[]; coq : CoqWorker; packages : CoqPkgInfo[]; packages_by_name: any; packages_by_uri: any; index ?: PackageIndex; constructor(panel_dom, packages, pkg_path_aliases, coq, backend=coq.config.backend) { this.backend = backend; this.panel = panel_dom; this.bundles = new Map(); this.loaded_pkgs = []; this.coq = coq; this.coq.observers.push(this); this.packages = []; this.packages_by_name = {}; this.packages_by_uri = {}; this.initializePackageList(packages, pkg_path_aliases); } /** * Creates CoqPkgInfo objects according to the paths in names in the given * `packages` object. * @param {object} packages (see constructor) * @param {object} aliases (ditto) */ initializePackageList(packages : string[], aliases={}) { this.packages = []; this.packages_by_name = {}; this.packages_by_uri = {}; // normalize all URI paths to end with a slash /** @type {(path: string) => string} */ let mkpath = path => path && path.replace(/([^/])$/, '$1/'); for (let [key, pkg_names] of Object.entries(packages)) { let base_uri = mkpath(aliases[key] || key); for (let pkg of pkg_names) { var uri = mkpath(aliases[`${key}/${pkg}`]) || base_uri; this.addPackage(new CoqPkgInfo(pkg, uri)); } } } /** * Returns the default package path * * @param {string} base_path root path of jscoq package * @return {string} * @memberof PackageManager */ static defaultPkgPath(base_path) { return new URL('coq-pkgs', base_path).href; } populate() { this.index = new PackageIndex(this.backend); return Promise.all(this.packages.map(async pkg => { var manifest = await pkg.fetchInfo(); if (manifest) this.addBundleInfo(pkg.name, manifest); else this.coqLibError(pkg.name); })); } /** * Adds a package * * @param {*} pkg * @memberof PackageManager */ addPackage(pkg) { this.packages.push(pkg); this.packages_by_name[pkg.name] = pkg; (this.packages_by_uri[pkg.base_uri] = this.packages_by_uri[pkg.base_uri] || []).push(pkg.name); } getPackage(pkg_name) { var pkg = this.packages_by_name[pkg_name]; if (!pkg) throw new Error(`internal error: unrecognized package '${pkg_name}'`); return pkg; } hasPackageInfo(pkg_name) { var pkg = this.packages_by_name[pkg_name]; return pkg && pkg.info; } addRow(bname, desc = bname, parent) { var row = $('
').addClass('package-row').attr('data-name', bname) .append($('