windscout 0.3.1 → 0.4.0
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/package.json +1 -1
- package/windscout.js +11 -6
package/package.json
CHANGED
package/windscout.js
CHANGED
|
@@ -175,6 +175,8 @@ const updateNotice = () => `update available: ${VERSION} → ${update} · run: $
|
|
|
175
175
|
|
|
176
176
|
const color = (code, s) => (process.env.NO_COLOR || !process.stdout.isTTY ? s : `\x1b[${code}m${s}\x1b[0m`);
|
|
177
177
|
const bold = (s) => color(1, s), dim = (s) => color(2, s), green = (s) => color(32, s);
|
|
178
|
+
// underline off (24) instead of a full reset, so it nests inside dim/bold
|
|
179
|
+
const under = (s) => (process.env.NO_COLOR || !process.stdout.isTTY ? s : `\x1b[4m${s}\x1b[24m`);
|
|
178
180
|
const cyan = (s) => color(36, s), yellow = (s) => color(33, s), red = (s) => color(31, s);
|
|
179
181
|
const fmt = (v, digits) => (v === null || v === undefined ? "-" : v.toFixed(digits));
|
|
180
182
|
const list = (s) => s.split(",").map((x) => x.trim()).filter(Boolean);
|
|
@@ -271,9 +273,12 @@ function matrix(results, protocols, { minWidth = 0, limit = Infinity } = {}) {
|
|
|
271
273
|
const reachable = ranked.filter((c) => c.good).length;
|
|
272
274
|
const rows = ranked.slice(0, limit).map(({ q, rs }) => {
|
|
273
275
|
const seen = rs.find((r) => r.status === "ok") ?? rs.find((r) => r.location);
|
|
276
|
+
// nickname = exact datacenter; protocols can land on different ones, so list each that connected
|
|
277
|
+
const nicks = [...new Set(rs.filter((r) => r.status === "ok").map((r) => r.location.split(" - ")[1]).filter(Boolean))];
|
|
274
278
|
return [
|
|
275
279
|
`${flag(q)} ${countryName(q)}`,
|
|
276
280
|
seen?.location?.split(" - ")[0] || dim("-"),
|
|
281
|
+
nicks.join(", ") || dim("-"),
|
|
277
282
|
...protocols.map((p) => {
|
|
278
283
|
const r = rs.find((x) => x.protocol === p);
|
|
279
284
|
return !r ? dim("·") : r.status === "ok" ? green("✓") : red("✗");
|
|
@@ -281,13 +286,13 @@ function matrix(results, protocols, { minWidth = 0, limit = Infinity } = {}) {
|
|
|
281
286
|
];
|
|
282
287
|
});
|
|
283
288
|
return grid(
|
|
284
|
-
[{ title: "Country" }, { title: "City" }, ...protocols.map((p) => ({ title: p, align: "center" }))],
|
|
289
|
+
[{ title: "Country" }, { title: "City" }, { title: "Location" }, ...protocols.map((p) => ({ title: p, align: "center" }))],
|
|
285
290
|
rows,
|
|
286
291
|
{
|
|
287
292
|
caption: bold("Availability"),
|
|
288
293
|
captionRight: dim(`${reachable}/${ranked.length} countries reachable${ranked.length > limit ? ` · top ${limit}` : ""}`),
|
|
289
294
|
minWidth,
|
|
290
|
-
stretch:
|
|
295
|
+
stretch: 2,
|
|
291
296
|
},
|
|
292
297
|
);
|
|
293
298
|
}
|
|
@@ -409,8 +414,8 @@ function pick(saved, timeout) {
|
|
|
409
414
|
top = Math.max(0, Math.min(top, list.length - height));
|
|
410
415
|
|
|
411
416
|
const protoLine = PROTOCOLS.map((p, i) =>
|
|
412
|
-
`${dim(String(i + 1))} ${protos.has(p) ? green("● " + p) : dim("○ " + p)}`).join(" ");
|
|
413
|
-
const speedLine = `${dim("s")} ${speedTest ? green("● speed test") : dim("○ speed test")} ${dim(speedTest
|
|
417
|
+
`${dim(under(String(i + 1)))} ${protos.has(p) ? green("● " + p) : dim("○ " + p)}`).join(" ");
|
|
418
|
+
const speedLine = `${dim(under("s"))} ${speedTest ? green("● speed test") : dim("○ speed test")} ${dim(speedTest
|
|
414
419
|
? "ranks by download speed · adds ~15s per working connection"
|
|
415
420
|
: "off: connect-only, ranks by latency")}`;
|
|
416
421
|
const search = searching
|
|
@@ -425,7 +430,7 @@ function pick(saved, timeout) {
|
|
|
425
430
|
return [`${here ? cyan("❯") : " "} ${mark}`, here ? bold(code) : dim(code), here ? bold(cyan(name)) : name];
|
|
426
431
|
});
|
|
427
432
|
if (!body.length) body.push([" ", "", dim("no country matches")]);
|
|
428
|
-
const buttons = [["start", "▶ Start"], ["all", query ? "
|
|
433
|
+
const buttons = [["start", "▶ Start"], ["all", under("A") + (query ? "ll shown" : "ll")], ["none", under("N") + (query ? "one shown" : "one")], ["quit", under("Q") + "uit"]];
|
|
429
434
|
const buttonLine = buttons.map(([id, label]) => (id === "start" ? bold(cyan(`[ ${label} ]`)) : dim(`[ ${label} ]`))).join(" ");
|
|
430
435
|
|
|
431
436
|
const table = grid([{ title: "" }, { title: "Code" }, { title: "Country" }], body,
|
|
@@ -796,7 +801,7 @@ async function main() {
|
|
|
796
801
|
if (!tty) throw new Error("no terminal for the picker: pass countries with -c");
|
|
797
802
|
const saved = loadConfig();
|
|
798
803
|
if (protocols && saved) saved.protocols = protocols.filter((p) => PROTOCOLS.includes(p));
|
|
799
|
-
speedTest = !a["no-speed"] && (saved?.speed ??
|
|
804
|
+
speedTest = !a["no-speed"] && (saved?.speed ?? false); // first run: connect-only
|
|
800
805
|
const choice = await pick(saved, timeout);
|
|
801
806
|
if (!choice) return;
|
|
802
807
|
countries = choice.countries;
|