@ggterm/core 0.3.1 → 0.3.2
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/cli-plot.js +75 -85
- package/dist/serve.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/cli-plot.js
CHANGED
|
@@ -14602,7 +14602,6 @@ __export(exports_serve, {
|
|
|
14602
14602
|
import { watch, writeFileSync as writeFileSync3, unlinkSync } from "fs";
|
|
14603
14603
|
import { join as join3 } from "path";
|
|
14604
14604
|
import { createServer } from "http";
|
|
14605
|
-
import { createHash } from "crypto";
|
|
14606
14605
|
import { spawn } from "child_process";
|
|
14607
14606
|
function plotToVegaLite(plot) {
|
|
14608
14607
|
const geomTypes = plot._provenance.geomTypes;
|
|
@@ -14620,27 +14619,6 @@ function getLatestPayload() {
|
|
|
14620
14619
|
const { spec, provenance } = plotToVegaLite(plot);
|
|
14621
14620
|
return JSON.stringify({ type: "plot", spec, provenance });
|
|
14622
14621
|
}
|
|
14623
|
-
function encodeWebSocketFrame(data) {
|
|
14624
|
-
const payload = Buffer.from(data, "utf-8");
|
|
14625
|
-
const len = payload.length;
|
|
14626
|
-
let header;
|
|
14627
|
-
if (len < 126) {
|
|
14628
|
-
header = Buffer.alloc(2);
|
|
14629
|
-
header[0] = 129;
|
|
14630
|
-
header[1] = len;
|
|
14631
|
-
} else if (len < 65536) {
|
|
14632
|
-
header = Buffer.alloc(4);
|
|
14633
|
-
header[0] = 129;
|
|
14634
|
-
header[1] = 126;
|
|
14635
|
-
header.writeUInt16BE(len, 2);
|
|
14636
|
-
} else {
|
|
14637
|
-
header = Buffer.alloc(10);
|
|
14638
|
-
header[0] = 129;
|
|
14639
|
-
header[1] = 127;
|
|
14640
|
-
header.writeBigUInt64BE(BigInt(len), 2);
|
|
14641
|
-
}
|
|
14642
|
-
return Buffer.concat([header, payload]);
|
|
14643
|
-
}
|
|
14644
14622
|
function jsonResponse(res, data, status = 200) {
|
|
14645
14623
|
const body = JSON.stringify(data);
|
|
14646
14624
|
res.writeHead(status, { "content-type": "application/json" });
|
|
@@ -14661,10 +14639,12 @@ function handleServe(port) {
|
|
|
14661
14639
|
const payload = getLatestPayload();
|
|
14662
14640
|
if (!payload)
|
|
14663
14641
|
return;
|
|
14664
|
-
const
|
|
14642
|
+
const sseData = `data: ${payload}
|
|
14643
|
+
|
|
14644
|
+
`;
|
|
14665
14645
|
for (const client of clients) {
|
|
14666
14646
|
try {
|
|
14667
|
-
client.write(
|
|
14647
|
+
client.write(sseData);
|
|
14668
14648
|
} catch {
|
|
14669
14649
|
clients.delete(client);
|
|
14670
14650
|
}
|
|
@@ -14673,6 +14653,21 @@ function handleServe(port) {
|
|
|
14673
14653
|
});
|
|
14674
14654
|
const server = createServer((req, res) => {
|
|
14675
14655
|
const url = new URL(req.url || "/", `http://localhost:${p}`);
|
|
14656
|
+
if (url.pathname === "/events") {
|
|
14657
|
+
res.writeHead(200, {
|
|
14658
|
+
"content-type": "text/event-stream",
|
|
14659
|
+
"cache-control": "no-cache",
|
|
14660
|
+
connection: "keep-alive"
|
|
14661
|
+
});
|
|
14662
|
+
clients.add(res);
|
|
14663
|
+
const payload = getLatestPayload();
|
|
14664
|
+
if (payload)
|
|
14665
|
+
res.write(`data: ${payload}
|
|
14666
|
+
|
|
14667
|
+
`);
|
|
14668
|
+
req.on("close", () => clients.delete(res));
|
|
14669
|
+
return;
|
|
14670
|
+
}
|
|
14676
14671
|
if (url.pathname === "/api/latest") {
|
|
14677
14672
|
const payload = getLatestPayload();
|
|
14678
14673
|
if (!payload)
|
|
@@ -14698,54 +14693,6 @@ function handleServe(port) {
|
|
|
14698
14693
|
res.writeHead(200, { "content-type": "text/html; charset=utf-8" });
|
|
14699
14694
|
res.end(CLIENT_HTML);
|
|
14700
14695
|
});
|
|
14701
|
-
server.on("upgrade", (req, socket, _head) => {
|
|
14702
|
-
const url = new URL(req.url || "/", `http://localhost:${p}`);
|
|
14703
|
-
if (url.pathname !== "/ws") {
|
|
14704
|
-
socket.destroy();
|
|
14705
|
-
return;
|
|
14706
|
-
}
|
|
14707
|
-
const key = req.headers["sec-websocket-key"];
|
|
14708
|
-
if (!key) {
|
|
14709
|
-
socket.destroy();
|
|
14710
|
-
return;
|
|
14711
|
-
}
|
|
14712
|
-
const accept = createHash("sha1").update(key + "258EAFA5-E914-47DA-95CA-5AB5DC85B7A8").digest("base64");
|
|
14713
|
-
socket.write(`HTTP/1.1 101 Switching Protocols\r
|
|
14714
|
-
` + `Upgrade: websocket\r
|
|
14715
|
-
` + `Connection: Upgrade\r
|
|
14716
|
-
` + `Sec-WebSocket-Accept: ${accept}\r
|
|
14717
|
-
` + `\r
|
|
14718
|
-
`);
|
|
14719
|
-
clients.add(socket);
|
|
14720
|
-
const payload = getLatestPayload();
|
|
14721
|
-
if (payload)
|
|
14722
|
-
socket.write(encodeWebSocketFrame(payload));
|
|
14723
|
-
socket.on("close", () => clients.delete(socket));
|
|
14724
|
-
socket.on("error", () => clients.delete(socket));
|
|
14725
|
-
socket.on("data", (data) => {
|
|
14726
|
-
if (data.length < 2)
|
|
14727
|
-
return;
|
|
14728
|
-
const opcode = data[0] & 15;
|
|
14729
|
-
if (opcode === 8) {
|
|
14730
|
-
const closeFrame = Buffer.alloc(2);
|
|
14731
|
-
closeFrame[0] = 136;
|
|
14732
|
-
closeFrame[1] = 0;
|
|
14733
|
-
try {
|
|
14734
|
-
socket.write(closeFrame);
|
|
14735
|
-
} catch {}
|
|
14736
|
-
socket.end();
|
|
14737
|
-
clients.delete(socket);
|
|
14738
|
-
return;
|
|
14739
|
-
}
|
|
14740
|
-
if (opcode === 9) {
|
|
14741
|
-
const pong = Buffer.from(data);
|
|
14742
|
-
pong[0] = pong[0] & 240 | 10;
|
|
14743
|
-
try {
|
|
14744
|
-
socket.write(pong);
|
|
14745
|
-
} catch {}
|
|
14746
|
-
}
|
|
14747
|
-
});
|
|
14748
|
-
});
|
|
14749
14696
|
server.listen(p, () => {
|
|
14750
14697
|
const url = `http://localhost:${p}`;
|
|
14751
14698
|
console.log(`ggterm live viewer running at ${url}`);
|
|
@@ -15034,7 +14981,6 @@ let history = [];
|
|
|
15034
14981
|
let historyIndex = {};
|
|
15035
14982
|
let currentIdx = -1;
|
|
15036
14983
|
let view = null;
|
|
15037
|
-
let ws = null;
|
|
15038
14984
|
|
|
15039
14985
|
function updateMeta(prov) {
|
|
15040
14986
|
if (!prov) return;
|
|
@@ -15192,17 +15138,12 @@ function downloadPNG() {
|
|
|
15192
15138
|
}
|
|
15193
15139
|
|
|
15194
15140
|
function connect() {
|
|
15195
|
-
const
|
|
15196
|
-
ws = new WebSocket(proto + '//' + location.host + '/ws');
|
|
15141
|
+
const es = new EventSource('/events');
|
|
15197
15142
|
|
|
15198
|
-
|
|
15199
|
-
|
|
15200
|
-
statusEl.classList.remove('connected');
|
|
15201
|
-
setTimeout(connect, 2000);
|
|
15202
|
-
};
|
|
15203
|
-
ws.onerror = () => ws.close();
|
|
15143
|
+
es.onopen = () => { statusEl.classList.add('connected'); };
|
|
15144
|
+
es.onerror = () => { statusEl.classList.remove('connected'); };
|
|
15204
15145
|
|
|
15205
|
-
|
|
15146
|
+
es.onmessage = (e) => {
|
|
15206
15147
|
const data = JSON.parse(e.data);
|
|
15207
15148
|
if (data.type === 'plot') {
|
|
15208
15149
|
history.push(data);
|
|
@@ -16389,19 +16330,68 @@ Examples:`);
|
|
|
16389
16330
|
Tip: Use "inspect <file>" to see available columns`);
|
|
16390
16331
|
process.exit(1);
|
|
16391
16332
|
}
|
|
16392
|
-
|
|
16333
|
+
const BUILTIN_DATASETS = {
|
|
16334
|
+
iris: () => {
|
|
16335
|
+
const species = ["setosa", "versicolor", "virginica"];
|
|
16336
|
+
const data2 = Array.from({ length: 150 }, (_, i) => {
|
|
16337
|
+
const sp = species[Math.floor(i / 50)];
|
|
16338
|
+
const base = sp === "setosa" ? 0 : sp === "versicolor" ? 1 : 2;
|
|
16339
|
+
return {
|
|
16340
|
+
sepal_length: +(5 + base * 0.5 + Math.random()).toFixed(1),
|
|
16341
|
+
sepal_width: +(3 + Math.random() * 0.5).toFixed(1),
|
|
16342
|
+
petal_length: +(1.5 + base * 2 + Math.random()).toFixed(1),
|
|
16343
|
+
petal_width: +(0.2 + base * 0.8 + Math.random() * 0.3).toFixed(1),
|
|
16344
|
+
species: sp
|
|
16345
|
+
};
|
|
16346
|
+
});
|
|
16347
|
+
return { headers: ["sepal_length", "sepal_width", "petal_length", "petal_width", "species"], data: data2 };
|
|
16348
|
+
},
|
|
16349
|
+
mtcars: () => {
|
|
16350
|
+
const data2 = [
|
|
16351
|
+
{ name: "Mazda RX4", mpg: 21, cyl: 6, hp: 110, wt: 2.62 },
|
|
16352
|
+
{ name: "Mazda RX4 Wag", mpg: 21, cyl: 6, hp: 110, wt: 2.875 },
|
|
16353
|
+
{ name: "Datsun 710", mpg: 22.8, cyl: 4, hp: 93, wt: 2.32 },
|
|
16354
|
+
{ name: "Hornet 4 Drive", mpg: 21.4, cyl: 6, hp: 110, wt: 3.215 },
|
|
16355
|
+
{ name: "Hornet Sportabout", mpg: 18.7, cyl: 8, hp: 175, wt: 3.44 },
|
|
16356
|
+
{ name: "Valiant", mpg: 18.1, cyl: 6, hp: 105, wt: 3.46 },
|
|
16357
|
+
{ name: "Duster 360", mpg: 14.3, cyl: 8, hp: 245, wt: 3.57 },
|
|
16358
|
+
{ name: "Merc 240D", mpg: 24.4, cyl: 4, hp: 62, wt: 3.19 },
|
|
16359
|
+
{ name: "Merc 230", mpg: 22.8, cyl: 4, hp: 95, wt: 3.15 },
|
|
16360
|
+
{ name: "Merc 280", mpg: 19.2, cyl: 6, hp: 123, wt: 3.44 },
|
|
16361
|
+
{ name: "Merc 280C", mpg: 17.8, cyl: 6, hp: 123, wt: 3.44 },
|
|
16362
|
+
{ name: "Merc 450SE", mpg: 16.4, cyl: 8, hp: 180, wt: 4.07 },
|
|
16363
|
+
{ name: "Merc 450SL", mpg: 17.3, cyl: 8, hp: 180, wt: 3.73 },
|
|
16364
|
+
{ name: "Merc 450SLC", mpg: 15.2, cyl: 8, hp: 180, wt: 3.78 },
|
|
16365
|
+
{ name: "Cadillac Fleetwood", mpg: 10.4, cyl: 8, hp: 205, wt: 5.25 },
|
|
16366
|
+
{ name: "Lincoln Continental", mpg: 10.4, cyl: 8, hp: 215, wt: 5.424 }
|
|
16367
|
+
];
|
|
16368
|
+
return { headers: ["name", "mpg", "cyl", "hp", "wt"], data: data2 };
|
|
16369
|
+
}
|
|
16370
|
+
};
|
|
16371
|
+
const [dataFile, x, y, color, title, geomSpec = "point", facetVar] = args;
|
|
16372
|
+
let headers;
|
|
16373
|
+
let data;
|
|
16374
|
+
if (BUILTIN_DATASETS[dataFile]) {
|
|
16375
|
+
const result = BUILTIN_DATASETS[dataFile]();
|
|
16376
|
+
headers = result.headers;
|
|
16377
|
+
data = result.data;
|
|
16378
|
+
} else if (!args[0].includes(".") && !fileExists(args[0])) {
|
|
16393
16379
|
console.error(`
|
|
16394
16380
|
Error: "${args[0]}" doesn't look like a file path`);
|
|
16395
16381
|
console.error(`
|
|
16382
|
+
Built-in datasets: iris, mtcars`);
|
|
16383
|
+
console.error(`
|
|
16396
16384
|
Did you mean one of these commands?`);
|
|
16397
16385
|
console.error(` inspect <file> - Show column types`);
|
|
16398
16386
|
console.error(` suggest <file> - Get plot suggestions`);
|
|
16399
16387
|
console.error(` history - List saved plots`);
|
|
16400
16388
|
console.error(` help - Show full usage`);
|
|
16401
16389
|
process.exit(1);
|
|
16390
|
+
} else {
|
|
16391
|
+
const loaded = loadData(dataFile);
|
|
16392
|
+
headers = loaded.headers;
|
|
16393
|
+
data = loaded.data;
|
|
16402
16394
|
}
|
|
16403
|
-
const [dataFile, x, y, color, title, geomSpec = "point", facetVar] = args;
|
|
16404
|
-
let { headers, data } = loadData(dataFile);
|
|
16405
16395
|
const { baseGeom: geomType, refLines } = parseGeomSpec(geomSpec);
|
|
16406
16396
|
if (geomType === "manhattan" && y && y !== "-") {
|
|
16407
16397
|
data = data.map((row) => {
|
package/dist/serve.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"serve.d.ts","sourceRoot":"","sources":["../src/serve.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;
|
|
1
|
+
{"version":3,"file":"serve.d.ts","sourceRoot":"","sources":["../src/serve.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AA0eH,wBAAgB,WAAW,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAmG/C"}
|