@juzi/wechaty-puppet-service 1.0.53 → 1.0.54
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/client/grpc-manager.d.ts +2 -2
- package/dist/cjs/src/client/grpc-manager.d.ts.map +1 -1
- package/dist/cjs/src/client/grpc-manager.js +1 -1
- package/dist/cjs/src/client/grpc-manager.js.map +1 -1
- package/dist/cjs/src/client/puppet-service.d.ts +3 -0
- package/dist/cjs/src/client/puppet-service.d.ts.map +1 -1
- package/dist/cjs/src/client/puppet-service.js +86 -0
- package/dist/cjs/src/client/puppet-service.js.map +1 -1
- package/dist/cjs/src/package-json.js +1 -1
- package/dist/cjs/src/server/event-stream-manager.d.ts.map +1 -1
- package/dist/cjs/src/server/event-stream-manager.js +15 -1
- package/dist/cjs/src/server/event-stream-manager.js.map +1 -1
- package/dist/cjs/tests/grpc-stream.spec.js +47 -0
- package/dist/cjs/tests/grpc-stream.spec.js.map +1 -1
- package/dist/esm/src/client/grpc-manager.d.ts +2 -2
- package/dist/esm/src/client/grpc-manager.d.ts.map +1 -1
- package/dist/esm/src/client/grpc-manager.js +1 -1
- package/dist/esm/src/client/grpc-manager.js.map +1 -1
- package/dist/esm/src/client/puppet-service.d.ts +3 -0
- package/dist/esm/src/client/puppet-service.d.ts.map +1 -1
- package/dist/esm/src/client/puppet-service.js +86 -0
- package/dist/esm/src/client/puppet-service.js.map +1 -1
- package/dist/esm/src/package-json.js +1 -1
- package/dist/esm/src/server/event-stream-manager.d.ts.map +1 -1
- package/dist/esm/src/server/event-stream-manager.js +15 -1
- package/dist/esm/src/server/event-stream-manager.js.map +1 -1
- package/dist/esm/tests/grpc-stream.spec.js +47 -0
- package/dist/esm/tests/grpc-stream.spec.js.map +1 -1
- package/package.json +1 -1
- package/src/client/grpc-manager.ts +3 -3
- package/src/client/puppet-service.ts +94 -0
- package/src/package-json.ts +1 -1
- package/src/server/event-stream-manager.ts +15 -1
|
@@ -60,6 +60,7 @@ import { GrpcManager } from './grpc-manager.js'
|
|
|
60
60
|
import { PayloadStore } from './payload-store.js'
|
|
61
61
|
import { channelPayloadToPb, channelPbToPayload, postPayloadToPb, urlLinkPbToPayload } from '../utils/pb-payload-helper.js'
|
|
62
62
|
import type { MessageBroadcastTargets } from '@juzi/wechaty-puppet/dist/esm/src/schemas/message.js'
|
|
63
|
+
import { timeoutPromise } from 'gerror'
|
|
63
64
|
|
|
64
65
|
export type PuppetServiceOptions = PUPPET.PuppetOptions & {
|
|
65
66
|
authority? : string
|
|
@@ -74,6 +75,9 @@ export type PuppetServiceOptions = PUPPET.PuppetOptions & {
|
|
|
74
75
|
}
|
|
75
76
|
}
|
|
76
77
|
|
|
78
|
+
const ResetLoginTimeout = 30 * 1000
|
|
79
|
+
const ResetReadyTimeout = 20 * 1000 // normally ready comes 15 seconds after login
|
|
80
|
+
|
|
77
81
|
class PuppetService extends PUPPET.Puppet {
|
|
78
82
|
|
|
79
83
|
static override readonly VERSION = VERSION
|
|
@@ -306,6 +310,10 @@ class PuppetService extends PUPPET.Puppet {
|
|
|
306
310
|
break
|
|
307
311
|
case grpcPuppet.EventType.EVENT_TYPE_LOGIN:
|
|
308
312
|
{
|
|
313
|
+
if (this.waitingForLogin) {
|
|
314
|
+
log.warn('PuppetService', 'this login event is ignored because the it is expected by event stream reconnect')
|
|
315
|
+
return
|
|
316
|
+
}
|
|
309
317
|
const loginPayload = JSON.parse(payload) as PUPPET.payloads.EventLogin
|
|
310
318
|
const accountId = await this._payloadStore.miscellaneous.get('accountId')
|
|
311
319
|
if (accountId !== loginPayload.contactId) {
|
|
@@ -350,6 +358,10 @@ class PuppetService extends PUPPET.Puppet {
|
|
|
350
358
|
this.emit('post-tap', JSON.parse(payload) as PUPPET.payloads.EventPostTap)
|
|
351
359
|
break
|
|
352
360
|
case grpcPuppet.EventType.EVENT_TYPE_READY:
|
|
361
|
+
if (this.waitingForLogin) {
|
|
362
|
+
log.warn('PuppetService', 'this ready event is ignored because the it is expected by event stream reconnect')
|
|
363
|
+
return
|
|
364
|
+
}
|
|
353
365
|
this.emit('ready', JSON.parse(payload) as PUPPET.payloads.EventReady)
|
|
354
366
|
break
|
|
355
367
|
case grpcPuppet.EventType.EVENT_TYPE_ROOM_INVITE:
|
|
@@ -2526,6 +2538,88 @@ class PuppetService extends PUPPET.Puppet {
|
|
|
2526
2538
|
clearInterval(this.healthCheckInterval!)
|
|
2527
2539
|
}
|
|
2528
2540
|
|
|
2541
|
+
// handle watchdog reset
|
|
2542
|
+
// goal: pain free reset of reconnect within threshold (like 30 seconds?)
|
|
2543
|
+
|
|
2544
|
+
private waitingForLogin = false
|
|
2545
|
+
private waitingForReady = false
|
|
2546
|
+
override async reset (): Promise<void> {
|
|
2547
|
+
if (!this._grpcManager) {
|
|
2548
|
+
log.warn('PuppetService', 'grpc manager not constructed, perform regular reset')
|
|
2549
|
+
return super.reset()
|
|
2550
|
+
}
|
|
2551
|
+
|
|
2552
|
+
if (!this.isLoggedIn) {
|
|
2553
|
+
log.warn('PuppetService', 'puppet not logged in, perform regular reset')
|
|
2554
|
+
return super.reset()
|
|
2555
|
+
}
|
|
2556
|
+
|
|
2557
|
+
this.grpcManager.stopStream()
|
|
2558
|
+
const lastEventTimestamp = await this._payloadStore.miscellaneous.get('eventTimestamp')
|
|
2559
|
+
const lastEventSeq = (Date.now() - Number(lastEventTimestamp || 0)) < this.timeoutMilliseconds ? await this._payloadStore.miscellaneous.get('eventSeq') : undefined
|
|
2560
|
+
const accountId = await this._payloadStore.miscellaneous.get('accountId')
|
|
2561
|
+
|
|
2562
|
+
const onLoginResolve = (resolve: () => void) => {
|
|
2563
|
+
const onLogin = (event: grpcPuppet.EventResponse) => {
|
|
2564
|
+
const type = event.getType()
|
|
2565
|
+
const payload = event.getPayload()
|
|
2566
|
+
if (this.waitingForLogin && type === grpcPuppet.EventType.EVENT_TYPE_LOGIN) {
|
|
2567
|
+
const payloadObj = JSON.parse(payload) as PUPPET.payloads.EventLogin
|
|
2568
|
+
this.waitingForLogin = false
|
|
2569
|
+
if (accountId && payloadObj.contactId !== accountId) {
|
|
2570
|
+
throw new Error('login with a different account, perform regular reset')
|
|
2571
|
+
}
|
|
2572
|
+
resolve()
|
|
2573
|
+
}
|
|
2574
|
+
}
|
|
2575
|
+
return onLogin
|
|
2576
|
+
}
|
|
2577
|
+
const onReadyResolve = (resolve: () => void) => {
|
|
2578
|
+
const onReady = (event: grpcPuppet.EventResponse) => {
|
|
2579
|
+
const type = event.getType()
|
|
2580
|
+
if (this.waitingForReady && type === grpcPuppet.EventType.EVENT_TYPE_READY) {
|
|
2581
|
+
this.waitingForReady = false
|
|
2582
|
+
resolve()
|
|
2583
|
+
}
|
|
2584
|
+
}
|
|
2585
|
+
return onReady
|
|
2586
|
+
}
|
|
2587
|
+
|
|
2588
|
+
let onLogin: ReturnType<typeof onLoginResolve>
|
|
2589
|
+
let onReady: ReturnType<typeof onReadyResolve>
|
|
2590
|
+
const loginFuture = new Promise<void>(resolve => {
|
|
2591
|
+
onLogin = onLoginResolve(resolve)
|
|
2592
|
+
this.grpcManager.on('data', onLogin)
|
|
2593
|
+
})
|
|
2594
|
+
const readyFuture = new Promise<void>(resolve => {
|
|
2595
|
+
onReady = onReadyResolve(resolve)
|
|
2596
|
+
this.grpcManager.on('data', onReady)
|
|
2597
|
+
})
|
|
2598
|
+
|
|
2599
|
+
this.waitingForLogin = true
|
|
2600
|
+
this.waitingForReady = true
|
|
2601
|
+
|
|
2602
|
+
// wait for server to clear stream
|
|
2603
|
+
await new Promise(resolve => {
|
|
2604
|
+
setTimeout(resolve, 5000)
|
|
2605
|
+
})
|
|
2606
|
+
|
|
2607
|
+
await this.grpcManager.startStream(lastEventSeq, accountId)
|
|
2608
|
+
try {
|
|
2609
|
+
await timeoutPromise(loginFuture, ResetLoginTimeout)
|
|
2610
|
+
.finally(() => this.grpcManager.off('data', onLogin))
|
|
2611
|
+
} catch (e) {
|
|
2612
|
+
log.warn('PuppetService', 'waiting for event reset login error, will perform regular reset')
|
|
2613
|
+
return super.reset()
|
|
2614
|
+
}
|
|
2615
|
+
try {
|
|
2616
|
+
await timeoutPromise(readyFuture, ResetReadyTimeout)
|
|
2617
|
+
.finally(() => this.grpcManager.off('data', onReady))
|
|
2618
|
+
} catch (e) {
|
|
2619
|
+
log.warn('PuppetService', 'waiting for event reset ready error, will do nothing')
|
|
2620
|
+
}
|
|
2621
|
+
}
|
|
2622
|
+
|
|
2529
2623
|
}
|
|
2530
2624
|
|
|
2531
2625
|
export {
|
package/src/package-json.ts
CHANGED
|
@@ -294,13 +294,27 @@ class EventStreamManager {
|
|
|
294
294
|
this.offCallbackList.push(off)
|
|
295
295
|
break
|
|
296
296
|
}
|
|
297
|
+
case 'post-comment': {
|
|
298
|
+
const listener = (payload: PUPPET.payloads.EventPostComment) => this.grpcEmit(grpcPuppet.EventType.EVENT_TYPE_POST_COMMENT, payload)
|
|
299
|
+
this.puppet.on('post-comment', listener)
|
|
300
|
+
const off = () => this.puppet.off('post-comment', listener)
|
|
301
|
+
this.offCallbackList.push(off)
|
|
302
|
+
break
|
|
303
|
+
}
|
|
304
|
+
case 'post-tap': {
|
|
305
|
+
const listener = (payload: PUPPET.payloads.EventPostTap) => this.grpcEmit(grpcPuppet.EventType.EVENT_TYPE_POST_TAP, payload)
|
|
306
|
+
this.puppet.on('post-tap', listener)
|
|
307
|
+
const off = () => this.puppet.off('post-tap', listener)
|
|
308
|
+
this.offCallbackList.push(off)
|
|
309
|
+
break
|
|
310
|
+
}
|
|
297
311
|
case 'reset':
|
|
298
312
|
// the `reset` event should be dealed internally, should not send out
|
|
299
313
|
break
|
|
300
314
|
|
|
301
315
|
default:
|
|
302
316
|
// Huan(202003): in default, the `eventName` type should be `never`, please check.
|
|
303
|
-
|
|
317
|
+
log.warn('eventName ' + eventName + ' unsupported!')
|
|
304
318
|
}
|
|
305
319
|
}
|
|
306
320
|
|