kandown 0.3.3 → 0.3.5
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/README.md +324 -427
- package/bin/kandown.js +18 -6
- package/dist/index.html +332 -332
- package/package.json +1 -1
package/bin/kandown.js
CHANGED
|
@@ -57,6 +57,8 @@ const PKG_ROOT = resolve(__dirname, '..');
|
|
|
57
57
|
// 📖 Default localhost range for the zero-config `kandown` web UI server.
|
|
58
58
|
const DEFAULT_SERVE_PORT = 2048;
|
|
59
59
|
const MAX_SERVE_PORT = 2060;
|
|
60
|
+
const START_PORT_RANGE = 2048;
|
|
61
|
+
const END_PORT_RANGE = 2060;
|
|
60
62
|
|
|
61
63
|
// 📖 Get current CLI version from package.json at PKG_ROOT
|
|
62
64
|
function getCurrentVersion() {
|
|
@@ -626,8 +628,8 @@ function listen(server, port) {
|
|
|
626
628
|
}
|
|
627
629
|
|
|
628
630
|
async function listenOnAvailablePort(kandownDir, preferredPort) {
|
|
629
|
-
const startPort = preferredPort ??
|
|
630
|
-
const endPort = preferredPort ??
|
|
631
|
+
const startPort = preferredPort ?? START_PORT_RANGE;
|
|
632
|
+
const endPort = preferredPort ?? END_PORT_RANGE;
|
|
631
633
|
|
|
632
634
|
for (let port = startPort; port <= endPort; port++) {
|
|
633
635
|
const server = createServeServer(kandownDir);
|
|
@@ -640,7 +642,7 @@ async function listenOnAvailablePort(kandownDir, preferredPort) {
|
|
|
640
642
|
}
|
|
641
643
|
|
|
642
644
|
const range = preferredPort === null
|
|
643
|
-
? `${
|
|
645
|
+
? `${START_PORT_RANGE}-${END_PORT_RANGE}`
|
|
644
646
|
: String(preferredPort);
|
|
645
647
|
err(`No free port available in ${c.bold}${range}${c.reset}.`);
|
|
646
648
|
process.exit(1);
|
|
@@ -690,17 +692,27 @@ async function cmdServe(rawArgs) {
|
|
|
690
692
|
}
|
|
691
693
|
|
|
692
694
|
/**
|
|
693
|
-
* 📖 Opens a
|
|
695
|
+
* 📖 Opens a URL in the system default browser after confirming the server is ready.
|
|
694
696
|
* Non-blocking — spawns the opener and returns immediately.
|
|
695
697
|
* macOS: open, Linux: xdg-open, Windows: start (via cmd.exe).
|
|
696
698
|
*/
|
|
697
|
-
function openInBrowser(
|
|
699
|
+
async function openInBrowser(url) {
|
|
700
|
+
// 📖 Wait for server to be truly ready (up to 2s) before opening browser.
|
|
701
|
+
// This prevents ERR_UNSAFE_PORT and similar race conditions.
|
|
702
|
+
for (let i = 0; i < 10; i++) {
|
|
703
|
+
try {
|
|
704
|
+
const res = await fetch(url, { method: 'HEAD', signal: AbortSignal.timeout(500) });
|
|
705
|
+
if (res.ok || res.status === 404) break; // server is up (404 means serving HTML)
|
|
706
|
+
} catch { /* server not ready yet */ }
|
|
707
|
+
await new Promise(r => setTimeout(r, 200));
|
|
708
|
+
}
|
|
709
|
+
|
|
698
710
|
const opener = process.platform === 'darwin'
|
|
699
711
|
? 'open'
|
|
700
712
|
: process.platform === 'win32'
|
|
701
713
|
? 'cmd'
|
|
702
714
|
: 'xdg-open';
|
|
703
|
-
const args = process.platform === 'win32' ? ['/c', 'start', '',
|
|
715
|
+
const args = process.platform === 'win32' ? ['/c', 'start', '', url] : [url];
|
|
704
716
|
const child = spawn(opener, args, { detached: true, stdio: 'ignore' });
|
|
705
717
|
child.on('error', (e) => warn(`Could not open browser automatically: ${e.message}`));
|
|
706
718
|
child.unref();
|