@@ -4,6 +4,8 @@ import { cache, performanceLog } from "../common/decorators";
44import { EventEmitter } from "events" ;
55
66export class RunController extends EventEmitter implements IRunController {
7+ private prepareReadyEventHandler : any = null ;
8+
79 constructor (
810 protected $analyticsService : IAnalyticsService ,
911 private $buildController : IBuildController ,
@@ -23,6 +25,7 @@ export class RunController extends EventEmitter implements IRunController {
2325 private $prepareController : IPrepareController ,
2426 private $prepareDataService : IPrepareDataService ,
2527 private $prepareNativePlatformService : IPrepareNativePlatformService ,
28+ private $projectChangesService : IProjectChangesService ,
2629 protected $projectDataService : IProjectDataService
2730 ) {
2831 super ( ) ;
@@ -45,9 +48,21 @@ export class RunController extends EventEmitter implements IRunController {
4548 this . $hmrStatusService . attachToHmrStatusEvent ( ) ;
4649 }
4750
48- this . $prepareController . on ( PREPARE_READY_EVENT_NAME , async data => {
49- await this . syncChangedDataOnDevices ( data , projectData , liveSyncInfo , deviceDescriptors ) ;
50- } ) ;
51+ if ( ! this . prepareReadyEventHandler ) {
52+ this . prepareReadyEventHandler = async ( data : IFilesChangeEventData ) => {
53+ if ( data . hasNativeChanges ) {
54+ const platformData = this . $platformsDataService . getPlatformData ( data . platform , projectData ) ;
55+ const prepareData = this . $prepareDataService . getPrepareData ( liveSyncInfo . projectDir , data . platform , { ...liveSyncInfo , watch : ! liveSyncInfo . skipWatcher } ) ;
56+ const changesInfo = await this . $projectChangesService . checkForChanges ( platformData , projectData , prepareData ) ;
57+ if ( changesInfo . hasChanges ) {
58+ await this . syncChangedDataOnDevices ( data , projectData , liveSyncInfo ) ;
59+ }
60+ } else {
61+ await this . syncChangedDataOnDevices ( data , projectData , liveSyncInfo ) ;
62+ }
63+ } ;
64+ this . $prepareController . on ( PREPARE_READY_EVENT_NAME , this . prepareReadyEventHandler . bind ( this ) ) ;
65+ }
5166
5267 await this . syncInitialDataOnDevices ( projectData , liveSyncInfo , deviceDescriptorsForInitialSync ) ;
5368
@@ -58,6 +73,7 @@ export class RunController extends EventEmitter implements IRunController {
5873 const { projectDir, deviceIdentifiers, stopOptions } = data ;
5974 const liveSyncProcessInfo = this . $liveSyncProcessDataService . getPersistedData ( projectDir ) ;
6075 if ( liveSyncProcessInfo && ! liveSyncProcessInfo . isStopped ) {
76+
6177 // In case we are coming from error during livesync, the current action is the one that erred (but we are still executing it),
6278 // so we cannot await it as this will cause infinite loop.
6379 const shouldAwaitPendingOperation = ! stopOptions || stopOptions . shouldAwaitAllActions ;
@@ -94,6 +110,11 @@ export class RunController extends EventEmitter implements IRunController {
94110
95111 liveSyncProcessInfo . deviceDescriptors = [ ] ;
96112
113+ if ( this . prepareReadyEventHandler ) {
114+ this . removeListener ( PREPARE_READY_EVENT_NAME , this . prepareReadyEventHandler ) ;
115+ this . prepareReadyEventHandler = null ;
116+ }
117+
97118 const projectData = this . $projectDataService . getProjectData ( projectDir ) ;
98119 await this . $hooksService . executeAfterHooks ( 'watch' , {
99120 hookArgs : {
@@ -313,10 +334,11 @@ export class RunController extends EventEmitter implements IRunController {
313334 await this . addActionToChain ( projectData . projectDir , ( ) => this . $devicesService . execute ( deviceAction , ( device : Mobile . IDevice ) => _ . some ( deviceDescriptors , deviceDescriptor => deviceDescriptor . identifier === device . deviceInfo . identifier ) ) ) ;
314335 }
315336
316- private async syncChangedDataOnDevices ( data : IFilesChangeEventData , projectData : IProjectData , liveSyncInfo : ILiveSyncInfo , deviceDescriptors : ILiveSyncDeviceDescriptor [ ] ) : Promise < void > {
337+ private async syncChangedDataOnDevices ( data : IFilesChangeEventData , projectData : IProjectData , liveSyncInfo : ILiveSyncInfo ) : Promise < void > {
317338 const rebuiltInformation : IDictionary < { packageFilePath : string , platform : string , isEmulator : boolean } > = { } ;
318339
319340 const deviceAction = async ( device : Mobile . IDevice ) => {
341+ const deviceDescriptors = this . $liveSyncProcessDataService . getDeviceDescriptors ( projectData . projectDir ) ;
320342 const deviceDescriptor = _ . find ( deviceDescriptors , dd => dd . identifier === device . deviceInfo . identifier ) ;
321343 const platformData = this . $platformsDataService . getPlatformData ( data . platform , projectData ) ;
322344 const prepareData = this . $prepareDataService . getPrepareData ( liveSyncInfo . projectDir , device . deviceInfo . platform ,
0 commit comments