mirror of
https://github.com/quine-global/hyper.git
synced 2026-01-12 20:18:41 -09:00
typing improvements
This commit is contained in:
parent
c17c4cd7bf
commit
d0e954def5
18 changed files with 56 additions and 50 deletions
|
|
@ -21,9 +21,10 @@ class AutoUpdater extends EventEmitter implements Electron.AutoUpdater {
|
|||
this.emit('checking-for-update');
|
||||
|
||||
fetch(this.updateURL)
|
||||
.then((res): any => {
|
||||
.then((res) => {
|
||||
if (res.status === 204) {
|
||||
return this.emit('update-not-available');
|
||||
this.emit('update-not-available');
|
||||
return;
|
||||
}
|
||||
// eslint-disable-next-line @typescript-eslint/camelcase
|
||||
return res.json().then(({name, notes, pub_date}) => {
|
||||
|
|
@ -40,7 +41,7 @@ class AutoUpdater extends EventEmitter implements Electron.AutoUpdater {
|
|||
.catch(this.emitError.bind(this));
|
||||
}
|
||||
|
||||
emitError(error: any) {
|
||||
emitError(error: string | Error) {
|
||||
if (typeof error === 'string') {
|
||||
error = new Error(error);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import {cfgPath, cfgDir} from './config/paths';
|
|||
import {getColorMap} from './utils/colors';
|
||||
import {parsedConfig, configOptions} from '../lib/config';
|
||||
|
||||
const watchers: any[] = [];
|
||||
const watchers: Function[] = [];
|
||||
let cfg: parsedConfig = {} as any;
|
||||
let _watcher: fs.FSWatcher;
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ const NEWS_URL = 'https://hyper-news.now.sh';
|
|||
|
||||
export default function fetchNotifications(win: BrowserWindow) {
|
||||
const {rpc} = win;
|
||||
const retry = (err?: any) => {
|
||||
const retry = (err?: Error) => {
|
||||
setTimeout(() => fetchNotifications(win), ms('30m'));
|
||||
if (err) {
|
||||
console.error('Notification messages fetch error', err.stack);
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import {Notification} from 'electron';
|
||||
import {icon} from './config/paths';
|
||||
|
||||
export default function notify(title: string, body = '', details: any = {}) {
|
||||
export default function notify(title: string, body = '', details: {error?: any} = {}) {
|
||||
console.log(`[Notification] ${title}: ${body}`);
|
||||
if (details.error) {
|
||||
console.error(details.error);
|
||||
|
|
|
|||
|
|
@ -153,7 +153,7 @@ export default class Session extends EventEmitter {
|
|||
this.batcher?.write(chunk as any);
|
||||
});
|
||||
|
||||
this.batcher.on('flush', (data) => {
|
||||
this.batcher.on('flush', (data: string) => {
|
||||
this.emit('data', data);
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -149,7 +149,7 @@ export function newWindow(
|
|||
activeUid: options.activeUid
|
||||
});
|
||||
|
||||
session.on('data', (data: any) => {
|
||||
session.on('data', (data: string) => {
|
||||
rpc.emit('session data', data);
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -86,7 +86,7 @@ const addBinToUserPath = () => {
|
|||
});
|
||||
};
|
||||
|
||||
const logNotify = (withNotification: boolean, title: string, body: string, details?: any) => {
|
||||
const logNotify = (withNotification: boolean, title: string, body: string, details?: {error?: any}) => {
|
||||
console.log(title, body, details);
|
||||
withNotification && notify(title, body, details);
|
||||
};
|
||||
|
|
|
|||
12
cli/index.ts
12
cli/index.ts
|
|
@ -1,6 +1,6 @@
|
|||
// This is a CLI tool, using console is OK
|
||||
/* eslint no-console: 0 */
|
||||
import {spawn, exec} from 'child_process';
|
||||
import {spawn, exec, SpawnOptions} from 'child_process';
|
||||
import {isAbsolute, resolve} from 'path';
|
||||
import {existsSync} from 'fs';
|
||||
import {version} from '../app/package.json';
|
||||
|
|
@ -42,7 +42,7 @@ args.command(
|
|||
commandPromise = api
|
||||
.install(pluginName)
|
||||
.then(() => console.log(chalk.green(`${pluginName} installed successfully!`)))
|
||||
.catch((err: any) => console.error(chalk.red(err)));
|
||||
.catch((err) => console.error(chalk.red(err)));
|
||||
},
|
||||
['i']
|
||||
);
|
||||
|
|
@ -202,7 +202,7 @@ const main = (argv: string[]) => {
|
|||
env['ELECTRON_ENABLE_LOGGING'] = '1';
|
||||
}
|
||||
|
||||
const options: any = {
|
||||
const options: SpawnOptions = {
|
||||
detached: true,
|
||||
env
|
||||
};
|
||||
|
|
@ -231,8 +231,8 @@ const main = (argv: string[]) => {
|
|||
const child = spawn(process.execPath, args_, options);
|
||||
|
||||
if (flags.verbose) {
|
||||
child.stdout.on('data', (data) => console.log(data.toString('utf8')));
|
||||
child.stderr.on('data', (data) => console.error(data.toString('utf8')));
|
||||
child.stdout?.on('data', (data) => console.log(data.toString('utf8')));
|
||||
child.stderr?.on('data', (data) => console.error(data.toString('utf8')));
|
||||
}
|
||||
if (flags.verbose) {
|
||||
return new Promise((c) => child.once('exit', () => c(null)));
|
||||
|
|
@ -247,7 +247,7 @@ function eventuallyExit(code: number) {
|
|||
|
||||
main(process.argv)
|
||||
.then(() => eventuallyExit(0))
|
||||
.catch((err: any) => {
|
||||
.catch((err) => {
|
||||
console.error(err.stack ? err.stack : err);
|
||||
eventuallyExit(1);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ export function requestSession() {
|
|||
};
|
||||
}
|
||||
|
||||
export function addSessionData(uid: string, data: any) {
|
||||
export function addSessionData(uid: string, data: string) {
|
||||
return (dispatch: HyperDispatch) => {
|
||||
dispatch({
|
||||
type: SESSION_ADD_DATA,
|
||||
|
|
@ -161,7 +161,7 @@ export function closeSearch(uid?: string, keyEvent?: any) {
|
|||
};
|
||||
}
|
||||
|
||||
export function sendSessionData(uid: string | null, data: any, escaped?: any) {
|
||||
export function sendSessionData(uid: string | null, data: any, escaped?: boolean | null) {
|
||||
return (dispatch: HyperDispatch, getState: () => HyperState) => {
|
||||
dispatch({
|
||||
type: SESSION_USER_DATA,
|
||||
|
|
|
|||
|
|
@ -112,16 +112,15 @@ export function windowGeometryUpdated(): HyperActions {
|
|||
|
||||
// Find all sessions that are below the given
|
||||
// termGroup uid in the hierarchy:
|
||||
const findChildSessions = (termGroups: any, uid: string): string[] => {
|
||||
const findChildSessions = (termGroups: HyperState['termGroups']['termGroups'], uid: string): string[] => {
|
||||
const group = termGroups[uid];
|
||||
if (group.sessionUid) {
|
||||
return [uid];
|
||||
}
|
||||
|
||||
return group.children.reduce(
|
||||
(total: string[], childUid: string) => total.concat(findChildSessions(termGroups, childUid)),
|
||||
[]
|
||||
);
|
||||
return group.children
|
||||
.asMutable()
|
||||
.reduce((total: string[], childUid: string) => total.concat(findChildSessions(termGroups, childUid)), []);
|
||||
};
|
||||
|
||||
// Get the index of the next or previous group,
|
||||
|
|
@ -318,7 +317,7 @@ export function openSSH(url: string) {
|
|||
};
|
||||
}
|
||||
|
||||
export function execCommand(command: string, fn: (...args: any[]) => void, e: any) {
|
||||
export function execCommand(command: string, fn: (e: any, dispatch: HyperDispatch) => void, e: any) {
|
||||
return (dispatch: HyperDispatch) =>
|
||||
dispatch({
|
||||
type: UI_COMMAND_EXEC,
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import {HyperDispatch} from './hyper';
|
|||
import {closeSearch} from './actions/sessions';
|
||||
// TODO: Should be updates to new async API https://medium.com/@nornagon/electrons-remote-module-considered-harmful-70d69500f31
|
||||
|
||||
const {getDecoratedKeymaps} = remote.require('./plugins');
|
||||
const {getDecoratedKeymaps} = remote.require('./plugins') as typeof import('../app/plugins');
|
||||
|
||||
let commands: Record<string, (event: any, dispatch: HyperDispatch) => void> = {
|
||||
'editor:search-close': (e, dispatch) => {
|
||||
|
|
@ -16,7 +16,7 @@ export const getRegisteredKeys = () => {
|
|||
|
||||
return Object.keys(keymaps).reduce((result: Record<string, string>, actionName) => {
|
||||
const commandKeys = keymaps[actionName];
|
||||
commandKeys.forEach((shortcut: string) => {
|
||||
commandKeys.forEach((shortcut) => {
|
||||
result[shortcut] = actionName;
|
||||
});
|
||||
return result;
|
||||
|
|
|
|||
|
|
@ -12,13 +12,13 @@ const SplitPane = decorate(SplitPane_, 'SplitPane');
|
|||
// eslint-disable-next-line @typescript-eslint/class-name-casing
|
||||
class TermGroup_ extends React.PureComponent<TermGroupProps> {
|
||||
bound: WeakMap<(uid: string, ...args: any[]) => any, Record<string, (...args: any[]) => any>>;
|
||||
term?: Term_;
|
||||
term?: Term_ | null;
|
||||
constructor(props: TermGroupProps, context: any) {
|
||||
super(props, context);
|
||||
this.bound = new WeakMap();
|
||||
}
|
||||
|
||||
bind<T extends (uid: string, ...args: any) => any>(
|
||||
bind<T extends (uid: string, ...args: any[]) => any>(
|
||||
fn: T,
|
||||
thisObj: any,
|
||||
uid: string
|
||||
|
|
@ -52,7 +52,7 @@ class TermGroup_ extends React.PureComponent<TermGroupProps> {
|
|||
);
|
||||
}
|
||||
|
||||
onTermRef = (uid: string, term: Term_) => {
|
||||
onTermRef = (uid: string, term: Term_ | null) => {
|
||||
this.term = term;
|
||||
this.props.ref_(uid, term);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import {decorate, getTermGroupProps} from '../utils/plugins';
|
|||
import {registerCommandHandlers} from '../command-registry';
|
||||
import TermGroup_ from './term-group';
|
||||
import StyleSheet_ from './style-sheet';
|
||||
import {TermsProps} from '../hyper';
|
||||
import {TermsProps, HyperDispatch} from '../hyper';
|
||||
import Term from './term';
|
||||
import {ObjectTypedKeys} from '../utils/object';
|
||||
|
||||
|
|
@ -14,7 +14,7 @@ const isMac = /Mac/.test(navigator.userAgent);
|
|||
|
||||
export default class Terms extends React.Component<TermsProps> {
|
||||
terms: Record<string, Term>;
|
||||
registerCommands: (cmds: Record<string, (...args: any[]) => void>) => void;
|
||||
registerCommands: (cmds: Record<string, (e: any, dispatch: HyperDispatch) => void>) => void;
|
||||
constructor(props: TermsProps, context: any) {
|
||||
super(props, context);
|
||||
this.terms = {};
|
||||
|
|
@ -29,7 +29,7 @@ export default class Terms extends React.Component<TermsProps> {
|
|||
);
|
||||
}
|
||||
|
||||
onRef = (uid: string, term: Term) => {
|
||||
onRef = (uid: string, term: Term | null) => {
|
||||
if (term) {
|
||||
this.terms[uid] = term;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,12 +10,13 @@ import {HeaderContainer} from './header';
|
|||
import TermsContainer from './terms';
|
||||
import NotificationsContainer from './notifications';
|
||||
import {HyperState, HyperProps, HyperDispatch} from '../hyper';
|
||||
import Terms from '../components/terms';
|
||||
|
||||
const isMac = /Mac/.test(navigator.userAgent);
|
||||
|
||||
class Hyper extends React.PureComponent<HyperProps> {
|
||||
mousetrap!: MousetrapInstance;
|
||||
terms: any;
|
||||
terms!: Terms;
|
||||
constructor(props: HyperProps) {
|
||||
super(props);
|
||||
}
|
||||
|
|
@ -35,8 +36,8 @@ class Hyper extends React.PureComponent<HyperProps> {
|
|||
}
|
||||
}
|
||||
|
||||
handleFocusActive = (uid: string) => {
|
||||
const term = this.terms.getTermByUid(uid);
|
||||
handleFocusActive = (uid?: string) => {
|
||||
const term = uid && this.terms.getTermByUid(uid);
|
||||
if (term) {
|
||||
term.focus();
|
||||
}
|
||||
|
|
@ -81,7 +82,7 @@ class Hyper extends React.PureComponent<HyperProps> {
|
|||
window.rpc.on('term selectAll', this.handleSelectAll);
|
||||
}
|
||||
|
||||
onTermsRef = (terms: any) => {
|
||||
onTermsRef = (terms: Terms) => {
|
||||
this.terms = terms;
|
||||
window.focusActiveTerm = this.handleFocusActive;
|
||||
};
|
||||
|
|
@ -153,7 +154,7 @@ const mapStateToProps = (state: HyperState) => {
|
|||
|
||||
const mapDispatchToProps = (dispatch: HyperDispatch) => {
|
||||
return {
|
||||
execCommand: (command: string, fn: (...args: any[]) => void, e: any) => {
|
||||
execCommand: (command: string, fn: (e: any, dispatch: HyperDispatch) => void, e: any) => {
|
||||
dispatch(uiActions.execCommand(command, fn, e));
|
||||
}
|
||||
};
|
||||
|
|
|
|||
23
lib/hyper.d.ts
vendored
23
lib/hyper.d.ts
vendored
|
|
@ -1,10 +1,11 @@
|
|||
import {Immutable} from 'seamless-immutable';
|
||||
import Client from './utils/rpc';
|
||||
|
||||
declare global {
|
||||
interface Window {
|
||||
__rpcId: string;
|
||||
rpc: any;
|
||||
focusActiveTerm: any;
|
||||
rpc: Client;
|
||||
focusActiveTerm: (uid?: string) => void;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -154,6 +155,7 @@ export type hyperPlugin = {
|
|||
mapNotificationsState: any;
|
||||
mapTermsState: any;
|
||||
middleware: Middleware;
|
||||
onRendererUnload: any;
|
||||
onRendererWindow: any;
|
||||
reduceSessions: ISessionReducer;
|
||||
reduceTermGroups: ITermGroupReducer;
|
||||
|
|
@ -190,11 +192,12 @@ import configureStore from './store/configure-store';
|
|||
export type HyperThunkDispatch = ThunkDispatch<HyperState, undefined, HyperActions>;
|
||||
export type HyperDispatch = ReturnType<typeof configureStore>['dispatch'];
|
||||
|
||||
import {ReactChild} from 'react';
|
||||
type extensionProps = Partial<{
|
||||
customChildren: any;
|
||||
customChildrenBefore: any;
|
||||
customChildren: ReactChild | ReactChild[];
|
||||
customChildrenBefore: ReactChild | ReactChild[];
|
||||
customCSS: string;
|
||||
customInnerChildren: any;
|
||||
customInnerChildren: ReactChild | ReactChild[];
|
||||
}>;
|
||||
|
||||
import {HeaderConnectedProps} from './containers/header';
|
||||
|
|
@ -206,8 +209,9 @@ export type HyperProps = HyperConnectedProps & extensionProps;
|
|||
import {NotificationsConnectedProps} from './containers/notifications';
|
||||
export type NotificationsProps = NotificationsConnectedProps & extensionProps;
|
||||
|
||||
import Terms from './components/terms';
|
||||
import {TermsConnectedProps} from './containers/terms';
|
||||
export type TermsProps = TermsConnectedProps & extensionProps & {ref_: any};
|
||||
export type TermsProps = TermsConnectedProps & extensionProps & {ref_: (terms: Terms | null) => void};
|
||||
|
||||
export type StyleSheetProps = {
|
||||
backgroundColor: string;
|
||||
|
|
@ -270,7 +274,7 @@ export type TermGroupOwnProps = {
|
|||
cursorAccentColor?: string;
|
||||
fontSmoothing?: string;
|
||||
parentProps: TermsProps;
|
||||
ref_: (uid: string, term: Term) => void;
|
||||
ref_: (uid: string, term: Term | null) => void;
|
||||
termGroup: Immutable<ITermGroup>;
|
||||
terms: Record<string, Term | null>;
|
||||
} & Pick<
|
||||
|
|
@ -354,7 +358,7 @@ export type TermProps = {
|
|||
onActive: () => void;
|
||||
onContextMenu: (selection: any) => void;
|
||||
onCursorMove?: (cursorFrame: {x: number; y: number; width: number; height: number; col: number; row: number}) => void;
|
||||
onData: (data: any) => void;
|
||||
onData: (data: string) => void;
|
||||
onResize: (cols: number, rows: number) => void;
|
||||
onTitle: (title: string) => void;
|
||||
padding: string;
|
||||
|
|
@ -371,6 +375,7 @@ export type TermProps = {
|
|||
url: string | null;
|
||||
webGLRenderer: boolean;
|
||||
webLinksActivationKey: string;
|
||||
} & extensionProps & {ref_?: any};
|
||||
ref_: (uid: string, term: Term | null) => void;
|
||||
} & extensionProps;
|
||||
|
||||
export type Assignable<T, U> = {[k in keyof U]: k extends keyof T ? T[k] : U[k]} & Partial<T>;
|
||||
|
|
|
|||
|
|
@ -76,7 +76,7 @@ rpc.on('session add', (data) => {
|
|||
store_.dispatch(sessionActions.addSession(data));
|
||||
});
|
||||
|
||||
rpc.on('session data', (d) => {
|
||||
rpc.on('session data', (d: string) => {
|
||||
// the uid is a uuid v4 so it's 36 chars long
|
||||
const uid = d.slice(0, 36);
|
||||
const data = d.slice(36);
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ const setActiveGroup = (state: ImmutableType<ITermState>, action: {uid: string})
|
|||
};
|
||||
|
||||
// Reduce existing sizes to fit a new split:
|
||||
const insertRebalance = (oldSizes: ImmutableType<number[]>, index: any) => {
|
||||
const insertRebalance = (oldSizes: ImmutableType<number[]>, index: number) => {
|
||||
const newSize = 1 / (oldSizes.length + 1);
|
||||
// We spread out how much each pane should be reduced
|
||||
// with based on their existing size:
|
||||
|
|
@ -167,7 +167,7 @@ const removeGroup = (state: ImmutableType<ITermState>, uid: string) => {
|
|||
// it's safe to remove the group.
|
||||
if (group.parentUid && state.termGroups[group.parentUid]) {
|
||||
const parent = state.termGroups[group.parentUid];
|
||||
const newChildren = parent.children.filter((childUid: any) => childUid !== uid);
|
||||
const newChildren = parent.children.filter((childUid) => childUid !== uid);
|
||||
if (newChildren.length === 1) {
|
||||
// Since we only have one child left,
|
||||
// we can merge the parent and child into one group:
|
||||
|
|
@ -188,7 +188,7 @@ const removeGroup = (state: ImmutableType<ITermState>, uid: string) => {
|
|||
.set('activeSessions', state.activeSessions.without(uid));
|
||||
};
|
||||
|
||||
const resizeGroup = (state: ImmutableType<ITermState>, uid: any, sizes: number[]) => {
|
||||
const resizeGroup = (state: ImmutableType<ITermState>, uid: string, sizes: number[]) => {
|
||||
// Make sure none of the sizes fall below MIN_SIZE:
|
||||
if (sizes.find((size) => size < MIN_SIZE)) {
|
||||
return state;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/* eslint no-new:0 */
|
||||
export default function notify(title: string, body: string, details: Record<string, any> = {}) {
|
||||
export default function notify(title: string, body: string, details: {error?: any} = {}) {
|
||||
console.log(`[Notification] ${title}: ${body}`);
|
||||
if (details.error) {
|
||||
console.error(details.error);
|
||||
|
|
|
|||
Loading…
Reference in a new issue