Skip to content

Commit 4ce8bd0

Browse files
committed
test npx
1 parent df9c41a commit 4ce8bd0

4 files changed

Lines changed: 374 additions & 190 deletions

File tree

README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,12 @@ and explore it at https://aiidateam.github.io/aiida-explorer/?api_url=http://127
3131

3232
(Note that some browser extensions might block access to localhost, and should be disabled for this to work).
3333

34+
Alternatively a cli tool is avaible that allows provides a interface to select the profile to explore.
35+
36+
```bash
37+
npx aiida-explorer # requires node https://nodejs.org/en/download
38+
```
39+
3440
## Installation and usage
3541

3642
Install via

cli.js

Lines changed: 43 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -1,90 +1,67 @@
11
#!/usr/bin/env node
22

33
import { spawn, spawnSync } from "child_process";
4-
import open from "open";
5-
import path from "path";
6-
import fs from "fs";
7-
import { fileURLToPath } from "url";
84
import { select } from "@inquirer/prompts";
5+
import open from "open";
96

10-
const __dirname = path.dirname(fileURLToPath(import.meta.url));
11-
12-
const FRONTEND_PORT = 4173;
137
const REST_PORT = 5000;
14-
15-
/* ---------------------------
16-
PRE-FLIGHT CHECKS
17-
---------------------------- */
8+
const FRONTEND_URL = "https://aiidateam.github.io/aiida-explorer/";
189

1910
function fail(msg) {
2011
console.error(`\n${msg}\n`);
2112
process.exit(1);
2213
}
2314

24-
function checkVerdi() {
25-
const res = spawnSync("verdi", ["--help"], { encoding: "utf-8" });
15+
/* ---------------------------
16+
CHECKS
17+
---------------------------- */
2618

27-
if (res.error) {
28-
fail('"verdi" not found. Is AiiDA installed and activated?');
29-
}
19+
function checkVerdi() {
20+
const res = spawnSync("verdi", ["--help"]);
21+
if (res.error) fail('"verdi" not found.');
3022
}
3123

3224
function checkRestApiDeps() {
33-
const res = spawnSync(
34-
"python",
35-
["-c", "from aiida.restapi.run_api import run_api"],
36-
{ encoding: "utf-8" },
37-
);
25+
const res = spawnSync("python", [
26+
"-c",
27+
"from aiida.restapi.run_api import run_api",
28+
]);
3829

3930
if (res.status !== 0) {
40-
fail(
41-
"Missing AiiDA REST API dependencies.\n\nFix:\n pip install aiida-core[rest-api]",
42-
);
43-
}
44-
}
45-
46-
function checkFrontend() {
47-
const distPath = path.join(__dirname, "dist");
48-
49-
if (!fs.existsSync(distPath)) {
50-
fail('Frontend build missing. Expected "dist/" in package.');
31+
fail("Missing AiiDA REST API dependencies.");
5132
}
5233
}
5334

5435
/* ---------------------------
55-
PROFILE SELECTION
36+
PROFILES
5637
---------------------------- */
5738

5839
function getProfiles() {
5940
const res = spawnSync("verdi", ["profile", "list"], {
6041
encoding: "utf-8",
6142
});
6243

63-
if (res.status !== 0) {
64-
fail("Failed to fetch AiiDA profiles");
65-
}
66-
67-
const lines = res.stdout.split("\n");
44+
if (res.status !== 0) fail("Failed to list profiles.");
6845

6946
let active = null;
7047

71-
const profiles = lines
48+
const profiles = res.stdout
49+
.split("\n")
7250
.map((l) => l.trim())
73-
.filter((l) => l && !l.startsWith("Report"))
51+
.filter(Boolean)
7452
.map((l) => {
7553
if (l.startsWith("*")) {
7654
active = l.replace(/^\*\s*/, "");
7755
return active;
7856
}
79-
return l.replace(/^\*\s*/, "");
80-
})
81-
.filter(Boolean);
57+
return l;
58+
});
8259

8360
return { profiles, active };
8461
}
8562

8663
async function selectProfile(profiles, active) {
87-
return await select({
64+
return select({
8865
message: "Select AiiDA profile",
8966
choices: profiles.map((p) => ({
9067
name: p,
@@ -96,41 +73,34 @@ async function selectProfile(profiles, active) {
9673
}
9774

9875
/* ---------------------------
99-
STARTUP
76+
REST API
10077
---------------------------- */
10178

102-
let restProc = null;
103-
let frontendProc = null;
104-
10579
function startRestApi(profile) {
106-
console.log(`Starting AiiDA REST API (profile: ${profile})...`);
80+
console.log(`Starting REST API (${profile})...`);
10781

108-
const proc = spawn("verdi", ["-p", profile, "restapi", "--port", REST_PORT], {
82+
return spawn("verdi", ["-p", profile, "restapi", "--port", REST_PORT], {
10983
stdio: "inherit",
11084
});
111-
112-
proc.on("exit", (code) => {
113-
console.log(`\nREST API exited with code ${code}`);
114-
});
115-
116-
return proc;
11785
}
11886

119-
function startFrontend() {
120-
console.log("🌐 Starting frontend (Vite preview)...");
87+
/* ---------------------------
88+
WAIT FOR API
89+
---------------------------- */
12190

122-
const viteBin = path.join(__dirname, "node_modules", ".bin", "vite");
91+
async function waitForApi() {
92+
const url = `http://localhost:${REST_PORT}/api/v4`;
12393

124-
const proc = spawn(viteBin, ["preview", "--port", FRONTEND_PORT], {
125-
cwd: __dirname,
126-
stdio: "inherit",
127-
});
94+
for (let i = 0; i < 30; i++) {
95+
try {
96+
const res = await fetch(url);
97+
if (res.ok) return url;
98+
} catch {}
12899

129-
proc.on("exit", (code) => {
130-
console.log(`\nFrontend exited with code ${code}`);
131-
});
100+
await new Promise((r) => setTimeout(r, 1000));
101+
}
132102

133-
return proc;
103+
fail("REST API did not start in time.");
134104
}
135105

136106
/* ---------------------------
@@ -140,31 +110,22 @@ function startFrontend() {
140110
async function main() {
141111
checkVerdi();
142112
checkRestApiDeps();
143-
checkFrontend();
144113

145114
const { profiles, active } = getProfiles();
146115
const selectedProfile = await selectProfile(profiles, active);
147116

148-
restProc = startRestApi(selectedProfile);
149-
frontendProc = startFrontend();
117+
const restProc = startRestApi(selectedProfile);
150118

151-
setTimeout(() => {
152-
const apiUrl = `http://localhost:${REST_PORT}/api/v4`;
119+
const apiUrl = await waitForApi();
153120

154-
const url =
155-
`http://localhost:${FRONTEND_PORT}/` +
156-
`?api_url=${encodeURIComponent(apiUrl)}`;
121+
const frontend = FRONTEND_URL + `?api_url=${encodeURIComponent(apiUrl)}`;
157122

158-
console.log("\nOpening browser...\n");
159-
open(url);
160-
}, 5000);
123+
console.log("\nOpening browser...");
124+
await open(frontend);
161125

162126
function shutdown() {
163127
console.log("\nShutting down...");
164-
165-
if (restProc) restProc.kill("SIGTERM");
166-
if (frontendProc) frontendProc.kill("SIGTERM");
167-
128+
restProc.kill("SIGTERM");
168129
process.exit(0);
169130
}
170131

0 commit comments

Comments
 (0)