mirror of
https://github.com/wavetermdev/waveterm.git
synced 2025-01-02 18:39:05 +01:00
parent
c91cae9463
commit
efd1e3c189
@ -10,6 +10,7 @@ import { atoms, globalStore, setBlockFocus, useBlockAtom } from "@/store/global"
|
|||||||
import * as services from "@/store/services";
|
import * as services from "@/store/services";
|
||||||
import * as WOS from "@/store/wos";
|
import * as WOS from "@/store/wos";
|
||||||
import * as util from "@/util/util";
|
import * as util from "@/util/util";
|
||||||
|
import { CpuPlotView, makeCpuPlotViewModel } from "@/view/cpuplot";
|
||||||
import { PlotView } from "@/view/plotview";
|
import { PlotView } from "@/view/plotview";
|
||||||
import { PreviewView, makePreviewModel } from "@/view/preview";
|
import { PreviewView, makePreviewModel } from "@/view/preview";
|
||||||
import { TerminalView, makeTerminalModel } from "@/view/term/term";
|
import { TerminalView, makeTerminalModel } from "@/view/term/term";
|
||||||
@ -521,6 +522,10 @@ function getViewElemAndModel(
|
|||||||
const waveAiModel = makeWaveAiViewModel(blockId);
|
const waveAiModel = makeWaveAiViewModel(blockId);
|
||||||
viewElem = <WaveAi key={blockId} model={waveAiModel} />;
|
viewElem = <WaveAi key={blockId} model={waveAiModel} />;
|
||||||
viewModel = waveAiModel;
|
viewModel = waveAiModel;
|
||||||
|
} else if (blockView === "cpuplot") {
|
||||||
|
const cpuPlotModel = makeCpuPlotViewModel(blockId);
|
||||||
|
viewElem = <CpuPlotView key={blockId} model={cpuPlotModel} />;
|
||||||
|
viewModel = cpuPlotModel;
|
||||||
}
|
}
|
||||||
if (viewModel == null) {
|
if (viewModel == null) {
|
||||||
viewElem = <CenteredDiv>Invalid View "{blockView}"</CenteredDiv>;
|
viewElem = <CenteredDiv>Invalid View "{blockView}"</CenteredDiv>;
|
||||||
|
45
frontend/app/hook/useWidth.tsx
Normal file
45
frontend/app/hook/useWidth.tsx
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
import debounce from "lodash.debounce";
|
||||||
|
import { useCallback, useEffect, useState } from "react";
|
||||||
|
|
||||||
|
const useWidth = (ref: React.RefObject<HTMLElement>, delay = 0) => {
|
||||||
|
const [width, setWidth] = useState<number | null>(null);
|
||||||
|
|
||||||
|
const updateWidth = useCallback(() => {
|
||||||
|
if (ref.current) {
|
||||||
|
const element = ref.current;
|
||||||
|
const style = window.getComputedStyle(element);
|
||||||
|
const paddingLeft = parseFloat(style.paddingLeft);
|
||||||
|
const paddingRight = parseFloat(style.paddingRight);
|
||||||
|
const marginLeft = parseFloat(style.marginLeft);
|
||||||
|
const marginRight = parseFloat(style.marginRight);
|
||||||
|
const parentWidth = element.clientWidth - paddingLeft - paddingRight - marginLeft - marginRight;
|
||||||
|
setWidth(parentWidth);
|
||||||
|
}
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const fUpdateWidth = useCallback(delay > 0 ? debounce(updateWidth, delay) : updateWidth, [updateWidth, delay]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const resizeObserver = new ResizeObserver(() => {
|
||||||
|
fUpdateWidth();
|
||||||
|
});
|
||||||
|
|
||||||
|
if (ref.current) {
|
||||||
|
resizeObserver.observe(ref.current);
|
||||||
|
fUpdateWidth();
|
||||||
|
}
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
if (ref.current) {
|
||||||
|
resizeObserver.unobserve(ref.current);
|
||||||
|
}
|
||||||
|
if (delay > 0) {
|
||||||
|
fUpdateWidth.cancel();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}, [fUpdateWidth]);
|
||||||
|
|
||||||
|
return width;
|
||||||
|
};
|
||||||
|
|
||||||
|
export { useWidth };
|
@ -102,6 +102,11 @@ class WshServerType {
|
|||||||
return WOS.wshServerRpcHelper_call("setview", data, opts);
|
return WOS.wshServerRpcHelper_call("setview", data, opts);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// command "streamcpudata" [responsestream]
|
||||||
|
StreamCpuDataCommand(data: CpuDataRequest, opts?: WshRpcCommandOpts): AsyncGenerator<CpuDataType, void, boolean> {
|
||||||
|
return WOS.wshServerRpcHelper_responsestream("streamcpudata", data, opts);
|
||||||
|
}
|
||||||
|
|
||||||
// command "streamtest" [responsestream]
|
// command "streamtest" [responsestream]
|
||||||
StreamTestCommand(opts?: WshRpcCommandOpts): AsyncGenerator<number, void, boolean> {
|
StreamTestCommand(opts?: WshRpcCommandOpts): AsyncGenerator<number, void, boolean> {
|
||||||
return WOS.wshServerRpcHelper_responsestream("streamtest", null, opts);
|
return WOS.wshServerRpcHelper_responsestream("streamtest", null, opts);
|
||||||
|
9
frontend/app/view/cpuplot.less
Normal file
9
frontend/app/view/cpuplot.less
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
// Copyright 2024, Command Line Inc.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
.plot-view {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: stretch;
|
||||||
|
width: 100%;
|
||||||
|
}
|
135
frontend/app/view/cpuplot.tsx
Normal file
135
frontend/app/view/cpuplot.tsx
Normal file
@ -0,0 +1,135 @@
|
|||||||
|
// Copyright 2024, Command Line Inc.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
import { useHeight } from "@/app/hook/useHeight";
|
||||||
|
import { useWidth } from "@/app/hook/useWidth";
|
||||||
|
import { WshServer } from "@/store/wshserver";
|
||||||
|
import * as Plot from "@observablehq/plot";
|
||||||
|
import dayjs from "dayjs";
|
||||||
|
import * as htl from "htl";
|
||||||
|
import * as jotai from "jotai";
|
||||||
|
import * as React from "react";
|
||||||
|
|
||||||
|
import "./cpuplot.less";
|
||||||
|
|
||||||
|
type Point = {
|
||||||
|
time: number;
|
||||||
|
value: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
class CpuPlotViewModel {
|
||||||
|
blockAtom: jotai.Atom<Block>;
|
||||||
|
termMode: jotai.Atom<string>;
|
||||||
|
htmlElemFocusRef: React.RefObject<HTMLInputElement>;
|
||||||
|
blockId: string;
|
||||||
|
viewIcon: jotai.Atom<string>;
|
||||||
|
viewText: jotai.Atom<string>;
|
||||||
|
viewName: jotai.Atom<string>;
|
||||||
|
dataAtom: jotai.PrimitiveAtom<Array<Point>>;
|
||||||
|
addDataAtom: jotai.WritableAtom<unknown, [Point], void>;
|
||||||
|
width: number;
|
||||||
|
|
||||||
|
constructor(blockId: string) {
|
||||||
|
this.blockId = blockId;
|
||||||
|
this.width = 100;
|
||||||
|
this.dataAtom = jotai.atom(this.getDefaultData());
|
||||||
|
this.addDataAtom = jotai.atom(null, (get, set, point) => {
|
||||||
|
// not efficient but should be okay for a demo?
|
||||||
|
const data = get(this.dataAtom);
|
||||||
|
set(this.dataAtom, [...data.slice(1), point]);
|
||||||
|
});
|
||||||
|
|
||||||
|
this.viewIcon = jotai.atom((get) => {
|
||||||
|
return "chart-line"; // should not be hardcoded
|
||||||
|
});
|
||||||
|
this.viewName = jotai.atom((get) => {
|
||||||
|
return "CPU %"; // should not be hardcoded
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
getDefaultData(): Array<Point> {
|
||||||
|
// set it back one to avoid backwards line being possible
|
||||||
|
const currentTime = Date.now() / 1000 - 1;
|
||||||
|
const points = [];
|
||||||
|
for (let i = this.width; i > -1; i--) {
|
||||||
|
points.push({ time: currentTime - i, value: 0 });
|
||||||
|
}
|
||||||
|
return points;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function makeCpuPlotViewModel(blockId: string): CpuPlotViewModel {
|
||||||
|
const cpuPlotViewModel = new CpuPlotViewModel(blockId);
|
||||||
|
return cpuPlotViewModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
function CpuPlotView({ model }: { model: CpuPlotViewModel }) {
|
||||||
|
const containerRef = React.useRef<HTMLInputElement>();
|
||||||
|
const plotData = jotai.useAtomValue(model.dataAtom);
|
||||||
|
const addPlotData = jotai.useSetAtom(model.addDataAtom);
|
||||||
|
const parentHeight = useHeight(containerRef);
|
||||||
|
const parentWidth = useWidth(containerRef);
|
||||||
|
|
||||||
|
React.useEffect(() => {
|
||||||
|
console.log("plotData:", plotData);
|
||||||
|
}, [plotData]);
|
||||||
|
|
||||||
|
React.useEffect(() => {
|
||||||
|
const temp = async () => {
|
||||||
|
const dataGen = WshServer.StreamCpuDataCommand(
|
||||||
|
{ id: model.blockId },
|
||||||
|
{ timeout: 999999999, noresponse: false }
|
||||||
|
);
|
||||||
|
try {
|
||||||
|
for await (const datum of dataGen) {
|
||||||
|
addPlotData(datum);
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.log(e);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
temp();
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
React.useEffect(() => {
|
||||||
|
const plot = Plot.plot({
|
||||||
|
x: { grid: true, label: "time", tickFormat: (d) => `${dayjs.unix(d).format("HH:mm:ss")}` },
|
||||||
|
y: { label: "%", domain: [0, 100] },
|
||||||
|
width: parentWidth,
|
||||||
|
height: parentHeight,
|
||||||
|
marks: [
|
||||||
|
() => htl.svg`<defs>
|
||||||
|
<linearGradient id="gradient" gradientTransform="rotate(90)">
|
||||||
|
<stop offset="0%" stop-color="#58C142" stop-opacity="0.7" />
|
||||||
|
<stop offset="100%" stop-color="#58C142" stop-opacity="0" />
|
||||||
|
</linearGradient>
|
||||||
|
</defs>`,
|
||||||
|
Plot.lineY(plotData, {
|
||||||
|
stroke: "#58C142",
|
||||||
|
strokeWidth: 2,
|
||||||
|
x: "time",
|
||||||
|
y: "value",
|
||||||
|
}),
|
||||||
|
Plot.areaY(plotData, {
|
||||||
|
fill: "url(#gradient)",
|
||||||
|
x: "time",
|
||||||
|
y: "value",
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
if (plot !== undefined) {
|
||||||
|
containerRef.current.append(plot);
|
||||||
|
}
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
if (plot !== undefined) {
|
||||||
|
plot.remove();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}, [plotData, parentHeight, parentWidth]);
|
||||||
|
|
||||||
|
return <div className="plot-view" ref={containerRef} />;
|
||||||
|
}
|
||||||
|
|
||||||
|
export { CpuPlotView, CpuPlotViewModel, makeCpuPlotViewModel };
|
@ -426,8 +426,10 @@ function TableBody({
|
|||||||
label: "Open Preview in New Block",
|
label: "Open Preview in New Block",
|
||||||
click: async () => {
|
click: async () => {
|
||||||
const blockDef = {
|
const blockDef = {
|
||||||
view: "preview",
|
meta: {
|
||||||
meta: { file: path },
|
view: "preview",
|
||||||
|
file: path,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
await createBlock(blockDef);
|
await createBlock(blockDef);
|
||||||
},
|
},
|
||||||
@ -438,10 +440,10 @@ function TableBody({
|
|||||||
label: "Open Terminal in New Block",
|
label: "Open Terminal in New Block",
|
||||||
click: async () => {
|
click: async () => {
|
||||||
const termBlockDef: BlockDef = {
|
const termBlockDef: BlockDef = {
|
||||||
controller: "shell",
|
|
||||||
view: "term",
|
|
||||||
meta: {
|
meta: {
|
||||||
cwd: path,
|
controller: "shell",
|
||||||
|
view: "term",
|
||||||
|
"cmd:cwd": path,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
await createBlock(termBlockDef);
|
await createBlock(termBlockDef);
|
||||||
|
11
frontend/types/gotypes.d.ts
vendored
11
frontend/types/gotypes.d.ts
vendored
@ -131,6 +131,17 @@ declare global {
|
|||||||
meta: MetaType;
|
meta: MetaType;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// wshrpc.CpuDataRequest
|
||||||
|
type CpuDataRequest = {
|
||||||
|
id: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
// wshrpc.CpuDataType
|
||||||
|
type CpuDataType = {
|
||||||
|
time: number;
|
||||||
|
value: number;
|
||||||
|
};
|
||||||
|
|
||||||
// wstore.FileDef
|
// wstore.FileDef
|
||||||
type FileDef = {
|
type FileDef = {
|
||||||
filetype?: string;
|
filetype?: string;
|
||||||
|
9
go.mod
9
go.mod
@ -18,6 +18,7 @@ require (
|
|||||||
github.com/mitchellh/mapstructure v1.5.0
|
github.com/mitchellh/mapstructure v1.5.0
|
||||||
github.com/sashabaranov/go-openai v1.27.1
|
github.com/sashabaranov/go-openai v1.27.1
|
||||||
github.com/sawka/txwrap v0.2.0
|
github.com/sawka/txwrap v0.2.0
|
||||||
|
github.com/shirou/gopsutil/v4 v4.24.6
|
||||||
github.com/spf13/cobra v1.8.1
|
github.com/spf13/cobra v1.8.1
|
||||||
github.com/wavetermdev/htmltoken v0.1.0
|
github.com/wavetermdev/htmltoken v0.1.0
|
||||||
github.com/wavetermdev/waveterm/wavesrv v0.0.0-20240508181017-d07068c09d94
|
github.com/wavetermdev/waveterm/wavesrv v0.0.0-20240508181017-d07068c09d94
|
||||||
@ -27,11 +28,17 @@ require (
|
|||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/felixge/httpsnoop v1.0.3 // indirect
|
github.com/felixge/httpsnoop v1.0.3 // indirect
|
||||||
|
github.com/go-ole/go-ole v1.2.6 // indirect
|
||||||
github.com/hashicorp/errwrap v1.1.0 // indirect
|
github.com/hashicorp/errwrap v1.1.0 // indirect
|
||||||
github.com/hashicorp/go-multierror v1.1.1 // indirect
|
github.com/hashicorp/go-multierror v1.1.1 // indirect
|
||||||
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
||||||
|
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect
|
||||||
|
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect
|
||||||
|
github.com/shoenig/go-m1cpu v0.1.6 // indirect
|
||||||
github.com/spf13/pflag v1.0.5 // indirect
|
github.com/spf13/pflag v1.0.5 // indirect
|
||||||
github.com/stretchr/testify v1.8.4 // indirect
|
github.com/tklauser/go-sysconf v0.3.12 // indirect
|
||||||
|
github.com/tklauser/numcpus v0.6.1 // indirect
|
||||||
|
github.com/yusufpapurcu/wmi v1.2.4 // indirect
|
||||||
go.uber.org/atomic v1.7.0 // indirect
|
go.uber.org/atomic v1.7.0 // indirect
|
||||||
golang.org/x/net v0.27.0 // indirect
|
golang.org/x/net v0.27.0 // indirect
|
||||||
golang.org/x/sys v0.22.0 // indirect
|
golang.org/x/sys v0.22.0 // indirect
|
||||||
|
30
go.sum
30
go.sum
@ -12,12 +12,17 @@ github.com/felixge/httpsnoop v1.0.3 h1:s/nj+GCswXYzN5v2DpNMuMQYe+0DDwt5WVCU6CWBd
|
|||||||
github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
|
github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
|
||||||
github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
|
github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
|
||||||
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
|
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
|
||||||
|
github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY=
|
||||||
|
github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
|
||||||
github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y=
|
github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y=
|
||||||
github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg=
|
github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg=
|
||||||
github.com/golang-jwt/jwt/v5 v5.2.1 h1:OuVbFODueb089Lh128TAcimifWaLhJwVflnrgM17wHk=
|
github.com/golang-jwt/jwt/v5 v5.2.1 h1:OuVbFODueb089Lh128TAcimifWaLhJwVflnrgM17wHk=
|
||||||
github.com/golang-jwt/jwt/v5 v5.2.1/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
|
github.com/golang-jwt/jwt/v5 v5.2.1/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
|
||||||
github.com/golang-migrate/migrate/v4 v4.17.1 h1:4zQ6iqL6t6AiItphxJctQb3cFqWiSpMnX7wLTPnnYO4=
|
github.com/golang-migrate/migrate/v4 v4.17.1 h1:4zQ6iqL6t6AiItphxJctQb3cFqWiSpMnX7wLTPnnYO4=
|
||||||
github.com/golang-migrate/migrate/v4 v4.17.1/go.mod h1:m8hinFyWBn0SA4QKHuKh175Pm9wjmxj3S2Mia7dbXzM=
|
github.com/golang-migrate/migrate/v4 v4.17.1/go.mod h1:m8hinFyWBn0SA4QKHuKh175Pm9wjmxj3S2Mia7dbXzM=
|
||||||
|
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
|
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||||
|
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||||
github.com/gorilla/handlers v1.5.2 h1:cLTUSsNkgcwhgRqvCNmdbRWG0A3N4F+M2nWKdScwyEE=
|
github.com/gorilla/handlers v1.5.2 h1:cLTUSsNkgcwhgRqvCNmdbRWG0A3N4F+M2nWKdScwyEE=
|
||||||
@ -37,17 +42,27 @@ github.com/jmoiron/sqlx v1.4.0 h1:1PLqN7S1UYp5t4SrVVnt4nUVNemrDAtxlulVe+Qgm3o=
|
|||||||
github.com/jmoiron/sqlx v1.4.0/go.mod h1:ZrZ7UsYB/weZdl2Bxg6jCRO9c3YHl8r3ahlKmRT4JLY=
|
github.com/jmoiron/sqlx v1.4.0/go.mod h1:ZrZ7UsYB/weZdl2Bxg6jCRO9c3YHl8r3ahlKmRT4JLY=
|
||||||
github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
|
github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
|
||||||
github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||||
|
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ81pIr0yLvtUWk2if982qA3F3QD6H4=
|
||||||
|
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I=
|
||||||
github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU=
|
github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU=
|
||||||
github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
|
github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
|
||||||
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
|
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
|
||||||
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
||||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
|
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c h1:ncq/mPwQF4JjgDlrVEn3C11VoGHZN7m8qihwgMEtzYw=
|
||||||
|
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE=
|
||||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||||
github.com/sashabaranov/go-openai v1.27.1 h1:7Nx6db5NXbcoutNmAUQulEQZEpHG/SkzfexP2X5RWMk=
|
github.com/sashabaranov/go-openai v1.27.1 h1:7Nx6db5NXbcoutNmAUQulEQZEpHG/SkzfexP2X5RWMk=
|
||||||
github.com/sashabaranov/go-openai v1.27.1/go.mod h1:lj5b/K+zjTSFxVLijLSTDZuP7adOgerWeFyZLUhAKRg=
|
github.com/sashabaranov/go-openai v1.27.1/go.mod h1:lj5b/K+zjTSFxVLijLSTDZuP7adOgerWeFyZLUhAKRg=
|
||||||
github.com/sawka/txwrap v0.2.0 h1:V3LfvKVLULxcYSxdMguLwFyQFMEU9nFDJopg0ZkL+94=
|
github.com/sawka/txwrap v0.2.0 h1:V3LfvKVLULxcYSxdMguLwFyQFMEU9nFDJopg0ZkL+94=
|
||||||
github.com/sawka/txwrap v0.2.0/go.mod h1:wwQ2SQiN4U+6DU/iVPhbvr7OzXAtgZlQCIGuvOswEfA=
|
github.com/sawka/txwrap v0.2.0/go.mod h1:wwQ2SQiN4U+6DU/iVPhbvr7OzXAtgZlQCIGuvOswEfA=
|
||||||
|
github.com/shirou/gopsutil/v4 v4.24.6 h1:9qqCSYF2pgOU+t+NgJtp7Co5+5mHF/HyKBUckySQL64=
|
||||||
|
github.com/shirou/gopsutil/v4 v4.24.6/go.mod h1:aoebb2vxetJ/yIDZISmduFvVNPHqXQ9SEJwRXxkf0RA=
|
||||||
|
github.com/shoenig/go-m1cpu v0.1.6 h1:nxdKQNcEB6vzgA2E2bvzKIYRuNj7XNJ4S/aRSwKzFtM=
|
||||||
|
github.com/shoenig/go-m1cpu v0.1.6/go.mod h1:1JJMcUBvfNwpq05QDQVAnx3gUHr9IYF7GNg9SUEw2VQ=
|
||||||
|
github.com/shoenig/test v0.6.4 h1:kVTaSd7WLz5WZ2IaoM0RSzRsUD+m8wRR+5qvntpn4LU=
|
||||||
|
github.com/shoenig/test v0.6.4/go.mod h1:byHiCGXqrVaflBLAMq/srcZIHynQPQgeyvkvXnjqq0k=
|
||||||
github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM=
|
github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM=
|
||||||
github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y=
|
github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y=
|
||||||
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
||||||
@ -55,25 +70,36 @@ github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An
|
|||||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||||
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
|
||||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||||
|
github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU=
|
||||||
|
github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI=
|
||||||
|
github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk=
|
||||||
|
github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY=
|
||||||
github.com/wavetermdev/htmltoken v0.1.0 h1:RMdA9zTfnYa5jRC4RRG3XNoV5NOP8EDxpaVPjuVz//Q=
|
github.com/wavetermdev/htmltoken v0.1.0 h1:RMdA9zTfnYa5jRC4RRG3XNoV5NOP8EDxpaVPjuVz//Q=
|
||||||
github.com/wavetermdev/htmltoken v0.1.0/go.mod h1:5FM0XV6zNYiNza2iaTcFGj+hnMtgqumFHO31Z8euquk=
|
github.com/wavetermdev/htmltoken v0.1.0/go.mod h1:5FM0XV6zNYiNza2iaTcFGj+hnMtgqumFHO31Z8euquk=
|
||||||
github.com/wavetermdev/ssh_config v0.0.0-20240306041034-17e2087ebde2 h1:onqZrJVap1sm15AiIGTfWzdr6cEF0KdtddeuuOVhzyY=
|
github.com/wavetermdev/ssh_config v0.0.0-20240306041034-17e2087ebde2 h1:onqZrJVap1sm15AiIGTfWzdr6cEF0KdtddeuuOVhzyY=
|
||||||
github.com/wavetermdev/ssh_config v0.0.0-20240306041034-17e2087ebde2/go.mod h1:q2RIzfka+BXARoNexmF9gkxEX7DmvbW9P4hIVx2Kg4M=
|
github.com/wavetermdev/ssh_config v0.0.0-20240306041034-17e2087ebde2/go.mod h1:q2RIzfka+BXARoNexmF9gkxEX7DmvbW9P4hIVx2Kg4M=
|
||||||
github.com/wavetermdev/waveterm/wavesrv v0.0.0-20240508181017-d07068c09d94 h1:/SPCxd4KHlS4eRTreYEXWFRr8WfRFBcChlV5cgkaO58=
|
github.com/wavetermdev/waveterm/wavesrv v0.0.0-20240508181017-d07068c09d94 h1:/SPCxd4KHlS4eRTreYEXWFRr8WfRFBcChlV5cgkaO58=
|
||||||
github.com/wavetermdev/waveterm/wavesrv v0.0.0-20240508181017-d07068c09d94/go.mod h1:ywoo7DXdYueQ0tTPhVoB+wzRTgERSE19EA3mR6KGRaI=
|
github.com/wavetermdev/waveterm/wavesrv v0.0.0-20240508181017-d07068c09d94/go.mod h1:ywoo7DXdYueQ0tTPhVoB+wzRTgERSE19EA3mR6KGRaI=
|
||||||
|
github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0=
|
||||||
|
github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
|
||||||
go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw=
|
go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw=
|
||||||
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
||||||
golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30=
|
golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30=
|
||||||
golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M=
|
golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M=
|
||||||
golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys=
|
golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys=
|
||||||
golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE=
|
golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE=
|
||||||
|
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI=
|
golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI=
|
||||||
golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
golang.org/x/term v0.22.0 h1:BbsgPEJULsl2fV/AT3v15Mjva5yXKQDyKf+TbDz7QJk=
|
golang.org/x/term v0.22.0 h1:BbsgPEJULsl2fV/AT3v15Mjva5yXKQDyKf+TbDz7QJk=
|
||||||
golang.org/x/term v0.22.0/go.mod h1:F3qCibpT5AMpCRfhfT53vVJwhLtIVHhB9XDjfFvnMI4=
|
golang.org/x/term v0.22.0/go.mod h1:F3qCibpT5AMpCRfhfT53vVJwhLtIVHhB9XDjfFvnMI4=
|
||||||
|
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||||
|
@ -89,6 +89,7 @@
|
|||||||
"css-tree": "^2.3.1",
|
"css-tree": "^2.3.1",
|
||||||
"dayjs": "^1.11.12",
|
"dayjs": "^1.11.12",
|
||||||
"electron-updater": "6.3.1",
|
"electron-updater": "6.3.1",
|
||||||
|
"htl": "^0.3.1",
|
||||||
"html-to-image": "^1.11.11",
|
"html-to-image": "^1.11.11",
|
||||||
"immer": "^10.1.1",
|
"immer": "^10.1.1",
|
||||||
"jotai": "^2.9.1",
|
"jotai": "^2.9.1",
|
||||||
|
@ -304,6 +304,15 @@ func applyDefaultSettings(settings *SettingsConfigType) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
Icon: "chart-line",
|
||||||
|
Label: "cpu",
|
||||||
|
BlockDef: wstore.BlockDef{
|
||||||
|
Meta: map[string]any{
|
||||||
|
wstore.MetaKey_View: "cpuplot",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
if settings.Widgets == nil {
|
if settings.Widgets == nil {
|
||||||
settings.Widgets = defaultWidgets
|
settings.Widgets = defaultWidgets
|
||||||
|
@ -125,6 +125,11 @@ func SetViewCommand(w *wshutil.WshRpc, data wshrpc.CommandBlockSetViewData, opts
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// command "streamcpudata", wshserver.StreamCpuDataCommand
|
||||||
|
func StreamCpuDataCommand(w *wshutil.WshRpc, data wshrpc.CpuDataRequest, opts *wshrpc.WshRpcCommandOpts) chan wshrpc.RespOrErrorUnion[wshrpc.CpuDataType] {
|
||||||
|
return sendRpcRequestResponseStreamHelper[wshrpc.CpuDataType](w, "streamcpudata", data, opts)
|
||||||
|
}
|
||||||
|
|
||||||
// command "streamtest", wshserver.StreamTestCommand
|
// command "streamtest", wshserver.StreamTestCommand
|
||||||
func StreamTestCommand(w *wshutil.WshRpc, opts *wshrpc.WshRpcCommandOpts) chan wshrpc.RespOrErrorUnion[int] {
|
func StreamTestCommand(w *wshutil.WshRpc, opts *wshrpc.WshRpcCommandOpts) chan wshrpc.RespOrErrorUnion[int] {
|
||||||
return sendRpcRequestResponseStreamHelper[int](w, "streamtest", nil, opts)
|
return sendRpcRequestResponseStreamHelper[int](w, "streamtest", nil, opts)
|
||||||
|
@ -43,6 +43,7 @@ const (
|
|||||||
Command_EventUnsubAll = "eventunsuball"
|
Command_EventUnsubAll = "eventunsuball"
|
||||||
Command_StreamTest = "streamtest"
|
Command_StreamTest = "streamtest"
|
||||||
Command_StreamWaveAi = "streamwaveai"
|
Command_StreamWaveAi = "streamwaveai"
|
||||||
|
Command_StreamCpuData = "streamcpudata"
|
||||||
)
|
)
|
||||||
|
|
||||||
type RespOrErrorUnion[T any] struct {
|
type RespOrErrorUnion[T any] struct {
|
||||||
@ -72,6 +73,7 @@ type WshRpcInterface interface {
|
|||||||
EventUnsubAllCommand(ctx context.Context) error
|
EventUnsubAllCommand(ctx context.Context) error
|
||||||
StreamTestCommand(ctx context.Context) chan RespOrErrorUnion[int]
|
StreamTestCommand(ctx context.Context) chan RespOrErrorUnion[int]
|
||||||
StreamWaveAiCommand(ctx context.Context, request OpenAiStreamRequest) chan RespOrErrorUnion[OpenAIPacketType]
|
StreamWaveAiCommand(ctx context.Context, request OpenAiStreamRequest) chan RespOrErrorUnion[OpenAIPacketType]
|
||||||
|
StreamCpuDataCommand(ctx context.Context, request CpuDataRequest) chan RespOrErrorUnion[CpuDataType]
|
||||||
}
|
}
|
||||||
|
|
||||||
// for frontend
|
// for frontend
|
||||||
@ -228,3 +230,12 @@ type OpenAIUsageType struct {
|
|||||||
CompletionTokens int `json:"completion_tokens,omitempty"`
|
CompletionTokens int `json:"completion_tokens,omitempty"`
|
||||||
TotalTokens int `json:"total_tokens,omitempty"`
|
TotalTokens int `json:"total_tokens,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type CpuDataRequest struct {
|
||||||
|
Id string `json:"id"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type CpuDataType struct {
|
||||||
|
Time int64 `json:"time"`
|
||||||
|
Value float64 `json:"value"`
|
||||||
|
}
|
||||||
|
@ -8,12 +8,14 @@ package wshserver
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/fs"
|
"io/fs"
|
||||||
"log"
|
"log"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/shirou/gopsutil/v4/cpu"
|
||||||
"github.com/wavetermdev/thenextwave/pkg/blockcontroller"
|
"github.com/wavetermdev/thenextwave/pkg/blockcontroller"
|
||||||
"github.com/wavetermdev/thenextwave/pkg/eventbus"
|
"github.com/wavetermdev/thenextwave/pkg/eventbus"
|
||||||
"github.com/wavetermdev/thenextwave/pkg/filestore"
|
"github.com/wavetermdev/thenextwave/pkg/filestore"
|
||||||
@ -67,6 +69,71 @@ func (ws *WshServer) StreamWaveAiCommand(ctx context.Context, request wshrpc.Ope
|
|||||||
return waveai.RunLocalCompletionStream(ctx, request)
|
return waveai.RunLocalCompletionStream(ctx, request)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ws *WshServer) StreamCpuDataCommand(ctx context.Context, request wshrpc.CpuDataRequest) chan wshrpc.RespOrErrorUnion[wshrpc.CpuDataType] {
|
||||||
|
rtn := make(chan wshrpc.RespOrErrorUnion[wshrpc.CpuDataType])
|
||||||
|
go func() {
|
||||||
|
defer close(rtn)
|
||||||
|
MakePlotData(ctx, request.Id)
|
||||||
|
// we can use the err from MakePlotData to determine if a routine is already running
|
||||||
|
// but we still need a way to close it or get data from it
|
||||||
|
for {
|
||||||
|
now := time.Now()
|
||||||
|
percent, err := cpu.Percent(0, false)
|
||||||
|
if err != nil {
|
||||||
|
rtn <- wshrpc.RespOrErrorUnion[wshrpc.CpuDataType]{Error: err}
|
||||||
|
}
|
||||||
|
var value float64
|
||||||
|
if len(percent) > 0 {
|
||||||
|
value = percent[0]
|
||||||
|
} else {
|
||||||
|
value = 0.0
|
||||||
|
}
|
||||||
|
cpuData := wshrpc.CpuDataType{Time: now.UnixMilli() / 1000, Value: value}
|
||||||
|
rtn <- wshrpc.RespOrErrorUnion[wshrpc.CpuDataType]{Response: cpuData}
|
||||||
|
time.Sleep(time.Second * 1)
|
||||||
|
// this will end the goroutine if the block is closed
|
||||||
|
err = SavePlotData(ctx, request.Id, "")
|
||||||
|
if err != nil {
|
||||||
|
rtn <- wshrpc.RespOrErrorUnion[wshrpc.CpuDataType]{Error: err}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
return rtn
|
||||||
|
}
|
||||||
|
|
||||||
|
func MakePlotData(ctx context.Context, blockId string) error {
|
||||||
|
block, err := wstore.DBMustGet[*wstore.Block](ctx, blockId)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
viewName := block.Meta.GetString(wstore.MetaKey_View, "")
|
||||||
|
if viewName != "cpuplot" {
|
||||||
|
return fmt.Errorf("invalid view type: %s", viewName)
|
||||||
|
}
|
||||||
|
return filestore.WFS.MakeFile(ctx, blockId, "cpuplotdata", nil, filestore.FileOptsType{})
|
||||||
|
}
|
||||||
|
|
||||||
|
func SavePlotData(ctx context.Context, blockId string, history string) error {
|
||||||
|
block, err := wstore.DBMustGet[*wstore.Block](ctx, blockId)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
viewName := block.Meta.GetString(wstore.MetaKey_View, "")
|
||||||
|
if viewName != "cpuplot" {
|
||||||
|
return fmt.Errorf("invalid view type: %s", viewName)
|
||||||
|
}
|
||||||
|
// todo: interpret the data being passed
|
||||||
|
// for now, this is just to throw an error if the block was closed
|
||||||
|
historyBytes, err := json.Marshal(history)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("unable to serialize plot data: %v", err)
|
||||||
|
}
|
||||||
|
// ignore MakeFile error (already exists is ok)
|
||||||
|
return filestore.WFS.WriteFile(ctx, blockId, "cpuplotdata", historyBytes)
|
||||||
|
}
|
||||||
|
|
||||||
func (ws *WshServer) GetMetaCommand(ctx context.Context, data wshrpc.CommandGetMetaData) (waveobj.MetaMapType, error) {
|
func (ws *WshServer) GetMetaCommand(ctx context.Context, data wshrpc.CommandGetMetaData) (waveobj.MetaMapType, error) {
|
||||||
log.Printf("calling meta: %s\n", data.ORef)
|
log.Printf("calling meta: %s\n", data.ORef)
|
||||||
obj, err := wstore.DBGetORef(ctx, data.ORef)
|
obj, err := wstore.DBGetORef(ctx, data.ORef)
|
||||||
|
@ -7934,6 +7934,13 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"htl@npm:^0.3.1":
|
||||||
|
version: 0.3.1
|
||||||
|
resolution: "htl@npm:0.3.1"
|
||||||
|
checksum: 10c0/36a22e10e0f11982c4e142c8c7bd389b3e9e7d70379c12f7572140a668a2a0328198f53fcb582281be761db91240ffb60261840256ebb10131739454baf82560
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"html-escaper@npm:^2.0.0":
|
"html-escaper@npm:^2.0.0":
|
||||||
version: 2.0.2
|
version: 2.0.2
|
||||||
resolution: "html-escaper@npm:2.0.2"
|
resolution: "html-escaper@npm:2.0.2"
|
||||||
@ -12099,6 +12106,7 @@ __metadata:
|
|||||||
electron-vite: "npm:^2.3.0"
|
electron-vite: "npm:^2.3.0"
|
||||||
eslint: "npm:^9.8.0"
|
eslint: "npm:^9.8.0"
|
||||||
eslint-config-prettier: "npm:^9.1.0"
|
eslint-config-prettier: "npm:^9.1.0"
|
||||||
|
htl: "npm:^0.3.1"
|
||||||
html-to-image: "npm:^1.11.11"
|
html-to-image: "npm:^1.11.11"
|
||||||
immer: "npm:^10.1.1"
|
immer: "npm:^10.1.1"
|
||||||
jotai: "npm:^2.9.1"
|
jotai: "npm:^2.9.1"
|
||||||
|
Loading…
Reference in New Issue
Block a user