Files
vscode-debug-visualizer/extension/ui/src/Model/Model.ts
Henning Dieterichs df6a8a8a22 Refactors code.
2019-08-12 10:48:33 +02:00

161 lines
3.6 KiB
TypeScript

import {
debugVisualizerUIContract,
DataExtractionState,
} from "@hediet/debug-visualizer-vscode-shared";
import { WebSocketStream } from "@hediet/typed-json-rpc-websocket";
import { ConsoleRpcLogger } from "@hediet/typed-json-rpc";
import { observable, action, computed, when } from "mobx";
import { DataExtractorId } from "@hediet/debug-visualizer-data-extraction";
import { Visualization, VisualizationId } from "../Visualizers/Visualizer";
import { knownVisualizations } from "../Visualizers";
import { getApi as getVsCodeApi } from "./VsCodeApi";
import { MonacoBridge } from "./MonacoBridge";
declare const window: Window & {
serverPort?: number;
};
export class Model {
port: number;
@observable expression: string = "";
@observable state: DataExtractionState | { kind: "noExpression" } = {
kind: "noExpression",
};
@observable private preferredVisualizationId:
| VisualizationId
| undefined = undefined;
@action
public setPreferredVisualizationId(id: VisualizationId) {
this.preferredVisualizationId = id;
}
@computed get visualizations():
| {
visualization: Visualization | undefined;
allVisualizations: Visualization[];
}
| undefined {
if (this.state.kind === "data") {
const vis = knownVisualizations.getBestVisualization(
this.state.result.data,
this.preferredVisualizationId
);
return vis;
} else {
return undefined;
}
}
@observable.ref
public server:
| typeof debugVisualizerUIContract.TServerInterface
| undefined = undefined;
private readonly vsCodeApi = getVsCodeApi<{ expression: string }>();
@observable private _loading = false;
public get loading(): boolean {
return this._loading;
}
private readonly _bridge = new MonacoBridge(this);
constructor() {
if (window.serverPort) {
this.port = window.serverPort;
} else {
const url = new URL(window.location.href);
const portStr = url.searchParams.get("serverPort");
if (!portStr) {
throw new Error("No port given.");
}
this.port = parseInt(portStr);
const expr = url.searchParams.get("expression");
if (expr) {
this.setExpression(expr);
}
}
this.stayConnected();
this.vsCodeApi.getState().then(state => {
if (state) {
this.setExpression(state.expression);
}
});
}
@action
setExpression(newExpression: string) {
this.expression = newExpression;
when(() => !!this.server).then(() => {
this.server!.setExpression({ newExpression });
});
this.vsCodeApi.setState({
expression: newExpression,
});
const url = new URL(window.location.href);
url.searchParams.set("expression", newExpression);
history.replaceState(null, document.title, url.toString());
}
setPreferredExtractorId(id: DataExtractorId) {
if (this.server) {
this.server.setPreferredDataExtractor({
dataExtractorId: id,
});
}
}
refresh() {
if (this.server) {
this.server.refresh();
}
}
async stayConnected(): Promise<void> {
while (true) {
try {
const stream = await WebSocketStream.connectTo({
host: "localhost",
port: this.port,
});
const {
server,
} = debugVisualizerUIContract.getServerFromStream(
stream,
new ConsoleRpcLogger(),
{
updateState: async ({ newState }) => {
this._loading = newState.kind === "loading";
if (!this._loading) {
this.state = newState;
}
},
}
);
this.server = server;
await stream.onClosed;
} catch (e) {}
}
}
openBrowser() {
if (this.server) {
this.server.openInBrowser();
}
}
useSelectionAsExpression() {
throw new Error("Method not implemented.");
}
}