kryptheon 0.1.40 → 0.1.41
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/bin/kryptheon.js +58 -3
- package/kryptheon-dashboard.js +4 -0
- package/package.json +1 -1
package/bin/kryptheon.js
CHANGED
|
@@ -2632,9 +2632,12 @@ function dashboardAlreadyRunning(port) {
|
|
|
2632
2632
|
res.on('data', (chunk) => { if (body.length < 5000000) body += chunk; });
|
|
2633
2633
|
res.on('end', () => {
|
|
2634
2634
|
try {
|
|
2635
|
-
const
|
|
2635
|
+
const state = JSON.parse(body);
|
|
2636
|
+
const root = state.project.root;
|
|
2636
2637
|
const same = (a) => (process.platform === 'win32' ? path.resolve(a).toLowerCase() : path.resolve(a));
|
|
2637
|
-
|
|
2638
|
+
if (res.statusCode !== 200 || typeof root !== 'string' || same(root) !== same(USER_DIR)) return resolve(false);
|
|
2639
|
+
// Before 0.1.41 a dashboard did not say which it was: an old one.
|
|
2640
|
+
resolve({ version: typeof state.kryptheon === 'string' ? state.kryptheon : null });
|
|
2638
2641
|
} catch (err) {
|
|
2639
2642
|
resolve(false);
|
|
2640
2643
|
}
|
|
@@ -2645,6 +2648,49 @@ function dashboardAlreadyRunning(port) {
|
|
|
2645
2648
|
});
|
|
2646
2649
|
}
|
|
2647
2650
|
|
|
2651
|
+
/** The process listening on 127.0.0.1:port, or null. */
|
|
2652
|
+
function listenerOn(port) {
|
|
2653
|
+
try {
|
|
2654
|
+
if (process.platform === 'win32') {
|
|
2655
|
+
const out = spawnSync('netstat', ['-ano', '-p', 'TCP'], { encoding: 'utf8', windowsHide: true, timeout: 10000 }).stdout || '';
|
|
2656
|
+
for (const line of out.split(/\r?\n/)) {
|
|
2657
|
+
const m = line.trim().split(/\s+/);
|
|
2658
|
+
if (m.length >= 5 && m[1] === '127.0.0.1:' + port && m[3] === 'LISTENING' && /^\d+$/.test(m[4])) return Number(m[4]);
|
|
2659
|
+
}
|
|
2660
|
+
return null;
|
|
2661
|
+
}
|
|
2662
|
+
const out = spawnSync('lsof', ['-nP', '-iTCP@127.0.0.1:' + port, '-sTCP:LISTEN', '-t'], { encoding: 'utf8', timeout: 10000 }).stdout || '';
|
|
2663
|
+
const pid = Number(out.trim().split(/\s+/)[0]);
|
|
2664
|
+
return pid > 0 ? pid : null;
|
|
2665
|
+
} catch (err) {
|
|
2666
|
+
return null;
|
|
2667
|
+
}
|
|
2668
|
+
}
|
|
2669
|
+
|
|
2670
|
+
/**
|
|
2671
|
+
* An older dashboard for this same folder, still running - from yesterday's
|
|
2672
|
+
* Win+R, or started at sign-in - is stopped so this version takes its place.
|
|
2673
|
+
* Found when the first paying user ran the new version and kept getting the
|
|
2674
|
+
* old page: npx fetched the new one, which then only opened the old one.
|
|
2675
|
+
* Only the process that answered as this folder's Kryptheon dashboard is
|
|
2676
|
+
* stopped. Whether the port came free is the answer.
|
|
2677
|
+
*/
|
|
2678
|
+
async function replaceOldDashboard(port) {
|
|
2679
|
+
const pid = listenerOn(port);
|
|
2680
|
+
if (!pid || pid === process.pid) return false;
|
|
2681
|
+
try {
|
|
2682
|
+
if (process.platform === 'win32') spawnSync('taskkill', ['/PID', String(pid), '/F'], { windowsHide: true, timeout: 10000 });
|
|
2683
|
+
else process.kill(pid, 'SIGTERM');
|
|
2684
|
+
} catch (err) {
|
|
2685
|
+
return false;
|
|
2686
|
+
}
|
|
2687
|
+
for (let i = 0; i < 50; i++) {
|
|
2688
|
+
if (listenerOn(port) === null) return true;
|
|
2689
|
+
await new Promise((r) => setTimeout(r, 100));
|
|
2690
|
+
}
|
|
2691
|
+
return false;
|
|
2692
|
+
}
|
|
2693
|
+
|
|
2648
2694
|
/**
|
|
2649
2695
|
* The dashboard, started from the home folder: kept in a kryptheon-tests
|
|
2650
2696
|
* folder there, the one record already uses - set up the first time, asked
|
|
@@ -2732,7 +2778,16 @@ async function dashboardCommand() {
|
|
|
2732
2778
|
}
|
|
2733
2779
|
// Running already: open that one rather than a second, which would watch
|
|
2734
2780
|
// the same project twice. Exit code 0 is how the launcher knows.
|
|
2735
|
-
|
|
2781
|
+
const running = await dashboardAlreadyRunning(DASHBOARD_PORT);
|
|
2782
|
+
const mine = require(path.join(PACKAGE_DIR, 'package.json')).version;
|
|
2783
|
+
if (running && running.version !== mine) {
|
|
2784
|
+
const was = running.version || 'from before 0.1.41';
|
|
2785
|
+
console.log('');
|
|
2786
|
+
console.log(await replaceOldDashboard(DASHBOARD_PORT)
|
|
2787
|
+
? ' An older Kryptheon dashboard (' + was + ') was running for this folder.\n It was closed, and ' + mine + ' starts in its place.'
|
|
2788
|
+
: ' An older Kryptheon dashboard (' + was + ') is still running and could not be\n closed. This one starts at another address; close the old window when you can.');
|
|
2789
|
+
}
|
|
2790
|
+
if (running && running.version === mine) {
|
|
2736
2791
|
const address = 'http://127.0.0.1:' + DASHBOARD_PORT + '/';
|
|
2737
2792
|
const shown = openInBrowser(address);
|
|
2738
2793
|
console.log('');
|
package/kryptheon-dashboard.js
CHANGED
|
@@ -25,6 +25,7 @@ const { spawnSync } = require('child_process');
|
|
|
25
25
|
const store = require('./kryptheon-store.js');
|
|
26
26
|
const changes = require('./kryptheon-changes.js');
|
|
27
27
|
const autostart = require('./kryptheon-autostart.js');
|
|
28
|
+
const VERSION = require('./package.json').version;
|
|
28
29
|
|
|
29
30
|
/**
|
|
30
31
|
* Every check the dashboard knows the name of, in the order the person asked
|
|
@@ -543,6 +544,9 @@ function buildState(root, env) {
|
|
|
543
544
|
|
|
544
545
|
return {
|
|
545
546
|
project: { name: path.basename(root), root: root, storeDir: paths.dir },
|
|
547
|
+
// Which kryptheon this dashboard is: a newer `dashboard` asks, and takes
|
|
548
|
+
// the place of an older one still running, instead of opening it.
|
|
549
|
+
kryptheon: VERSION,
|
|
546
550
|
looks: looks,
|
|
547
551
|
proven: proven,
|
|
548
552
|
checks: checks,
|