performance improvements

This commit is contained in:
Guillermo Rauch 2016-07-14 16:40:15 -07:00
parent 2f2268906a
commit 5ba9f27c5d
7 changed files with 64 additions and 44 deletions

View file

@ -19,7 +19,7 @@ import {
SESSION_SET_PROCESS_TITLE SESSION_SET_PROCESS_TITLE
} from '../constants/sessions'; } from '../constants/sessions';
export function addSession (uid) { export function addSession (uid, shell) {
return (dispatch, getState) => { return (dispatch, getState) => {
const { sessions } = getState(); const { sessions } = getState();
@ -31,7 +31,8 @@ export function addSession (uid) {
dispatch({ dispatch({
type: SESSION_ADD, type: SESSION_ADD,
uid uid,
shell
}); });
}; };
} }
@ -51,13 +52,14 @@ export function requestSession (uid) {
} }
export function addSessionData (uid, data) { export function addSessionData (uid, data) {
return (dispatch, getState) => { return function (dispatch, getState) {
dispatch({ dispatch({
type: SESSION_ADD_DATA, type: SESSION_ADD_DATA,
data, data,
effect () { effect () {
const url = getURL(data); const { shell } = getState().sessions.sessions[uid];
if (null != url) { const url = getURL(shell, data);
if (null !== url) {
dispatch({ dispatch({
type: SESSION_URL_SET, type: SESSION_URL_SET,
uid, uid,
@ -101,10 +103,13 @@ export function userExitSession (uid) {
type: SESSION_USER_EXIT, type: SESSION_USER_EXIT,
uid, uid,
effect () { effect () {
rpc.emit('exit', { uid }); const { sessions } = getState().sessions;
const sessions = keys(getState().sessions.sessions); if (sessions[uid]) {
if (!sessions.length) { rpc.emit('exit', { uid });
window.close(); const sessions = keys(getState().sessions.sessions);
if (!sessions.length) {
window.close();
}
} }
} }
}); });

View file

@ -1,4 +1,4 @@
/* global Blob,URL */ /* global Blob,URL,requestAnimationFrame */
import React from 'react'; import React from 'react';
import hterm from '../hterm'; import hterm from '../hterm';
import Component from '../component'; import Component from '../component';
@ -73,7 +73,9 @@ export default class Term extends Component {
} }
write (data) { write (data) {
this.term.io.print(data); requestAnimationFrame(() => {
this.term.io.print(data);
});
} }
focus () { focus () {

View file

@ -41,8 +41,8 @@ rpc.on('ready', () => {
store_.dispatch(init()); store_.dispatch(init());
}); });
rpc.on('session add', ({ uid }) => { rpc.on('session add', ({ uid, shell }) => {
store_.dispatch(sessionActions.addSession(uid)); store_.dispatch(sessionActions.addSession(uid, shell));
}); });
rpc.on('session data', ({ uid, data }) => { rpc.on('session data', ({ uid, data }) => {

View file

@ -25,7 +25,8 @@ function Session (obj) {
title: '', title: '',
write: null, write: null,
url: null, url: null,
cleared: false cleared: false,
shell: ''
}).merge(obj); }).merge(obj);
} }
@ -37,14 +38,12 @@ function Write (obj) {
} }
const reducer = (state = initialState, action) => { const reducer = (state = initialState, action) => {
// prune the last write to the terminal
if (state.write) {
state = state.set('write', null);
}
switch (action.type) { switch (action.type) {
case SESSION_ADD: case SESSION_ADD:
return state.setIn(['sessions', action.uid], Session({ uid: action.uid })); return state.setIn(['sessions', action.uid], Session({
uid: action.uid,
shell: action.shell.split('/').pop()
}));
case SESSION_URL_SET: case SESSION_URL_SET:
return state.setIn(['sessions', action.uid, 'url'], action.url); return state.setIn(['sessions', action.uid, 'url'], action.url);
@ -65,8 +64,9 @@ const reducer = (state = initialState, action) => {
}, { deep: true }); }, { deep: true });
case SESSION_PTY_DATA: case SESSION_PTY_DATA:
return state.merge({ return state
write: Write(action), .set('write', Write(action))
.merge({
sessions: { sessions: {
[action.uid]: { [action.uid]: {
cleared: false cleared: false

View file

@ -1,30 +1,40 @@
import * as regex from './url-regex'; import * as regex from './url-regex';
export default function isUrlCommand (data) { export const domainRegex = /\b((?=[a-z0-9-]{1,63}\.)(xn--)?[a-z0-9]+(-[a-z0-9]+)*\.)+[a-z]{2,63}\b/;
let match = data.match(regex.bash);
let url; export default function isUrlCommand (shell, data) {
const matcher = regex[shell];
if (undefined === matcher) return null;
let url, i;
switch (matcher) {
case regex.bash:
i = 5;
break;
case regex.zsh:
i = 7;
break;
case regex.fish:
i = 4;
break;
}
let match = data.match(matcher);
if (match) { if (match) {
url = match[5]; url = match[i];
} else { if (url) {
match = data.match(regex.zsh); // extract the domain portion from the url
if (match) { const domain = url.split('/')[0];
url = match[7]; if (domainRegex.test(domain)) {
} else { return toURL(url);
match = data.match(regex.fish);
if (match) {
url = match[4];
} }
} }
} }
if (url) { return null;
// extract the domain portion from the url
const domain = url.split('/')[0];
if (regex.domain.test(domain)) {
return toURL(url);
}
}
} }
function toURL (domain) { function toURL (domain) {

View file

@ -1,4 +1,4 @@
export const domain = /\b((?=[a-z0-9-]{1,63}\.)(xn--)?[a-z0-9]+(-[a-z0-9]+)*\.)+[a-z]{2,63}\b/; export const sh = /(ba)?sh: ((https?:\/\/)|(\/\/))?(.*): ((command not found)|(No such file or directory))/;
export const bash = /(ba)?sh: ((https?:\/\/)|(\/\/))?(.*): ((command not found)|(No such file or directory))/; export const bash = sh;
export const zsh = /zsh: ((command not found)|(no such file or directory)): ((https?:\/\/)|(\/\/))?([^\n]+)/; export const zsh = /zsh: ((command not found)|(no such file or directory)): ((https?:\/\/)|(\/\/))?([^\n]+)/;
export const fish = /fish: Unknown command '((https?:\/\/)|(\/\/))?([^']+)'/; export const fish = /fish: Unknown command '((https?:\/\/)|(\/\/))?([^']+)'/;

View file

@ -78,7 +78,10 @@ app.on('ready', () => {
rpc.on('new', ({ rows = 40, cols = 100 }) => { rpc.on('new', ({ rows = 40, cols = 100 }) => {
initSession({ rows, cols }, (uid, session) => { initSession({ rows, cols }, (uid, session) => {
sessions.set(uid, session); sessions.set(uid, session);
rpc.emit('session add', { uid }); rpc.emit('session add', {
uid,
shell: session.shell
});
session.on('data', (data) => { session.on('data', (data) => {
rpc.emit('session data', { uid, data }); rpc.emit('session data', { uid, data });