|
|
@ -6,6 +6,8 @@ const ansi = require('ansi-escapes') |
|
|
|
const io = require('socket.io-client') |
|
|
|
const chalk = require('chalk') |
|
|
|
|
|
|
|
const {compare, deserialize} = require('./logs') |
|
|
|
|
|
|
|
class Lines { |
|
|
|
constructor(maxLines = 100) { |
|
|
|
this.max = maxLines |
|
|
@ -40,13 +42,16 @@ module.exports = class Logger extends EventEmitter { |
|
|
|
// readyState
|
|
|
|
this.building = false |
|
|
|
|
|
|
|
this.socket = io(`https://io.now.sh?host=${host}`) |
|
|
|
this.socket = io(`https://io.now.sh/states?host=${host}&v=2`) |
|
|
|
this.socket.once('error', this.onSocketError.bind(this)) |
|
|
|
this.socket.on('state', this.onState.bind(this)) |
|
|
|
this.socket.on('logs', this.onLog.bind(this)) |
|
|
|
this.socket.on('backend', this.onComplete.bind(this)) |
|
|
|
|
|
|
|
this.lines = new Lines(10) |
|
|
|
|
|
|
|
// log buffer
|
|
|
|
this.buf = [] |
|
|
|
} |
|
|
|
|
|
|
|
onState(state) { |
|
|
@ -84,23 +89,19 @@ module.exports = class Logger extends EventEmitter { |
|
|
|
return |
|
|
|
} |
|
|
|
|
|
|
|
if (log.type === 'command') { |
|
|
|
console.log(`${chalk.gray('>')} ▲ ${log.data}`) |
|
|
|
this.lines.reset() |
|
|
|
} else if (log.type === 'stderr') { |
|
|
|
log.data.split('\n').forEach(v => { |
|
|
|
if (v.length > 0) { |
|
|
|
console.error(chalk.gray(`> ${v}`)) |
|
|
|
} |
|
|
|
}) |
|
|
|
this.lines.reset() |
|
|
|
} else if (log.type === 'stdout') { |
|
|
|
log.data.split('\n').forEach(v => { |
|
|
|
if (v.length > 0) { |
|
|
|
this.lines.write(`${chalk.gray('>')} ${v}`) |
|
|
|
} |
|
|
|
}) |
|
|
|
} |
|
|
|
log = deserialize(log) |
|
|
|
|
|
|
|
const timer = setTimeout(() => { |
|
|
|
this.buf.sort((a, b) => compare(a.log, b.log)) |
|
|
|
const idx = this.buf.findIndex(b => b.log.id === log.id) + 1 |
|
|
|
for (const b of this.buf.slice(0, idx)) { |
|
|
|
clearTimeout(b.timer) |
|
|
|
this.printLog(b.log) |
|
|
|
} |
|
|
|
this.buf = this.buf.slice(idx) |
|
|
|
}, 300) |
|
|
|
|
|
|
|
this.buf.push({log, timer}) |
|
|
|
} |
|
|
|
|
|
|
|
onComplete() { |
|
|
@ -110,6 +111,15 @@ module.exports = class Logger extends EventEmitter { |
|
|
|
this.building = false |
|
|
|
} |
|
|
|
|
|
|
|
this.buf.sort((a, b) => compare(a.log, b.log)) |
|
|
|
|
|
|
|
// flush all buffer
|
|
|
|
for (const b of this.buf) { |
|
|
|
clearTimeout(b.timer) |
|
|
|
this.printLog(b.log) |
|
|
|
} |
|
|
|
this.buf = [] |
|
|
|
|
|
|
|
this.emit('close') |
|
|
|
} |
|
|
|
|
|
|
@ -118,4 +128,26 @@ module.exports = class Logger extends EventEmitter { |
|
|
|
console.log(`> [debug] Socket error ${err}\n${err.stack}`) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
printLog(log) { |
|
|
|
const data = log.object ? JSON.stringify(log.object) : log.text |
|
|
|
|
|
|
|
if (log.type === 'command') { |
|
|
|
console.log(`${chalk.gray('>')} ▲ ${data}`) |
|
|
|
this.lines.reset() |
|
|
|
} else if (log.type === 'stderr') { |
|
|
|
data.split('\n').forEach(v => { |
|
|
|
if (v.length > 0) { |
|
|
|
console.error(chalk.gray(`> ${v}`)) |
|
|
|
} |
|
|
|
}) |
|
|
|
this.lines.reset() |
|
|
|
} else if (log.type === 'stdout') { |
|
|
|
data.split('\n').forEach(v => { |
|
|
|
if (v.length > 0) { |
|
|
|
this.lines.write(`${chalk.gray('>')} ${v}`) |
|
|
|
} |
|
|
|
}) |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|