1010import throwError from '../tools/throwError' ;
1111import { unique } from '../tools/tools' ;
1212import { debug } from '../tools/debug' ;
13+ import type EventBus from '../events/eventBus' ;
14+ import type { EventTarget , RequestedPayload } from '../events/eventTypes' ;
1315
1416interface toggleParams {
1517 [ name :string ] :unknown
1618}
1719
20+ interface SocialEventHandlers {
21+ target : EventTarget
22+ init ?: ( payload : RequestedPayload ) => Promise < boolean | 'skip' >
23+ toggle ?: ( payload : RequestedPayload ) => Promise < boolean >
24+ }
25+
1826/**
1927 * 抽象类,表示社交功能的基类。
2028 *
@@ -29,6 +37,64 @@ abstract class Social {
2937 * @description 当前的社交任务列表。
3038 */
3139 protected tasks ! : socialTasks ;
40+ protected eventBus ?: EventBus ;
41+ private readonly eventHandlers : Array < SocialEventHandlers > = [ ] ;
42+ private listenersAttached = false ;
43+ private readonly handleInitRequested = async ( payload : RequestedPayload ) : Promise < void > => {
44+ for ( const handler of this . eventHandlers ) {
45+ if ( ! handler . init || payload . target !== handler . target ) continue ;
46+ try {
47+ const result = await handler . init ( payload ) ;
48+ const isSkip = result === 'skip' ;
49+ const isSuccess = result === true || isSkip ;
50+ await this . eventBus ?. emit ( 'social.init.completed' , {
51+ runId : payload . runId ,
52+ timestamp : Date . now ( ) ,
53+ source : 'social' ,
54+ target : handler . target ,
55+ ok : isSuccess ,
56+ processedCount : result === true ? 1 : 0
57+ } ) ;
58+ } catch ( error ) {
59+ await this . eventBus ?. emit ( 'social.init.completed' , {
60+ runId : payload . runId ,
61+ timestamp : Date . now ( ) ,
62+ source : 'social' ,
63+ target : handler . target ,
64+ ok : false ,
65+ processedCount : 0 ,
66+ error : ( error as Error ) ?. message || String ( error )
67+ } ) ;
68+ }
69+ }
70+ } ;
71+ private readonly handleToggleRequested = async ( payload : RequestedPayload ) : Promise < void > => {
72+ const sanitizedPayload = this . sanitizeRequestedPayload ( payload ) ;
73+ for ( const handler of this . eventHandlers ) {
74+ if ( ! handler . toggle || sanitizedPayload . target !== handler . target ) continue ;
75+ try {
76+ const result = await handler . toggle ( sanitizedPayload ) ;
77+ await this . eventBus ?. emit ( 'social.toggle.completed' , {
78+ runId : sanitizedPayload . runId ,
79+ timestamp : Date . now ( ) ,
80+ source : 'social' ,
81+ target : handler . target ,
82+ ok : ! ! result ,
83+ processedCount : result ? 1 : 0
84+ } ) ;
85+ } catch ( error ) {
86+ await this . eventBus ?. emit ( 'social.toggle.completed' , {
87+ runId : sanitizedPayload . runId ,
88+ timestamp : Date . now ( ) ,
89+ source : 'social' ,
90+ target : handler . target ,
91+ ok : false ,
92+ processedCount : 0 ,
93+ error : ( error as Error ) ?. message || String ( error )
94+ } ) ;
95+ }
96+ }
97+ } ;
3298
3399 /**
34100 * 初始化社交功能。
@@ -55,6 +121,49 @@ abstract class Social {
55121 */
56122 abstract toggle ( toggleParams : toggleParams ) : Promise < boolean > ;
57123
124+ setEventBus ( eventBus : EventBus ) : void {
125+ if ( this . eventBus && this . listenersAttached ) {
126+ this . eventBus . off ( 'social.init.requested' , this . handleInitRequested ) ;
127+ this . eventBus . off ( 'social.toggle.requested' , this . handleToggleRequested ) ;
128+ this . listenersAttached = false ;
129+ }
130+ this . eventBus = eventBus ;
131+ this . attachEventBusListeners ( ) ;
132+ }
133+
134+ protected registerEventBusHandlers ( handlers : SocialEventHandlers ) : void {
135+ this . eventHandlers . push ( handlers ) ;
136+ this . attachEventBusListeners ( ) ;
137+ }
138+
139+ private attachEventBusListeners ( ) : void {
140+ if ( ! this . eventBus || this . listenersAttached || this . eventHandlers . length === 0 ) return ;
141+ this . listenersAttached = true ;
142+ this . eventBus . on ( 'social.init.requested' , this . handleInitRequested ) ;
143+ this . eventBus . on ( 'social.toggle.requested' , this . handleToggleRequested ) ;
144+ }
145+
146+ private sanitizeRequestedPayload ( payload : RequestedPayload ) : RequestedPayload {
147+ const rawTasks = payload . tasks as Record < string , unknown > | undefined ;
148+ if ( ! rawTasks || typeof rawTasks !== 'object' ) {
149+ return {
150+ ...payload ,
151+ tasks : { }
152+ } ;
153+ }
154+
155+ const tasks = Object . entries ( rawTasks ) . reduce < Record < string , Array < string > > > ( ( acc , [ key , value ] ) => {
156+ if ( ! Array . isArray ( value ) ) return acc ;
157+ acc [ key ] = value . filter ( ( item ) : item is string => typeof item === 'string' ) ;
158+ return acc ;
159+ } , { } ) ;
160+
161+ return {
162+ ...payload ,
163+ tasks
164+ } ;
165+ }
166+
58167 /**
59168 * 获取实际参数数组,用于执行任务。
60169 *
0 commit comments