diffwiki 0.2.0-rc.f44d17c → 0.3.0-rc.202607211217.f5290fa
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/dist/bin.js +142 -0
- package/package.json +2 -2
package/dist/bin.js
CHANGED
|
@@ -45,11 +45,112 @@ function withErrors(fn) {
|
|
|
45
45
|
var collect = (value, previous) => previous.concat([value]);
|
|
46
46
|
var splitTags = (raw) => raw.flatMap((t) => t.split(",")).map((t) => t.trim()).filter((t) => t.length > 0);
|
|
47
47
|
|
|
48
|
+
// src/ui-server.ts
|
|
49
|
+
import { spawn } from "child_process";
|
|
50
|
+
import { platform } from "os";
|
|
51
|
+
import fs from "fs/promises";
|
|
52
|
+
import path from "path";
|
|
53
|
+
import http from "http";
|
|
54
|
+
import { resolveHome } from "diffwiki-core";
|
|
55
|
+
var DEFAULT_PORT = 4321;
|
|
56
|
+
function statePath() {
|
|
57
|
+
return path.join(resolveHome(), "ui.json");
|
|
58
|
+
}
|
|
59
|
+
async function readState() {
|
|
60
|
+
try {
|
|
61
|
+
return JSON.parse(await fs.readFile(statePath(), "utf8"));
|
|
62
|
+
} catch {
|
|
63
|
+
return void 0;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
async function writeState(state) {
|
|
67
|
+
await fs.mkdir(resolveHome(), { recursive: true });
|
|
68
|
+
await fs.writeFile(statePath(), `${JSON.stringify(state, null, 2)}
|
|
69
|
+
`, "utf8");
|
|
70
|
+
}
|
|
71
|
+
async function clearState() {
|
|
72
|
+
await fs.rm(statePath(), { force: true });
|
|
73
|
+
}
|
|
74
|
+
function isAlive(pid) {
|
|
75
|
+
try {
|
|
76
|
+
process.kill(pid, 0);
|
|
77
|
+
return true;
|
|
78
|
+
} catch {
|
|
79
|
+
return false;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
function openCommand() {
|
|
83
|
+
switch (platform()) {
|
|
84
|
+
case "darwin":
|
|
85
|
+
return { cmd: "open", args: (u) => [u] };
|
|
86
|
+
case "win32":
|
|
87
|
+
return { cmd: "cmd", args: (u) => ["/c", "start", "", u] };
|
|
88
|
+
default:
|
|
89
|
+
return { cmd: "xdg-open", args: (u) => [u] };
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
function openBrowser(url) {
|
|
93
|
+
const { cmd, args } = openCommand();
|
|
94
|
+
spawn(cmd, args(url), { stdio: "ignore", detached: true }).unref();
|
|
95
|
+
}
|
|
96
|
+
function waitForServer(url, timeoutMs = 3e4) {
|
|
97
|
+
const deadline = Date.now() + timeoutMs;
|
|
98
|
+
return new Promise((resolve) => {
|
|
99
|
+
const tick = () => {
|
|
100
|
+
const req = http.get(url, (res) => {
|
|
101
|
+
res.resume();
|
|
102
|
+
resolve(true);
|
|
103
|
+
});
|
|
104
|
+
req.on("error", () => {
|
|
105
|
+
if (Date.now() > deadline) resolve(false);
|
|
106
|
+
else setTimeout(tick, 500);
|
|
107
|
+
});
|
|
108
|
+
};
|
|
109
|
+
tick();
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
async function startUi(port = DEFAULT_PORT) {
|
|
113
|
+
const child = spawn("npx", ["-y", "diffwiki-app@latest", "--port", String(port)], {
|
|
114
|
+
env: { ...process.env, PORT: String(port), HOST: "127.0.0.1" },
|
|
115
|
+
detached: true,
|
|
116
|
+
stdio: "ignore"
|
|
117
|
+
});
|
|
118
|
+
if (child.pid === void 0) {
|
|
119
|
+
throw new Error("failed to spawn diffwiki-app");
|
|
120
|
+
}
|
|
121
|
+
child.on("close", () => {
|
|
122
|
+
void clearState();
|
|
123
|
+
});
|
|
124
|
+
child.unref();
|
|
125
|
+
const state = {
|
|
126
|
+
pid: child.pid,
|
|
127
|
+
port,
|
|
128
|
+
url: `http://127.0.0.1:${port}`,
|
|
129
|
+
startedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
130
|
+
};
|
|
131
|
+
await writeState(state);
|
|
132
|
+
return state;
|
|
133
|
+
}
|
|
134
|
+
async function stopUi() {
|
|
135
|
+
const state = await readState();
|
|
136
|
+
if (!state) return void 0;
|
|
137
|
+
try {
|
|
138
|
+
if (platform() === "win32") process.kill(state.pid);
|
|
139
|
+
else process.kill(-state.pid);
|
|
140
|
+
} catch {
|
|
141
|
+
}
|
|
142
|
+
await clearState();
|
|
143
|
+
return state;
|
|
144
|
+
}
|
|
145
|
+
|
|
48
146
|
// src/cli.ts
|
|
49
147
|
var icon = (level) => level === "ok" ? "\u2713" : level === "warn" ? "!" : "\u2716";
|
|
50
148
|
function createProgram() {
|
|
51
149
|
const program = new Command();
|
|
52
150
|
program.name("diffwiki").description("A git-based knowledge base").version(version).showHelpAfterError();
|
|
151
|
+
program.action(() => {
|
|
152
|
+
program.outputHelp();
|
|
153
|
+
});
|
|
53
154
|
program.command("list").description("List all collections").action(
|
|
54
155
|
withErrors(async () => {
|
|
55
156
|
const collections = await listCollections();
|
|
@@ -144,6 +245,47 @@ function createProgram() {
|
|
|
144
245
|
}
|
|
145
246
|
})
|
|
146
247
|
);
|
|
248
|
+
program.command("up").description("Start the diffwiki UI (latest published diffwiki-app)").option("-p, --port <port>", "port to serve on", "4321").action(
|
|
249
|
+
withErrors(async (opts) => {
|
|
250
|
+
const existing = await readState();
|
|
251
|
+
if (existing && isAlive(existing.pid)) {
|
|
252
|
+
console.log(`UI already running at ${existing.url} (pid ${existing.pid})`);
|
|
253
|
+
return;
|
|
254
|
+
}
|
|
255
|
+
const state = await startUi(Number(opts.port));
|
|
256
|
+
const ok = await waitForServer(state.url);
|
|
257
|
+
console.log(
|
|
258
|
+
ok ? `UI started at ${state.url} (pid ${state.pid})` : `Launched (pid ${state.pid}) but ${state.url} did not respond yet \u2014 check \`diffwiki status\``
|
|
259
|
+
);
|
|
260
|
+
})
|
|
261
|
+
);
|
|
262
|
+
program.command("down").description("Stop the running diffwiki UI").action(
|
|
263
|
+
withErrors(async () => {
|
|
264
|
+
const stopped = await stopUi();
|
|
265
|
+
console.log(stopped ? `Stopped UI (pid ${stopped.pid})` : "UI is not running.");
|
|
266
|
+
})
|
|
267
|
+
);
|
|
268
|
+
program.command("status").description("Show whether the diffwiki UI is running").action(
|
|
269
|
+
withErrors(async () => {
|
|
270
|
+
const state = await readState();
|
|
271
|
+
if (state && isAlive(state.pid)) {
|
|
272
|
+
console.log(`running \xB7 ${state.url} \xB7 pid ${state.pid} \xB7 since ${state.startedAt}`);
|
|
273
|
+
} else {
|
|
274
|
+
console.log("stopped");
|
|
275
|
+
}
|
|
276
|
+
})
|
|
277
|
+
);
|
|
278
|
+
program.command("open").description("Open the diffwiki UI in the browser (starting it if needed)").option("-p, --port <port>", "port to serve on", "4321").action(
|
|
279
|
+
withErrors(async (opts) => {
|
|
280
|
+
let state = await readState();
|
|
281
|
+
if (!state || !isAlive(state.pid)) {
|
|
282
|
+
state = await startUi(Number(opts.port));
|
|
283
|
+
await waitForServer(state.url);
|
|
284
|
+
}
|
|
285
|
+
openBrowser(state.url);
|
|
286
|
+
console.log(`Opening ${state.url}`);
|
|
287
|
+
})
|
|
288
|
+
);
|
|
147
289
|
return program;
|
|
148
290
|
}
|
|
149
291
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "diffwiki",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0-rc.202607211217.f5290fa",
|
|
4
4
|
"description": "diffwiki command-line interface",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
},
|
|
16
16
|
"dependencies": {
|
|
17
17
|
"commander": "^13.0.0",
|
|
18
|
-
"diffwiki-core": "0.
|
|
18
|
+
"diffwiki-core": "0.3.0-rc.202607211217.f5290fa"
|
|
19
19
|
},
|
|
20
20
|
"devDependencies": {
|
|
21
21
|
"@types/node": "^22.0.0"
|