Merge pull request #2 from orus-dev/simple-working-mvp
Simple working mvp
This commit is contained in:
Generated
+146
@@ -9,8 +9,11 @@
|
||||
"version": "0.0.1",
|
||||
"dependencies": {
|
||||
"@types/cors": "^2.8.19",
|
||||
"@types/diff-match-patch": "^1.0.36",
|
||||
"@types/express": "^5.0.6",
|
||||
"axios": "^1.13.5",
|
||||
"cors": "^2.8.6",
|
||||
"diff-match-patch": "^1.0.5",
|
||||
"express": "^5.2.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
@@ -301,6 +304,12 @@
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/diff-match-patch": {
|
||||
"version": "1.0.36",
|
||||
"resolved": "https://registry.npmjs.org/@types/diff-match-patch/-/diff-match-patch-1.0.36.tgz",
|
||||
"integrity": "sha512-xFdR6tkm0MWvBfO8xXCSsinYxHcqkQUlcHeSpMC2ukzOb6lwQAfDmW+Qt0AvlGd8HpsS28qKsB+oPeJn9I39jg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/express": {
|
||||
"version": "5.0.6",
|
||||
"resolved": "https://registry.npmjs.org/@types/express/-/express-5.0.6.tgz",
|
||||
@@ -769,6 +778,23 @@
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/asynckit": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
|
||||
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/axios": {
|
||||
"version": "1.13.5",
|
||||
"resolved": "https://registry.npmjs.org/axios/-/axios-1.13.5.tgz",
|
||||
"integrity": "sha512-cz4ur7Vb0xS4/KUN0tPWe44eqxrIu31me+fbang3ijiNscE129POzipJJA6zniq2C/Z6sJCjMimjS8Lc/GAs8Q==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"follow-redirects": "^1.15.11",
|
||||
"form-data": "^4.0.5",
|
||||
"proxy-from-env": "^1.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/balanced-match": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
|
||||
@@ -1063,6 +1089,18 @@
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/combined-stream": {
|
||||
"version": "1.0.8",
|
||||
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
|
||||
"integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"delayed-stream": "~1.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/concat-map": {
|
||||
"version": "0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
|
||||
@@ -1186,6 +1224,15 @@
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/delayed-stream": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
|
||||
"integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=0.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/depd": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
|
||||
@@ -1205,6 +1252,12 @@
|
||||
"node": ">=0.3.1"
|
||||
}
|
||||
},
|
||||
"node_modules/diff-match-patch": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/diff-match-patch/-/diff-match-patch-1.0.5.tgz",
|
||||
"integrity": "sha512-IayShXAgj/QMXgB0IWmKx+rOPuGMhqm5w6jvFxmVenXKIzRqTAAsbBPT3kWQeGANj3jGgvcvv4yK6SxqYmikgw==",
|
||||
"license": "Apache-2.0"
|
||||
},
|
||||
"node_modules/dir-glob": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz",
|
||||
@@ -1304,6 +1357,21 @@
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/es-set-tostringtag": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz",
|
||||
"integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"es-errors": "^1.3.0",
|
||||
"get-intrinsic": "^1.2.6",
|
||||
"has-tostringtag": "^1.0.2",
|
||||
"hasown": "^2.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/escalade": {
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
|
||||
@@ -1717,6 +1785,26 @@
|
||||
"dev": true,
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/follow-redirects": {
|
||||
"version": "1.15.11",
|
||||
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz",
|
||||
"integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "individual",
|
||||
"url": "https://github.com/sponsors/RubenVerborgh"
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=4.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"debug": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/foreground-child": {
|
||||
"version": "3.3.1",
|
||||
"resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz",
|
||||
@@ -1734,6 +1822,43 @@
|
||||
"url": "https://github.com/sponsors/isaacs"
|
||||
}
|
||||
},
|
||||
"node_modules/form-data": {
|
||||
"version": "4.0.5",
|
||||
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.5.tgz",
|
||||
"integrity": "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"asynckit": "^0.4.0",
|
||||
"combined-stream": "^1.0.8",
|
||||
"es-set-tostringtag": "^2.1.0",
|
||||
"hasown": "^2.0.2",
|
||||
"mime-types": "^2.1.12"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 6"
|
||||
}
|
||||
},
|
||||
"node_modules/form-data/node_modules/mime-db": {
|
||||
"version": "1.52.0",
|
||||
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
|
||||
"integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/form-data/node_modules/mime-types": {
|
||||
"version": "2.1.35",
|
||||
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
|
||||
"integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"mime-db": "1.52.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/forwarded": {
|
||||
"version": "0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
|
||||
@@ -1972,6 +2097,21 @@
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/has-tostringtag": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz",
|
||||
"integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"has-symbols": "^1.0.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/hasown": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
|
||||
@@ -3090,6 +3230,12 @@
|
||||
"node": ">= 0.10"
|
||||
}
|
||||
},
|
||||
"node_modules/proxy-from-env": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
|
||||
"integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/punycode": {
|
||||
"version": "2.3.1",
|
||||
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
|
||||
|
||||
@@ -31,8 +31,38 @@
|
||||
"command": "devrun-vscode.stopServer",
|
||||
"title": "DevRun: Stop the run server (for quick run starts)"
|
||||
}
|
||||
],
|
||||
"menus": {
|
||||
"commandPalette": [
|
||||
{
|
||||
"command": "devrun-vscode.startRun",
|
||||
"when": "!devrun.runActive"
|
||||
},
|
||||
{
|
||||
"command": "devrun-vscode.stopRun",
|
||||
"when": "devrun.runActive"
|
||||
},
|
||||
{
|
||||
"command": "devrun-vscode.startServer",
|
||||
"when": "!devrun.serverActive"
|
||||
},
|
||||
{
|
||||
"command": "devrun-vscode.stopServer",
|
||||
"when": "devrun.serverActive"
|
||||
}
|
||||
]
|
||||
},
|
||||
"configuration": {
|
||||
"title": "DevRun",
|
||||
"properties": {
|
||||
"devrun.autoStartServer": {
|
||||
"type": "boolean",
|
||||
"default": false,
|
||||
"description": "Automatically start the server when vscode starts"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"scripts": {
|
||||
"vscode:prepublish": "npm run compile",
|
||||
"compile": "tsc -p ./",
|
||||
@@ -54,8 +84,11 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@types/cors": "^2.8.19",
|
||||
"@types/diff-match-patch": "^1.0.36",
|
||||
"@types/express": "^5.0.6",
|
||||
"axios": "^1.13.5",
|
||||
"cors": "^2.8.6",
|
||||
"diff-match-patch": "^1.0.5",
|
||||
"express": "^5.2.1"
|
||||
}
|
||||
}
|
||||
|
||||
+54
-10
@@ -1,13 +1,57 @@
|
||||
export interface LiveRunMove {
|
||||
latency: number;
|
||||
cursor: number;
|
||||
changes?: {
|
||||
from: number;
|
||||
to: number;
|
||||
insert: string;
|
||||
};
|
||||
import axios from "axios";
|
||||
import { LiveRunMove } from "./types";
|
||||
|
||||
var cookies: string | undefined;
|
||||
|
||||
export function getCookies(): string | undefined {
|
||||
return cookies;
|
||||
}
|
||||
export function setCookies(c: string) {
|
||||
cookies = c;
|
||||
}
|
||||
|
||||
export async function submitRun() {}
|
||||
export async function addRun(problem: string, mode: string): Promise<string> {
|
||||
return (
|
||||
await axios.put(
|
||||
"http://localhost:3000/api/run",
|
||||
{
|
||||
problem,
|
||||
category: mode,
|
||||
},
|
||||
{
|
||||
headers: {
|
||||
Cookie: cookies,
|
||||
},
|
||||
},
|
||||
)
|
||||
).data.runId;
|
||||
}
|
||||
|
||||
export async function addRunMoves() {}
|
||||
export async function submitRun(runId: string) {
|
||||
await axios.post(
|
||||
"http://localhost:3000/api/run",
|
||||
{
|
||||
runId,
|
||||
},
|
||||
{
|
||||
headers: {
|
||||
Cookie: cookies,
|
||||
},
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
export async function addRunMoves(runId: string, moves: LiveRunMove[]) {
|
||||
await axios.post(
|
||||
"http://localhost:3000/api/run/move",
|
||||
{
|
||||
runId,
|
||||
moves,
|
||||
},
|
||||
{
|
||||
headers: {
|
||||
Cookie: cookies,
|
||||
},
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
+97
-2
@@ -1,10 +1,12 @@
|
||||
import * as vscode from "vscode";
|
||||
import { currentRun, startRun, stopRun } from "./run";
|
||||
import { startServer, stopServer } from "./server";
|
||||
import os from "os";
|
||||
import { exec } from "child_process";
|
||||
import net from "net";
|
||||
|
||||
export function activate(context: vscode.ExtensionContext) {
|
||||
console.log("dev-run Activated");
|
||||
|
||||
const config = vscode.workspace.getConfiguration("devrun");
|
||||
const statusBarItem = vscode.window.createStatusBarItem(
|
||||
vscode.StatusBarAlignment.Left,
|
||||
10,
|
||||
@@ -49,8 +51,101 @@ export function activate(context: vscode.ExtensionContext) {
|
||||
stopServer(statusBarItem),
|
||||
),
|
||||
);
|
||||
console.log("dev-run Activated");
|
||||
|
||||
// Security check - Make sure there aren't any malicious servers currently running
|
||||
const autoStart = config.get<boolean>("autoStartServer");
|
||||
|
||||
canConnect(63780)
|
||||
.then((canConnect) => {
|
||||
if (canConnect) {
|
||||
console.error(
|
||||
"Unable to start due to another process listening on port 63780",
|
||||
);
|
||||
|
||||
console.error("Possible malicious dev-run instance running");
|
||||
|
||||
vscode.window
|
||||
.showErrorMessage(
|
||||
"Possible malicious dev-run instance running",
|
||||
"Kill the process listening on port 63780",
|
||||
)
|
||||
.then(async (response) => {
|
||||
if (!response) return;
|
||||
|
||||
if (response === "Kill the process listening on port 63780") {
|
||||
await killProcessOnPort(63780);
|
||||
|
||||
if (autoStart) {
|
||||
startServer(statusBarItem);
|
||||
console.log("dev-run server auto started!");
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (autoStart) {
|
||||
startServer(statusBarItem);
|
||||
console.log("dev-run server auto started!");
|
||||
}
|
||||
})
|
||||
.catch(() => {});
|
||||
}
|
||||
|
||||
export function deactivate() {
|
||||
stopRun();
|
||||
}
|
||||
|
||||
export function canConnect(
|
||||
port: number,
|
||||
host = "127.0.0.1",
|
||||
timeout = 1000,
|
||||
): Promise<boolean> {
|
||||
return new Promise((resolve) => {
|
||||
const socket = new net.Socket();
|
||||
|
||||
socket.setTimeout(timeout);
|
||||
|
||||
socket.once("connect", () => {
|
||||
socket.destroy();
|
||||
resolve(true);
|
||||
});
|
||||
|
||||
socket.once("timeout", () => {
|
||||
socket.destroy();
|
||||
resolve(false);
|
||||
});
|
||||
|
||||
socket.once("error", () => {
|
||||
resolve(false);
|
||||
});
|
||||
|
||||
socket.connect(port, host);
|
||||
});
|
||||
}
|
||||
|
||||
export function killProcessOnPort(port: number): Promise<void> {
|
||||
return new Promise((resolve, reject) => {
|
||||
const platform = os.platform();
|
||||
|
||||
let cmd: string;
|
||||
|
||||
if (platform === "win32") {
|
||||
// Windows
|
||||
cmd = `for /f "tokens=5" %a in ('netstat -ano ^| findstr :${port}') do taskkill /PID %a /F`;
|
||||
} else {
|
||||
// macOS / Linux
|
||||
cmd = `lsof -ti tcp:${port} | xargs kill -9`;
|
||||
}
|
||||
|
||||
exec(cmd, (error) => {
|
||||
if (error) {
|
||||
resolve();
|
||||
} else {
|
||||
resolve();
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
+112
@@ -0,0 +1,112 @@
|
||||
import * as vscode from "vscode";
|
||||
import { diff_match_patch, Diff } from "diff-match-patch";
|
||||
import { LiveRunMove } from "./types";
|
||||
import { addRunMoves } from "./client";
|
||||
|
||||
export function startMonitoring(runId: string) {
|
||||
const dmp = new diff_match_patch();
|
||||
|
||||
let moveId = 0;
|
||||
let moves: LiveRunMove[] = [];
|
||||
|
||||
let lastText = "";
|
||||
let lastEventTime = Date.now();
|
||||
let idleTimeout: NodeJS.Timeout | undefined;
|
||||
let isSending = false;
|
||||
|
||||
const IDLE_MS = 350;
|
||||
|
||||
const editor = vscode.window.activeTextEditor;
|
||||
if (editor) {
|
||||
lastText = editor.document.getText();
|
||||
}
|
||||
|
||||
async function flush() {
|
||||
if (!moves.length || isSending) return;
|
||||
|
||||
isSending = true;
|
||||
const batch = moves;
|
||||
moves = [];
|
||||
|
||||
try {
|
||||
await addRunMoves(runId, batch);
|
||||
} finally {
|
||||
isSending = false;
|
||||
}
|
||||
}
|
||||
|
||||
const readInterval = setInterval(() => {
|
||||
const editor = vscode.window.activeTextEditor;
|
||||
if (!editor) return;
|
||||
|
||||
const newText = editor.document.getText();
|
||||
if (newText === lastText) return;
|
||||
|
||||
const now = Date.now();
|
||||
const latency = capLatency(now - lastEventTime, IDLE_MS);
|
||||
lastEventTime = now;
|
||||
|
||||
const diffs = dmp.diff_main(lastText, newText);
|
||||
dmp.diff_cleanupEfficiency(diffs);
|
||||
|
||||
const changes = diffsToChanges(diffs);
|
||||
|
||||
lastText = newText;
|
||||
|
||||
for (const change of changes) {
|
||||
moves.push({
|
||||
moveId: moveId++,
|
||||
latency,
|
||||
cursor: editor.document.offsetAt(editor.selection.active),
|
||||
changes: change,
|
||||
});
|
||||
}
|
||||
|
||||
if (idleTimeout) clearTimeout(idleTimeout);
|
||||
idleTimeout = setTimeout(flush, IDLE_MS);
|
||||
}, 500);
|
||||
|
||||
return () => {
|
||||
clearInterval(readInterval);
|
||||
if (idleTimeout) clearTimeout(idleTimeout);
|
||||
flush();
|
||||
};
|
||||
}
|
||||
|
||||
function diffsToChanges(diffs: Diff[]) {
|
||||
const changes: {
|
||||
from: number;
|
||||
to: number;
|
||||
insert: string;
|
||||
}[] = [];
|
||||
|
||||
let offset = 0;
|
||||
|
||||
for (const [op, text] of diffs) {
|
||||
if (op === 0) {
|
||||
// equal
|
||||
offset += text.length;
|
||||
} else if (op === -1) {
|
||||
// delete
|
||||
changes.push({
|
||||
from: offset,
|
||||
to: offset + text.length,
|
||||
insert: "",
|
||||
});
|
||||
} else if (op === 1) {
|
||||
// insert
|
||||
changes.push({
|
||||
from: offset,
|
||||
to: offset,
|
||||
insert: text,
|
||||
});
|
||||
offset += text.length;
|
||||
}
|
||||
}
|
||||
|
||||
return changes;
|
||||
}
|
||||
|
||||
function capLatency(value: number, max: number) {
|
||||
return value > max ? 0 : value;
|
||||
}
|
||||
+15
-1
@@ -1,9 +1,13 @@
|
||||
import * as vscode from "vscode";
|
||||
import { addRun, submitRun } from "./client";
|
||||
import { startMonitoring } from "./move";
|
||||
|
||||
export var currentRun: {
|
||||
interval: NodeJS.Timeout;
|
||||
stopMonitoring: () => void;
|
||||
problemId: string;
|
||||
start: Date;
|
||||
id: string;
|
||||
} | null = null;
|
||||
|
||||
export async function startRun(
|
||||
@@ -36,11 +40,15 @@ export async function startRun(
|
||||
|
||||
if (!mode) return;
|
||||
|
||||
const runId = await addRun(problemId, mode);
|
||||
|
||||
let start = Date.now();
|
||||
|
||||
currentRun = {
|
||||
id: runId,
|
||||
problemId,
|
||||
start: new Date(),
|
||||
stopMonitoring: startMonitoring(runId),
|
||||
interval: setInterval(() => {
|
||||
const elapsed = Date.now() - start;
|
||||
|
||||
@@ -53,11 +61,17 @@ export async function startRun(
|
||||
.padStart(2, "0")}`;
|
||||
}, 50),
|
||||
};
|
||||
|
||||
await vscode.commands.executeCommand("setContext", "devrun.runActive", true);
|
||||
}
|
||||
|
||||
export async function stopRun() {
|
||||
if (currentRun) {
|
||||
clearTimeout(currentRun.interval);
|
||||
clearInterval(currentRun.interval);
|
||||
submitRun(currentRun.id);
|
||||
|
||||
currentRun = null;
|
||||
}
|
||||
|
||||
await vscode.commands.executeCommand("setContext", "devrun.runActive", false);
|
||||
}
|
||||
|
||||
+25
-3
@@ -2,15 +2,16 @@ import * as vscode from "vscode";
|
||||
import express from "express";
|
||||
import * as http from "http";
|
||||
import cors from "cors";
|
||||
import { getCookies, setCookies } from "./client";
|
||||
|
||||
let server: http.Server | undefined;
|
||||
var server: http.Server | undefined;
|
||||
|
||||
const app = express();
|
||||
|
||||
app.use(express.json());
|
||||
app.use(
|
||||
cors({
|
||||
origin: (origin, callback) => {
|
||||
// allow requests with no origin (e.g., direct curl)
|
||||
if (
|
||||
!origin ||
|
||||
origin.includes("localhost") ||
|
||||
@@ -25,10 +26,19 @@ app.use(
|
||||
}),
|
||||
);
|
||||
|
||||
app.post("/auth", (req, res) => {
|
||||
const { saveCookies } = req.body;
|
||||
|
||||
setCookies(saveCookies);
|
||||
|
||||
res.json({ ok: true });
|
||||
});
|
||||
|
||||
app.get("/start-run/:problemId", (req, res) => {
|
||||
const { problemId } = req.params;
|
||||
|
||||
// trigger VS Code command
|
||||
if (!getCookies()) return res.json({ ok: false, code: "auth" });
|
||||
|
||||
vscode.commands.executeCommand("devrun-vscode.startRun", problemId);
|
||||
|
||||
res.json({ ok: true, problemId });
|
||||
@@ -42,6 +52,12 @@ export async function startServer(statusBarItem: vscode.StatusBarItem) {
|
||||
server = app.listen(63780, "127.0.0.1", () => {
|
||||
setTimeout(() => (statusBarItem.text = "$(clock) No active run"), 500);
|
||||
});
|
||||
|
||||
await vscode.commands.executeCommand(
|
||||
"setContext",
|
||||
"devrun.serverActive",
|
||||
true,
|
||||
);
|
||||
}
|
||||
|
||||
export async function stopServer(statusBarItem: vscode.StatusBarItem) {
|
||||
@@ -57,4 +73,10 @@ export async function stopServer(statusBarItem: vscode.StatusBarItem) {
|
||||
|
||||
server = undefined;
|
||||
setTimeout(() => (statusBarItem.text = "$(clock) No active run"), 500);
|
||||
|
||||
await vscode.commands.executeCommand(
|
||||
"setContext",
|
||||
"devrun.serverActive",
|
||||
false,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
export interface LiveRunMove {
|
||||
latency: number;
|
||||
cursor: number;
|
||||
changes?: {
|
||||
from: number;
|
||||
to: number;
|
||||
insert: string;
|
||||
};
|
||||
moveId: number;
|
||||
}
|
||||
Reference in New Issue
Block a user