@@ -31,11 +31,13 @@ export class MainController extends EventEmitter {
3131 private $workflowDataService : WorkflowDataService
3232 ) { super ( ) ; }
3333
34- public async preparePlatform ( platform : string , projectDir : string , options : IOptions ) : Promise < void > {
34+ public async preparePlatform ( platform : string , projectDir : string , options : IOptions ) : Promise < boolean > {
3535 const { nativePlatformData, projectData, addPlatformData, preparePlatformData } = this . $workflowDataService . createWorkflowData ( platform , projectDir , options ) ;
3636
3737 await this . $addPlatformService . addPlatformIfNeeded ( nativePlatformData , projectData , addPlatformData ) ;
38- await this . $preparePlatformService . preparePlatform ( nativePlatformData , projectData , preparePlatformData ) ;
38+ const result = await this . $preparePlatformService . preparePlatform ( nativePlatformData , projectData , preparePlatformData ) ;
39+
40+ return result ;
3941 }
4042
4143 public async buildPlatform ( platform : string , projectDir : string , options : IOptions | any ) : Promise < string > {
@@ -74,34 +76,40 @@ export class MainController extends EventEmitter {
7476 await this . $addPlatformService . addPlatformIfNeeded ( nativePlatformData , projectData , addPlatformData ) ;
7577 }
7678
77- // TODO: Consider to handle correctly the descriptors when livesync is executed for second time for the same projectDir
79+ const currentRunOnDevicesData = this . $runOnDevicesDataService . getDataForProject ( projectData . projectDir ) ;
80+ const isAlreadyLiveSyncing = currentRunOnDevicesData && ! currentRunOnDevicesData . isStopped ;
81+ // Prevent cases where liveSync is called consecutive times with the same device, for example [ A, B, C ] and then [ A, B, D ] - we want to execute initialSync only for D.
82+ const deviceDescriptorsForInitialSync = isAlreadyLiveSyncing ? _ . differenceBy ( deviceDescriptors , currentRunOnDevicesData . deviceDescriptors , "identifier" ) : deviceDescriptors ;
7883
79- this . $runOnDevicesDataService . persistData ( projectDir , deviceDescriptors ) ;
84+ this . $runOnDevicesDataService . persistData ( projectDir , deviceDescriptors , platforms ) ;
8085
8186 const shouldStartWatcher = ! liveSyncInfo . skipWatcher && ( liveSyncInfo . syncToPreviewApp || this . $runOnDevicesDataService . hasDeviceDescriptors ( projectDir ) ) ;
8287 if ( shouldStartWatcher ) {
83- this . handleRunOnDeviceEvents ( projectDir ) ;
88+ this . handleRunOnDeviceError ( projectDir ) ;
8489
8590 this . $platformWatcherService . on ( INITIAL_SYNC_EVENT_NAME , async ( data : IInitialSyncEventData ) => {
86- await this . $runOnDevicesController . syncInitialDataOnDevice ( data , projectData , liveSyncInfo , deviceDescriptors ) ;
91+ await this . $runOnDevicesController . syncInitialDataOnDevices ( data , projectData , liveSyncInfo , deviceDescriptorsForInitialSync ) ;
8792 } ) ;
8893 this . $platformWatcherService . on ( FILES_CHANGE_EVENT_NAME , async ( data : IFilesChangeEventData ) => {
89- await this . $runOnDevicesController . syncChangedDataOnDevice ( data , projectData , liveSyncInfo , deviceDescriptors ) ;
94+ await this . $runOnDevicesController . syncChangedDataOnDevices ( data , projectData , liveSyncInfo , deviceDescriptors ) ;
9095 } ) ;
9196
9297 for ( const platform of platforms ) {
9398 const { nativePlatformData, preparePlatformData } = this . $workflowDataService . createWorkflowData ( platform , projectDir , liveSyncInfo ) ;
9499 await this . $platformWatcherService . startWatchers ( nativePlatformData , projectData , preparePlatformData ) ;
95100 }
101+ } else {
102+ for ( const platform of platforms ) {
103+ const hasNativeChanges = await this . preparePlatform ( platform , projectDir , < any > liveSyncInfo ) ;
104+ await this . $runOnDevicesController . syncInitialDataOnDevices ( { platform, hasNativeChanges } , projectData , liveSyncInfo , deviceDescriptorsForInitialSync ) ;
105+ }
96106 }
97107
98- // TODO: Consider how to handle --justlaunch
99-
100108 this . attachDeviceLostHandler ( ) ;
101109 }
102110
103111 public async stopRunOnDevices ( projectDir : string , deviceIdentifiers ?: string [ ] , stopOptions ?: { shouldAwaitAllActions : boolean } ) : Promise < void > {
104- const liveSyncProcessInfo = this . $runOnDevicesDataService . getData ( projectDir ) ;
112+ const liveSyncProcessInfo = this . $runOnDevicesDataService . getDataForProject ( projectDir ) ;
105113 if ( liveSyncProcessInfo && ! liveSyncProcessInfo . isStopped ) {
106114 // In case we are coming from error during livesync, the current action is the one that erred (but we are still executing it),
107115 // so we cannot await it as this will cause infinite loop.
@@ -112,15 +120,22 @@ export class MainController extends EventEmitter {
112120 const removedDeviceIdentifiers = _ . remove ( liveSyncProcessInfo . deviceDescriptors , descriptor => _ . includes ( deviceIdentifiersToRemove , descriptor . identifier ) )
113121 . map ( descriptor => descriptor . identifier ) ;
114122
123+ // Handle the case when no more devices left for any of the persisted platforms
124+ _ . each ( liveSyncProcessInfo . platforms , platform => {
125+ const devices = this . $devicesService . getDevicesForPlatform ( platform ) ;
126+ if ( ! devices || ! devices . length ) {
127+ this . $platformWatcherService . stopWatchers ( projectDir , platform ) ;
128+ }
129+ } ) ;
130+
115131 // In case deviceIdentifiers are not passed, we should stop the whole LiveSync.
116132 if ( ! deviceIdentifiers || ! deviceIdentifiers . length || ! liveSyncProcessInfo . deviceDescriptors || ! liveSyncProcessInfo . deviceDescriptors . length ) {
117133 if ( liveSyncProcessInfo . timer ) {
118134 clearTimeout ( liveSyncProcessInfo . timer ) ;
119135 }
120136
121- _ . each ( liveSyncProcessInfo . deviceDescriptors , deviceDescriptor => {
122- const device = this . $devicesService . getDeviceByIdentifier ( deviceDescriptor . identifier ) ;
123- this . $platformWatcherService . stopWatchers ( projectDir , device . deviceInfo . platform ) ;
137+ _ . each ( liveSyncProcessInfo . platforms , platform => {
138+ this . $platformWatcherService . stopWatchers ( projectDir , platform ) ;
124139 } ) ;
125140
126141 liveSyncProcessInfo . isStopped = true ;
@@ -131,12 +146,6 @@ export class MainController extends EventEmitter {
131146
132147 liveSyncProcessInfo . deviceDescriptors = [ ] ;
133148
134- if ( liveSyncProcessInfo . syncToPreviewApp ) {
135- // await this.$previewAppLiveSyncService.stopLiveSync();
136- // this.$previewAppLiveSyncService.removeAllListeners();
137- }
138-
139- // Kill typescript watcher
140149 const projectData = this . $projectDataService . getProjectData ( projectDir ) ;
141150 await this . $hooksService . executeAfterHooks ( 'watch' , {
142151 hookArgs : {
@@ -158,22 +167,12 @@ export class MainController extends EventEmitter {
158167 return this . $runOnDevicesDataService . getDeviceDescriptors ( projectDir ) ;
159168 }
160169
161- private handleRunOnDeviceEvents ( projectDir : string ) : void {
162- this . $runOnDevicesController . on ( RunOnDeviceEvents . runOnDeviceError , async data => {
170+ private handleRunOnDeviceError ( projectDir : string ) : void {
171+ this . $runOnDevicesEmitter . on ( RunOnDeviceEvents . runOnDeviceError , async data => {
163172 await this . stopRunOnDevices ( projectDir , [ data . deviceIdentifier ] , { shouldAwaitAllActions : false } ) ;
164173 } ) ;
165174 }
166175
167- // TODO: expose previewOnDevice() method { }
168- // TODO: enableDebugging -> mainController
169- // TODO: disableDebugging -> mainController
170- // TODO: attachDebugger -> mainController
171- // mainController.runOnDevices(), runOnDevicesController.on("event", () => {})
172-
173- // debugOnDevicesController.enableDebugging()
174- // debugOnDevicesController.disableDebugging()
175- // debugOnDevicesController.attachDebugger
176-
177176 private async initializeSetup ( projectData : IProjectData ) : Promise < void > {
178177 try {
179178 await this . $pluginsService . ensureAllDependenciesAreInstalled ( projectData ) ;
0 commit comments