@@ -11,6 +11,7 @@ import {
1111 HandleModule ,
1212 ICloudModule ,
1313 MessageModule ,
14+ PollModule ,
1415 ScheduledMessageModule ,
1516 ServerModule ,
1617} from "./modules" ;
@@ -47,6 +48,7 @@ export class AdvancedIMessageKit extends EventEmitter implements TypedEventEmitt
4748 public readonly facetime : FaceTimeModule ;
4849 public readonly icloud : ICloudModule ;
4950
51+ public readonly polls : PollModule ;
5052 public readonly scheduledMessages : ScheduledMessageModule ;
5153 public readonly server : ServerModule ;
5254
@@ -63,6 +65,12 @@ export class AdvancedIMessageKit extends EventEmitter implements TypedEventEmitt
6365 // a single user/SDK instance are sent in strict order, preventing race conditions.
6466 private sendQueue : Promise < unknown > = Promise . resolve ( ) ;
6567
68+ // Flag to track if 'ready' event has been emitted
69+ //
70+ // Purpose: Prevent duplicate 'ready' events when both legacy mode (no API key)
71+ // and auth-ok events occur, which would cause user callbacks to fire twice.
72+ private readyEmitted = false ;
73+
6674 private constructor ( config : ClientConfig = { } ) {
6775 super ( ) ;
6876
@@ -114,6 +122,7 @@ export class AdvancedIMessageKit extends EventEmitter implements TypedEventEmitt
114122 this . facetime = new FaceTimeModule ( this . http ) ;
115123 this . icloud = new ICloudModule ( this . http ) ;
116124
125+ this . polls = new PollModule ( this . http ) ;
117126 this . scheduledMessages = new ScheduledMessageModule ( this . http ) ;
118127 this . server = new ServerModule ( this . http ) ;
119128 }
@@ -218,13 +227,17 @@ export class AdvancedIMessageKit extends EventEmitter implements TypedEventEmitt
218227
219228 this . socket . on ( "disconnect" , ( ) => {
220229 this . logger . info ( "Disconnected from iMessage server" ) ;
230+ this . readyEmitted = false ;
221231 this . emit ( "disconnect" ) ;
222232 } ) ;
223233
224234 // Listen for authentication success
225235 this . socket . on ( "auth-ok" , ( ) => {
226236 this . logger . info ( "Authentication successful" ) ;
227- this . emit ( "ready" ) ;
237+ if ( ! this . readyEmitted ) {
238+ this . readyEmitted = true ;
239+ this . emit ( "ready" ) ;
240+ }
228241 } ) ;
229242
230243 // Listen for authentication errors
@@ -243,7 +256,10 @@ export class AdvancedIMessageKit extends EventEmitter implements TypedEventEmitt
243256 // If no apiKey, assume legacy server that doesn't require auth - emit ready immediately
244257 if ( ! this . config . apiKey ) {
245258 this . logger . info ( "No API key provided, skipping authentication (legacy server mode)" ) ;
246- this . emit ( "ready" ) ;
259+ if ( ! this . readyEmitted ) {
260+ this . readyEmitted = true ;
261+ this . emit ( "ready" ) ;
262+ }
247263 }
248264 } ) ;
249265
0 commit comments