@juzi/wechaty 1.0.60 → 1.0.62
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/src/package-json.d.ts.map +1 -1
- package/dist/cjs/src/package-json.js +3 -2
- package/dist/cjs/src/package-json.js.map +1 -1
- package/dist/cjs/src/user-modules/room.d.ts.map +1 -1
- package/dist/cjs/src/user-modules/room.js +1 -0
- package/dist/cjs/src/user-modules/room.js.map +1 -1
- package/dist/cjs/src/wechaty/wechaty-base.d.ts +31 -0
- package/dist/cjs/src/wechaty/wechaty-base.d.ts.map +1 -1
- package/dist/cjs/src/wechaty/wechaty-base.spec.js +75 -2
- package/dist/cjs/src/wechaty/wechaty-base.spec.js.map +1 -1
- package/dist/cjs/src/wechaty-mixins/login-mixin.d.ts +4 -0
- package/dist/cjs/src/wechaty-mixins/login-mixin.d.ts.map +1 -1
- package/dist/cjs/src/wechaty-mixins/misc-mixin.d.ts +4 -0
- package/dist/cjs/src/wechaty-mixins/misc-mixin.d.ts.map +1 -1
- package/dist/cjs/src/wechaty-mixins/plugin-mixin.d.ts +6 -0
- package/dist/cjs/src/wechaty-mixins/plugin-mixin.d.ts.map +1 -1
- package/dist/cjs/src/wechaty-mixins/puppet-mixin.d.ts +12 -12
- package/dist/cjs/src/wechaty-mixins/puppet-mixin.d.ts.map +1 -1
- package/dist/cjs/src/wechaty-mixins/puppet-mixin.js +49 -3
- package/dist/cjs/src/wechaty-mixins/puppet-mixin.js.map +1 -1
- package/dist/esm/src/package-json.d.ts.map +1 -1
- package/dist/esm/src/package-json.js +3 -2
- package/dist/esm/src/package-json.js.map +1 -1
- package/dist/esm/src/user-modules/room.d.ts.map +1 -1
- package/dist/esm/src/user-modules/room.js +1 -0
- package/dist/esm/src/user-modules/room.js.map +1 -1
- package/dist/esm/src/wechaty/wechaty-base.d.ts +31 -0
- package/dist/esm/src/wechaty/wechaty-base.d.ts.map +1 -1
- package/dist/esm/src/wechaty/wechaty-base.spec.js +75 -2
- package/dist/esm/src/wechaty/wechaty-base.spec.js.map +1 -1
- package/dist/esm/src/wechaty-mixins/login-mixin.d.ts +4 -0
- package/dist/esm/src/wechaty-mixins/login-mixin.d.ts.map +1 -1
- package/dist/esm/src/wechaty-mixins/misc-mixin.d.ts +4 -0
- package/dist/esm/src/wechaty-mixins/misc-mixin.d.ts.map +1 -1
- package/dist/esm/src/wechaty-mixins/plugin-mixin.d.ts +6 -0
- package/dist/esm/src/wechaty-mixins/plugin-mixin.d.ts.map +1 -1
- package/dist/esm/src/wechaty-mixins/puppet-mixin.d.ts +12 -12
- package/dist/esm/src/wechaty-mixins/puppet-mixin.d.ts.map +1 -1
- package/dist/esm/src/wechaty-mixins/puppet-mixin.js +50 -4
- package/dist/esm/src/wechaty-mixins/puppet-mixin.js.map +1 -1
- package/package.json +2 -1
- package/src/package-json.ts +3 -2
- package/src/user-modules/room.ts +1 -0
- package/src/wechaty/wechaty-base.spec.ts +96 -3
- package/src/wechaty-mixins/puppet-mixin.ts +60 -6
|
@@ -50,6 +50,7 @@ import type {
|
|
|
50
50
|
WechatyInterface,
|
|
51
51
|
} from '../wechaty/wechaty-impl.js'
|
|
52
52
|
import { WechatySkeleton } from './wechaty-skeleton.js'
|
|
53
|
+
import { WechatyBuilder } from '../mods/mod.js'
|
|
53
54
|
|
|
54
55
|
class WechatyTest extends WechatyBase {
|
|
55
56
|
}
|
|
@@ -246,21 +247,30 @@ test('@event ready', async t => {
|
|
|
246
247
|
const sandbox = sinon.createSandbox()
|
|
247
248
|
const spy = sandbox.spy()
|
|
248
249
|
|
|
250
|
+
const mockContact = puppet.mocker.createContact({ name: 'any' })
|
|
251
|
+
|
|
249
252
|
wechaty.on('ready', spy)
|
|
250
253
|
t.ok(spy.notCalled, 'should no ready event with new wechaty instance')
|
|
251
254
|
|
|
252
255
|
await wechaty.start()
|
|
253
256
|
t.ok(spy.notCalled, 'should no ready event right start wechaty started')
|
|
254
257
|
|
|
258
|
+
await puppet.mocker.login(mockContact)
|
|
255
259
|
puppet.emit('ready', { data: 'test' })
|
|
260
|
+
await new Promise(resolve => {
|
|
261
|
+
setTimeout(resolve, 16 * 1000)
|
|
262
|
+
})
|
|
256
263
|
t.equal(spy.callCount, 1, 'should fire ready event after puppet ready')
|
|
257
264
|
|
|
258
265
|
await wechaty.stop()
|
|
259
266
|
await wechaty.start()
|
|
260
267
|
t.equal(spy.callCount, 1, 'should fire ready event second time after stop/start wechaty')
|
|
261
268
|
|
|
269
|
+
await puppet.mocker.login(mockContact)
|
|
262
270
|
puppet.emit('ready', { data: 'test' })
|
|
263
|
-
|
|
271
|
+
await new Promise(resolve => {
|
|
272
|
+
setTimeout(resolve, 16 * 1000)
|
|
273
|
+
})
|
|
264
274
|
t.equal(spy.callCount, 2, 'should fire ready event third time after stop/start wechaty')
|
|
265
275
|
|
|
266
276
|
await wechaty.stop()
|
|
@@ -274,6 +284,8 @@ test('ready()', async t => {
|
|
|
274
284
|
|
|
275
285
|
const spy = sandbox.spy()
|
|
276
286
|
|
|
287
|
+
const mockContact = puppet.mocker.createContact({ name: 'any' })
|
|
288
|
+
|
|
277
289
|
wechaty.ready()
|
|
278
290
|
.then(spy)
|
|
279
291
|
.catch(e => t.fail('rejection: ' + e))
|
|
@@ -284,8 +296,11 @@ test('ready()', async t => {
|
|
|
284
296
|
|
|
285
297
|
t.ok(spy.notCalled, 'should not ready after right start wechaty')
|
|
286
298
|
|
|
299
|
+
await puppet.mocker.login(mockContact)
|
|
287
300
|
puppet.emit('ready', { data: 'test' })
|
|
288
|
-
await new Promise(resolve =>
|
|
301
|
+
await new Promise(resolve => {
|
|
302
|
+
setTimeout(resolve, 16 * 1000)
|
|
303
|
+
})
|
|
289
304
|
t.ok(spy.calledOnce, 'should ready after puppet ready')
|
|
290
305
|
|
|
291
306
|
await wechaty.stop()
|
|
@@ -294,8 +309,11 @@ test('ready()', async t => {
|
|
|
294
309
|
.then(spy)
|
|
295
310
|
.catch(e => t.fail('rejection: ' + e))
|
|
296
311
|
|
|
312
|
+
await puppet.mocker.login(mockContact)
|
|
297
313
|
puppet.emit('ready', { data: 'test' })
|
|
298
|
-
await new Promise(resolve =>
|
|
314
|
+
await new Promise(resolve => {
|
|
315
|
+
setTimeout(resolve, 16 * 1000)
|
|
316
|
+
})
|
|
299
317
|
t.ok(spy.calledTwice, 'should ready again after stop/start wechaty')
|
|
300
318
|
|
|
301
319
|
await wechaty.stop()
|
|
@@ -390,3 +408,78 @@ test('WechatySkeleton: super.{start,stop}()', async t => {
|
|
|
390
408
|
t.ok(startStub.calledOnce, 'should only call start once')
|
|
391
409
|
t.ok(stopStub.calledOnce, 'should call the skeleton stop(), which means all mixin stops()s are chained correctly')
|
|
392
410
|
})
|
|
411
|
+
|
|
412
|
+
test('ReadyDelay', async t => {
|
|
413
|
+
|
|
414
|
+
const puppet = new PuppetMock() as any
|
|
415
|
+
const wechaty = WechatyBuilder.build({ puppet })
|
|
416
|
+
|
|
417
|
+
const mockContact = puppet.mocker.createContact({ name: 'any' })
|
|
418
|
+
|
|
419
|
+
await wechaty.start()
|
|
420
|
+
|
|
421
|
+
let loginCalled = false
|
|
422
|
+
wechaty.on('login', () => {
|
|
423
|
+
loginCalled = true
|
|
424
|
+
})
|
|
425
|
+
|
|
426
|
+
const future = new Promise<void>(resolve => {
|
|
427
|
+
wechaty.on('ready', () => {
|
|
428
|
+
if (loginCalled) {
|
|
429
|
+
t.pass('ready emitted after login')
|
|
430
|
+
} else {
|
|
431
|
+
t.fail('ready emitted before login')
|
|
432
|
+
}
|
|
433
|
+
resolve()
|
|
434
|
+
})
|
|
435
|
+
})
|
|
436
|
+
|
|
437
|
+
puppet.emit('ready')
|
|
438
|
+
await puppet.mocker.login(mockContact)
|
|
439
|
+
|
|
440
|
+
await future
|
|
441
|
+
await wechaty.stop()
|
|
442
|
+
})
|
|
443
|
+
|
|
444
|
+
test('ReadyMeetsLogout', async t => {
|
|
445
|
+
const puppet = new PuppetMock() as any
|
|
446
|
+
const wechaty = WechatyBuilder.build({ puppet })
|
|
447
|
+
|
|
448
|
+
const mockContact = puppet.mocker.createContact({ name: 'any' })
|
|
449
|
+
|
|
450
|
+
await wechaty.start()
|
|
451
|
+
await puppet.mocker.login(mockContact)
|
|
452
|
+
|
|
453
|
+
let readyEmitted = false
|
|
454
|
+
wechaty.on('ready', () => {
|
|
455
|
+
readyEmitted = true
|
|
456
|
+
})
|
|
457
|
+
|
|
458
|
+
puppet.emit('ready')
|
|
459
|
+
await new Promise(resolve => {
|
|
460
|
+
setTimeout(resolve, 5 * 1000)
|
|
461
|
+
})
|
|
462
|
+
|
|
463
|
+
puppet.emit('logout', { contactId: mockContact.id })
|
|
464
|
+
await new Promise(resolve => {
|
|
465
|
+
setTimeout(resolve, 15 * 1000)
|
|
466
|
+
})
|
|
467
|
+
|
|
468
|
+
t.ok(!readyEmitted, 'ready should not be emitted because puppet logout')
|
|
469
|
+
|
|
470
|
+
puppet.emit('login', { contactId: mockContact.id })
|
|
471
|
+
|
|
472
|
+
await new Promise(resolve => {
|
|
473
|
+
setTimeout(resolve, 5 * 1000)
|
|
474
|
+
})
|
|
475
|
+
|
|
476
|
+
t.ok(!readyEmitted, 'ready should not be emitted because it should wait for a new ready')
|
|
477
|
+
|
|
478
|
+
puppet.emit('ready')
|
|
479
|
+
await new Promise(resolve => {
|
|
480
|
+
setTimeout(resolve, 16 * 1000)
|
|
481
|
+
})
|
|
482
|
+
t.ok(readyEmitted, 'ready should be emitted')
|
|
483
|
+
|
|
484
|
+
await wechaty.stop()
|
|
485
|
+
})
|
|
@@ -6,10 +6,11 @@ import {
|
|
|
6
6
|
TimeoutPromiseGError,
|
|
7
7
|
} from 'gerror'
|
|
8
8
|
|
|
9
|
-
import {
|
|
10
|
-
|
|
9
|
+
import {
|
|
10
|
+
StateSwitch,
|
|
11
|
+
BooleanIndicator,
|
|
11
12
|
StateSwitchInterface,
|
|
12
|
-
}
|
|
13
|
+
} from 'state-switch'
|
|
13
14
|
|
|
14
15
|
import { config, PUPPET_PAYLOAD_SYNC_GAP, PUPPET_PAYLOAD_SYNC_MAX_RETRY } from '../config.js'
|
|
15
16
|
import { timestampToDate } from '../pure-functions/timestamp-to-date.js'
|
|
@@ -57,13 +58,18 @@ const puppetMixin = <MixinBase extends WechatifyUserModuleMixin & GErrorMixin &
|
|
|
57
58
|
|
|
58
59
|
readonly __readyState : StateSwitchInterface
|
|
59
60
|
|
|
61
|
+
__loginIndicator: BooleanIndicator
|
|
62
|
+
|
|
60
63
|
__puppetMixinInited = false
|
|
61
64
|
|
|
65
|
+
__offCallbackList: (() => void)[] = []
|
|
66
|
+
|
|
62
67
|
constructor (...args: any[]) {
|
|
63
68
|
log.verbose('WechatyPuppetMixin', 'construct()')
|
|
64
69
|
super(...args)
|
|
65
70
|
|
|
66
71
|
this.__readyState = new StateSwitch('WechatyReady', { log })
|
|
72
|
+
this.__loginIndicator = new BooleanIndicator()
|
|
67
73
|
}
|
|
68
74
|
|
|
69
75
|
override async start (): Promise<void> {
|
|
@@ -111,6 +117,20 @@ const puppetMixin = <MixinBase extends WechatifyUserModuleMixin & GErrorMixin &
|
|
|
111
117
|
} catch (e) {
|
|
112
118
|
this.emitError(e)
|
|
113
119
|
}
|
|
120
|
+
|
|
121
|
+
const loginListener = () => {
|
|
122
|
+
this.__loginIndicator.value(true)
|
|
123
|
+
}
|
|
124
|
+
this.on('login', loginListener)
|
|
125
|
+
const offLoginListener = () => this.off('login', loginListener)
|
|
126
|
+
this.__offCallbackList.push(offLoginListener)
|
|
127
|
+
|
|
128
|
+
const logoutListener = () => {
|
|
129
|
+
this.__loginIndicator.value(false)
|
|
130
|
+
}
|
|
131
|
+
this.on('logout', logoutListener)
|
|
132
|
+
const offLogoutListener = () => this.off('logout', logoutListener)
|
|
133
|
+
this.__offCallbackList.push(offLogoutListener)
|
|
114
134
|
}
|
|
115
135
|
|
|
116
136
|
override async stop (): Promise<void> {
|
|
@@ -134,6 +154,11 @@ const puppetMixin = <MixinBase extends WechatifyUserModuleMixin & GErrorMixin &
|
|
|
134
154
|
log.verbose('WechatyPuppetMixin', 'stop() super.stop() ...')
|
|
135
155
|
await super.stop()
|
|
136
156
|
log.verbose('WechatyPuppetMixin', 'stop() super.stop() ... done')
|
|
157
|
+
|
|
158
|
+
while (this.__offCallbackList.length > 0) {
|
|
159
|
+
const func = this.__offCallbackList.pop()
|
|
160
|
+
func && func()
|
|
161
|
+
}
|
|
137
162
|
}
|
|
138
163
|
|
|
139
164
|
async ready (): Promise<void> {
|
|
@@ -359,11 +384,38 @@ const puppetMixin = <MixinBase extends WechatifyUserModuleMixin & GErrorMixin &
|
|
|
359
384
|
break
|
|
360
385
|
|
|
361
386
|
case 'ready':
|
|
362
|
-
puppet.on('ready', () => {
|
|
387
|
+
puppet.on('ready', async () => {
|
|
363
388
|
log.silly('WechatyPuppetMixin', '__setupPuppetEvents() puppet.on(ready)')
|
|
364
389
|
|
|
365
|
-
|
|
366
|
-
|
|
390
|
+
// ready event should be emitted 15s after login
|
|
391
|
+
let onceLogout: () => void
|
|
392
|
+
let timeout: ReturnType<typeof setTimeout> // 'NodeJS' is not defined.
|
|
393
|
+
const future = new Promise((resolve, reject) => {
|
|
394
|
+
onceLogout = () => {
|
|
395
|
+
reject(new Error('puppet logout!'))
|
|
396
|
+
}
|
|
397
|
+
puppet.once('logout', onceLogout)
|
|
398
|
+
timeout = setTimeout(() => {
|
|
399
|
+
reject(new Error('waiting for login timeout'))
|
|
400
|
+
}, 60 * 1000)
|
|
401
|
+
void this.__loginIndicator.ready(true).then(resolve)
|
|
402
|
+
}).finally(() => {
|
|
403
|
+
puppet.off('logout', onceLogout)
|
|
404
|
+
clearTimeout(timeout)
|
|
405
|
+
})
|
|
406
|
+
|
|
407
|
+
try {
|
|
408
|
+
await future
|
|
409
|
+
await new Promise(resolve => {
|
|
410
|
+
setTimeout(resolve, 15 * 1000)
|
|
411
|
+
})
|
|
412
|
+
if (this.__loginIndicator.value()) {
|
|
413
|
+
this.emit('ready')
|
|
414
|
+
this.__readyState.active(true)
|
|
415
|
+
}
|
|
416
|
+
} catch (e) {
|
|
417
|
+
log.error(`ready ignored: ${(e as Error).message}`)
|
|
418
|
+
}
|
|
367
419
|
})
|
|
368
420
|
break
|
|
369
421
|
|
|
@@ -747,6 +799,8 @@ type ProtectedPropertyPuppetMixin =
|
|
|
747
799
|
| '__puppet'
|
|
748
800
|
| '__readyState'
|
|
749
801
|
| '__setupPuppetEvents'
|
|
802
|
+
| '__loginIndicator'
|
|
803
|
+
| '__offCallbackList'
|
|
750
804
|
|
|
751
805
|
export type {
|
|
752
806
|
PuppetMixin,
|