2021-05-16 18:36:33 +03:00
|
|
|
import { Observable, Subject } from 'rxjs'
|
2021-07-06 00:56:38 +03:00
|
|
|
import { Logger } from 'tabby-core'
|
|
|
|
import { LoginScriptProcessor, LoginScriptsOptions } from './api/loginScriptProcessing'
|
2021-05-16 18:36:33 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* A session object for a [[BaseTerminalTabComponent]]
|
|
|
|
* Extend this to implement custom I/O and process management for your terminal tab
|
|
|
|
*/
|
|
|
|
export abstract class BaseSession {
|
|
|
|
open: boolean
|
|
|
|
name: string
|
|
|
|
truePID: number
|
|
|
|
protected output = new Subject<string>()
|
|
|
|
protected binaryOutput = new Subject<Buffer>()
|
|
|
|
protected closed = new Subject<void>()
|
|
|
|
protected destroyed = new Subject<void>()
|
2021-07-06 00:56:38 +03:00
|
|
|
protected loginScriptProcessor: LoginScriptProcessor | null = null
|
2021-05-16 18:36:33 +03:00
|
|
|
private initialDataBuffer = Buffer.from('')
|
|
|
|
private initialDataBufferReleased = false
|
|
|
|
|
|
|
|
get output$ (): Observable<string> { return this.output }
|
|
|
|
get binaryOutput$ (): Observable<Buffer> { return this.binaryOutput }
|
|
|
|
get closed$ (): Observable<void> { return this.closed }
|
|
|
|
get destroyed$ (): Observable<void> { return this.destroyed }
|
|
|
|
|
2021-07-06 00:56:38 +03:00
|
|
|
constructor (protected logger: Logger) { }
|
|
|
|
|
2021-05-16 18:36:33 +03:00
|
|
|
emitOutput (data: Buffer): void {
|
|
|
|
if (!this.initialDataBufferReleased) {
|
|
|
|
this.initialDataBuffer = Buffer.concat([this.initialDataBuffer, data])
|
|
|
|
} else {
|
|
|
|
this.output.next(data.toString())
|
|
|
|
this.binaryOutput.next(data)
|
2021-07-06 00:56:38 +03:00
|
|
|
this.loginScriptProcessor?.feedFromSession(data)
|
2021-05-16 18:36:33 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
releaseInitialDataBuffer (): void {
|
|
|
|
this.initialDataBufferReleased = true
|
|
|
|
this.output.next(this.initialDataBuffer.toString())
|
|
|
|
this.binaryOutput.next(this.initialDataBuffer)
|
|
|
|
this.initialDataBuffer = Buffer.from('')
|
|
|
|
}
|
|
|
|
|
2021-07-06 00:56:38 +03:00
|
|
|
setLoginScriptsOptions (options: LoginScriptsOptions): void {
|
|
|
|
this.loginScriptProcessor?.close()
|
|
|
|
this.loginScriptProcessor = new LoginScriptProcessor(this.logger, options)
|
|
|
|
this.loginScriptProcessor.outputToSession$.subscribe(data => this.write(data))
|
|
|
|
}
|
|
|
|
|
2021-05-16 18:36:33 +03:00
|
|
|
async destroy (): Promise<void> {
|
|
|
|
if (this.open) {
|
2021-07-06 00:56:38 +03:00
|
|
|
this.logger.info('Destroying')
|
2021-05-16 18:36:33 +03:00
|
|
|
this.open = false
|
2021-07-06 00:56:38 +03:00
|
|
|
this.loginScriptProcessor?.close()
|
2021-05-16 18:36:33 +03:00
|
|
|
this.closed.next()
|
|
|
|
this.destroyed.next()
|
|
|
|
await this.gracefullyKillProcess()
|
|
|
|
}
|
2021-07-04 17:48:48 +03:00
|
|
|
this.closed.complete()
|
|
|
|
this.destroyed.complete()
|
|
|
|
this.output.complete()
|
|
|
|
this.binaryOutput.complete()
|
2021-05-16 18:36:33 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
abstract start (options: unknown): void
|
|
|
|
abstract resize (columns: number, rows: number): void
|
|
|
|
abstract write (data: Buffer): void
|
|
|
|
abstract kill (signal?: string): void
|
|
|
|
abstract gracefullyKillProcess (): Promise<void>
|
|
|
|
abstract supportsWorkingDirectory (): boolean
|
|
|
|
abstract getWorkingDirectory (): Promise<string|null>
|
|
|
|
}
|