limina 0.1.1 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/chunks/{dep-C5gcXDHp.js → dep-DJz9JBTi.js} +119 -10
- package/chunks/dep-mnWOqiGN.js +244 -0
- package/cli.js +1488 -386
- package/flow-renderer-process.js +23 -31
- package/index.js +1 -1
- package/package.json +1 -1
- package/schemas/tsconfig-schema.json +23 -0
- package/chunks/dep-CuMHuWBQ.js +0 -87
package/flow-renderer-process.js
CHANGED
|
@@ -1,53 +1,46 @@
|
|
|
1
|
-
import { a as
|
|
1
|
+
import { a as SPINNER_FRAMES, l as hasRunningSnapshotWork, n as TerminalFrameTracker, o as SPINNER_INTERVAL_MS, t as DEFAULT_TERMINAL_COLUMNS, u as renderSnapshotLinesForTerminal } from "./chunks/dep-mnWOqiGN.js";
|
|
2
2
|
|
|
3
3
|
//#region src/flow/renderer-process.ts
|
|
4
|
-
const DEFAULT_TERMINAL_COLUMNS = 80;
|
|
5
|
-
const ANSI_ESCAPE = String.fromCodePoint(27);
|
|
6
|
-
const ANSI_PATTERN = new RegExp(String.raw`${ANSI_ESCAPE}\[[\d:;<=>?]*[\u0020-\u002F]*[\u0040-\u007E]`, "gu");
|
|
7
4
|
let snapshot = {
|
|
8
5
|
entries: [],
|
|
9
6
|
treeRoots: []
|
|
10
7
|
};
|
|
11
|
-
|
|
12
|
-
|
|
8
|
+
const terminalFrame = new TerminalFrameTracker(getTerminalColumns);
|
|
9
|
+
const FLOW_RENDERER_TEST_COLUMNS_ENV = "LIMINA_FLOW_RENDERER_TEST_COLUMNS";
|
|
13
10
|
let spinnerFrameIndex = 0;
|
|
14
11
|
let spinnerTimer;
|
|
15
12
|
let closed = false;
|
|
16
13
|
function send(message) {
|
|
17
14
|
if (typeof process.send === "function") process.send(message);
|
|
18
15
|
}
|
|
19
|
-
function
|
|
20
|
-
|
|
16
|
+
function readPositiveInteger(value) {
|
|
17
|
+
if (value === void 0) return;
|
|
18
|
+
const parsed = Number.parseInt(value, 10);
|
|
19
|
+
return Number.isInteger(parsed) && parsed > 0 ? parsed : void 0;
|
|
21
20
|
}
|
|
22
|
-
function
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
terminalLineCount += 1;
|
|
28
|
-
terminalColumn = 0;
|
|
29
|
-
continue;
|
|
30
|
-
}
|
|
31
|
-
terminalColumn += 1;
|
|
32
|
-
if (terminalColumn >= columns) {
|
|
33
|
-
terminalLineCount += 1;
|
|
34
|
-
terminalColumn = 0;
|
|
35
|
-
}
|
|
36
|
-
}
|
|
21
|
+
function getTerminalColumns() {
|
|
22
|
+
return Math.max(1, readPositiveInteger(process.env[FLOW_RENDERER_TEST_COLUMNS_ENV]) ?? process.stdout.columns ?? snapshot.terminalDimensions?.columns ?? DEFAULT_TERMINAL_COLUMNS);
|
|
23
|
+
}
|
|
24
|
+
function getTerminalRows() {
|
|
25
|
+
return readPositiveInteger(process.env.LIMINA_FLOW_RENDERER_TEST_ROWS) ?? process.stdout.rows;
|
|
37
26
|
}
|
|
38
27
|
function writeTracked(message, stream) {
|
|
39
|
-
|
|
28
|
+
terminalFrame.record(message);
|
|
40
29
|
stream.write(message);
|
|
41
30
|
}
|
|
42
31
|
function clearRenderedFrame() {
|
|
43
|
-
if (
|
|
44
|
-
process.stdout.write(`\r\u001B[${
|
|
45
|
-
|
|
46
|
-
terminalColumn = 0;
|
|
32
|
+
if (terminalFrame.lineCount <= 0) return;
|
|
33
|
+
process.stdout.write(`\r\u001B[${terminalFrame.lineCount}A\u001B[J`);
|
|
34
|
+
terminalFrame.reset();
|
|
47
35
|
}
|
|
48
36
|
function render() {
|
|
49
37
|
clearRenderedFrame();
|
|
50
|
-
|
|
38
|
+
const dimensions = {
|
|
39
|
+
columns: getTerminalColumns(),
|
|
40
|
+
rows: snapshot.terminalDimensions?.rows ?? getTerminalRows()
|
|
41
|
+
};
|
|
42
|
+
const renderedLines = renderSnapshotLinesForTerminal(snapshot, spinnerFrameIndex, dimensions);
|
|
43
|
+
for (const line of renderedLines) writeTracked(`${line}\n`, process.stdout);
|
|
51
44
|
}
|
|
52
45
|
function syncSpinnerTimer() {
|
|
53
46
|
if (closed || !hasRunningSnapshotWork(snapshot)) {
|
|
@@ -66,8 +59,7 @@ function syncSpinnerTimer() {
|
|
|
66
59
|
function writeOutput(message) {
|
|
67
60
|
clearRenderedFrame();
|
|
68
61
|
writeTracked(message.output.text, message.output.stream === "stderr" ? process.stderr : process.stdout);
|
|
69
|
-
|
|
70
|
-
terminalColumn = 0;
|
|
62
|
+
terminalFrame.reset();
|
|
71
63
|
render();
|
|
72
64
|
}
|
|
73
65
|
process.on("message", (rawMessage) => {
|
package/index.js
CHANGED
package/package.json
CHANGED
|
@@ -47,6 +47,29 @@
|
|
|
47
47
|
}
|
|
48
48
|
}
|
|
49
49
|
},
|
|
50
|
+
"outputs": {
|
|
51
|
+
"type": "object",
|
|
52
|
+
"description": "User-facing artifact output build options for this ordinary source tsconfig.",
|
|
53
|
+
"additionalProperties": false,
|
|
54
|
+
"properties": {
|
|
55
|
+
"target": {
|
|
56
|
+
"$ref": "#/definitions/nonEmptyString",
|
|
57
|
+
"description": "TypeScript target for generated artifact output builds."
|
|
58
|
+
},
|
|
59
|
+
"rootDir": {
|
|
60
|
+
"$ref": "#/definitions/nonEmptyString",
|
|
61
|
+
"description": "Artifact build rootDir, relative to this tsconfig."
|
|
62
|
+
},
|
|
63
|
+
"outDir": {
|
|
64
|
+
"$ref": "#/definitions/nonEmptyString",
|
|
65
|
+
"description": "Artifact build outDir, relative to this tsconfig."
|
|
66
|
+
},
|
|
67
|
+
"tsBuildInfoFile": {
|
|
68
|
+
"$ref": "#/definitions/nonEmptyString",
|
|
69
|
+
"description": "Artifact build tsBuildInfoFile, relative to this tsconfig."
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
},
|
|
50
73
|
"graphRules": {
|
|
51
74
|
"type": "array",
|
|
52
75
|
"description": "Graph rule labels from limina.config.mjs#graph.rules that apply to this declaration leaf.",
|
package/chunks/dep-CuMHuWBQ.js
DELETED
|
@@ -1,87 +0,0 @@
|
|
|
1
|
-
//#region src/flow/render-model.ts
|
|
2
|
-
const ANSI_RESET = "\x1B[0m";
|
|
3
|
-
const ANSI_GREEN = "\x1B[32m";
|
|
4
|
-
const ANSI_RED = "\x1B[31m";
|
|
5
|
-
const ANSI_YELLOW = "\x1B[33m";
|
|
6
|
-
const SPINNER_FRAMES = [
|
|
7
|
-
"⠋",
|
|
8
|
-
"⠙",
|
|
9
|
-
"⠹",
|
|
10
|
-
"⠸",
|
|
11
|
-
"⠼",
|
|
12
|
-
"⠴",
|
|
13
|
-
"⠦",
|
|
14
|
-
"⠧",
|
|
15
|
-
"⠇",
|
|
16
|
-
"⠏"
|
|
17
|
-
];
|
|
18
|
-
const SPINNER_INTERVAL_MS = 80;
|
|
19
|
-
const FLOW_SYMBOL_BY_STATUS = {
|
|
20
|
-
fail: "✕",
|
|
21
|
-
info: "│",
|
|
22
|
-
pass: "◆",
|
|
23
|
-
planned: "◇",
|
|
24
|
-
skip: "◇",
|
|
25
|
-
start: "◇",
|
|
26
|
-
warn: "▲"
|
|
27
|
-
};
|
|
28
|
-
function colorInteractiveSymbol(status, symbol) {
|
|
29
|
-
if (status === "pass") return `${ANSI_GREEN}${symbol}${ANSI_RESET}`;
|
|
30
|
-
if (status === "fail") return `${ANSI_RED}${symbol}${ANSI_RESET}`;
|
|
31
|
-
if (status === "warn") return `${ANSI_YELLOW}${symbol}${ANSI_RESET}`;
|
|
32
|
-
return symbol;
|
|
33
|
-
}
|
|
34
|
-
function formatElapsedTime(milliseconds) {
|
|
35
|
-
if (milliseconds < 1e3) return `${Math.round(milliseconds)}ms`;
|
|
36
|
-
return `${(milliseconds / 1e3).toFixed(2)}s`;
|
|
37
|
-
}
|
|
38
|
-
function formatMessageWithElapsed(message, elapsedTimeMs) {
|
|
39
|
-
return typeof elapsedTimeMs === "number" ? `${message} (${formatElapsedTime(elapsedTimeMs)})` : message;
|
|
40
|
-
}
|
|
41
|
-
function indentMessage(message, depth) {
|
|
42
|
-
if (depth <= 0) return message;
|
|
43
|
-
return `${" ".repeat(depth)}${message}`;
|
|
44
|
-
}
|
|
45
|
-
function formatInteractiveLine(status, message, depth, spinnerFrameIndex) {
|
|
46
|
-
const renderedMessage = indentMessage(message, depth);
|
|
47
|
-
return `${colorInteractiveSymbol(status, status === "start" ? SPINNER_FRAMES[spinnerFrameIndex % SPINNER_FRAMES.length] : FLOW_SYMBOL_BY_STATUS[status])} ${renderedMessage}`;
|
|
48
|
-
}
|
|
49
|
-
function toTreeFlowStatus(status) {
|
|
50
|
-
switch (status) {
|
|
51
|
-
case "failed": return "fail";
|
|
52
|
-
case "passed": return "pass";
|
|
53
|
-
case "planned": return "planned";
|
|
54
|
-
case "running": return "start";
|
|
55
|
-
case "skipped": return "skip";
|
|
56
|
-
}
|
|
57
|
-
throw new Error(`Unsupported flow tree node status: ${status}`);
|
|
58
|
-
}
|
|
59
|
-
function isTreeNodeTerminal(node) {
|
|
60
|
-
return node.status === "failed" || node.status === "passed" || node.status === "skipped";
|
|
61
|
-
}
|
|
62
|
-
function areTreeNodeDescendantsTerminal(node) {
|
|
63
|
-
return node.children.every((child) => isTreeNodeTerminal(child) && areTreeNodeDescendantsTerminal(child));
|
|
64
|
-
}
|
|
65
|
-
function renderTreeNodeLines(node, spinnerFrameIndex) {
|
|
66
|
-
const elapsedTimeMs = isTreeNodeTerminal(node) && areTreeNodeDescendantsTerminal(node) ? node.elapsedTimeMs : void 0;
|
|
67
|
-
return [formatInteractiveLine(toTreeFlowStatus(node.status), formatMessageWithElapsed(node.message, elapsedTimeMs), node.depth, spinnerFrameIndex), ...node.children.flatMap((child) => renderTreeNodeLines(child, spinnerFrameIndex))];
|
|
68
|
-
}
|
|
69
|
-
function renderSnapshotLines(snapshot, spinnerFrameIndex) {
|
|
70
|
-
const lines = snapshot.entries.flatMap((entry) => {
|
|
71
|
-
if (entry.kind === "line") return [entry.line];
|
|
72
|
-
if (entry.kind === "flow-line") return [formatInteractiveLine(entry.status, formatMessageWithElapsed(entry.message, entry.elapsedTimeMs), entry.depth, spinnerFrameIndex)];
|
|
73
|
-
return snapshot.treeRoots.flatMap((root) => renderTreeNodeLines(root, spinnerFrameIndex));
|
|
74
|
-
});
|
|
75
|
-
return snapshot.outroMessage ? [...lines, `└ ${snapshot.outroMessage}`] : lines;
|
|
76
|
-
}
|
|
77
|
-
function hasRunningSnapshotWork(snapshot) {
|
|
78
|
-
const hasRunningTreeNode = (node) => node.status === "running" || node.children.some(hasRunningTreeNode);
|
|
79
|
-
return snapshot.entries.some((entry) => entry.kind === "flow-line" && entry.status === "start") || snapshot.treeRoots.some(hasRunningTreeNode);
|
|
80
|
-
}
|
|
81
|
-
function toWritableText(chunk) {
|
|
82
|
-
if (chunk instanceof Uint8Array) return Buffer.from(chunk).toString();
|
|
83
|
-
return String(chunk);
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
//#endregion
|
|
87
|
-
export { hasRunningSnapshotWork as a, toWritableText as c, formatMessageWithElapsed as i, SPINNER_INTERVAL_MS as n, renderSnapshotLines as o, formatInteractiveLine as r, toTreeFlowStatus as s, SPINNER_FRAMES as t };
|