| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657 |
- /** @hidden */
- module.exports = function patchPTYModule (mod) {
- const oldSpawn = mod.spawn
- if (mod.patched) {
- return
- }
- mod.patched = true
- mod.spawn = (file, args, opt) => {
- let terminal = oldSpawn(file, args, opt)
- let timeout = null
- let buffer = Buffer.from('')
- let lastFlush = 0
- let nextTimeout = 0
- // Minimum prebuffering window (ms) if the input is non-stop flowing
- const minWindow = 5
- // Maximum buffering time (ms) until output must be flushed unconditionally
- const maxWindow = 100
- function flush () {
- if (buffer.length) {
- terminal.emit('data-buffered', buffer)
- }
- lastFlush = Date.now()
- buffer = Buffer.from('')
- }
- function reschedule () {
- if (timeout) {
- clearTimeout(timeout)
- }
- nextTimeout = Date.now() + minWindow
- timeout = setTimeout(() => {
- timeout = null
- flush()
- }, minWindow)
- }
- terminal.on('data', data => {
- if (typeof data === 'string') {
- data = Buffer.from(data)
- }
- buffer = Buffer.concat([buffer, data])
- if (Date.now() - lastFlush > maxWindow) {
- // Taking too much time buffering, flush to keep things interactive
- flush()
- } else {
- if (Date.now() > nextTimeout - maxWindow / 10) {
- // Extend the window if it's expiring
- reschedule()
- }
- }
- })
- return terminal
- }
- }
|