1
1
mirror of https://github.com/Eugeny/tabby.git synced 2024-09-11 13:13:59 +03:00

moved more electron stuff out of tabby-local

This commit is contained in:
Eugene Pankov 2023-03-19 13:20:30 +01:00
parent 35ca7015c8
commit 8cba805522
No known key found for this signature in database
GPG Key ID: 5896FCBBDD1CF4F4
12 changed files with 207 additions and 179 deletions

View File

@ -16,16 +16,15 @@
], ],
"author": "Eugene Pankov", "author": "Eugene Pankov",
"license": "MIT", "license": "MIT",
"dependencies": {
"hasbin": "^1.2.3"
},
"peerDependencies": { "peerDependencies": {
"@angular/core": "^9.1.9", "@angular/core": "^9.1.9",
"tabby-local": "*" "tabby-local": "*"
}, },
"devDependencies": { "devDependencies": {
"electron-promise-ipc": "^2.2.4", "electron-promise-ipc": "^2.2.4",
"ps-node": "^0.1.6",
"tmp-promise": "^3.0.2", "tmp-promise": "^3.0.2",
"hasbin": "^1.2.3",
"winston": "^3.3.3" "winston": "^3.3.3"
} }
} }

View File

@ -2,7 +2,7 @@ import { NgModule } from '@angular/core'
import { PlatformService, LogService, UpdaterService, DockingService, HostAppService, ThemesService, Platform, AppService, ConfigService, WIN_BUILD_FLUENT_BG_SUPPORTED, isWindowsBuild, HostWindowService, HotkeyProvider, ConfigProvider, FileProvider } from 'tabby-core' import { PlatformService, LogService, UpdaterService, DockingService, HostAppService, ThemesService, Platform, AppService, ConfigService, WIN_BUILD_FLUENT_BG_SUPPORTED, isWindowsBuild, HostWindowService, HotkeyProvider, ConfigProvider, FileProvider } from 'tabby-core'
import { TerminalColorSchemeProvider } from 'tabby-terminal' import { TerminalColorSchemeProvider } from 'tabby-terminal'
import { SFTPContextMenuItemProvider, SSHProfileImporter, AutoPrivateKeyLocator } from 'tabby-ssh' import { SFTPContextMenuItemProvider, SSHProfileImporter, AutoPrivateKeyLocator } from 'tabby-ssh'
import { ShellProvider, UACService } from 'tabby-local' import { PTYInterface, ShellProvider, UACService } from 'tabby-local'
import { auditTime } from 'rxjs' import { auditTime } from 'rxjs'
import { HyperColorSchemes } from './colorSchemes' import { HyperColorSchemes } from './colorSchemes'
@ -16,11 +16,13 @@ import { ElectronFileProvider } from './services/fileProvider.service'
import { ElectronHostAppService } from './services/hostApp.service' import { ElectronHostAppService } from './services/hostApp.service'
import { ElectronService } from './services/electron.service' import { ElectronService } from './services/electron.service'
import { DockMenuService } from './services/dockMenu.service' import { DockMenuService } from './services/dockMenu.service'
import { ElectronUACService } from './services/uac.service'
import { ElectronHotkeyProvider } from './hotkeys' import { ElectronHotkeyProvider } from './hotkeys'
import { ElectronConfigProvider } from './config' import { ElectronConfigProvider } from './config'
import { EditSFTPContextMenu } from './sftpContextMenu' import { EditSFTPContextMenu } from './sftpContextMenu'
import { OpenSSHImporter, PrivateKeyLocator, StaticFileImporter } from './sshImporters' import { OpenSSHImporter, PrivateKeyLocator, StaticFileImporter } from './sshImporters'
import { ElectronUACService } from './services/uac.service' import { ElectronPTYInterface } from './pty'
import { CmderShellProvider } from './shells/cmder' import { CmderShellProvider } from './shells/cmder'
import { Cygwin32ShellProvider } from './shells/cygwin32' import { Cygwin32ShellProvider } from './shells/cygwin32'
@ -69,6 +71,8 @@ import { VSDevToolsProvider } from './shells/vs'
{ provide: UACService, useClass: ElectronUACService }, { provide: UACService, useClass: ElectronUACService },
{ provide: PTYInterface, useClass: ElectronPTYInterface },
// For WindowsDefaultShellProvider // For WindowsDefaultShellProvider
PowerShellCoreShellProvider, PowerShellCoreShellProvider,
WSLShellProvider, WSLShellProvider,

140
tabby-electron/src/pty.ts Normal file
View File

@ -0,0 +1,140 @@
import * as psNode from 'ps-node'
import { ipcRenderer } from 'electron'
import { ChildProcess, PTYInterface, PTYProxy } from 'tabby-local'
import { getWorkingDirectoryFromPID } from 'native-process-working-directory'
/* eslint-disable block-scoped-var */
try {
var macOSNativeProcessList = require('macos-native-processlist') // eslint-disable-line @typescript-eslint/no-var-requires, no-var
} catch { }
try {
var windowsProcessTree = require('windows-process-tree') // eslint-disable-line @typescript-eslint/no-var-requires, no-var
} catch { }
export class ElectronPTYInterface extends PTYInterface {
async spawn (...options: any[]): Promise<PTYProxy> {
const id = ipcRenderer.sendSync('pty:spawn', ...options)
return new ElectronPTYProxy(id)
}
async restore (id: string): Promise<ElectronPTYProxy|null> {
if (ipcRenderer.sendSync('pty:exists', id)) {
return new ElectronPTYProxy(id)
}
return null
}
}
// eslint-disable-next-line @typescript-eslint/no-extraneous-class
export class ElectronPTYProxy extends PTYProxy {
private subscriptions: Map<string, any> = new Map()
private truePID: Promise<number>
constructor (
private id: string,
) {
super()
this.truePID = new Promise(async (resolve) => {
let pid = await this.getPID()
try {
await new Promise(r => setTimeout(r, 2000))
// Retrieve any possible single children now that shell has fully started
let processes = await this.getChildProcessesInternal(pid)
while (pid && processes.length === 1) {
if (!processes[0].pid) {
break
}
pid = processes[0].pid
processes = await this.getChildProcessesInternal(pid)
}
} finally {
resolve(pid)
}
})
this.truePID = this.truePID.catch(() => this.getPID())
}
getID (): string {
return this.id
}
getTruePID(): Promise<number> {
return this.truePID
}
async getPID (): Promise<number> {
return ipcRenderer.sendSync('pty:get-pid', this.id)
}
subscribe (event: string, handler: (..._: any[]) => void): void {
const key = `pty:${this.id}:${event}`
const newHandler = (_event, ...args) => handler(...args)
this.subscriptions.set(key, newHandler)
ipcRenderer.on(key, newHandler)
}
ackData (length: number): void {
ipcRenderer.send('pty:ack-data', this.id, length)
}
unsubscribeAll (): void {
for (const k of this.subscriptions.keys()) {
ipcRenderer.off(k, this.subscriptions.get(k))
}
}
async resize (columns: number, rows: number): Promise<void> {
ipcRenderer.send('pty:resize', this.id, columns, rows)
}
async write (data: Buffer): Promise<void> {
ipcRenderer.send('pty:write', this.id, data)
}
async kill (signal?: string): Promise<void> {
ipcRenderer.send('pty:kill', this.id, signal)
}
async getChildProcesses (): Promise<ChildProcess[]> {
return this.getChildProcessesInternal(await this.getTruePID())
}
async getChildProcessesInternal (truePID: number): Promise<ChildProcess[]> {
if (process.platform === 'darwin') {
const processes = await macOSNativeProcessList.getProcessList()
return processes.filter(x => x.ppid === truePID).map(p => ({
pid: p.pid,
ppid: p.ppid,
command: p.name,
}))
}
if (process.platform === 'win32') {
return new Promise<ChildProcess[]>(resolve => {
windowsProcessTree.getProcessTree(truePID, tree => {
resolve(tree ? tree.children.map(child => ({
pid: child.pid,
ppid: tree.pid,
command: child.name,
})) : [])
})
})
}
return new Promise<ChildProcess[]>((resolve, reject) => {
psNode.lookup({ ppid: truePID }, (err, processes) => {
if (err) {
reject(err)
return
}
resolve(processes as ChildProcess[])
})
})
}
async getWorkingDirectory (): Promise<string|null> {
return getWorkingDirectoryFromPID(await this.getTruePID())
}
}

View File

@ -93,6 +93,11 @@ concat-map@0.0.1:
resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=
connected-domain@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/connected-domain/-/connected-domain-1.0.0.tgz#bfe77238c74be453a79f0cb6058deeb4f2358e93"
integrity sha512-lHlohUiJxlpunvDag2Y0pO20bnvarMjnrdciZeuJUqRwrf/5JHNhdpiPIr5GQ8IkqrFj5TDMQwcCjblGo1oeuA==
define-properties@^1.1.3: define-properties@^1.1.3:
version "1.1.3" version "1.1.3"
resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1"
@ -368,6 +373,13 @@ path-is-absolute@^1.0.0:
resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f"
integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18=
ps-node@^0.1.6:
version "0.1.6"
resolved "https://registry.yarnpkg.com/ps-node/-/ps-node-0.1.6.tgz#9af67a99d7b1d0132e51a503099d38a8d2ace2c3"
integrity sha512-w7QJhUTbu70hpDso0YXDRNKCPNuchV8UTUZsAv0m7Qj5g85oHOJfr9drA1EjvK4nQK/bG8P97W4L6PJ3IQLoOA==
dependencies:
table-parser "^0.1.3"
readable-stream@^3.4.0, readable-stream@^3.6.0: readable-stream@^3.4.0, readable-stream@^3.6.0:
version "3.6.0" version "3.6.0"
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198"
@ -436,6 +448,13 @@ string_decoder@^1.1.1:
dependencies: dependencies:
safe-buffer "~5.2.0" safe-buffer "~5.2.0"
table-parser@^0.1.3:
version "0.1.3"
resolved "https://registry.yarnpkg.com/table-parser/-/table-parser-0.1.3.tgz#0441cfce16a59481684c27d1b5a67ff15a43c7b0"
integrity sha512-LCYeuvqqoPII3lzzYaXKbC3Forb+d2u4bNwhk/9FlivuGRxPE28YEWAYcujeSlLLDlMfvy29+WPybFJZFiKMYg==
dependencies:
connected-domain "^1.0.0"
text-hex@1.0.x: text-hex@1.0.x:
version "1.0.0" version "1.0.0"
resolved "https://registry.yarnpkg.com/text-hex/-/text-hex-1.0.0.tgz#69dc9c1b17446ee79a92bf5b884bb4b9127506f5" resolved "https://registry.yarnpkg.com/text-hex/-/text-hex-1.0.0.tgz#69dc9c1b17446ee79a92bf5b884bb4b9127506f5"

View File

@ -19,7 +19,6 @@
"devDependencies": { "devDependencies": {
"ansi-colors": "^4.1.1", "ansi-colors": "^4.1.1",
"dataurl": "0.1.0", "dataurl": "0.1.0",
"ps-node": "^0.1.6",
"runes": "^0.4.2" "runes": "^0.4.2"
}, },
"peerDependencies": { "peerDependencies": {

View File

@ -59,3 +59,22 @@ export abstract class UACService {
abstract patchSessionOptionsForUAC (sessionOptions: SessionOptions): SessionOptions abstract patchSessionOptionsForUAC (sessionOptions: SessionOptions): SessionOptions
} }
export abstract class PTYProxy {
abstract getID (): string
abstract getPID (): Promise<number>
abstract resize (columns: number, rows: number): Promise<void>
abstract write (data: Buffer): Promise<void>
abstract kill (signal?: string): Promise<void>
abstract ackData (length: number): void
abstract subscribe (event: string, handler: (..._: any[]) => void): void
abstract unsubscribeAll (): void
abstract getChildProcesses (): Promise<ChildProcess[]>
abstract getTruePID (): Promise<number>
abstract getWorkingDirectory (): Promise<string|null>
}
export abstract class PTYInterface {
abstract spawn (...options: any[]): Promise<PTYProxy>
abstract restore (id: string): Promise<PTYProxy|null>
}

View File

@ -51,7 +51,7 @@ export class TerminalTabComponent extends BaseTerminalTabComponent<LocalProfile>
protected onFrontendReady (): void { protected onFrontendReady (): void {
this.initializeSession(this.size.columns, this.size.rows) this.initializeSession(this.size.columns, this.size.rows)
this.savedStateIsLive = this.profile.options.restoreFromPTYID === this.session?.getPTYID() this.savedStateIsLive = this.profile.options.restoreFromPTYID === this.session?.getID()
super.onFrontendReady() super.onFrontendReady()
} }
@ -82,7 +82,7 @@ export class TerminalTabComponent extends BaseTerminalTabComponent<LocalProfile>
options: { options: {
...this.profile.options, ...this.profile.options,
cwd: cwd ?? this.profile.options.cwd, cwd: cwd ?? this.profile.options.cwd,
restoreFromPTYID: options?.includeState && this.session?.getPTYID(), restoreFromPTYID: options?.includeState && this.session?.getID(),
}, },
}, },
savedState: options?.includeState && this.frontend?.saveState(), savedState: options?.includeState && this.frontend?.saveState(),

View File

@ -1,87 +1,12 @@
import * as psNode from 'ps-node'
import * as fs from 'mz/fs' import * as fs from 'mz/fs'
import * as fsSync from 'fs' import * as fsSync from 'fs'
import { Injector } from '@angular/core' import { Injector } from '@angular/core'
import { HostAppService, ConfigService, WIN_BUILD_CONPTY_SUPPORTED, isWindowsBuild, Platform, BootstrapData, BOOTSTRAP_DATA, LogService } from 'tabby-core' import { HostAppService, ConfigService, WIN_BUILD_CONPTY_SUPPORTED, isWindowsBuild, Platform, BootstrapData, BOOTSTRAP_DATA, LogService } from 'tabby-core'
import { BaseSession } from 'tabby-terminal' import { BaseSession } from 'tabby-terminal'
import { ipcRenderer } from 'electron' import { SessionOptions, ChildProcess, PTYInterface, PTYProxy } from './api'
import { getWorkingDirectoryFromPID } from 'native-process-working-directory'
import { SessionOptions, ChildProcess } from './api'
/* eslint-disable block-scoped-var */
try {
var macOSNativeProcessList = require('macos-native-processlist') // eslint-disable-line @typescript-eslint/no-var-requires, no-var
} catch { }
try {
var windowsProcessTree = require('windows-process-tree') // eslint-disable-line @typescript-eslint/no-var-requires, no-var
} catch { }
const windowsDirectoryRegex = /([a-zA-Z]:[^\:\[\]\?\"\<\>\|]+)/mi const windowsDirectoryRegex = /([a-zA-Z]:[^\:\[\]\?\"\<\>\|]+)/mi
// eslint-disable-next-line @typescript-eslint/no-extraneous-class
export class PTYProxy {
private id: string
private subscriptions: Map<string, any> = new Map()
static spawn (...options: any[]): PTYProxy {
return new PTYProxy(null, ...options)
}
static restore (id: string): PTYProxy|null {
if (ipcRenderer.sendSync('pty:exists', id)) {
return new PTYProxy(id)
}
return null
}
private constructor (id: string|null, ...options: any[]) {
if (id) {
this.id = id
} else {
this.id = ipcRenderer.sendSync('pty:spawn', ...options)
}
}
getPTYID (): string {
return this.id
}
getPID (): number {
return ipcRenderer.sendSync('pty:get-pid', this.id)
}
subscribe (event: string, handler: (..._: any[]) => void): void {
const key = `pty:${this.id}:${event}`
const newHandler = (_event, ...args) => handler(...args)
this.subscriptions.set(key, newHandler)
ipcRenderer.on(key, newHandler)
}
ackData (length: number): void {
ipcRenderer.send('pty:ack-data', this.id, length)
}
unsubscribeAll (): void {
for (const k of this.subscriptions.keys()) {
ipcRenderer.off(k, this.subscriptions.get(k))
}
}
resize (columns: number, rows: number): void {
ipcRenderer.send('pty:resize', this.id, columns, rows)
}
write (data: Buffer): void {
ipcRenderer.send('pty:write', this.id, data)
}
kill (signal?: string): void {
ipcRenderer.send('pty:kill', this.id, signal)
}
}
function mergeEnv (...envs) { function mergeEnv (...envs) {
const result = {} const result = {}
const keyMap = {} const keyMap = {}
@ -121,19 +46,23 @@ export class Session extends BaseSession {
private config: ConfigService private config: ConfigService
private hostApp: HostAppService private hostApp: HostAppService
private bootstrapData: BootstrapData private bootstrapData: BootstrapData
private ptyInterface: PTYInterface
constructor (injector: Injector) { constructor (
injector: Injector,
) {
super(injector.get(LogService).create('local')) super(injector.get(LogService).create('local'))
this.config = injector.get(ConfigService) this.config = injector.get(ConfigService)
this.hostApp = injector.get(HostAppService) this.hostApp = injector.get(HostAppService)
this.ptyInterface = injector.get(PTYInterface)
this.bootstrapData = injector.get(BOOTSTRAP_DATA) this.bootstrapData = injector.get(BOOTSTRAP_DATA)
} }
start (options: SessionOptions): void { async start (options: SessionOptions): Promise<void> {
let pty: PTYProxy|null = null let pty: PTYProxy|null = null
if (options.restoreFromPTYID) { if (options.restoreFromPTYID) {
pty = PTYProxy.restore(options.restoreFromPTYID) pty = await this.ptyInterface.restore(options.restoreFromPTYID)
options.restoreFromPTYID = undefined options.restoreFromPTYID = undefined
} }
@ -175,7 +104,7 @@ export class Session extends BaseSession {
cwd = undefined cwd = undefined
} }
pty = PTYProxy.spawn(options.command, options.args ?? [], { pty = await this.ptyInterface.spawn(options.command, options.args ?? [], {
name: 'xterm-256color', name: 'xterm-256color',
cols: options.width ?? 80, cols: options.width ?? 80,
rows: options.height ?? 30, rows: options.height ?? 30,
@ -191,17 +120,9 @@ export class Session extends BaseSession {
this.pty = pty this.pty = pty
this.truePID = this.pty.getPID() pty.getTruePID().then(async () => {
setTimeout(async () => {
// Retrieve any possible single children now that shell has fully started
let processes = await this.getChildProcesses()
while (processes.length === 1) {
this.truePID = processes[0].pid
processes = await this.getChildProcesses()
}
this.initialCWD = await this.getWorkingDirectory() this.initialCWD = await this.getWorkingDirectory()
}, 2000) })
this.open = true this.open = true
@ -236,8 +157,8 @@ export class Session extends BaseSession {
this.destroyed$.subscribe(() => this.pty!.unsubscribeAll()) this.destroyed$.subscribe(() => this.pty!.unsubscribeAll())
} }
getPTYID (): string|null { getID (): string|null {
return this.pty?.getPTYID() ?? null return this.pty?.getID() ?? null
} }
resize (columns: number, rows: number): void { resize (columns: number, rows: number): void {
@ -258,37 +179,7 @@ export class Session extends BaseSession {
} }
async getChildProcesses (): Promise<ChildProcess[]> { async getChildProcesses (): Promise<ChildProcess[]> {
if (!this.truePID) { return this.pty?.getChildProcesses() ?? []
return []
}
if (this.hostApp.platform === Platform.macOS) {
const processes = await macOSNativeProcessList.getProcessList()
return processes.filter(x => x.ppid === this.truePID).map(p => ({
pid: p.pid,
ppid: p.ppid,
command: p.name,
}))
}
if (this.hostApp.platform === Platform.Windows) {
return new Promise<ChildProcess[]>(resolve => {
windowsProcessTree.getProcessTree(this.truePID, tree => {
resolve(tree ? tree.children.map(child => ({
pid: child.pid,
ppid: tree.pid,
command: child.name,
})) : [])
})
})
}
return new Promise<ChildProcess[]>((resolve, reject) => {
psNode.lookup({ ppid: this.truePID }, (err, processes) => {
if (err) {
reject(err)
return
}
resolve(processes as ChildProcess[])
})
})
} }
async gracefullyKillProcess (): Promise<void> { async gracefullyKillProcess (): Promise<void> {
@ -297,9 +188,9 @@ export class Session extends BaseSession {
} else { } else {
await new Promise<void>((resolve) => { await new Promise<void>((resolve) => {
this.kill('SIGTERM') this.kill('SIGTERM')
setTimeout(() => { setTimeout(async () => {
try { try {
process.kill(this.pty!.getPID(), 0) process.kill(await this.pty!.getPID(), 0)
// still alive // still alive
this.kill('SIGKILL') this.kill('SIGKILL')
resolve() resolve()
@ -312,19 +203,16 @@ export class Session extends BaseSession {
} }
supportsWorkingDirectory (): boolean { supportsWorkingDirectory (): boolean {
return !!(this.truePID ?? this.reportedCWD ?? this.guessedCWD) return !!(this.initialCWD ?? this.reportedCWD ?? this.guessedCWD)
} }
async getWorkingDirectory (): Promise<string|null> { async getWorkingDirectory (): Promise<string|null> {
if (this.reportedCWD) { if (this.reportedCWD) {
return this.reportedCWD return this.reportedCWD
} }
if (!this.truePID) {
return null
}
let cwd: string|null = null let cwd: string|null = null
try { try {
cwd = getWorkingDirectoryFromPID(this.truePID) cwd = await this.pty?.getWorkingDirectory() ?? null
} catch (exc) { } catch (exc) {
console.info('Could not read working directory:', exc) console.info('Could not read working directory:', exc)
} }

View File

@ -7,31 +7,12 @@ ansi-colors@^4.1.1:
resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348" resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348"
integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA== integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==
connected-domain@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/connected-domain/-/connected-domain-1.0.0.tgz#bfe77238c74be453a79f0cb6058deeb4f2358e93"
integrity sha1-v+dyOMdL5FOnnwy2BY3utPI1jpM=
dataurl@0.1.0: dataurl@0.1.0:
version "0.1.0" version "0.1.0"
resolved "https://registry.yarnpkg.com/dataurl/-/dataurl-0.1.0.tgz#1f4734feddec05ffe445747978d86759c4b33199" resolved "https://registry.yarnpkg.com/dataurl/-/dataurl-0.1.0.tgz#1f4734feddec05ffe445747978d86759c4b33199"
integrity sha1-H0c0/t3sBf/kRXR5eNhnWcSzMZk= integrity sha1-H0c0/t3sBf/kRXR5eNhnWcSzMZk=
ps-node@^0.1.6:
version "0.1.6"
resolved "https://registry.yarnpkg.com/ps-node/-/ps-node-0.1.6.tgz#9af67a99d7b1d0132e51a503099d38a8d2ace2c3"
integrity sha1-mvZ6mdex0BMuUaUDCZ04qNKs4sM=
dependencies:
table-parser "^0.1.3"
runes@^0.4.2: runes@^0.4.2:
version "0.4.3" version "0.4.3"
resolved "https://registry.yarnpkg.com/runes/-/runes-0.4.3.tgz#32f7738844bc767b65cc68171528e3373c7bb355" resolved "https://registry.yarnpkg.com/runes/-/runes-0.4.3.tgz#32f7738844bc767b65cc68171528e3373c7bb355"
integrity sha512-K6p9y4ZyL9wPzA+PMDloNQPfoDGTiFYDvdlXznyGKgD10BJpcAosvATKrExRKOrNLgD8E7Um7WGW0lxsnOuNLg== integrity sha512-K6p9y4ZyL9wPzA+PMDloNQPfoDGTiFYDvdlXznyGKgD10BJpcAosvATKrExRKOrNLgD8E7Um7WGW0lxsnOuNLg==
table-parser@^0.1.3:
version "0.1.3"
resolved "https://registry.yarnpkg.com/table-parser/-/table-parser-0.1.3.tgz#0441cfce16a59481684c27d1b5a67ff15a43c7b0"
integrity sha1-BEHPzhallIFoTCfRtaZ/8VpDx7A=
dependencies:
connected-domain "^1.0.0"

View File

@ -26,7 +26,6 @@
"hexer": "^1.5.0", "hexer": "^1.5.0",
"ngx-colors": "^3.4.0", "ngx-colors": "^3.4.0",
"patch-package": "^6.5.0", "patch-package": "^6.5.0",
"ps-node": "^0.1.6",
"runes": "^0.4.2", "runes": "^0.4.2",
"xterm": "^5.1.0", "xterm": "^5.1.0",
"xterm-addon-canvas": "^0.3.0", "xterm-addon-canvas": "^0.3.0",

View File

@ -10,7 +10,6 @@ import { SessionMiddlewareStack } from './api/middleware'
*/ */
export abstract class BaseSession { export abstract class BaseSession {
open: boolean open: boolean
truePID?: number
readonly oscProcessor = new OSCProcessor() readonly oscProcessor = new OSCProcessor()
readonly middleware = new SessionMiddlewareStack() readonly middleware = new SessionMiddlewareStack()
protected output = new Subject<string>() protected output = new Subject<string>()
@ -85,7 +84,7 @@ export abstract class BaseSession {
this.binaryOutput.complete() this.binaryOutput.complete()
} }
abstract start (options: unknown): void abstract start (options: unknown): Promise<void>
abstract resize (columns: number, rows: number): void abstract resize (columns: number, rows: number): void
abstract write (data: Buffer): void abstract write (data: Buffer): void
abstract kill (signal?: string): void abstract kill (signal?: string): void

View File

@ -89,11 +89,6 @@ concat-map@0.0.1:
resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==
connected-domain@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/connected-domain/-/connected-domain-1.0.0.tgz#bfe77238c74be453a79f0cb6058deeb4f2358e93"
integrity sha1-v+dyOMdL5FOnnwy2BY3utPI1jpM=
crc-32@^1.1.1: crc-32@^1.1.1:
version "1.2.0" version "1.2.0"
resolved "https://registry.yarnpkg.com/crc-32/-/crc-32-1.2.0.tgz#cb2db6e29b88508e32d9dd0ec1693e7b41a18208" resolved "https://registry.yarnpkg.com/crc-32/-/crc-32-1.2.0.tgz#cb2db6e29b88508e32d9dd0ec1693e7b41a18208"
@ -382,13 +377,6 @@ promise-stream-reader@^1.0.1:
resolved "https://registry.yarnpkg.com/promise-stream-reader/-/promise-stream-reader-1.0.1.tgz#4e793a79c9d49a73ccd947c6da9c127f12923649" resolved "https://registry.yarnpkg.com/promise-stream-reader/-/promise-stream-reader-1.0.1.tgz#4e793a79c9d49a73ccd947c6da9c127f12923649"
integrity sha512-Tnxit5trUjBAqqZCGWwjyxhmgMN4hGrtpW3Oc/tRI4bpm/O2+ej72BB08l6JBnGQgVDGCLvHFGjGgQS6vzhwXg== integrity sha512-Tnxit5trUjBAqqZCGWwjyxhmgMN4hGrtpW3Oc/tRI4bpm/O2+ej72BB08l6JBnGQgVDGCLvHFGjGgQS6vzhwXg==
ps-node@^0.1.6:
version "0.1.6"
resolved "https://registry.yarnpkg.com/ps-node/-/ps-node-0.1.6.tgz#9af67a99d7b1d0132e51a503099d38a8d2ace2c3"
integrity sha1-mvZ6mdex0BMuUaUDCZ04qNKs4sM=
dependencies:
table-parser "^0.1.3"
rimraf@^2.6.3: rimraf@^2.6.3:
version "2.7.1" version "2.7.1"
resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec"
@ -430,13 +418,6 @@ supports-color@^7.1.0:
dependencies: dependencies:
has-flag "^4.0.0" has-flag "^4.0.0"
table-parser@^0.1.3:
version "0.1.3"
resolved "https://registry.yarnpkg.com/table-parser/-/table-parser-0.1.3.tgz#0441cfce16a59481684c27d1b5a67ff15a43c7b0"
integrity sha1-BEHPzhallIFoTCfRtaZ/8VpDx7A=
dependencies:
connected-domain "^1.0.0"
tiny-inflate@^1.0.2: tiny-inflate@^1.0.2:
version "1.0.3" version "1.0.3"
resolved "https://registry.yarnpkg.com/tiny-inflate/-/tiny-inflate-1.0.3.tgz#122715494913a1805166aaf7c93467933eea26c4" resolved "https://registry.yarnpkg.com/tiny-inflate/-/tiny-inflate-1.0.3.tgz#122715494913a1805166aaf7c93467933eea26c4"