提交 04cd6e17 编写于 作者: Huan (李卓桓)'s avatar Huan (李卓桓)

Merge branch 'master' of github.com:wechaty/wechaty

...@@ -16,22 +16,17 @@ Wechaty is a Bot Framework for Wechat **Personal** Account that help you easy cr ...@@ -16,22 +16,17 @@ Wechaty is a Bot Framework for Wechat **Personal** Account that help you easy cr
# ATTENTION # ATTENTION
## Wechaty is just converted to Typescript from Javascript. ## Wechaty was converted to Typescript from Javascript on 12th Oct 2016.
Details: https://github.com/wechaty/wechaty/issues/40 Details: https://github.com/wechaty/wechaty/issues/40
```diff ```diff
+ Typescripted ... + Typescriptilized ...
- Please do not clone/pull until you are really want to play with typescript wechaty in alpha stage.
``` ```
VSCode is recommended for typescript because we can get benifit of [intelligent code completion, parameter info, and member lists](https://code.visualstudio.com/docs/languages/javascript). VSCode is recommended for typescript because we can get benifit of [intelligent code completion, parameter info, and member lists](https://code.visualstudio.com/docs/languages/javascript).
The last Javascript version is: [v0.4.0](https://github.com/wechaty/wechaty/releases/tag/v0.4.0) (2016/10/9) The last Javascript version is: [v0.4.0](https://github.com/wechaty/wechaty/releases/tag/v0.4.0) (2016/10/9) , or install v0.4 by `npm install wechaty`.
Or install v0.4 via `npm install wechaty`
Thanks.
- See Also: [Why we decided to move from plain JavaScript to TypeScript for Babylon.js](https://www.eternalcoding.com/?p=103) - See Also: [Why we decided to move from plain JavaScript to TypeScript for Babylon.js](https://www.eternalcoding.com/?p=103)
...@@ -713,8 +708,8 @@ npm test ...@@ -713,8 +708,8 @@ npm test
## v0.5.0 master (2016/10) The First Typescript Version ## v0.5.0 master (2016/10) The First Typescript Version
1. [#40](https://github.com/wechaty/wechaty/issues/40) Converted to Typescript (2016/10/11) 1. [#40](https://github.com/wechaty/wechaty/issues/40) Converted to Typescript (2016/10/11)
1. [#41](https://github.com/wechaty/wechaty/issues/41) added `say()` method to Contact/Room instance, and to `this` inside wechaty event listeners, to make them `Sayable` 1. [#41](https://github.com/wechaty/wechaty/issues/41) Sayablization: Make Wechaty/Contact/Room `Sayable`, and all `this` inside wechaty event listeners are `Sayable` too.
1. BREAKING CHANGE: global event `scan` arguments changed from 1 to 2: now is (url: string, code: number) instead of {url, code} before. 1. BREAKING CHANGE: global event `scan` listener arguments changed from 1 to 2: now is `function(this: Sayable, url: string, code: number)` instead of `function({url, code})` before.
## [v0.4.0](https://github.com/wechaty/wechaty/releases/tag/v0.4.0) (2016/10/9) The Latest Javascript Version ## [v0.4.0](https://github.com/wechaty/wechaty/releases/tag/v0.4.0) (2016/10/9) The Latest Javascript Version
1. [#32](https://github.com/wechaty/wechaty/issues/32) Extend Room Class with: 1. [#32](https://github.com/wechaty/wechaty/issues/32) Extend Room Class with:
...@@ -724,9 +719,9 @@ npm test ...@@ -724,9 +719,9 @@ npm test
1. Add/Del/Topic for Room 1. Add/Del/Topic for Room
1. Other methods like nick/member/has/etc... 1. Other methods like nick/member/has/etc...
1. [#33](https://github.com/wechaty/wechaty/issues/33) New Class `FriendRequest` with: 1. [#33](https://github.com/wechaty/wechaty/issues/33) New Class `FriendRequest` with:
1. `Wechaty.on('friend', (contact, request) => {})` with Wechaty new Event `friend` 1. `Wechaty.on('friend', function(contact: Contact, request: FriendRequest) {})` with Wechaty new Event `friend`
1. `accept()` to accept a friend request 1. `request.accept()` to accept a friend request
1. `send()` to send new friend request 1. `requestsend()` to send new friend request
## v0.3.13 (2016/09) ## v0.3.13 (2016/09)
1. Managed by Cloud Manager: https://app.wechaty.io 1. Managed by Cloud Manager: https://app.wechaty.io
......
...@@ -19,28 +19,20 @@ ...@@ -19,28 +19,20 @@
* *
* put name of one of your friend here, or create room will not work. * put name of one of your friend here, or create room will not work.
* *
* ::: ___CHANGE ME___ ::: * ::::::::: ___CHANGE ME___ :::::::::
* vvvvvvvvvvvvvvv * vvvvvvvvv
* vvvvvvvvv
* vvvvvvvvv
*/ */
const HELPER_CONTACT_NAME = 'Bruce LEE' const HELPER_CONTACT_NAME = 'Bruce LEE'
/**
* ^^^^^^^^^
* ^^^^^^^^^
* ^^^^^^^^^
* ::::::::: ___CHANGE ME___ :::::::::
*
*/
import { import {
Config Config
...@@ -312,7 +304,6 @@ function checkRoomJoin(room: Room, invitee: Contact|Contact[] , inviter: Contact ...@@ -312,7 +304,6 @@ function checkRoomJoin(room: Room, invitee: Contact|Contact[] , inviter: Contact
, invitee , invitee
) )
room.topic('ding - warn ' + inviter.name()) room.topic('ding - warn ' + inviter.name())
setTimeout(_ => { setTimeout(_ => {
Array.isArray(invitee) Array.isArray(invitee)
......
...@@ -144,4 +144,6 @@ export interface Sayable { ...@@ -144,4 +144,6 @@ export interface Sayable {
say(content: string, replyTo?: any): Promise<any> say(content: string, replyTo?: any): Promise<any>
} }
export * from './brolog-env'
export default Config export default Config
...@@ -29,8 +29,8 @@ type BrowserSetting = { ...@@ -29,8 +29,8 @@ type BrowserSetting = {
class Browser extends EventEmitter { class Browser extends EventEmitter {
private _targetState private _targetState: string
private _currentState private _currentState: string
public driver: WebDriver public driver: WebDriver
...@@ -54,7 +54,7 @@ class Browser extends EventEmitter { ...@@ -54,7 +54,7 @@ class Browser extends EventEmitter {
} }
// currentState : 'opening' | 'open' | 'closing' | 'close' // currentState : 'opening' | 'open' | 'closing' | 'close'
private currentState(newState?) { public currentState(newState?) {
if (newState) { if (newState) {
log.verbose('PuppetWebBrowser', 'currentState(%s)', newState) log.verbose('PuppetWebBrowser', 'currentState(%s)', newState)
this._currentState = newState this._currentState = newState
...@@ -264,32 +264,35 @@ class Browser extends EventEmitter { ...@@ -264,32 +264,35 @@ class Browser extends EventEmitter {
return driver return driver
} }
public async quit(restart?: boolean): Promise<any> { public async restart(): Promise<void> {
log.verbose('PuppetWebBrowser', 'quit()') log.verbose('PuppetWebBrowser', 'restart()')
await this.quit()
if (!restart) { if (this.targetState() !== 'open'
this.targetState('close') && this.currentState() !== 'opening') {
this.currentState('closing') await this.init()
} }
}
// this.live = false public async quit(): Promise<any> {
log.verbose('PuppetWebBrowser', 'quit()')
this.targetState('close')
this.currentState('closing')
if (!this.driver) { if (!this.driver) {
log.verbose('PuppetWebBrowser', 'driver.quit() skipped because no driver') log.verbose('PuppetWebBrowser', 'driver.quit() skipped because no driver')
this.currentState('close') this.currentState('close')
return Promise.resolve('no driver') return 'no driver'
} else if (!this.driver.getSession()) { } else if (!this.driver.getSession()) {
this.driver = null this.driver = null
log.verbose('PuppetWebBrowser', 'driver.quit() skipped because no driver session') log.verbose('PuppetWebBrowser', 'driver.quit() skipped because no driver session')
this.currentState('close') this.currentState('close')
return Promise.resolve('no driver session') return 'no driver session'
} }
// return co.call(this, function* () {
try { try {
log.silly('PuppetWebBrowser', 'quit() co()')
await this.driver.close() // http://stackoverflow.com/a/32341885/1123955 await this.driver.close() // http://stackoverflow.com/a/32341885/1123955
log.silly('PuppetWebBrowser', 'quit() driver.close()-ed') log.silly('PuppetWebBrowser', 'quit() driver.close()-ed')
await this.driver.quit() await this.driver.quit()
...@@ -304,10 +307,8 @@ class Browser extends EventEmitter { ...@@ -304,10 +307,8 @@ class Browser extends EventEmitter {
* *
*/ */
await this.clean() await this.clean()
this.currentState('close')
log.silly('PuppetWebBrowser', 'quit() co() end') log.silly('PuppetWebBrowser', 'quit() co() end')
// }).catch(e => {
} catch (e) { } catch (e) {
// console.log(e) // console.log(e)
// log.warn('PuppetWebBrowser', 'err: %s %s %s %s', e.code, e.errno, e.syscall, e.message) // log.warn('PuppetWebBrowser', 'err: %s %s %s %s', e.code, e.errno, e.syscall, e.message)
...@@ -323,12 +324,11 @@ class Browser extends EventEmitter { ...@@ -323,12 +324,11 @@ class Browser extends EventEmitter {
if (crashRegex.test(e.message)) { log.warn('PuppetWebBrowser', 'driver.quit() browser crashed') } if (crashRegex.test(e.message)) { log.warn('PuppetWebBrowser', 'driver.quit() browser crashed') }
else { log.warn('PuppetWebBrowser', 'driver.quit() exception: %s', e.message) } else { log.warn('PuppetWebBrowser', 'driver.quit() exception: %s', e.message) }
// XXX fail safe to `close` ?
this.currentState('close')
/* fail safe */ /* fail safe */
} }
this.currentState('close')
return return
} }
...@@ -494,61 +494,58 @@ class Browser extends EventEmitter { ...@@ -494,61 +494,58 @@ class Browser extends EventEmitter {
* check whether browser is full functional * check whether browser is full functional
* *
*/ */
public readyLive(): Promise<any> { public async readyLive(): Promise<boolean> {
log.verbose('PuppetWebBrowser', 'readyLive()') log.verbose('PuppetWebBrowser', 'readyLive()')
if (this.dead()) { if (this.dead()) {
return Promise.reject(new Error('this.dead() true')) log.silly('PuppetWebBrowser', 'readyLive() dead() is true')
return false
} }
return new Promise((resolve, reject) => {
this.execute('return 1+1') let two
.then(r => {
if (r === 2) { try {
resolve(true) // browser ok, living two = await this.execute('return 1+1')
return } catch (e) {
} two = e && e.message
const errMsg = 'deadEx() found dead browser coz 1+1 = ' + r + ' (not 2)' }
log.verbose('PuppetWebBrowser', errMsg)
this.dead(errMsg) if (two === 2) {
reject(new Error(errMsg)) // browser not ok, dead return true // browser ok, living
return }
})
.catch(e => { const errMsg = 'found dead browser coz 1+1 = ' + two + ' (not 2)'
const errMsg = 'deadEx() found dead browser coz 1+1 = ' + e.message log.warn('PuppetWebBrowser', 'readyLive() %s', errMsg)
log.verbose('PuppetWebBrowser', errMsg) this.dead(errMsg)
this.dead(errMsg) return false // browser not ok, dead
reject(new Error(errMsg)) // browser not live
return
})
})
} }
public dead(forceReason?) { public dead(forceReason?: string): boolean {
let errMsg log.verbose('PuppetWebBrowser', 'dead(%s)', forceReason ? forceReason : '')
let msg
let dead = false let dead = false
if (forceReason) { if (forceReason) {
dead = true dead = true
errMsg = forceReason msg = forceReason
// } else if (!this.live) {
} else if (this.targetState() !== 'open') { } else if (this.targetState() !== 'open') {
dead = true dead = true
// errMsg = 'browser not live' msg = 'targetState not open'
errMsg = 'targetState not open'
} else if (!this.driver || !this.driver.getSession()) { } else if (!this.driver || !this.driver.getSession()) {
dead = true dead = true
errMsg = 'no driver or session' msg = 'no driver or session'
} }
if (dead) { if (dead) {
log.warn('PuppetWebBrowser', 'dead() because %s', errMsg) log.warn('PuppetWebBrowser', 'dead() because %s', msg)
// this.live = false
this.currentState('closing') this.currentState('closing')
this.quit().then(_ => this.currentState('close')) this.restart().then(_ => this.currentState('close'))
// must use nextTick here, or promise will hang... 2016/6/10 // must use nextTick here, or promise will hang... 2016/6/10
process.nextTick(_ => { setImmediate(_ => {
log.verbose('PuppetWebBrowser', 'dead() emit a `dead` event because %s', errMsg) log.verbose('PuppetWebBrowser', 'dead() emit a `dead` event because %s', msg)
this.emit('dead', errMsg) this.emit('dead', msg)
}) })
} }
return dead return dead
......
...@@ -47,7 +47,7 @@ const PuppetWebEvent = { ...@@ -47,7 +47,7 @@ const PuppetWebEvent = {
, onServerMessage , onServerMessage
} }
async function onBrowserDead(e): Promise<void> { async function onBrowserDead(this: PuppetWeb, e): Promise<void> {
log.verbose('PuppetWebEvent', 'onBrowserDead(%s)', e && e.message || e) log.verbose('PuppetWebEvent', 'onBrowserDead(%s)', e && e.message || e)
// because this function is async, so maybe entry more than one times. // because this function is async, so maybe entry more than one times.
// guard by variable: isBrowserBirthing to prevent the 2nd time entrance. // guard by variable: isBrowserBirthing to prevent the 2nd time entrance.
...@@ -88,9 +88,9 @@ async function onBrowserDead(e): Promise<void> { ...@@ -88,9 +88,9 @@ async function onBrowserDead(e): Promise<void> {
log.verbose('PuppetWebEvent', 'onBrowserDead() try to reborn browser') log.verbose('PuppetWebEvent', 'onBrowserDead() try to reborn browser')
await this.browser.quit(true) await this.browser.restart()
.catch(error => { // fail safe .catch((err: Error) => { // fail safe
log.warn('PuppetWebEvent', 'browser.quit() exception: %s, %s', error.message, error.stack) log.warn('PuppetWebEvent', 'browser.quit() exception: %s', err.stack)
}) })
log.verbose('PuppetWebEvent', 'onBrowserDead() old browser quited') log.verbose('PuppetWebEvent', 'onBrowserDead() old browser quited')
...@@ -135,7 +135,7 @@ async function onBrowserDead(e): Promise<void> { ...@@ -135,7 +135,7 @@ async function onBrowserDead(e): Promise<void> {
return return
} }
function onServerDing(data) { function onServerDing(this: PuppetWeb, data) {
log.silly('PuppetWebEvent', 'onServerDing(%s)', data) log.silly('PuppetWebEvent', 'onServerDing(%s)', data)
// this.watchDog(data) // this.watchDog(data)
this.emit('watchdog', { data }) this.emit('watchdog', { data })
...@@ -172,8 +172,8 @@ function onServerConnection(data) { ...@@ -172,8 +172,8 @@ function onServerConnection(data) {
log.verbose('PuppetWebEvent', 'onServerConnection: %s', data) log.verbose('PuppetWebEvent', 'onServerConnection: %s', data)
} }
function onServerDisconnect(data) { async function onServerDisconnect(this: PuppetWeb, data): Promise<void> {
log.verbose('PuppetWebEvent', 'onServerDisconnect: %s', data) log.verbose('PuppetWebEvent', 'onServerDisconnect(%s)', data)
if (this.userId) { if (this.userId) {
log.verbose('PuppetWebEvent', 'onServerDisconnect() there has userId set. emit a logout event and set userId to null') log.verbose('PuppetWebEvent', 'onServerDisconnect() there has userId set. emit a logout event and set userId to null')
...@@ -206,31 +206,33 @@ function onServerDisconnect(data) { ...@@ -206,31 +206,33 @@ function onServerDisconnect(data) {
return return
} }
this.browser.readyLive() const live = await this.browser.readyLive()
.then(r => { // browser is alive, and we have a bridge to it
log.verbose('PuppetWebEvent', 'onServerDisconnect() re-initing bridge') if (!live) { // browser is in indeed dead, or almost dead. readyLive() will auto recover itself.
// must use setTimeout to wait a while. log.verbose('PuppetWebEvent', 'onServerDisconnect() browser dead after readyLive() check. waiting it recover itself')
// because the browser has just refreshed, need some time to re-init to be ready.
// if the browser is not ready, bridge init will fail,
// caused browser dead and have to be restarted. 2016/6/12
setTimeout(_ => {
if (!this.bridge) {
// XXX: sometimes this.bridge gone in this timeout. why?
// what's happend between the last if(!this.bridge) check and the timeout call?
throw new Error('bridge gone after setTimeout? why???')
}
this.bridge.init()
.then(ret => {
log.verbose('PuppetWebEvent', 'onServerDisconnect() bridge re-inited: %s', ret)
})
.catch(e => log.error('PuppetWebEvent', 'onServerDisconnect() exception: [%s]', e))
}, 1000) // 1 second instead of 10 seconds? try. (should be enough to wait)
return
})
.catch(e => { // browser is in indeed dead, or almost dead. readyLive() will auto recover itself.
log.verbose('PuppetWebEvent', 'onServerDisconnect() browser dead, waiting it recover itself: %s', e.message)
return return
}) }
// browser is alive, and we have a bridge to it
log.verbose('PuppetWebEvent', 'onServerDisconnect() re-initing bridge')
// must use setTimeout to wait a while.
// because the browser has just refreshed, need some time to re-init to be ready.
// if the browser is not ready, bridge init will fail,
// caused browser dead and have to be restarted. 2016/6/12
setTimeout(_ => {
if (!this.bridge) {
// XXX: sometimes this.bridge gone in this timeout. why?
// what's happend between the last if(!this.bridge) check and the timeout call?
const e = new Error('bridge gone after setTimeout? why???')
log.warn('PuppetWebEvent', 'onServerDisconnect() setTimeout() %s', e.message)
throw e
}
this.bridge.init()
.then(ret => log.verbose('PuppetWebEvent', 'onServerDisconnect() setTimeout() bridge re-inited: %s', ret))
.catch(e => log.error('PuppetWebEvent', 'onServerDisconnect() setTimeout() exception: [%s]', e))
}, 1000) // 1 second instead of 10 seconds? try. (should be enough to wait)
return
} }
/** /**
...@@ -246,7 +248,7 @@ function onServerDisconnect(data) { ...@@ -246,7 +248,7 @@ function onServerDisconnect(data) {
* 3. browser quit(crash?) * 3. browser quit(crash?)
* 4. ... * 4. ...
*/ */
function onServerUnload(data) { function onServerUnload(this: PuppetWeb, data) {
log.warn('PuppetWebEvent', 'onServerUnload(%s)', data) log.warn('PuppetWebEvent', 'onServerUnload(%s)', data)
// onServerLogout.call(this, data) // XXX: should emit event[logout] from browser // onServerLogout.call(this, data) // XXX: should emit event[logout] from browser
...@@ -286,7 +288,7 @@ function onServerLog(data) { ...@@ -286,7 +288,7 @@ function onServerLog(data) {
log.silly('PuppetWebEvent', 'onServerLog(%s)', data) log.silly('PuppetWebEvent', 'onServerLog(%s)', data)
} }
async function onServerLogin(data, attempt = 0): Promise<void> { async function onServerLogin(this: PuppetWeb, data, attempt = 0): Promise<void> {
log.verbose('PuppetWebEvent', 'onServerLogin(%s, %d)', data, attempt) log.verbose('PuppetWebEvent', 'onServerLogin(%s, %d)', data, attempt)
this.scan = null this.scan = null
...@@ -332,7 +334,7 @@ async function onServerLogin(data, attempt = 0): Promise<void> { ...@@ -332,7 +334,7 @@ async function onServerLogin(data, attempt = 0): Promise<void> {
return return
} }
function onServerLogout(data) { function onServerLogout(this: PuppetWeb, data) {
this.emit('logout', this.user || this.userId) this.emit('logout', this.user || this.userId)
if (!this.user && !this.userId) { if (!this.user && !this.userId) {
...@@ -348,7 +350,7 @@ function onServerLogout(data) { ...@@ -348,7 +350,7 @@ function onServerLogout(data) {
// }) // })
} }
async function onServerMessage(data): Promise<void> { async function onServerMessage(this: PuppetWeb, data): Promise<void> {
let m = new Message(data) let m = new Message(data)
// co.call(this, function* () { // co.call(this, function* () {
......
...@@ -171,7 +171,7 @@ export class PuppetWeb extends Puppet { ...@@ -171,7 +171,7 @@ export class PuppetWeb extends Puppet {
// }) // })
} }
private async initBrowser(): Promise<Browser> { public async initBrowser(): Promise<Browser> {
log.verbose('PuppetWeb', 'initBrowser()') log.verbose('PuppetWeb', 'initBrowser()')
const browser = new Browser({ const browser = new Browser({
head: this.setting.head head: this.setting.head
...@@ -199,7 +199,7 @@ export class PuppetWeb extends Puppet { ...@@ -199,7 +199,7 @@ export class PuppetWeb extends Puppet {
return browser // follow func name meaning return browser // follow func name meaning
} }
private initBridge(): Promise<Bridge> { public initBridge(): Promise<Bridge> {
log.verbose('PuppetWeb', 'initBridge()') log.verbose('PuppetWeb', 'initBridge()')
const bridge = new Bridge( const bridge = new Bridge(
this // use puppet instead of browser, is because browser might change(die) duaring run time this // use puppet instead of browser, is because browser might change(die) duaring run time
...@@ -358,7 +358,7 @@ export class PuppetWeb extends Puppet { ...@@ -358,7 +358,7 @@ export class PuppetWeb extends Puppet {
}) })
} }
public logined() { return !!(this.user) } public logined() { return !!(this.user) }
public ding(data: any): Promise<any> { public ding(data?: any): Promise<any> {
if (!this.bridge) { if (!this.bridge) {
return Promise.reject(new Error('ding fail: no bridge(yet)!')) return Promise.reject(new Error('ding fail: no bridge(yet)!'))
} }
......
...@@ -130,7 +130,7 @@ class Server extends EventEmitter { ...@@ -130,7 +130,7 @@ class Server extends EventEmitter {
this.emit('connection', client) this.emit('connection', client)
client.on('disconnect', e => { client.on('disconnect', e => {
log.silly('PuppetWebServer', 'socket.io disconnect: %s', e) log.silly('PuppetWebServer', 'initEventsFromClient() on(discohnnect) socket.io disconnect: %s', e)
// 1. Browser reload / 2. Lost connection(Bad network) // 1. Browser reload / 2. Lost connection(Bad network)
this.socketClient = undefined this.socketClient = undefined
this.emit('disconnect', e) this.emit('disconnect', e)
...@@ -138,7 +138,7 @@ class Server extends EventEmitter { ...@@ -138,7 +138,7 @@ class Server extends EventEmitter {
client.on('error' , e => { client.on('error' , e => {
// log.error('PuppetWebServer', 'initEventsFromClient() client on error: %s', e) // log.error('PuppetWebServer', 'initEventsFromClient() client on error: %s', e)
log.error('PuppetWebServer', 'initEventsFromClient() client on error: %s', e.stack) log.error('PuppetWebServer', 'initEventsFromClient() on(error): %s', e.stack)
}) })
// Events from Wechaty@Broswer --to--> Server // Events from Wechaty@Broswer --to--> Server
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
* *
* Helper Class for Manage State Change * Helper Class for Manage State Change
*/ */
import { log } from './config'
/** /**
* A - State A * A - State A
...@@ -21,7 +22,9 @@ export class StateMonitor <A, B>{ ...@@ -21,7 +22,9 @@ export class StateMonitor <A, B>{
private _current: A|B private _current: A|B
private _stable: boolean private _stable: boolean
constructor(initState: A|B) { constructor(private client: string, initState: A|B) {
log.verbose('StateMonitor', 'constructor(%s, %s)', client, initState)
this.target(initState) this.target(initState)
this.current(initState) this.current(initState)
this.stable(true) this.stable(true)
...@@ -29,22 +32,42 @@ export class StateMonitor <A, B>{ ...@@ -29,22 +32,42 @@ export class StateMonitor <A, B>{
public target(newState?: A|B): A|B { public target(newState?: A|B): A|B {
if (newState) { if (newState) {
log.verbose('StateMonitor', 'target(%s) %s state change from %s to %s'
, this.client, newState
, this._target, newState
)
this._target = newState this._target = newState
} else {
log.verbose('StateMonitor', 'target() %s state is %s', this.client, this._target)
} }
return this._target return this._target
} }
public current(newState?: A|B, stable = true): A|B { public current(newState?: A|B, stable = true): A|B {
if (newState) { if (newState) {
log.verbose('StateMonitor', 'current(%s, %s) %s state change from %s:%s to %s:%s'
, newState, stable
, this.client
, this._current, this._stable
, newState, stable
)
this._current = newState this._current = newState
this.stable(stable) this._stable = stable
} else {
log.verbose('StateMonitor', 'current() %s state is %s', this.client, this._current)
} }
return this._current return this._current
} }
public stable(isStable?: boolean) { public stable(stable?: boolean) {
if (typeof isStable === 'boolean') { if (typeof stable === 'boolean') {
this._stable = isStable log.verbose('StateMonitor', 'stable(%s) %s state change from %s to %s'
, stable
, this.client
, this._stable, stable)
this._stable = stable
} else {
log.verbose('StateMonitor', 'stable() %s state is %s', this.client, this._stable)
} }
return this._stable return this._stable
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册