@@ -2,9 +2,12 @@ import React, { Component, Fragment } from 'react';
22import PropTypes from 'prop-types' ;
33import { connect } from 'react-redux' ;
44import { withPreferences } from 'compass-preferences-model' ;
5+ import type { Shell as ShellType } from '@mongosh/browser-repl' ;
56
67// The browser-repl package.json defines exports['.'].require but not .module, hence require() instead of import
7- const { Shell } = require ( '@mongosh/browser-repl' ) ;
8+ const { Shell } =
9+ // eslint-disable-next-line @typescript-eslint/no-var-requires, @typescript-eslint/consistent-type-imports
10+ require ( '@mongosh/browser-repl' ) as typeof import ( '@mongosh/browser-repl' ) ;
811import {
912 ResizeHandle ,
1013 ResizeDirection ,
@@ -16,6 +19,9 @@ import {
1619
1720import ShellInfoModal from '../shell-info-modal' ;
1821import ShellHeader from '../shell-header' ;
22+ import type { WorkerRuntime } from '@mongosh/node-runtime-worker-thread' ;
23+ import type { HistoryStorage } from '../../modules/history-storage' ;
24+ import type { RootState } from '../../modules' ;
1925
2026const compassShellStyles = css (
2127 {
@@ -50,13 +56,34 @@ function getMaxShellHeight() {
5056
5157// Apply bounds to the shell height when resizing to ensure it's always
5258// visible and usable to the user.
53- function boundShellHeight ( attemptedHeight ) {
59+ function boundShellHeight ( attemptedHeight : number ) : number {
5460 const maxHeight = getMaxShellHeight ( ) ;
5561
5662 return Math . min ( maxHeight , Math . max ( shellMinHeightOpened , attemptedHeight ) ) ;
5763}
5864
59- export class CompassShell extends Component {
65+ export interface CompassShellProps {
66+ emitShellPluginOpened ?: ( ) => void ;
67+ runtime : WorkerRuntime | null ;
68+ shellOutput ?: ShellOutputEntry [ ] ;
69+ historyStorage ?: HistoryStorage ;
70+ enableShell : boolean ;
71+ }
72+
73+ interface CompassShellState {
74+ height : number ;
75+ prevHeight : number ;
76+ initialHistory : string [ ] | null ;
77+ isOperationInProgress : boolean ;
78+ showInfoModal : boolean ;
79+ }
80+
81+ type ShellOutputEntry = ShellType [ 'state' ] [ 'output' ] [ number ] ;
82+
83+ export class CompassShell extends Component <
84+ CompassShellProps ,
85+ CompassShellState
86+ > {
6087 static propTypes = {
6188 emitShellPluginOpened : PropTypes . func ,
6289 runtime : PropTypes . object ,
@@ -65,15 +92,18 @@ export class CompassShell extends Component {
6592 enableShell : PropTypes . bool ,
6693 } ;
6794
95+ shellRef = React . createRef < ShellType > ( ) ;
96+ shellOutput : readonly ShellOutputEntry [ ] ;
97+
6898 static defaultProps = {
69- emitShellPluginOpened : ( ) => { } ,
99+ emitShellPluginOpened : ( ) => {
100+ /* ignore */
101+ } ,
70102 runtime : null ,
71103 } ;
72- constructor ( props ) {
104+ constructor ( props : CompassShellProps ) {
73105 super ( props ) ;
74106
75- this . shellRef = React . createRef ( ) ;
76-
77107 this . shellOutput = this . props . shellOutput || [ ] ;
78108
79109 this . state = {
@@ -86,25 +116,28 @@ export class CompassShell extends Component {
86116 }
87117
88118 componentDidMount ( ) {
89- this . loadHistory ( ) ;
119+ void this . loadHistory ( ) ;
90120 window . addEventListener ( 'beforeunload' , this . terminateRuntime ) ;
91121 }
92122
93- componentDidUpdate ( prevProps , prevState ) {
123+ componentDidUpdate (
124+ prevProps : CompassShellProps ,
125+ prevState : CompassShellState
126+ ) {
94127 const { height } = this . state ;
95128 if (
96129 prevState . height < shellMinHeightOpened &&
97130 height > shellMinHeightOpened
98131 ) {
99- this . props . emitShellPluginOpened ( ) ;
132+ this . props . emitShellPluginOpened ?. ( ) ;
100133 }
101134 }
102135
103136 componentWillUnmount ( ) {
104137 window . removeEventListener ( 'beforeunload' , this . terminateRuntime ) ;
105138 }
106139
107- onShellOutputChanged = ( output ) => {
140+ onShellOutputChanged = ( output : readonly ShellOutputEntry [ ] ) => {
108141 this . shellOutput = output ;
109142 } ;
110143
@@ -122,21 +155,23 @@ export class CompassShell extends Component {
122155
123156 terminateRuntime = ( ) => {
124157 if ( this . props . runtime ) {
125- this . props . runtime . terminate ( ) ;
158+ void this . props . runtime . terminate ( ) ;
126159 }
127160 } ;
128161
129- saveHistory = async ( history ) => {
130- if ( ! this . props . historyStorage ) {
131- return ;
132- }
133-
134- try {
135- await this . props . historyStorage . save ( history ) ;
136- } catch ( error ) {
137- // eslint-disable-next-line no-console
138- console . error ( error ) ;
139- }
162+ saveHistory = ( history : readonly string [ ] ) => {
163+ void ( async ( ) => {
164+ if ( ! this . props . historyStorage ) {
165+ return ;
166+ }
167+
168+ try {
169+ await this . props . historyStorage . save ( [ ...history ] ) ;
170+ } catch ( error ) {
171+ // eslint-disable-next-line no-console
172+ console . error ( error ) ;
173+ }
174+ } ) ( ) ;
140175 } ;
141176
142177 loadHistory = async ( ) => {
@@ -158,19 +193,19 @@ export class CompassShell extends Component {
158193 }
159194 } ;
160195
161- updateHeight ( height ) {
162- this . setState (
163- height > shellMinHeightOpened
164- ? {
165- height,
166- // Store the previous height to use when toggling open/close
167- // when we resize while the shell is expanded.
168- prevHeight : height ,
169- }
170- : {
171- height,
172- }
173- ) ;
196+ updateHeight ( height : number ) {
197+ if ( height > shellMinHeightOpened ) {
198+ this . setState ( {
199+ height ,
200+ // Store the previous height to use when toggling open/close
201+ // when we resize while the shell is expanded.
202+ prevHeight : height ,
203+ } ) ;
204+ } else {
205+ this . setState ( {
206+ height,
207+ } ) ;
208+ }
174209 }
175210
176211 hideInfoModal ( ) {
@@ -179,7 +214,8 @@ export class CompassShell extends Component {
179214
180215 focusEditor ( ) {
181216 if ( this . shellRef . current && window . getSelection ( ) ?. type !== 'Range' ) {
182- this . shellRef . current . focusEditor ( ) ;
217+ ( this . shellRef . current as any ) /* private ... */
218+ . focusEditor ( ) ;
183219 }
184220 }
185221
@@ -266,7 +302,7 @@ export class CompassShell extends Component {
266302 }
267303}
268304
269- export default connect ( ( state ) => ( {
305+ export default connect ( ( state : RootState ) => ( {
270306 emitShellPluginOpened : ( ) => {
271307 if ( state . appRegistry && state . appRegistry . globalAppRegistry ) {
272308 state . appRegistry . globalAppRegistry . emit ( 'compass:compass-shell:opened' ) ;
0 commit comments