@aaronbassett/midnight-local-devnet 0.2.1 → 0.3.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/README.md +16 -26
- package/dist/cli/commands/dashboard.js +53 -14
- package/dist/cli/commands/dashboard.js.map +1 -1
- package/dist/cli/dashboard/html.d.ts +3 -0
- package/dist/cli/dashboard/html.js +1095 -0
- package/dist/cli/dashboard/html.js.map +1 -0
- package/dist/cli/dashboard/server.d.ts +17 -0
- package/dist/cli/dashboard/server.js +133 -0
- package/dist/cli/dashboard/server.js.map +1 -0
- package/dist/cli/dashboard/state-collector.d.ts +67 -0
- package/dist/cli/dashboard/state-collector.js +121 -0
- package/dist/cli/dashboard/state-collector.js.map +1 -0
- package/package.json +4 -5
- package/dist/cli/dashboard/app.d.ts +0 -9
- package/dist/cli/dashboard/app.js +0 -106
- package/dist/cli/dashboard/app.js.map +0 -1
- package/dist/cli/dashboard/components/gauge.d.ts +0 -9
- package/dist/cli/dashboard/components/gauge.js +0 -10
- package/dist/cli/dashboard/components/gauge.js.map +0 -1
- package/dist/cli/dashboard/components/panel-box.d.ts +0 -10
- package/dist/cli/dashboard/components/panel-box.js +0 -6
- package/dist/cli/dashboard/components/panel-box.js.map +0 -1
- package/dist/cli/dashboard/components/sparkline.d.ts +0 -9
- package/dist/cli/dashboard/components/sparkline.js +0 -25
- package/dist/cli/dashboard/components/sparkline.js.map +0 -1
- package/dist/cli/dashboard/components/status-badge.d.ts +0 -6
- package/dist/cli/dashboard/components/status-badge.js +0 -24
- package/dist/cli/dashboard/components/status-badge.js.map +0 -1
- package/dist/cli/dashboard/hooks/use-breakpoint.d.ts +0 -7
- package/dist/cli/dashboard/hooks/use-breakpoint.js +0 -15
- package/dist/cli/dashboard/hooks/use-breakpoint.js.map +0 -1
- package/dist/cli/dashboard/hooks/use-health.d.ts +0 -9
- package/dist/cli/dashboard/hooks/use-health.js +0 -35
- package/dist/cli/dashboard/hooks/use-health.js.map +0 -1
- package/dist/cli/dashboard/hooks/use-indexer-info.d.ts +0 -5
- package/dist/cli/dashboard/hooks/use-indexer-info.js +0 -19
- package/dist/cli/dashboard/hooks/use-indexer-info.js.map +0 -1
- package/dist/cli/dashboard/hooks/use-logs.d.ts +0 -19
- package/dist/cli/dashboard/hooks/use-logs.js +0 -55
- package/dist/cli/dashboard/hooks/use-logs.js.map +0 -1
- package/dist/cli/dashboard/hooks/use-node-info.d.ts +0 -21
- package/dist/cli/dashboard/hooks/use-node-info.js +0 -49
- package/dist/cli/dashboard/hooks/use-node-info.js.map +0 -1
- package/dist/cli/dashboard/hooks/use-polling.d.ts +0 -7
- package/dist/cli/dashboard/hooks/use-polling.js +0 -35
- package/dist/cli/dashboard/hooks/use-polling.js.map +0 -1
- package/dist/cli/dashboard/hooks/use-proof-server.d.ts +0 -7
- package/dist/cli/dashboard/hooks/use-proof-server.js +0 -14
- package/dist/cli/dashboard/hooks/use-proof-server.js.map +0 -1
- package/dist/cli/dashboard/hooks/use-services.d.ts +0 -3
- package/dist/cli/dashboard/hooks/use-services.js +0 -6
- package/dist/cli/dashboard/hooks/use-services.js.map +0 -1
- package/dist/cli/dashboard/hooks/use-terminal-size.d.ts +0 -5
- package/dist/cli/dashboard/hooks/use-terminal-size.js +0 -22
- package/dist/cli/dashboard/hooks/use-terminal-size.js.map +0 -1
- package/dist/cli/dashboard/hooks/use-wallet-state.d.ts +0 -10
- package/dist/cli/dashboard/hooks/use-wallet-state.js +0 -63
- package/dist/cli/dashboard/hooks/use-wallet-state.js.map +0 -1
- package/dist/cli/dashboard/layouts/large.d.ts +0 -7
- package/dist/cli/dashboard/layouts/large.js +0 -13
- package/dist/cli/dashboard/layouts/large.js.map +0 -1
- package/dist/cli/dashboard/layouts/medium.d.ts +0 -7
- package/dist/cli/dashboard/layouts/medium.js +0 -11
- package/dist/cli/dashboard/layouts/medium.js.map +0 -1
- package/dist/cli/dashboard/layouts/small.d.ts +0 -7
- package/dist/cli/dashboard/layouts/small.js +0 -11
- package/dist/cli/dashboard/layouts/small.js.map +0 -1
- package/dist/cli/dashboard/panels/indexer-panel.d.ts +0 -11
- package/dist/cli/dashboard/panels/indexer-panel.js +0 -17
- package/dist/cli/dashboard/panels/indexer-panel.js.map +0 -1
- package/dist/cli/dashboard/panels/log-panel.d.ts +0 -13
- package/dist/cli/dashboard/panels/log-panel.js +0 -27
- package/dist/cli/dashboard/panels/log-panel.js.map +0 -1
- package/dist/cli/dashboard/panels/node-panel.d.ts +0 -10
- package/dist/cli/dashboard/panels/node-panel.js +0 -17
- package/dist/cli/dashboard/panels/node-panel.js.map +0 -1
- package/dist/cli/dashboard/panels/proof-panel.d.ts +0 -10
- package/dist/cli/dashboard/panels/proof-panel.js +0 -20
- package/dist/cli/dashboard/panels/proof-panel.js.map +0 -1
- package/dist/cli/dashboard/panels/response-graph.d.ts +0 -10
- package/dist/cli/dashboard/panels/response-graph.js +0 -12
- package/dist/cli/dashboard/panels/response-graph.js.map +0 -1
- package/dist/cli/dashboard/panels/wallet-panel.d.ts +0 -9
- package/dist/cli/dashboard/panels/wallet-panel.js +0 -24
- package/dist/cli/dashboard/panels/wallet-panel.js.map +0 -1
- package/dist/cli/dashboard/types.d.ts +0 -39
- package/dist/cli/dashboard/types.js +0 -2
- package/dist/cli/dashboard/types.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"html.js","sourceRoot":"","sources":["../../../src/cli/dashboard/html.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,SAAS,gBAAgB,CAAC,KAAa;IACrC,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC;SACzB,OAAO,CAAC,IAAI,EAAE,SAAS,CAAC;SACxB,OAAO,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;AAC9B,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,EAAE,KAAK,EAAqB;IAChE,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;qBAwoBY,gBAAgB,CAAC,KAAK,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QAkbpC,CAAC;AACT,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Hono } from 'hono';
|
|
2
|
+
import { WebSocketServer } from 'ws';
|
|
3
|
+
import type { Server } from 'node:http';
|
|
4
|
+
import type { NetworkConfig } from '../../core/types.js';
|
|
5
|
+
import type { NetworkManager } from '../../core/network-manager.js';
|
|
6
|
+
export interface DashboardServerOptions {
|
|
7
|
+
config: NetworkConfig;
|
|
8
|
+
manager: NetworkManager;
|
|
9
|
+
port: number;
|
|
10
|
+
}
|
|
11
|
+
export declare function createDashboardApp(opts: DashboardServerOptions): {
|
|
12
|
+
app: Hono<import("hono/types").BlankEnv, import("hono/types").BlankSchema, "/">;
|
|
13
|
+
setupWebSocket: (server: Server) => WebSocketServer;
|
|
14
|
+
startPolling: () => void;
|
|
15
|
+
stopPolling: () => void;
|
|
16
|
+
shutdown: () => void;
|
|
17
|
+
};
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import { Hono } from 'hono';
|
|
2
|
+
import { WebSocketServer } from 'ws';
|
|
3
|
+
import { StateCollector } from './state-collector.js';
|
|
4
|
+
import { generateDashboardHtml } from './html.js';
|
|
5
|
+
import { getWalletBalances } from '../../core/wallet.js';
|
|
6
|
+
export function createDashboardApp(opts) {
|
|
7
|
+
const { config, manager, port } = opts;
|
|
8
|
+
const app = new Hono();
|
|
9
|
+
const collector = new StateCollector(config);
|
|
10
|
+
const clients = new Set();
|
|
11
|
+
let pollingInterval = null;
|
|
12
|
+
// ---------- GET / — serve dashboard HTML ----------
|
|
13
|
+
app.get('/', (c) => {
|
|
14
|
+
const html = generateDashboardHtml({ wsUrl: `ws://localhost:${port}/ws` });
|
|
15
|
+
return c.html(html);
|
|
16
|
+
});
|
|
17
|
+
// ---------- WebSocket setup ----------
|
|
18
|
+
function setupWebSocket(server) {
|
|
19
|
+
const wss = new WebSocketServer({ server, path: '/ws' });
|
|
20
|
+
wss.on('connection', (ws) => {
|
|
21
|
+
clients.add(ws);
|
|
22
|
+
ws.on('close', () => {
|
|
23
|
+
clients.delete(ws);
|
|
24
|
+
});
|
|
25
|
+
ws.on('message', (raw) => {
|
|
26
|
+
handleClientMessage(ws, raw);
|
|
27
|
+
});
|
|
28
|
+
});
|
|
29
|
+
return wss;
|
|
30
|
+
}
|
|
31
|
+
// ---------- Client message handling ----------
|
|
32
|
+
async function handleClientMessage(ws, raw) {
|
|
33
|
+
try {
|
|
34
|
+
const text = typeof raw === 'string' ? raw : raw.toString();
|
|
35
|
+
const msg = JSON.parse(text);
|
|
36
|
+
if (msg.type === 'command' && msg.action) {
|
|
37
|
+
await handleCommand(ws, msg.action);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
catch {
|
|
41
|
+
// Ignore malformed messages
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
async function handleCommand(ws, action) {
|
|
45
|
+
try {
|
|
46
|
+
if (action === 'start') {
|
|
47
|
+
await manager.start({ pull: false });
|
|
48
|
+
}
|
|
49
|
+
else if (action === 'stop') {
|
|
50
|
+
await manager.stop({ removeVolumes: false });
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
sendToClient(ws, { type: 'result', action, success: false, error: `Unknown action: ${action}` });
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
sendToClient(ws, { type: 'result', action, success: true });
|
|
57
|
+
}
|
|
58
|
+
catch (err) {
|
|
59
|
+
const error = err instanceof Error ? err.message : String(err);
|
|
60
|
+
sendToClient(ws, { type: 'result', action, success: false, error });
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
function sendToClient(ws, data) {
|
|
64
|
+
if (ws.readyState === ws.OPEN) {
|
|
65
|
+
ws.send(JSON.stringify(data));
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
// ---------- Polling + broadcast ----------
|
|
69
|
+
async function collectAndBroadcast() {
|
|
70
|
+
try {
|
|
71
|
+
let walletInfo;
|
|
72
|
+
const walletCtx = manager.getMasterWallet();
|
|
73
|
+
if (walletCtx) {
|
|
74
|
+
try {
|
|
75
|
+
const balances = await getWalletBalances(walletCtx);
|
|
76
|
+
walletInfo = {
|
|
77
|
+
address: null, // Address extraction requires wallet SDK; use null for MVP
|
|
78
|
+
connected: true,
|
|
79
|
+
unshielded: balances.unshielded.toString(),
|
|
80
|
+
shielded: balances.shielded.toString(),
|
|
81
|
+
dust: balances.dust.toString(),
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
catch {
|
|
85
|
+
walletInfo = {
|
|
86
|
+
address: null,
|
|
87
|
+
connected: false,
|
|
88
|
+
unshielded: '0',
|
|
89
|
+
shielded: '0',
|
|
90
|
+
dust: '0',
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
const state = await collector.collect(walletInfo, manager.getStatus());
|
|
95
|
+
// JSON.stringify with bigint-safe replacer (just in case)
|
|
96
|
+
const json = JSON.stringify({ type: 'state', data: state }, (_key, value) => typeof value === 'bigint' ? value.toString() : value);
|
|
97
|
+
for (const ws of clients) {
|
|
98
|
+
if (ws.readyState === ws.OPEN) {
|
|
99
|
+
ws.send(json);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
catch {
|
|
104
|
+
// Swallow polling errors to keep the interval running
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
function startPolling() {
|
|
108
|
+
// Collect immediately, then every 3 seconds
|
|
109
|
+
collectAndBroadcast();
|
|
110
|
+
pollingInterval = setInterval(collectAndBroadcast, 3000);
|
|
111
|
+
}
|
|
112
|
+
function stopPolling() {
|
|
113
|
+
if (pollingInterval !== null) {
|
|
114
|
+
clearInterval(pollingInterval);
|
|
115
|
+
pollingInterval = null;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
function shutdown() {
|
|
119
|
+
stopPolling();
|
|
120
|
+
for (const ws of clients) {
|
|
121
|
+
ws.close();
|
|
122
|
+
}
|
|
123
|
+
clients.clear();
|
|
124
|
+
}
|
|
125
|
+
return {
|
|
126
|
+
app,
|
|
127
|
+
setupWebSocket,
|
|
128
|
+
startPolling,
|
|
129
|
+
stopPolling,
|
|
130
|
+
shutdown,
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../../src/cli/dashboard/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,eAAe,EAAiC,MAAM,IAAI,CAAC;AAIpE,OAAO,EAAE,cAAc,EAAmB,MAAM,sBAAsB,CAAC;AACvE,OAAO,EAAE,qBAAqB,EAAE,MAAM,WAAW,CAAC;AAClD,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAQzD,MAAM,UAAU,kBAAkB,CAAC,IAA4B;IAC7D,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,GAAG,IAAI,CAAC;IACvC,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;IACvB,MAAM,SAAS,GAAG,IAAI,cAAc,CAAC,MAAM,CAAC,CAAC;IAC7C,MAAM,OAAO,GAAG,IAAI,GAAG,EAAe,CAAC;IACvC,IAAI,eAAe,GAA0C,IAAI,CAAC;IAElE,qDAAqD;IACrD,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,EAAE;QACjB,MAAM,IAAI,GAAG,qBAAqB,CAAC,EAAE,KAAK,EAAE,kBAAkB,IAAI,KAAK,EAAE,CAAC,CAAC;QAC3E,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACtB,CAAC,CAAC,CAAC;IAEH,wCAAwC;IACxC,SAAS,cAAc,CAAC,MAAc;QACpC,MAAM,GAAG,GAAG,IAAI,eAAe,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;QAEzD,GAAG,CAAC,EAAE,CAAC,YAAY,EAAE,CAAC,EAAe,EAAE,EAAE;YACvC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YAEhB,EAAE,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE;gBAClB,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;YACrB,CAAC,CAAC,CAAC;YAEH,EAAE,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,GAAoC,EAAE,EAAE;gBACxD,mBAAmB,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC;YAC/B,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,OAAO,GAAG,CAAC;IACb,CAAC;IAED,gDAAgD;IAChD,KAAK,UAAU,mBAAmB,CAAC,EAAe,EAAE,GAAoC;QACtF,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,OAAO,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC;YAC5D,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAuC,CAAC;YAEnE,IAAI,GAAG,CAAC,IAAI,KAAK,SAAS,IAAI,GAAG,CAAC,MAAM,EAAE,CAAC;gBACzC,MAAM,aAAa,CAAC,EAAE,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;YACtC,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,4BAA4B;QAC9B,CAAC;IACH,CAAC;IAED,KAAK,UAAU,aAAa,CAAC,EAAe,EAAE,MAAc;QAC1D,IAAI,CAAC;YACH,IAAI,MAAM,KAAK,OAAO,EAAE,CAAC;gBACvB,MAAM,OAAO,CAAC,KAAK,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;YACvC,CAAC;iBAAM,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;gBAC7B,MAAM,OAAO,CAAC,IAAI,CAAC,EAAE,aAAa,EAAE,KAAK,EAAE,CAAC,CAAC;YAC/C,CAAC;iBAAM,CAAC;gBACN,YAAY,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,mBAAmB,MAAM,EAAE,EAAE,CAAC,CAAC;gBACjG,OAAO;YACT,CAAC;YACD,YAAY,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;QAC9D,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,KAAK,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YAC/D,YAAY,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC;QACtE,CAAC;IACH,CAAC;IAED,SAAS,YAAY,CAAC,EAAe,EAAE,IAAa;QAClD,IAAI,EAAE,CAAC,UAAU,KAAK,EAAE,CAAC,IAAI,EAAE,CAAC;YAC9B,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC;QAChC,CAAC;IACH,CAAC;IAED,4CAA4C;IAC5C,KAAK,UAAU,mBAAmB;QAChC,IAAI,CAAC;YACH,IAAI,UAAkC,CAAC;YAEvC,MAAM,SAAS,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC;YAC5C,IAAI,SAAS,EAAE,CAAC;gBACd,IAAI,CAAC;oBACH,MAAM,QAAQ,GAAG,MAAM,iBAAiB,CAAC,SAAS,CAAC,CAAC;oBACpD,UAAU,GAAG;wBACX,OAAO,EAAE,IAAI,EAAE,2DAA2D;wBAC1E,SAAS,EAAE,IAAI;wBACf,UAAU,EAAE,QAAQ,CAAC,UAAU,CAAC,QAAQ,EAAE;wBAC1C,QAAQ,EAAE,QAAQ,CAAC,QAAQ,CAAC,QAAQ,EAAE;wBACtC,IAAI,EAAE,QAAQ,CAAC,IAAI,CAAC,QAAQ,EAAE;qBAC/B,CAAC;gBACJ,CAAC;gBAAC,MAAM,CAAC;oBACP,UAAU,GAAG;wBACX,OAAO,EAAE,IAAI;wBACb,SAAS,EAAE,KAAK;wBAChB,UAAU,EAAE,GAAG;wBACf,QAAQ,EAAE,GAAG;wBACb,IAAI,EAAE,GAAG;qBACV,CAAC;gBACJ,CAAC;YACH,CAAC;YAED,MAAM,KAAK,GAAG,MAAM,SAAS,CAAC,OAAO,CAAC,UAAU,EAAE,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC;YAEvE,0DAA0D;YAC1D,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAC1E,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,KAAK,CACrD,CAAC;YAEF,KAAK,MAAM,EAAE,IAAI,OAAO,EAAE,CAAC;gBACzB,IAAI,EAAE,CAAC,UAAU,KAAK,EAAE,CAAC,IAAI,EAAE,CAAC;oBAC9B,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBAChB,CAAC;YACH,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,sDAAsD;QACxD,CAAC;IACH,CAAC;IAED,SAAS,YAAY;QACnB,4CAA4C;QAC5C,mBAAmB,EAAE,CAAC;QACtB,eAAe,GAAG,WAAW,CAAC,mBAAmB,EAAE,IAAI,CAAC,CAAC;IAC3D,CAAC;IAED,SAAS,WAAW;QAClB,IAAI,eAAe,KAAK,IAAI,EAAE,CAAC;YAC7B,aAAa,CAAC,eAAe,CAAC,CAAC;YAC/B,eAAe,GAAG,IAAI,CAAC;QACzB,CAAC;IACH,CAAC;IAED,SAAS,QAAQ;QACf,WAAW,EAAE,CAAC;QACd,KAAK,MAAM,EAAE,IAAI,OAAO,EAAE,CAAC;YACzB,EAAE,CAAC,KAAK,EAAE,CAAC;QACb,CAAC;QACD,OAAO,CAAC,KAAK,EAAE,CAAC;IAClB,CAAC;IAED,OAAO;QACL,GAAG;QACH,cAAc;QACd,YAAY;QACZ,WAAW;QACX,QAAQ;KACT,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import type { NetworkConfig, ServiceStatus } from '../../core/types.js';
|
|
2
|
+
import type { ParsedLogLine } from './lib/log-parser.js';
|
|
3
|
+
export interface DashboardState {
|
|
4
|
+
node: {
|
|
5
|
+
chain: string | null;
|
|
6
|
+
name: string | null;
|
|
7
|
+
version: string | null;
|
|
8
|
+
blockHeight: number | null;
|
|
9
|
+
/** Average block production time in milliseconds, or null if insufficient data */
|
|
10
|
+
avgBlockTime: number | null;
|
|
11
|
+
peers: number | null;
|
|
12
|
+
syncing: boolean | null;
|
|
13
|
+
};
|
|
14
|
+
indexer: {
|
|
15
|
+
ready: boolean;
|
|
16
|
+
responseTime: number | null;
|
|
17
|
+
};
|
|
18
|
+
proofServer: {
|
|
19
|
+
version: string | null;
|
|
20
|
+
ready: boolean;
|
|
21
|
+
jobsProcessing: number | null;
|
|
22
|
+
jobsPending: number | null;
|
|
23
|
+
jobCapacity: number | null;
|
|
24
|
+
proofVersions: string[] | null;
|
|
25
|
+
};
|
|
26
|
+
wallet: {
|
|
27
|
+
address: string | null;
|
|
28
|
+
connected: boolean;
|
|
29
|
+
unshielded: string;
|
|
30
|
+
shielded: string;
|
|
31
|
+
dust: string;
|
|
32
|
+
};
|
|
33
|
+
health: {
|
|
34
|
+
node: {
|
|
35
|
+
status: 'healthy' | 'unhealthy';
|
|
36
|
+
history: number[];
|
|
37
|
+
};
|
|
38
|
+
indexer: {
|
|
39
|
+
status: 'healthy' | 'unhealthy';
|
|
40
|
+
history: number[];
|
|
41
|
+
};
|
|
42
|
+
proofServer: {
|
|
43
|
+
status: 'healthy' | 'unhealthy';
|
|
44
|
+
history: number[];
|
|
45
|
+
};
|
|
46
|
+
};
|
|
47
|
+
containers: ServiceStatus[];
|
|
48
|
+
logs: ParsedLogLine[];
|
|
49
|
+
networkStatus: string;
|
|
50
|
+
}
|
|
51
|
+
export interface WalletInfo {
|
|
52
|
+
address: string | null;
|
|
53
|
+
connected: boolean;
|
|
54
|
+
unshielded: string;
|
|
55
|
+
shielded: string;
|
|
56
|
+
dust: string;
|
|
57
|
+
}
|
|
58
|
+
export declare class StateCollector {
|
|
59
|
+
private readonly config;
|
|
60
|
+
private readonly nodeHistory;
|
|
61
|
+
private readonly indexerHistory;
|
|
62
|
+
private readonly proofHistory;
|
|
63
|
+
private lastBlockHeight;
|
|
64
|
+
private lastBlockTime;
|
|
65
|
+
constructor(config: NetworkConfig);
|
|
66
|
+
collect(walletInfo?: WalletInfo, networkStatus?: string): Promise<DashboardState>;
|
|
67
|
+
}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import { parseLogLines } from './lib/log-parser.js';
|
|
2
|
+
import { fetchSystemChain, fetchSystemName, fetchSystemVersion, fetchSystemHealth, fetchBestBlockHeader, } from './lib/substrate-rpc.js';
|
|
3
|
+
import { fetchProofServerReady, fetchProofServerVersion, fetchProofVersions, } from './lib/proof-server-api.js';
|
|
4
|
+
import { composePs, composeLogs } from '../../core/docker.js';
|
|
5
|
+
import { checkAllHealth } from '../../core/health.js';
|
|
6
|
+
const MAX_HISTORY = 30;
|
|
7
|
+
async function safeCall(fn, fallback) {
|
|
8
|
+
try {
|
|
9
|
+
return await fn();
|
|
10
|
+
}
|
|
11
|
+
catch {
|
|
12
|
+
return fallback;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
export class StateCollector {
|
|
16
|
+
config;
|
|
17
|
+
nodeHistory = [];
|
|
18
|
+
indexerHistory = [];
|
|
19
|
+
proofHistory = [];
|
|
20
|
+
lastBlockHeight = null;
|
|
21
|
+
lastBlockTime = null;
|
|
22
|
+
constructor(config) {
|
|
23
|
+
this.config = config;
|
|
24
|
+
}
|
|
25
|
+
async collect(walletInfo, networkStatus) {
|
|
26
|
+
const [chain, name, version, systemHealth, blockHeader, proofVersion, proofReady, proofVersions, containers, rawLogs, healthReport,] = await Promise.all([
|
|
27
|
+
safeCall(() => fetchSystemChain(this.config.node), null),
|
|
28
|
+
safeCall(() => fetchSystemName(this.config.node), null),
|
|
29
|
+
safeCall(() => fetchSystemVersion(this.config.node), null),
|
|
30
|
+
safeCall(() => fetchSystemHealth(this.config.node), null),
|
|
31
|
+
safeCall(() => fetchBestBlockHeader(this.config.node), null),
|
|
32
|
+
safeCall(() => fetchProofServerVersion(this.config.proofServer), null),
|
|
33
|
+
safeCall(() => fetchProofServerReady(this.config.proofServer), null),
|
|
34
|
+
safeCall(() => fetchProofVersions(this.config.proofServer), null),
|
|
35
|
+
safeCall(() => composePs(), []),
|
|
36
|
+
safeCall(() => composeLogs({ lines: 100 }), ''),
|
|
37
|
+
safeCall(() => checkAllHealth(this.config), null),
|
|
38
|
+
]);
|
|
39
|
+
// Compute avgBlockTime
|
|
40
|
+
const blockHeight = blockHeader?.number ?? null;
|
|
41
|
+
let avgBlockTime = null;
|
|
42
|
+
const now = Date.now();
|
|
43
|
+
if (blockHeight !== null &&
|
|
44
|
+
this.lastBlockHeight !== null &&
|
|
45
|
+
this.lastBlockTime !== null &&
|
|
46
|
+
blockHeight > this.lastBlockHeight) {
|
|
47
|
+
const elapsed = now - this.lastBlockTime;
|
|
48
|
+
const blocksProduced = blockHeight - this.lastBlockHeight;
|
|
49
|
+
avgBlockTime = elapsed / blocksProduced;
|
|
50
|
+
}
|
|
51
|
+
if (blockHeight !== null && (this.lastBlockHeight === null || blockHeight > this.lastBlockHeight)) {
|
|
52
|
+
this.lastBlockHeight = blockHeight;
|
|
53
|
+
this.lastBlockTime = now;
|
|
54
|
+
}
|
|
55
|
+
// Update response time history
|
|
56
|
+
if (healthReport?.node.responseTime != null) {
|
|
57
|
+
this.nodeHistory.push(healthReport.node.responseTime);
|
|
58
|
+
if (this.nodeHistory.length > MAX_HISTORY)
|
|
59
|
+
this.nodeHistory.shift();
|
|
60
|
+
}
|
|
61
|
+
if (healthReport?.indexer.responseTime != null) {
|
|
62
|
+
this.indexerHistory.push(healthReport.indexer.responseTime);
|
|
63
|
+
if (this.indexerHistory.length > MAX_HISTORY)
|
|
64
|
+
this.indexerHistory.shift();
|
|
65
|
+
}
|
|
66
|
+
if (healthReport?.proofServer.responseTime != null) {
|
|
67
|
+
this.proofHistory.push(healthReport.proofServer.responseTime);
|
|
68
|
+
if (this.proofHistory.length > MAX_HISTORY)
|
|
69
|
+
this.proofHistory.shift();
|
|
70
|
+
}
|
|
71
|
+
const logs = parseLogLines(rawLogs);
|
|
72
|
+
return {
|
|
73
|
+
node: {
|
|
74
|
+
chain,
|
|
75
|
+
name,
|
|
76
|
+
version,
|
|
77
|
+
blockHeight,
|
|
78
|
+
avgBlockTime,
|
|
79
|
+
peers: systemHealth?.peers ?? null,
|
|
80
|
+
syncing: systemHealth?.isSyncing ?? null,
|
|
81
|
+
},
|
|
82
|
+
indexer: {
|
|
83
|
+
ready: healthReport?.indexer.healthy ?? false,
|
|
84
|
+
responseTime: healthReport?.indexer.responseTime ?? null,
|
|
85
|
+
},
|
|
86
|
+
proofServer: {
|
|
87
|
+
version: proofVersion,
|
|
88
|
+
ready: proofReady?.status === 'ok',
|
|
89
|
+
jobsProcessing: proofReady?.jobsProcessing ?? null,
|
|
90
|
+
jobsPending: proofReady?.jobsPending ?? null,
|
|
91
|
+
jobCapacity: proofReady?.jobCapacity ?? null,
|
|
92
|
+
proofVersions,
|
|
93
|
+
},
|
|
94
|
+
wallet: walletInfo ?? {
|
|
95
|
+
address: null,
|
|
96
|
+
connected: false,
|
|
97
|
+
unshielded: '0',
|
|
98
|
+
shielded: '0',
|
|
99
|
+
dust: '0',
|
|
100
|
+
},
|
|
101
|
+
health: {
|
|
102
|
+
node: {
|
|
103
|
+
status: healthReport?.node.healthy ? 'healthy' : 'unhealthy',
|
|
104
|
+
history: [...this.nodeHistory],
|
|
105
|
+
},
|
|
106
|
+
indexer: {
|
|
107
|
+
status: healthReport?.indexer.healthy ? 'healthy' : 'unhealthy',
|
|
108
|
+
history: [...this.indexerHistory],
|
|
109
|
+
},
|
|
110
|
+
proofServer: {
|
|
111
|
+
status: healthReport?.proofServer.healthy ? 'healthy' : 'unhealthy',
|
|
112
|
+
history: [...this.proofHistory],
|
|
113
|
+
},
|
|
114
|
+
},
|
|
115
|
+
containers,
|
|
116
|
+
logs,
|
|
117
|
+
networkStatus: networkStatus ?? 'unknown',
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
//# sourceMappingURL=state-collector.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"state-collector.js","sourceRoot":"","sources":["../../../src/cli/dashboard/state-collector.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aaronbassett/midnight-local-devnet",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "Local Midnight development network manager — CLI and MCP server",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -39,6 +39,7 @@
|
|
|
39
39
|
"test:watch": "vitest"
|
|
40
40
|
},
|
|
41
41
|
"dependencies": {
|
|
42
|
+
"@hono/node-server": "^1.19.9",
|
|
42
43
|
"@midnight-ntwrk/ledger-v7": "7.0.0",
|
|
43
44
|
"@midnight-ntwrk/midnight-js-network-id": "3.1.0",
|
|
44
45
|
"@midnight-ntwrk/wallet-sdk-abstractions": "1.0.0",
|
|
@@ -51,19 +52,17 @@
|
|
|
51
52
|
"@modelcontextprotocol/sdk": "^1.12.1",
|
|
52
53
|
"@scure/bip39": "^2.0.1",
|
|
53
54
|
"commander": "^13.1.0",
|
|
54
|
-
"
|
|
55
|
+
"hono": "^4.12.3",
|
|
56
|
+
"open": "^11.0.0",
|
|
55
57
|
"pino": "^10.1.0",
|
|
56
58
|
"pino-pretty": "^13.1.3",
|
|
57
|
-
"react": "^19.2.4",
|
|
58
59
|
"rxjs": "^7.8.1",
|
|
59
60
|
"ws": "^8.18.3",
|
|
60
61
|
"zod": "^3.24.0"
|
|
61
62
|
},
|
|
62
63
|
"devDependencies": {
|
|
63
64
|
"@types/node": "^22.0.0",
|
|
64
|
-
"@types/react": "^19.2.14",
|
|
65
65
|
"@types/ws": "^8.18.1",
|
|
66
|
-
"ink-testing-library": "^4.0.0",
|
|
67
66
|
"typescript": "^5.9.3",
|
|
68
67
|
"vitest": "^3.1.0"
|
|
69
68
|
},
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import type { NetworkManager } from '../../core/network-manager.js';
|
|
3
|
-
import type { NetworkConfig } from '../../core/types.js';
|
|
4
|
-
interface AppProps {
|
|
5
|
-
manager: NetworkManager;
|
|
6
|
-
config: NetworkConfig;
|
|
7
|
-
}
|
|
8
|
-
export declare function App({ manager, config }: AppProps): React.ReactElement;
|
|
9
|
-
export {};
|
|
@@ -1,106 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { useState } from 'react';
|
|
3
|
-
import { Box, Text, useInput, useApp } from 'ink';
|
|
4
|
-
import { useBreakpoint } from './hooks/use-breakpoint.js';
|
|
5
|
-
import { useNodeInfo } from './hooks/use-node-info.js';
|
|
6
|
-
import { useProofServer } from './hooks/use-proof-server.js';
|
|
7
|
-
import { useHealth } from './hooks/use-health.js';
|
|
8
|
-
import { useIndexerInfo } from './hooks/use-indexer-info.js';
|
|
9
|
-
import { useWalletState } from './hooks/use-wallet-state.js';
|
|
10
|
-
import { useLogs } from './hooks/use-logs.js';
|
|
11
|
-
import { SmallLayout } from './layouts/small.js';
|
|
12
|
-
import { MediumLayout } from './layouts/medium.js';
|
|
13
|
-
import { LargeLayout } from './layouts/large.js';
|
|
14
|
-
const PANEL_CYCLE = ['node', 'indexer', 'proof', 'wallet', 'logs', 'graph'];
|
|
15
|
-
export function App({ manager, config }) {
|
|
16
|
-
const { exit } = useApp();
|
|
17
|
-
const { breakpoint, columns, rows } = useBreakpoint();
|
|
18
|
-
// Data hooks
|
|
19
|
-
const nodeInfo = useNodeInfo(config.node);
|
|
20
|
-
const proofServer = useProofServer(config.proofServer);
|
|
21
|
-
const health = useHealth(config);
|
|
22
|
-
const indexerInfo = useIndexerInfo(config.indexer);
|
|
23
|
-
const walletState = useWalletState(manager);
|
|
24
|
-
const logs = useLogs();
|
|
25
|
-
// UI state
|
|
26
|
-
const [focusedPanel, setFocusedPanel] = useState('node');
|
|
27
|
-
const [searchMode, setSearchMode] = useState(false);
|
|
28
|
-
const [searchText, setSearchText] = useState('');
|
|
29
|
-
const isInteractive = process.stdin.isTTY === true;
|
|
30
|
-
useInput((input, key) => {
|
|
31
|
-
if (searchMode) {
|
|
32
|
-
if (key.escape || key.return) {
|
|
33
|
-
setSearchMode(false);
|
|
34
|
-
if (key.return)
|
|
35
|
-
logs.setSearch(searchText);
|
|
36
|
-
if (key.escape) {
|
|
37
|
-
setSearchText('');
|
|
38
|
-
logs.setSearch('');
|
|
39
|
-
}
|
|
40
|
-
return;
|
|
41
|
-
}
|
|
42
|
-
if (key.backspace || key.delete) {
|
|
43
|
-
setSearchText((prev) => prev.slice(0, -1));
|
|
44
|
-
return;
|
|
45
|
-
}
|
|
46
|
-
setSearchText((prev) => prev + input);
|
|
47
|
-
return;
|
|
48
|
-
}
|
|
49
|
-
if (input === 'q') {
|
|
50
|
-
exit();
|
|
51
|
-
return;
|
|
52
|
-
}
|
|
53
|
-
if (key.tab) {
|
|
54
|
-
setFocusedPanel((prev) => {
|
|
55
|
-
const idx = PANEL_CYCLE.indexOf(prev);
|
|
56
|
-
return PANEL_CYCLE[(idx + 1) % PANEL_CYCLE.length];
|
|
57
|
-
});
|
|
58
|
-
return;
|
|
59
|
-
}
|
|
60
|
-
if (input === 's') {
|
|
61
|
-
logs.cycleService();
|
|
62
|
-
return;
|
|
63
|
-
}
|
|
64
|
-
if (input === 'l') {
|
|
65
|
-
logs.cycleLevel();
|
|
66
|
-
return;
|
|
67
|
-
}
|
|
68
|
-
if (input === '/') {
|
|
69
|
-
setSearchMode(true);
|
|
70
|
-
setSearchText('');
|
|
71
|
-
return;
|
|
72
|
-
}
|
|
73
|
-
if (key.upArrow) {
|
|
74
|
-
if (focusedPanel === 'logs')
|
|
75
|
-
logs.scrollUp();
|
|
76
|
-
return;
|
|
77
|
-
}
|
|
78
|
-
if (key.downArrow) {
|
|
79
|
-
if (focusedPanel === 'logs')
|
|
80
|
-
logs.scrollDown();
|
|
81
|
-
return;
|
|
82
|
-
}
|
|
83
|
-
}, { isActive: isInteractive });
|
|
84
|
-
const data = {
|
|
85
|
-
node: nodeInfo.data,
|
|
86
|
-
nodeLoading: nodeInfo.loading,
|
|
87
|
-
indexer: indexerInfo.data,
|
|
88
|
-
indexerLoading: indexerInfo.loading,
|
|
89
|
-
proofServer: proofServer.data,
|
|
90
|
-
proofServerLoading: proofServer.loading,
|
|
91
|
-
wallet: walletState,
|
|
92
|
-
logs,
|
|
93
|
-
healthHistory: {
|
|
94
|
-
nodeHistory: health.data?.nodeHistory ?? [],
|
|
95
|
-
indexerHistory: health.data?.indexerHistory ?? [],
|
|
96
|
-
proofServerHistory: health.data?.proofServerHistory ?? [],
|
|
97
|
-
},
|
|
98
|
-
focusedPanel,
|
|
99
|
-
searchMode,
|
|
100
|
-
searchText,
|
|
101
|
-
columns,
|
|
102
|
-
rows,
|
|
103
|
-
};
|
|
104
|
-
return (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Box, { justifyContent: "space-between", children: [_jsx(Text, { bold: true, color: "cyan", children: "Midnight Local Devnet" }), _jsxs(Text, { color: "gray", children: [columns, "x", rows, " | ", breakpoint, " | Tab=focus q=quit s=svc l=lvl /=search"] })] }), breakpoint === 'small' && _jsx(SmallLayout, { data: data }), breakpoint === 'medium' && _jsx(MediumLayout, { data: data }), breakpoint === 'large' && _jsx(LargeLayout, { data: data })] }));
|
|
105
|
-
}
|
|
106
|
-
//# sourceMappingURL=app.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"app.js","sourceRoot":"","sources":["../../../src/cli/dashboard/app.tsx"],"names":[],"mappings":"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"}
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { Text } from 'ink';
|
|
3
|
-
export function Gauge({ value, max, width = 10, label }) {
|
|
4
|
-
const filled = max > 0 ? Math.round((value / max) * width) : 0;
|
|
5
|
-
const empty = width - filled;
|
|
6
|
-
const percentage = max > 0 ? Math.round((value / max) * 100) : 0;
|
|
7
|
-
const color = percentage >= 90 ? 'red' : percentage >= 70 ? 'yellow' : 'green';
|
|
8
|
-
return (_jsxs(Text, { children: [_jsx(Text, { color: color, children: '█'.repeat(filled) }), _jsx(Text, { color: "gray", children: '░'.repeat(empty) }), _jsxs(Text, { children: [" ", value, "/", max] }), label ? _jsxs(Text, { children: [" ", label] }) : null] }));
|
|
9
|
-
}
|
|
10
|
-
//# sourceMappingURL=gauge.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"gauge.js","sourceRoot":"","sources":["../../../../src/cli/dashboard/components/gauge.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAS3B,MAAM,UAAU,KAAK,CAAC,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,GAAG,EAAE,EAAE,KAAK,EAAc;IACjE,MAAM,MAAM,GAAG,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,KAAK,GAAG,GAAG,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC/D,MAAM,KAAK,GAAG,KAAK,GAAG,MAAM,CAAC;IAC7B,MAAM,UAAU,GAAG,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,KAAK,GAAG,GAAG,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAEjE,MAAM,KAAK,GAAG,UAAU,IAAI,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,UAAU,IAAI,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC;IAE/E,OAAO,CACL,MAAC,IAAI,eACH,KAAC,IAAI,IAAC,KAAK,EAAE,KAAK,YAAG,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,GAAQ,EAC/C,KAAC,IAAI,IAAC,KAAK,EAAC,MAAM,YAAE,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,GAAQ,EAC7C,MAAC,IAAI,oBAAG,KAAK,OAAG,GAAG,IAAQ,EAC1B,KAAK,CAAC,CAAC,CAAC,MAAC,IAAI,oBAAG,KAAK,IAAQ,CAAC,CAAC,CAAC,IAAI,IAChC,CACR,CAAC;AACJ,CAAC"}
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
interface PanelBoxProps {
|
|
3
|
-
title: string;
|
|
4
|
-
focused?: boolean;
|
|
5
|
-
width?: number | string;
|
|
6
|
-
height?: number;
|
|
7
|
-
children: React.ReactNode;
|
|
8
|
-
}
|
|
9
|
-
export declare function PanelBox({ title, focused, width, height, children }: PanelBoxProps): React.ReactElement;
|
|
10
|
-
export {};
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { Box, Text } from 'ink';
|
|
3
|
-
export function PanelBox({ title, focused, width, height, children }) {
|
|
4
|
-
return (_jsxs(Box, { flexDirection: "column", borderStyle: focused ? 'bold' : 'single', borderColor: focused ? 'cyan' : 'gray', width: width, height: height, paddingX: 1, children: [_jsx(Text, { bold: true, color: focused ? 'cyan' : 'white', children: title }), children] }));
|
|
5
|
-
}
|
|
6
|
-
//# sourceMappingURL=panel-box.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"panel-box.js","sourceRoot":"","sources":["../../../../src/cli/dashboard/components/panel-box.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAUhC,MAAM,UAAU,QAAQ,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAiB;IACjF,OAAO,CACL,MAAC,GAAG,IACF,aAAa,EAAC,QAAQ,EACtB,WAAW,EAAE,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,EACxC,WAAW,EAAE,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EACtC,KAAK,EAAE,KAAK,EACZ,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,CAAC,aAEX,KAAC,IAAI,IAAC,IAAI,QAAC,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,YACzC,KAAK,GACD,EACN,QAAQ,IACL,CACP,CAAC;AACJ,CAAC"}
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
export declare function renderSparkline(data: number[], maxWidth?: number): string;
|
|
3
|
-
interface SparklineProps {
|
|
4
|
-
data: number[];
|
|
5
|
-
maxWidth?: number;
|
|
6
|
-
color?: string;
|
|
7
|
-
}
|
|
8
|
-
export declare function Sparkline({ data, maxWidth, color }: SparklineProps): React.ReactElement;
|
|
9
|
-
export {};
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import { Text } from 'ink';
|
|
3
|
-
const BARS = ['▁', '▂', '▃', '▄', '▅', '▆', '▇', '█'];
|
|
4
|
-
export function renderSparkline(data, maxWidth) {
|
|
5
|
-
if (data.length === 0)
|
|
6
|
-
return '';
|
|
7
|
-
const values = maxWidth && data.length > maxWidth ? data.slice(-maxWidth) : data;
|
|
8
|
-
const min = Math.min(...values);
|
|
9
|
-
const max = Math.max(...values);
|
|
10
|
-
const range = max - min;
|
|
11
|
-
if (range === 0) {
|
|
12
|
-
const mid = Math.floor((BARS.length - 1) / 2);
|
|
13
|
-
return values.map(() => BARS[mid]).join('');
|
|
14
|
-
}
|
|
15
|
-
return values
|
|
16
|
-
.map((v) => {
|
|
17
|
-
const idx = Math.round(((v - min) / range) * (BARS.length - 1));
|
|
18
|
-
return BARS[idx];
|
|
19
|
-
})
|
|
20
|
-
.join('');
|
|
21
|
-
}
|
|
22
|
-
export function Sparkline({ data, maxWidth, color }) {
|
|
23
|
-
return _jsx(Text, { color: color, children: renderSparkline(data, maxWidth) });
|
|
24
|
-
}
|
|
25
|
-
//# sourceMappingURL=sparkline.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"sparkline.js","sourceRoot":"","sources":["../../../../src/cli/dashboard/components/sparkline.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAE3B,MAAM,IAAI,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAU,CAAC;AAE/D,MAAM,UAAU,eAAe,CAAC,IAAc,EAAE,QAAiB;IAC/D,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IAEjC,MAAM,MAAM,GAAG,QAAQ,IAAI,IAAI,CAAC,MAAM,GAAG,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IACjF,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,CAAC;IAChC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,CAAC;IAChC,MAAM,KAAK,GAAG,GAAG,GAAG,GAAG,CAAC;IAExB,IAAI,KAAK,KAAK,CAAC,EAAE,CAAC;QAChB,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QAC9C,OAAO,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC9C,CAAC;IAED,OAAO,MAAM;SACV,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;QACT,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC;QAChE,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC;IACnB,CAAC,CAAC;SACD,IAAI,CAAC,EAAE,CAAC,CAAC;AACd,CAAC;AAQD,MAAM,UAAU,SAAS,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAkB;IACjE,OAAO,KAAC,IAAI,IAAC,KAAK,EAAE,KAAK,YAAG,eAAe,CAAC,IAAI,EAAE,QAAQ,CAAC,GAAQ,CAAC;AACtE,CAAC"}
|