checkpoint working on electron

This commit is contained in:
sawka
2022-07-09 01:37:19 -07:00
parent 96961822a3
commit 5dc0e6b651
12 changed files with 3204 additions and 179 deletions
+7 -1
View File
@@ -5,8 +5,10 @@
"license": "Proprietary",
"dependencies": {
"autobind-decorator": "^2.4.0",
"better-sqlite3": "^7.6.0",
"classnames": "^2.3.1",
"dayjs": "^1.11.3",
"fs-ext": "^2.0.0",
"mobx": "^6.6.0",
"mobx-react": "^7.5.0",
"react": "^18.1.0",
@@ -25,14 +27,18 @@
"@babel/preset-env": "^7.18.2",
"@babel/preset-react": "^7.17.12",
"@babel/preset-typescript": "^7.17.12",
"@electron-forge/cli": "^6.0.0-beta.64",
"@types/classnames": "^2.3.1",
"@types/node": "^17.0.40",
"@types/electron": "^1.6.10",
"@types/node": "^18.0.3",
"@types/react": "^18.0.12",
"@types/uuid": "^8.3.4",
"babel-loader": "^8.2.5",
"babel-plugin-jsx-control-statements": "^4.1.2",
"copy-webpack-plugin": "^11.0.0",
"css-loader": "^6.7.1",
"electron": "^19.0.8",
"electron-rebuild": "^3.2.8",
"http-server": "^14.1.1",
"less": "^4.1.2",
"less-loader": "^11.0.0",
+21 -3
View File
@@ -2,18 +2,36 @@
```bash
# @scripthaus command webpack-watch
# @scripthaus cd :current
# @scripthaus cd :playbook
node_modules/.bin/webpack --watch --config webpack.dev.js
```
```bash
# @scripthaus command webpack-electron-watch
# @scripthaus cd :playbook
node_modules/.bin/webpack --watch --config webpack.electron.js
```
```bash
# @scripthaus command electron-rebuild
# @scripthaus cd :playbook
node_modules/.bin/electron-rebuild
```
```bash
# @scripthaus command electron
# @scripthaus cd :playbook
node_modules/.bin/electron dist/emain-dev.js
```
```bash
# @scripthaus command devserver
# @scripthaus cd :current
# @scripthaus cd :playbook
node_modules/.bin/webpack-dev-server --config webpack.dev.js --host 0.0.0.0
```
```bash
# @scripthaus command typecheck
# @scripthaus cd :current
# @scripthaus cd :playbook
node_modules/.bin/tsc --jsx preserve --noEmit --esModuleInterop --target ES5 --experimentalDecorators --downlevelIteration src/sh2.ts
```
+37
View File
@@ -0,0 +1,37 @@
import * as path from "path";
import * as fs from "fs";
import {flockSync} from "fs-ext";
const HomeVarName = "HOME";
const ScHomeVarName = "SCRIPTHAUS_HOME";
const SCLockFile = "sh2-electron.lock";
const DBFileName = "sh2.db";
const SessionsDirBaseName = "sessions";
const RemotesDirBaseName = "remotes";
const ScDirName = "scripthaus";
function getScHomeDir() : string {
if (process.env[ScHomeVarName]) {
return process.env[ScHomeVarName];
}
let homeDir = process.env[HomeVarName];
if (!homeDir) {
homeDir = "/";
}
return path.join(homeDir, ScDirName);
}
function getDBName() : string {
let scHome = getScHomeDir();
return path.join(scHome, DBFileName);
}
function acquireSCElectronLock() : File {
let scHome = getScHomeDir();
let lockFileName = path.join(scHome, SCLockFile);
let fd = fs.openSync(lockFileName, "w", 0o600);
flockSync(fd, "exnb");
return fd;
}
export {getScHomeDir, getDBName, acquireSCElectronLock};
+4
View File
@@ -0,0 +1,4 @@
import {sprintf} from "sprintf-js";
import {Database} from "better-sqlite3";
let DB = new Database();
+54
View File
@@ -0,0 +1,54 @@
import * as electron from "electron";
import {acquireSCElectronLock} from "./base";
import * as path from "path";
import * as fs from "fs";
let app = electron.app;
app.setAppLogsPath(__dirname, "../logs");
let lock : File;
try {
lock = acquireSCElectronLock();
}
catch (e) {
app.exit(0);
}
console.log("ACQUIRED LOCK");
let MainWindow = null;
function createWindow() {
let win = new electron.BrowserWindow({
width: 1800,
height: 1200,
webPreferences: {
preload: path.join(__dirname, "../src/preload.js"),
},
});
win.loadFile("../static/index.html");
return win;
}
app.whenReady().then(() => {
MainWindow = createWindow();
MainWindow.webContents.openDevTools();
app.on('activate', () => {
if (electron.BrowserWindow.getAllWindows().length === 0) {
createWindow();
}
})
});
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') app.quit()
});
electron.ipcMain.on("relaunch", (event) => {
console.log("RELAUNCH!");
app.relaunch();
app.exit(0);
console.log("test", event);
});
+10 -2
View File
@@ -8,7 +8,7 @@ import {If, For, When, Otherwise, Choose} from "tsx-control-statements/component
import cn from "classnames"
import {TermWrap} from "./term";
import {getCurrentSession, getLineId, Session, newSession, getAllSessions, getCurrentSessionId} from "./session";
import type {SessionType, LineType, CmdDataType, RemoteType} from "./session";
import type {SessionDataType, LineType, CmdDataType, RemoteType} from "./types";
import localizedFormat from 'dayjs/plugin/localizedFormat';
dayjs.extend(localizedFormat)
@@ -426,11 +426,16 @@ class MainSideBar extends React.Component<{}, {}> {
handleSessionClick(sessionId : string) {
console.log("click session", sessionId);
}
handleReload() {
console.log("reload");
window.api.relaunch();
}
render() {
let curSessionId = getCurrentSessionId();
let sessions = getAllSessions();
let session : SessionType = null;
let session : SessionDataType = null;
return (
<div className={cn("main-sidebar", {"collapsed": this.collapsed.get()})}>
<div className="collapse-container">
@@ -494,6 +499,9 @@ class MainSideBar extends React.Component<{}, {}> {
<li><a><i className="status fa fa-circle"/>mike@test01.ec2</a></li>
<li><a><i className="status offline fa fa-circle"/>root@app01.ec2</a></li>
</ul>
<p className="menu-label relaunch" onClick={this.handleReload} style={{cursor: "pointer"}}>
Relaunch
</p>
<div className="bottom-spacer"></div>
</div>
</div>
+7
View File
@@ -0,0 +1,7 @@
let {contextBridge, ipcRenderer} = require("electron");
console.log("RUNNING PRELOAD");
contextBridge.exposeInMainWorld("api", {
relaunch: () => ipcRenderer.send("relaunch"),
});
+8 -119
View File
@@ -4,57 +4,10 @@ import {boundMethod} from "autobind-decorator";
import {handleJsonFetchResponse} from "./util";
import {TermWrap} from "./term";
import {v4 as uuidv4} from "uuid";
import type {SessionDataType, WindowDataType, LineType, RemoteType, HistoryItem, RemoteInstanceType, CmdDataType, FeCmdPacketType} from "./types";
var GlobalUser = "sawka";
function makeTermKey(sessionId : string, cmdId : string, windowId : string, lineid : number) : string {
return sprintf("%s/%s/%s/%s", sessionId, cmdId, windowId, lineid);
}
type SessionType = {
sessionid : string,
name : string,
};
type LineType = {
sessionid : string,
windowid : string,
lineid : number,
ts : number,
userid : string,
linetype : string,
text : string,
cmdid : string,
isnew : boolean,
};
function getLineId(line : LineType) : string {
return sprintf("%s-%s-%s", line.sessionid, line.windowid, line.lineid);
}
type RemoteType = {
remotetype : string,
remoteid : string,
remotename : string,
remotevars : Record<string, string>,
status : string,
defaultstate : RemoteStateType,
};
type RemoteStateType = {
cwd : string,
};
type RemoteInstanceType = {
riid : string,
name : string,
sessionid : string,
windowid : string,
remoteid : string,
sessionscope : boolean,
state : RemoteStateType,
}
type WindowType = {
sessionid : string,
windowid : string,
@@ -65,76 +18,13 @@ type WindowType = {
version : number,
};
type WindowDataType = {
sessionid : string,
windowid : string,
name : string,
curremote : string,
lines : LineType[],
version : number,
};
type HistoryItem = {
cmdtext : string,
};
type SessionDataType = {
sessionid : string,
name : string,
windows : WindowDataType[],
cmds : CmdDataType[],
};
type CmdRemoteStateType = {
remoteid : string
remotename : string,
cwd : string,
};
type FeCmdPacketType = {
type : string,
sessionid : string,
windowid : string,
userid : string,
cmdstr : string,
remotestate : CmdRemoteStateType,
function makeTermKey(sessionId : string, cmdId : string, windowId : string, lineid : number) : string {
return sprintf("%s/%s/%s/%s", sessionId, cmdId, windowId, lineid);
}
type TermOptsType = {
rows : number,
cols : number,
flexrows : boolean,
};
type CmdStartPacketType = {
type : string,
respid : string,
ts : number,
ck : string,
pid : number,
mshellpid : number,
};
type CmdDonePacketType = {
type : string,
ts : number,
ck : string,
exitcode : number,
durationms : number,
};
type CmdDataType = {
sessionid : string,
cmdid : string,
remoteid : string,
cmdstr : string,
remotestate : RemoteStateType,
termopts : TermOptsType,
status : string,
startpk : CmdStartPacketType,
donepk : CmdDonePacketType,
runout : any[],
};
function getLineId(line : LineType) : string {
return sprintf("%s-%s-%s", line.sessionid, line.windowid, line.lineid);
}
class Session {
sessionId : string;
@@ -392,7 +282,7 @@ class Session {
}
}
var SessionList : mobx.IObservableArray<SessionType> = mobx.observable.array([]);
var SessionList : mobx.IObservableArray<SessionDataType> = mobx.observable.array([]);
var CurrentSession : Session = new Session();
var CurrentSessionId : mobx.IObservableValue<string> = mobx.observable.box(null);
@@ -479,7 +369,7 @@ function loadSessionList(init : boolean) {
});
}
function getAllSessions() : mobx.IObservableArray<SessionType> {
function getAllSessions() : mobx.IObservableArray<SessionDataType> {
return SessionList;
}
@@ -498,4 +388,3 @@ function getCurrentSessionId() : string {
}
export {Session, getCurrentSession, getLineId, newSession, loadSessionList, getAllSessions, getCurrentSessionId};
export type {LineType, WindowType, CmdDataType, RemoteType, SessionType};
+109
View File
@@ -0,0 +1,109 @@
import * as mobx from "mobx";
type SessionDataType = {
sessionid : string,
name : string,
windows : WindowDataType[],
cmds : CmdDataType[],
};
type LineType = {
sessionid : string,
windowid : string,
lineid : number,
ts : number,
userid : string,
linetype : string,
text : string,
cmdid : string,
isnew : boolean,
};
type RemoteType = {
remotetype : string,
remoteid : string,
remotename : string,
remotevars : Record<string, string>,
status : string,
defaultstate : RemoteStateType,
};
type RemoteStateType = {
cwd : string,
};
type RemoteInstanceType = {
riid : string,
name : string,
sessionid : string,
windowid : string,
remoteid : string,
sessionscope : boolean,
state : RemoteStateType,
}
type WindowDataType = {
sessionid : string,
windowid : string,
name : string,
curremote : string,
lines : LineType[],
version : number,
};
type HistoryItem = {
cmdtext : string,
};
type CmdRemoteStateType = {
remoteid : string
remotename : string,
cwd : string,
};
type FeCmdPacketType = {
type : string,
sessionid : string,
windowid : string,
userid : string,
cmdstr : string,
remotestate : CmdRemoteStateType,
}
type TermOptsType = {
rows : number,
cols : number,
flexrows : boolean,
};
type CmdStartPacketType = {
type : string,
respid : string,
ts : number,
ck : string,
pid : number,
mshellpid : number,
};
type CmdDonePacketType = {
type : string,
ts : number,
ck : string,
exitcode : number,
durationms : number,
};
type CmdDataType = {
sessionid : string,
cmdid : string,
remoteid : string,
cmdstr : string,
remotestate : RemoteStateType,
termopts : TermOptsType,
status : string,
startpk : CmdStartPacketType,
donepk : CmdDonePacketType,
runout : any[],
};
export type {SessionDataType, LineType, RemoteType, RemoteStateType, RemoteInstanceType, WindowDataType, HistoryItem, CmdRemoteStateType, FeCmdPacketType, TermOptsType, CmdStartPacketType, CmdDonePacketType, CmdDataType};
+4 -4
View File
@@ -1,17 +1,17 @@
<!DOCTYPE html>
<html>
<head>
<base href="../">
<link rel="preconnect" href="https://fonts.gstatic.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<script src="/sh2-dev.js"></script>
<script src="dist/sh2-dev.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bulma@0.9.2/css/bulma.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@200;400;600&display=swap" rel="stylesheet">
<link rel="stylesheet" href="/xterm.css" />
<link rel="stylesheet" href="/sh2.css" />
<link rel="stylesheet" href="static/xterm.css" />
<link rel="stylesheet" href="dist/sh2.css" />
</head>
<body>
<div id="app"></div>
</body>
+51
View File
@@ -0,0 +1,51 @@
const path = require("path");
module.exports = {
mode: "development",
entry: {
emain: ["./src/emain.ts"],
},
target: "electron-main",
output: {
path: path.resolve(__dirname, "dist"),
filename: "[name]-dev.js"
},
externals: {
"fs": "require('fs')",
"fs-ext": "require('fs-ext')",
},
module: {
rules: [
{
test: /\.tsx?$/,
// exclude: /node_modules/,
use: {
loader: "babel-loader",
options: {
presets: [
[
"@babel/preset-env",
{
targets: "defaults and not ie > 0 and not op_mini all and not op_mob > 0 and not kaios > 0 and not and_qq > 0 and not and_uc > 0 and not baidu > 0",
},
],
"@babel/preset-react",
"@babel/preset-typescript"],
plugins: [
["@babel/transform-runtime", {"regenerator": true}],
"@babel/plugin-transform-react-jsx",
["@babel/plugin-proposal-decorators", { "legacy": true }],
["@babel/plugin-proposal-class-properties", { "loose": true }],
["@babel/plugin-proposal-private-methods", { "loose": true }],
["@babel/plugin-proposal-private-property-in-object", { "loose": true }],
"babel-plugin-jsx-control-statements",
],
},
},
},
]
},
resolve: {
extensions: ['.ts', '.tsx', '.js']
},
}
+2892 -50
View File
File diff suppressed because it is too large Load Diff