diff --git a/extension/src/ConnectionHandler.ts b/extension/src/ConnectionHandler.ts new file mode 100644 index 0000000..ba3c03c --- /dev/null +++ b/extension/src/ConnectionHandler.ts @@ -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(); + }); + } +} diff --git a/extension/src/Server.ts b/extension/src/Server.ts new file mode 100644 index 0000000..0417e00 --- /dev/null +++ b/extension/src/Server.ts @@ -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; + } +} diff --git a/extension/src/WebViews.ts b/extension/src/WebViews.ts new file mode 100644 index 0000000..62a338b --- /dev/null +++ b/extension/src/WebViews.ts @@ -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(); + + 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 ` + + + + + + + ${ + isDev + ? `` + : `` + } + + + `; +} diff --git a/extension/src/extension.ts b/extension/src/extension.ts index ef152c0..03531b3 100644 --- a/extension/src/extension.ts +++ b/extension/src/extension.ts @@ -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 ` - - - - - - - ${ - isDev - ? `` - : `` - } - - - `; -} - -class WebViews { - private readonly debugVisualizations = new Map(); - - 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(); }