• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1import { exec, Debouncer } from "./utils.mjs";
2import { resolve } from "path";
3import { findUpRoot } from "./findUpDir.mjs";
4import assert from "assert";
5
6class ProjectQueue {
7    /**
8     * @param {(projects: string[], lkg: boolean, force: boolean) => Promise<any>} action
9     */
10    constructor(action) {
11        /** @type {{ lkg: boolean, force: boolean, projects?: string[], debouncer: Debouncer }[]} */
12        this._debouncers = [];
13        this._action = action;
14    }
15
16    /**
17     * @param {string} project
18     * @param {{ lkg?: boolean; force?: boolean; }} options
19     */
20    enqueue(project, { lkg = true, force = false } = {}) {
21        let entry = this._debouncers.find(entry => entry.lkg === lkg && entry.force === force);
22        if (!entry) {
23            const debouncer = new Debouncer(100, async () => {
24                assert(entry);
25                const projects = entry.projects;
26                if (projects) {
27                    entry.projects = undefined;
28                    await this._action(projects, lkg, force);
29                }
30            });
31            this._debouncers.push(entry = { lkg, force, debouncer });
32        }
33        if (!entry.projects) entry.projects = [];
34        entry.projects.push(project);
35        return entry.debouncer.enqueue();
36    }
37}
38
39const execTsc = (/** @type {boolean} */ lkg, /** @type {string[]} */ ...args) =>
40    exec(process.execPath,
41         [resolve(findUpRoot(), lkg ? "./lib/tsc" : "./built/local/tsc"),
42          "-b", ...args],
43         { hidePrompt: true });
44
45const projectBuilder = new ProjectQueue((projects, lkg, force) => execTsc(lkg, ...(force ? ["--force"] : []), ...projects));
46
47/**
48 * @param {string} project
49 * @param {object} options
50 * @param {boolean} [options.lkg=true]
51 * @param {boolean} [options.force=false]
52 */
53export const buildProject = (project, { lkg, force } = {}) => projectBuilder.enqueue(project, { lkg, force });
54
55const projectCleaner = new ProjectQueue((projects, lkg) => execTsc(lkg, "--clean", ...projects));
56
57/**
58 * @param {string} project
59 */
60 export const cleanProject = (project) => projectCleaner.enqueue(project);
61
62const projectWatcher = new ProjectQueue((projects) => execTsc(/*lkg*/ true, "--watch", ...projects));
63
64/**
65 * @param {string} project
66 * @param {object} options
67 * @param {boolean} [options.lkg=true]
68 */
69export const watchProject = (project, { lkg } = {}) => projectWatcher.enqueue(project, { lkg });
70