More refactoring.

This commit is contained in:
Henning Dieterichs
2019-07-31 20:26:15 +02:00
parent e4e17c69b6
commit aa2dbc8719
4 changed files with 180 additions and 184 deletions

View File

@@ -0,0 +1,59 @@
import { Disposable } from "@hediet/std/disposable";
import { debugVisualizerUIContract } from "@hediet/debug-visualizer-vscode-shared";
import { ConsoleRpcLogger } from "@hediet/typed-json-rpc";
import { EvaluationWatcher } from "./DataSource/DataSource";
import { WebSocketStream } from "@hediet/typed-json-rpc-websocket";
import { observable, autorun } from "mobx";
import { Sources } from "./extension";
import { Server } from "./Server";
import * as open from "open";
export class ConnectionHandler {
public readonly dispose = Disposable.fn();
@observable
private watcher: EvaluationWatcher | undefined = undefined;
constructor(sources: Sources, stream: WebSocketStream, server: Server) {
const {
client,
channel,
} = debugVisualizerUIContract.registerServerToStream(
stream,
new ConsoleRpcLogger(),
{
refresh: async () => {
if (this.watcher) {
this.watcher.refresh();
}
},
setExpression: async ({ newExpression }) => {
if (this.watcher) {
this.dispose.untrack(this.watcher).dispose();
}
this.watcher = this.dispose.track(
sources.jsSource.createEvaluationWatcher(newExpression)
);
},
openInBrowser: async ({}) => {
open(server.indexUrl);
},
}
);
this.dispose.track(
Disposable.create(
autorun(() => {
if (this.watcher) {
client.updateState({
newState: this.watcher.state,
});
}
})
)
);
stream.onClosed.then(() => {
this.dispose();
});
}
}

42
extension/src/Server.ts Normal file
View File

@@ -0,0 +1,42 @@
import { WebSocketStream } from "@hediet/typed-json-rpc-websocket";
import { AddressInfo } from "net";
import WebSocket = require("ws");
import { join } from "path";
import { ConnectionHandler } from "./ConnectionHandler";
import { Sources } from "./extension";
import * as express from "express";
import * as http from "http";
import * as serveStatic from "serve-static";
export class Server {
private server: http.Server;
constructor(sources: Sources) {
const app = express();
app.use(serveStatic(join(__dirname, "../ui/dist")));
this.server = app.listen();
const wss = new WebSocket.Server({ server: this.server });
wss.on("connection", ws => {
const stream = new WebSocketStream(ws);
new ConnectionHandler(sources, stream, this);
});
console.log(this.port);
}
public get indexUrl(): string {
return `http://localhost:${this.port}/index.html?serverPort=${
this.port
}`;
}
public get mainBundle(): string {
return `http://localhost:${this.port}/main.js`;
}
public get port(): number {
const httpPort = (this.server.address() as AddressInfo).port;
return httpPort;
}
}

76
extension/src/WebViews.ts Normal file
View File

@@ -0,0 +1,76 @@
import { window, ViewColumn, WebviewPanel } from "vscode";
import { Server } from "./Server";
export const debugVisualizer = "debugVisualizer";
export class WebViews {
private readonly debugVisualizations = new Map<WebviewPanel, WebView>();
constructor(private readonly server: Server) {}
public createNew() {
const panel = window.createWebviewPanel(
debugVisualizer,
"Debug Visualizer",
ViewColumn.Two,
{ enableScripts: true }
);
this.setupView(panel);
}
public restore(webviewPanel: WebviewPanel) {
this.setupView(webviewPanel);
}
private setupView(webviewPanel: WebviewPanel) {
webviewPanel.webview.html = getHtml(this.server);
const view = new WebView(webviewPanel);
this.debugVisualizations.set(webviewPanel, view);
webviewPanel.onDidDispose(() => {
this.debugVisualizations.delete(webviewPanel);
});
}
public dispose() {
for (const panel of this.debugVisualizations.keys()) {
panel.dispose();
}
}
}
export class WebView {
private expression: string | null = null;
private lastFrameId: number | null = null;
constructor(private readonly webviewPanel: WebviewPanel) {}
}
export function getHtml(server: Server) {
const isDev = false;
return `
<html>
<head>
<style>
html { height: 100%; width: 100%; padding: 0; margin: 0; }
body { height: 100%; width: 100%; padding: 0; margin: 0; }
iframe { height: 100%; width: 100%; padding: 0; margin: 0; border: 0; display: block; }
</style>
</head>
<body>
<script>
window.serverPort = ${server.port};
</script>
${
isDev
? `<iframe src="http://localhost:8080/?serverPort=${
server.port
}" tabindex="0"></iframe>`
: `<script type="text/javascript" src="${
server.mainBundle
}"></script>`
}
</body>
</html>
`;
}

View File

@@ -1,13 +1,4 @@
import {
window,
OutputChannel,
ExtensionContext,
StatusBarAlignment,
commands,
workspace,
ViewColumn,
WebviewPanel,
} from "vscode";
import { window, ExtensionContext, WebviewPanel } from "vscode";
import {
enableHotReload,
hotRequireExportedFn,
@@ -18,184 +9,12 @@ enableHotReload({ entryModule: module });
import { Disposable } from "@hediet/std/disposable";
import { createJsDebuggerSource } from "./DataSource/JsDebuggerSource";
import { debugVisualizerUIContract } from "@hediet/debug-visualizer-vscode-shared";
import { ConsoleRpcLogger } from "@hediet/typed-json-rpc";
import { EvaluationWatcher } from "./DataSource/DataSource";
import { WebSocketStream } from "@hediet/typed-json-rpc-websocket";
import { observable, autorun } from "mobx";
import * as express from "express";
import * as http from "http";
import * as serveStatic from "serve-static";
import { AddressInfo } from "net";
import WebSocket = require("ws");
import { join } from "path";
import { WebViews } from "./WebViews";
import { Server } from "./Server";
registerUpdateReconciler(module);
class WebView {
private expression: string | null = null;
private lastFrameId: number | null = null;
constructor(private readonly webviewPanel: WebviewPanel) {}
}
const debugVisualizer = "debugVisualizer";
function getHtml(server: Server) {
const isDev = false;
return `
<html>
<head>
<style>
html { height: 100%; width: 100%; padding: 0; margin: 0; }
body { height: 100%; width: 100%; padding: 0; margin: 0; }
iframe { height: 100%; width: 100%; padding: 0; margin: 0; border: 0; display: block; }
</style>
</head>
<body>
<script>
window.serverPort = ${server.port};
</script>
${
isDev
? `<iframe src="http://localhost:8080/?serverPort=${
server.port
}" tabindex="0"></iframe>`
: `<script type="text/javascript" src="${
server.mainBundle
}"></script>`
}
</body>
</html>
`;
}
class WebViews {
private readonly debugVisualizations = new Map<WebviewPanel, WebView>();
constructor(private readonly server: Server) {}
public createNew() {
const panel = window.createWebviewPanel(
debugVisualizer,
"Debug Visualizer",
ViewColumn.Two,
{ enableScripts: true }
);
this.setupView(panel);
}
public restore(webviewPanel: WebviewPanel) {
this.setupView(webviewPanel);
}
private setupView(webviewPanel: WebviewPanel) {
webviewPanel.webview.html = getHtml(this.server);
const view = new WebView(webviewPanel);
this.debugVisualizations.set(webviewPanel, view);
webviewPanel.onDidDispose(() => {
this.debugVisualizations.delete(webviewPanel);
});
}
public dispose() {
for (const panel of this.debugVisualizations.keys()) {
panel.dispose();
}
}
}
// js-debug value-printer value-viewer
// #src: bla
// editor-src typescript-ast-viewer
import * as open from "open";
class ConnectionHandler {
public readonly dispose = Disposable.fn();
@observable
private watcher: EvaluationWatcher | undefined = undefined;
constructor(sources: Sources, stream: WebSocketStream, server: Server) {
const {
client,
channel,
} = debugVisualizerUIContract.registerServerToStream(
stream,
new ConsoleRpcLogger(),
{
refresh: async () => {
if (this.watcher) {
this.watcher.refresh();
}
},
setExpression: async ({ newExpression }) => {
if (this.watcher) {
this.dispose.untrack(this.watcher).dispose();
}
this.watcher = this.dispose.track(
sources.jsSource.createEvaluationWatcher(newExpression)
);
},
openInBrowser: async ({}) => {
open(server.indexUrl);
},
}
);
this.dispose.track(
Disposable.create(
autorun(() => {
if (this.watcher) {
client.updateState({
newState: this.watcher.state,
});
}
})
)
);
stream.onClosed.then(() => {
this.dispose();
});
}
}
class Server {
private server: http.Server;
constructor(sources: Sources) {
const app = express();
app.use(serveStatic(join(__dirname, "../ui/dist")));
this.server = app.listen();
const wss = new WebSocket.Server({ server: this.server });
wss.on("connection", ws => {
const stream = new WebSocketStream(ws);
new ConnectionHandler(sources, stream, this);
});
console.log(this.port);
}
public get indexUrl(): string {
return `http://localhost:${this.port}/index.html?serverPort=${
this.port
}`;
}
public get mainBundle(): string {
return `http://localhost:${this.port}/main.js`;
}
public get port(): number {
const httpPort = (this.server.address() as AddressInfo).port;
return httpPort;
}
}
export class Sources {
public readonly jsSource = createJsDebuggerSource();
}