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

Refactored PuppetAccessory to add `wechaty` property

上级 4df22d6d
......@@ -25,16 +25,18 @@ import {
cloneClass,
} from 'clone-class'
import PuppetAccessory from './puppet-accessory'
import {
Accessory,
} from './accessory'
import { Puppet } from './puppet/'
const EXPECTED_PUPPET1 = {p: 1} as any as Puppet
const EXPECTED_PUPPET2 = {p: 2} as any as Puppet
test('PuppetAccessory smoke testing', async t => {
test('Accessory smoke testing', async t => {
class FixtureClass extends PuppetAccessory {}
class FixtureClass extends Accessory {}
t.throws(() => FixtureClass.puppet, 'should throw if read static puppet before initialize')
......@@ -45,14 +47,14 @@ test('PuppetAccessory smoke testing', async t => {
t.equal(FixtureClass.puppet, EXPECTED_PUPPET1, 'should get EXPECTED_PUPPET1 from static puppet after set static puppet')
t.equal(c.puppet, EXPECTED_PUPPET1, 'should get EXPECTED_PUPPET1 from instance puppet after set static puppet')
c.puppet = EXPECTED_PUPPET2
t.equal(FixtureClass.puppet, EXPECTED_PUPPET1, 'should get EXPECTED_PUPPET1 from static puppet after set instance puppet to EXPECTED_PUPPET2')
t.equal(c.puppet, EXPECTED_PUPPET2, 'should get EXPECTED_PUPPET2 from instance puppet after set instance puppet to EXPECTED_PUPPET2')
// c.puppet = EXPECTED_PUPPET2
// t.equal(FixtureClass.puppet, EXPECTED_PUPPET1, 'should get EXPECTED_PUPPET1 from static puppet after set instance puppet to EXPECTED_PUPPET2')
// t.equal(c.puppet, EXPECTED_PUPPET2, 'should get EXPECTED_PUPPET2 from instance puppet after set instance puppet to EXPECTED_PUPPET2')
})
test('Two clone-ed classes', async t => {
class FixtureClass extends PuppetAccessory {}
class FixtureClass extends Accessory {}
// tslint:disable-next-line:variable-name
const ClonedClass1 = cloneClass(FixtureClass)
......
......@@ -4,6 +4,7 @@ import { instanceToClass } from 'clone-class'
import { log } from './config'
import { Wechaty } from './wechaty'
import { Puppet } from './puppet/'
// use Symbol to prevent conflicting with the child class properties
......@@ -14,7 +15,7 @@ export const SYMBOL_COUNTER = Symbol('counter')
let COUNTER = 0
export abstract class PuppetAccessory extends EventEmitter {
export abstract class Accessory extends EventEmitter {
// Not work???
// private static readonly PUPPET_ACCESSORY_NAME = Symbol('name')
......@@ -26,18 +27,23 @@ export abstract class PuppetAccessory extends EventEmitter {
* 1. Static Properties & Methods
*
*/
private static _puppet?: Puppet
private static _puppet? : Puppet
private static _wechaty? : Wechaty
public static set puppet(puppet: Puppet) {
log.silly('PuppetAccessory', '<%s> static set puppet(%s)',
log.silly('Accessory', '<%s> static set puppet(%s)',
this.name,
puppet,
)
if (this._puppet) {
throw new Error('puppet can not be set twice!')
}
this._puppet = puppet
}
public static get puppet(): Puppet {
log.silly('PuppetAccessory', '<%s> static get puppet()',
log.silly('Accessory', '<%s> static get puppet()',
this.name,
)
......@@ -50,37 +56,79 @@ export abstract class PuppetAccessory extends EventEmitter {
)
}
public static set wechaty(wechaty: Wechaty) {
log.silly('Accessory', '<%s> static set wechaty(%s)',
this.name,
wechaty,
)
this._wechaty = wechaty
}
public static get wechaty(): Wechaty {
log.silly('Accessory', '<%s> static get wechaty()',
this.name,
)
if (this._wechaty) {
return this._wechaty
}
throw new Error('static wechaty not found for '
+ this.name,
)
}
/**
*
* 2. Instance Properties & Methods
*
*/
private _puppet?: Puppet
public set puppet(puppet: Puppet) {
log.silly('PuppetAccessory', '<%s> set puppet(%s)',
log.silly('Accessory', '<%s> set puppet(%s)',
this[SYMBOL_NAME] || this,
puppet,
)
this._puppet = puppet
instanceToClass(this, Accessory).puppet = puppet
}
public get puppet(): Puppet {
log.silly('PuppetAccessory', '#%d<%s> get puppet()',
log.silly('Accessory', '#%d<%s> get puppet()',
this[SYMBOL_COUNTER],
this[SYMBOL_NAME] || this,
)
if (this._puppet) {
return this._puppet
}
// if (this._puppet) {
// return this._puppet
// }
/**
* Get `puppet` from Class Static puppet property
* note: use `instanceToClass` at here is because
* we might have many copy/child of `Accessory` Classes
*/
return instanceToClass(this, Accessory).puppet
}
public set wechaty(wechaty: Wechaty) {
log.silly('Accessory', '<%s> set wechaty(%s)',
this[SYMBOL_NAME] || this,
wechaty,
)
instanceToClass(this, Accessory).wechaty = wechaty
}
public get wechaty(): Wechaty {
log.silly('Accessory', '#%d<%s> get wechaty()',
this[SYMBOL_COUNTER],
this[SYMBOL_NAME] || this,
)
/**
* Get `puppet` from Class Static puppet property
* note: use `instanceToClass` at here is because
* we might have many copy/child of `PuppetAccessory` Classes
* we might have many copy/child of `Accessory` Classes
*/
return instanceToClass(this, PuppetAccessory).puppet
return instanceToClass(this, Accessory).wechaty
}
constructor(
......@@ -91,7 +139,7 @@ export abstract class PuppetAccessory extends EventEmitter {
this[SYMBOL_NAME] = name || this.toString()
this[SYMBOL_COUNTER] = COUNTER++
log.silly('PuppetAccessory', '#%d<%s> constructor(%s)',
log.silly('Accessory', '#%d<%s> constructor(%s)',
this[SYMBOL_COUNTER],
this[SYMBOL_NAME],
name || '',
......@@ -100,4 +148,4 @@ export abstract class PuppetAccessory extends EventEmitter {
}
export default PuppetAccessory
export default Accessory
......@@ -24,8 +24,10 @@ import {
log,
Raven,
Sayable,
} from './config'
import { PuppetAccessory } from './puppet-accessory'
} from './config'
import {
Accessory,
} from './accessory'
// import Message from './message'
......@@ -78,7 +80,7 @@ export const POOL = Symbol('pool')
* `Contact` is `Sayable`,
* [Examples/Contact-Bot]{@link https://github.com/Chatie/wechaty/blob/master/examples/contact-bot.ts}
*/
export class Contact extends PuppetAccessory implements Sayable {
export class Contact extends Accessory implements Sayable {
// tslint:disable-next-line:variable-name
public static Type = ContactType
......
......@@ -29,11 +29,17 @@ import {
import {
log,
Sayable,
} from './config'
import PuppetAccessory from './puppet-accessory'
} from './config'
import {
Accessory,
} from './accessory'
import Contact from './contact'
import Room from './room'
import {
Contact,
} from './contact'
import {
Room,
} from './room'
export enum MessageType {
Unknown = 0,
......@@ -66,7 +72,7 @@ export interface MessagePayload {
* `Message` is `Sayable`,
* [Examples/Ding-Dong-Bot]{@link https://github.com/Chatie/wechaty/blob/master/examples/ding-dong-bot.ts}
*/
export class Message extends PuppetAccessory implements Sayable {
export class Message extends Accessory implements Sayable {
/**
*
......@@ -208,7 +214,7 @@ export class Message extends PuppetAccessory implements Sayable {
throw new Error('no from')
}
const from = this.puppet.Contact.load(fromId)
const from = this.wechaty.Contact.load(fromId)
return from
}
......@@ -227,7 +233,7 @@ export class Message extends PuppetAccessory implements Sayable {
return null
}
const to = this.puppet.Contact.load(toId)
const to = this.wechaty.Contact.load(toId)
return to
}
......@@ -246,7 +252,7 @@ export class Message extends PuppetAccessory implements Sayable {
return null
}
const room = this.puppet.Room.load(roomId)
const room = this.wechaty.Room.load(roomId)
return room
}
......@@ -538,13 +544,13 @@ export class Message extends PuppetAccessory implements Sayable {
const toId = this.payload.toId
if (fromId) {
await this.puppet.Contact.load(fromId).ready()
await this.wechaty.Contact.load(fromId).ready()
}
if (roomId) {
await this.puppet.Room.load(roomId).ready()
await this.wechaty.Room.load(roomId).ready()
}
if (toId) {
await this.puppet.Contact.load(toId).ready()
await this.wechaty.Contact.load(toId).ready()
}
}
......
......@@ -32,9 +32,13 @@ import {
Sayable,
log,
} from './config'
import { PuppetAccessory } from './puppet-accessory'
import {
Accessory,
} from './accessory'
import { Contact } from './contact'
import {
Contact,
} from './contact'
// import Message from './message'
export const ROOM_EVENT_DICT = {
......@@ -71,7 +75,7 @@ export interface RoomPayload {
* `Room` is `Sayable`,
* [Examples/Room-Bot]{@link https://github.com/Chatie/wechaty/blob/master/examples/room-bot.ts}
*/
export class Room extends PuppetAccessory implements Sayable {
export class Room extends Accessory implements Sayable {
protected static pool: Map<string, Room>
......@@ -245,17 +249,19 @@ export class Room extends PuppetAccessory implements Sayable {
/**
* @private
*/
public async ready(): Promise<void> {
public async ready(
noCache = false,
): Promise<void> {
log.verbose('Room', 'ready()')
if (this.isReady()) {
if (!noCache && this.isReady()) {
return
}
const payload = await this.puppet.roomPayload(this.id)
const payload = await this.puppet.roomPayload(this.id, noCache)
await Promise.all(
payload.memberIdList
.map(id => this.puppet.Contact.load(id))
.map(id => this.wechaty.Contact.load(id))
.map(contact => contact.ready()),
)
// log.silly('Room', 'ready() this.payload="%s"',
......@@ -674,7 +680,7 @@ export class Room extends PuppetAccessory implements Sayable {
log.silly('Room', 'memberAll() check %s from %s: %s', filterValue, filterKey, JSON.stringify(filterMap))
if (idList.length) {
return idList.map(id => this.puppet.Contact.load(id))
return idList.map(id => this.wechaty.Contact.load(id))
} else {
return []
}
......@@ -751,7 +757,7 @@ export class Room extends PuppetAccessory implements Sayable {
})
return []
}
const memberList = this.payload.memberIdList.map(id => this.puppet.Contact.load(id))
const memberList = this.payload.memberIdList.map(id => this.wechaty.Contact.load(id))
return memberList
}
......@@ -793,7 +799,7 @@ export class Room extends PuppetAccessory implements Sayable {
return null
}
const owner = this.puppet.Contact.load(ownerId)
const owner = this.wechaty.Contact.load(ownerId)
return owner
}
......
......@@ -32,6 +32,9 @@ import {
} from 'hot-import'
import StateSwitch from 'state-switch'
import {
Accessory,
} from './accessory'
import {
VERSION,
config,
......@@ -40,11 +43,14 @@ import {
Sayable,
} from './config'
import Profile from './profile'
import PuppetAccessory from './puppet-accessory'
import {
PUPPET_DICT,
PuppetName,
} from './puppet-config'
import {
Puppet, PuppetOptions,
} from './puppet/'
import {
Contact,
......@@ -58,9 +64,6 @@ import {
import {
Room,
} from './room'
import {
Puppet,
} from './puppet/'
export const WECHAT_EVENT_DICT = {
friend : 'tbw',
......@@ -99,7 +102,7 @@ export interface WechatyOptions {
* import { Wechaty } from 'wechaty'
*
*/
export class Wechaty extends PuppetAccessory implements Sayable {
export class Wechaty extends Accessory implements Sayable {
/**
* singleton globalInstance
* @private
......@@ -118,7 +121,7 @@ export class Wechaty extends PuppetAccessory implements Sayable {
* the cuid
* @private
*/
public readonly cuid : string
public readonly id : string
// tslint:disable-next-line:variable-name
public readonly Contact : typeof Contact
......@@ -168,7 +171,7 @@ export class Wechaty extends PuppetAccessory implements Sayable {
this.profile = new Profile(options.profile)
this.cuid = cuid()
this.id = cuid()
/**
* Clone Classes for this bot and attach the `puppet` to the Class
......@@ -193,7 +196,8 @@ export class Wechaty extends PuppetAccessory implements Sayable {
}
return [
'Wechaty',
'Wechaty#',
this.id,
`<${this.options && this.options.puppet || ''}>`,
`(${this.profile && this.profile.name || ''})`,
].join('')
......@@ -375,14 +379,14 @@ export class Wechaty extends PuppetAccessory implements Sayable {
)
if (typeof listener === 'function') {
this.onFunction(event, listener)
this.addListenerFunction(event, listener)
} else {
this.onModulePath(event, listener)
this.addListenerModuleFile(event, listener)
}
return this
}
private onModulePath(event: WechatyEventName, modulePath: string): void {
private addListenerModuleFile(event: WechatyEventName, modulePath: string): void {
const absoluteFilename = callerResolve(modulePath, __filename)
log.verbose('Wechaty', 'onModulePath() hotImpor(%s)', absoluteFilename)
hotImport(absoluteFilename)
......@@ -402,7 +406,7 @@ export class Wechaty extends PuppetAccessory implements Sayable {
})
}
private onFunction(event: WechatyEventName, listener: Function): void {
private addListenerFunction(event: WechatyEventName, listener: Function): void {
log.verbose('Wechaty', 'onFunction(%s)', event)
super.on(event, (...args: any[]) => {
......@@ -423,23 +427,23 @@ export class Wechaty extends PuppetAccessory implements Sayable {
* When we declare a wechaty without a puppet instance,
* the wechaty need to attach to puppet at here.
*/
public attach(puppet: Puppet) {
log.verbose('Wechaty', 'attach(%s) this.options.puppet="%s"',
puppet,
this.options.puppet && this.options.puppet.toString() || '',
)
if (this.options.puppet instanceof Puppet) {
if (this.options.puppet === puppet) {
log.silly('Wechaty', 'attach(%s) called again', puppet)
return
} else {
throw new Error('puppet can only be attached once!')
}
}
this.options.puppet = puppet
}
// public attach(puppet: Puppet) {
// log.verbose('Wechaty', 'attach(%s) this.options.puppet="%s"',
// puppet,
// this.options.puppet && this.options.puppet.toString() || '',
// )
// if (this.options.puppet instanceof Puppet) {
// if (this.options.puppet === puppet) {
// log.silly('Wechaty', 'attach(%s) called again', puppet)
// return
// } else {
// throw new Error('puppet can only be attached once!')
// }
// }
// this.options.puppet = puppet
// }
/**
* @private
......@@ -480,9 +484,9 @@ export class Wechaty extends PuppetAccessory implements Sayable {
throw new Error('no such puppet: ' + puppet)
}
const options = {
profile: this.profile,
wechaty: this,
const options: PuppetOptions = {
profile : this.profile,
// wechaty: this,
}
return new MyPuppet(options)
......@@ -652,7 +656,13 @@ export class Wechaty extends PuppetAccessory implements Sayable {
this.Message.puppet = puppet
this.Room.puppet = puppet
this.puppet = puppet
this.Contact.wechaty = this
this.FriendRequest.wechaty = this
this.Message.wechaty = this
this.Room.wechaty = this
this.puppet = puppet
this.wechaty = this
}
/**
......@@ -667,7 +677,7 @@ export class Wechaty extends PuppetAccessory implements Sayable {
log.info('Wechaty', 'v%s starting...' , this.version())
log.verbose('Wechaty', 'puppet: %s' , this.options.puppet)
log.verbose('Wechaty', 'profile: %s' , this.options.profile)
log.verbose('Wechaty', 'cuid: %s' , this.cuid)
log.verbose('Wechaty', 'id: %s' , this.id)
if (this.state.on()) {
log.silly('Wechaty', 'start() on a starting/started instance')
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册