More refactoring.
This commit is contained in:
59
extension/src/ConnectionHandler.ts
Normal file
59
extension/src/ConnectionHandler.ts
Normal 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
42
extension/src/Server.ts
Normal 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
76
extension/src/WebViews.ts
Normal 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>
|
||||
`;
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user