@@ -37,13 +37,13 @@ export class LiveSyncService extends EventEmitter implements IDebugLiveSyncServi
37
37
private $debugDataService : IDebugDataService ,
38
38
private $analyticsService : IAnalyticsService ,
39
39
private $usbLiveSyncService : DeprecatedUsbLiveSyncService ,
40
+ private $previewAppLiveSyncService : IPreviewAppLiveSyncService ,
40
41
private $injector : IInjector ) {
41
42
super ( ) ;
42
43
}
43
44
44
45
public async liveSync ( deviceDescriptors : ILiveSyncDeviceInfo [ ] , liveSyncData : ILiveSyncInfo ) : Promise < void > {
45
46
const projectData = this . $projectDataService . getProjectData ( liveSyncData . projectDir ) ;
46
- await this . $pluginsService . ensureAllDependenciesAreInstalled ( projectData ) ;
47
47
await this . liveSyncOperation ( deviceDescriptors , liveSyncData , projectData ) ;
48
48
}
49
49
@@ -318,16 +318,22 @@ export class LiveSyncService extends EventEmitter implements IDebugLiveSyncServi
318
318
319
319
@hook ( "liveSync" )
320
320
private async liveSyncOperation ( deviceDescriptors : ILiveSyncDeviceInfo [ ] , liveSyncData : ILiveSyncInfo , projectData : IProjectData ) : Promise < void > {
321
- // In case liveSync is called for a second time for the same projectDir.
322
- const isAlreadyLiveSyncing = this . liveSyncProcessesInfo [ projectData . projectDir ] && ! this . liveSyncProcessesInfo [ projectData . projectDir ] . isStopped ;
321
+ let deviceDescriptorsForInitialSync : ILiveSyncDeviceInfo [ ] = [ ] ;
323
322
324
- // 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.
325
- const currentlyRunningDeviceDescriptors = this . getLiveSyncDeviceDescriptors ( projectData . projectDir ) ;
326
- const deviceDescriptorsForInitialSync = isAlreadyLiveSyncing ? _ . differenceBy ( deviceDescriptors , currentlyRunningDeviceDescriptors , deviceDescriptorPrimaryKey ) : deviceDescriptors ;
323
+ if ( ! liveSyncData . syncToPreviewApp ) {
324
+ await this . $pluginsService . ensureAllDependenciesAreInstalled ( projectData ) ;
325
+ // In case liveSync is called for a second time for the same projectDir.
326
+ const isAlreadyLiveSyncing = this . liveSyncProcessesInfo [ projectData . projectDir ] && ! this . liveSyncProcessesInfo [ projectData . projectDir ] . isStopped ;
327
+
328
+ // 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.
329
+ const currentlyRunningDeviceDescriptors = this . getLiveSyncDeviceDescriptors ( projectData . projectDir ) ;
330
+ deviceDescriptorsForInitialSync = isAlreadyLiveSyncing ? _ . differenceBy ( deviceDescriptors , currentlyRunningDeviceDescriptors , deviceDescriptorPrimaryKey ) : deviceDescriptors ;
331
+ }
327
332
328
333
this . setLiveSyncProcessInfo ( liveSyncData . projectDir , deviceDescriptors ) ;
329
334
330
- if ( ! liveSyncData . skipWatcher && this . liveSyncProcessesInfo [ projectData . projectDir ] . deviceDescriptors . length ) {
335
+ const shouldStartWatcher = liveSyncData . syncToPreviewApp || ( ! liveSyncData . skipWatcher && this . liveSyncProcessesInfo [ projectData . projectDir ] . deviceDescriptors . length ) ;
336
+ if ( shouldStartWatcher ) {
331
337
// Should be set after prepare
332
338
this . $usbLiveSyncService . isInitialized = true ;
333
339
await this . startWatcher ( projectData , liveSyncData , deviceDescriptors ) ;
@@ -448,6 +454,27 @@ export class LiveSyncService extends EventEmitter implements IDebugLiveSyncServi
448
454
}
449
455
450
456
private async initialSync ( projectData : IProjectData , liveSyncData : ILiveSyncInfo , deviceDescriptors : ILiveSyncDeviceInfo [ ] ) : Promise < void > {
457
+ if ( liveSyncData . syncToPreviewApp ) {
458
+ await this . initialSyncToPreviewApp ( projectData , liveSyncData ) ;
459
+ } else {
460
+ await this . initialCableSync ( projectData , liveSyncData , deviceDescriptors ) ;
461
+ }
462
+ }
463
+
464
+ private async initialSyncToPreviewApp ( projectData : IProjectData , liveSyncData : ILiveSyncInfo ) {
465
+ this . addActionToChain ( projectData . projectDir , async ( ) => {
466
+ await this . $previewAppLiveSyncService . initialSync ( {
467
+ appFilesUpdaterOptions : {
468
+ bundle : liveSyncData . bundle ,
469
+ release : liveSyncData . release
470
+ } ,
471
+ env : liveSyncData . env ,
472
+ projectData
473
+ } ) ;
474
+ } ) ;
475
+ }
476
+
477
+ private async initialCableSync ( projectData : IProjectData , liveSyncData : ILiveSyncInfo , deviceDescriptors : ILiveSyncDeviceInfo [ ] ) : Promise < void > {
451
478
const preparedPlatforms : string [ ] = [ ] ;
452
479
const rebuiltInformation : ILiveSyncBuildInfo [ ] = [ ] ;
453
480
@@ -552,82 +579,95 @@ export class LiveSyncService extends EventEmitter implements IDebugLiveSyncServi
552
579
553
580
const startSyncFilesTimeout = ( ) => {
554
581
timeoutTimer = setTimeout ( async ( ) => {
555
- // Push actions to the queue, do not start them simultaneously
556
- await this . addActionToChain ( projectData . projectDir , async ( ) => {
557
- if ( filesToSync . length || filesToRemove . length ) {
558
- try {
559
- const currentFilesToSync = _ . cloneDeep ( filesToSync ) ;
560
- filesToSync . splice ( 0 , filesToSync . length ) ;
561
-
562
- const currentFilesToRemove = _ . cloneDeep ( filesToRemove ) ;
563
- filesToRemove = [ ] ;
564
-
565
- const allModifiedFiles = [ ] . concat ( currentFilesToSync ) . concat ( currentFilesToRemove ) ;
566
-
567
- const preparedPlatforms : string [ ] = [ ] ;
568
- const rebuiltInformation : ILiveSyncBuildInfo [ ] = [ ] ;
569
-
570
- const latestAppPackageInstalledSettings = this . getDefaultLatestAppPackageInstalledSettings ( ) ;
571
-
572
- await this . $devicesService . execute ( async ( device : Mobile . IDevice ) => {
573
- const liveSyncProcessInfo = this . liveSyncProcessesInfo [ projectData . projectDir ] ;
574
- const deviceBuildInfoDescriptor = _ . find ( liveSyncProcessInfo . deviceDescriptors , dd => dd . identifier === device . deviceInfo . identifier ) ;
575
-
576
- const appInstalledOnDeviceResult = await this . ensureLatestAppPackageIsInstalledOnDevice ( {
577
- device,
578
- preparedPlatforms,
579
- rebuiltInformation,
580
- projectData,
581
- deviceBuildInfoDescriptor,
582
- liveSyncData,
583
- settings : latestAppPackageInstalledSettings ,
584
- modifiedFiles : allModifiedFiles ,
585
- filesToRemove : currentFilesToRemove ,
586
- filesToSync : currentFilesToSync ,
587
- bundle : liveSyncData . bundle ,
588
- release : liveSyncData . release ,
589
- env : liveSyncData . env ,
590
- skipModulesNativeCheck : ! liveSyncData . watchAllFiles
591
- } , { skipNativePrepare : deviceBuildInfoDescriptor . skipNativePrepare } ) ;
592
-
593
- const service = this . getLiveSyncService ( device . deviceInfo . platform ) ;
594
- const settings : ILiveSyncWatchInfo = {
595
- projectData,
596
- filesToRemove : currentFilesToRemove ,
597
- filesToSync : currentFilesToSync ,
598
- isReinstalled : appInstalledOnDeviceResult . appInstalled ,
599
- syncAllFiles : liveSyncData . watchAllFiles ,
600
- useHotModuleReload : liveSyncData . useHotModuleReload
601
- } ;
602
-
603
- const liveSyncResultInfo = await service . liveSyncWatchAction ( device , settings ) ;
604
- await this . refreshApplication ( projectData , liveSyncResultInfo , deviceBuildInfoDescriptor . debugOptions , deviceBuildInfoDescriptor . outputPath ) ;
582
+ if ( liveSyncData . syncToPreviewApp ) {
583
+ await this . addActionToChain ( projectData . projectDir , async ( ) => {
584
+ await this . $previewAppLiveSyncService . syncFiles ( {
585
+ appFilesUpdaterOptions : {
586
+ bundle : liveSyncData . bundle ,
587
+ release : liveSyncData . release
605
588
} ,
606
- ( device : Mobile . IDevice ) => {
589
+ env : liveSyncData . env ,
590
+ projectData : projectData
591
+ } , filesToSync ) ;
592
+ } ) ;
593
+ } else {
594
+ // Push actions to the queue, do not start them simultaneously
595
+ await this . addActionToChain ( projectData . projectDir , async ( ) => {
596
+ if ( filesToSync . length || filesToRemove . length ) {
597
+ try {
598
+ const currentFilesToSync = _ . cloneDeep ( filesToSync ) ;
599
+ filesToSync . splice ( 0 , filesToSync . length ) ;
600
+
601
+ const currentFilesToRemove = _ . cloneDeep ( filesToRemove ) ;
602
+ filesToRemove = [ ] ;
603
+
604
+ const allModifiedFiles = [ ] . concat ( currentFilesToSync ) . concat ( currentFilesToRemove ) ;
605
+
606
+ const preparedPlatforms : string [ ] = [ ] ;
607
+ const rebuiltInformation : ILiveSyncBuildInfo [ ] = [ ] ;
608
+
609
+ const latestAppPackageInstalledSettings = this . getDefaultLatestAppPackageInstalledSettings ( ) ;
610
+
611
+ await this . $devicesService . execute ( async ( device : Mobile . IDevice ) => {
607
612
const liveSyncProcessInfo = this . liveSyncProcessesInfo [ projectData . projectDir ] ;
608
- return liveSyncProcessInfo && _ . some ( liveSyncProcessInfo . deviceDescriptors , deviceDescriptor => deviceDescriptor . identifier === device . deviceInfo . identifier ) ;
609
- }
610
- ) ;
611
- } catch ( err ) {
612
- const allErrors = ( < Mobile . IDevicesOperationError > err ) . allErrors ;
613
-
614
- if ( allErrors && _ . isArray ( allErrors ) ) {
615
- for ( const deviceError of allErrors ) {
616
- this . $logger . warn ( `Unable to apply changes for device: ${ deviceError . deviceIdentifier } . Error is: ${ deviceError . message } .` ) ;
617
-
618
- this . emit ( LiveSyncEvents . liveSyncError , {
619
- error : deviceError ,
620
- deviceIdentifier : deviceError . deviceIdentifier ,
621
- projectDir : projectData . projectDir ,
622
- applicationIdentifier : projectData . projectId
623
- } ) ;
624
-
625
- await this . stopLiveSync ( projectData . projectDir , [ deviceError . deviceIdentifier ] , { shouldAwaitAllActions : false } ) ;
613
+ const deviceBuildInfoDescriptor = _ . find ( liveSyncProcessInfo . deviceDescriptors , dd => dd . identifier === device . deviceInfo . identifier ) ;
614
+
615
+ const appInstalledOnDeviceResult = await this . ensureLatestAppPackageIsInstalledOnDevice ( {
616
+ device,
617
+ preparedPlatforms,
618
+ rebuiltInformation,
619
+ projectData,
620
+ deviceBuildInfoDescriptor,
621
+ liveSyncData,
622
+ settings : latestAppPackageInstalledSettings ,
623
+ modifiedFiles : allModifiedFiles ,
624
+ filesToRemove : currentFilesToRemove ,
625
+ filesToSync : currentFilesToSync ,
626
+ bundle : liveSyncData . bundle ,
627
+ release : liveSyncData . release ,
628
+ env : liveSyncData . env ,
629
+ skipModulesNativeCheck : ! liveSyncData . watchAllFiles
630
+ } , { skipNativePrepare : deviceBuildInfoDescriptor . skipNativePrepare } ) ;
631
+
632
+ const service = this . getLiveSyncService ( device . deviceInfo . platform ) ;
633
+ const settings : ILiveSyncWatchInfo = {
634
+ projectData,
635
+ filesToRemove : currentFilesToRemove ,
636
+ filesToSync : currentFilesToSync ,
637
+ isReinstalled : appInstalledOnDeviceResult . appInstalled ,
638
+ syncAllFiles : liveSyncData . watchAllFiles ,
639
+ useHotModuleReload : liveSyncData . useHotModuleReload
640
+ } ;
641
+
642
+ const liveSyncResultInfo = await service . liveSyncWatchAction ( device , settings ) ;
643
+ await this . refreshApplication ( projectData , liveSyncResultInfo , deviceBuildInfoDescriptor . debugOptions , deviceBuildInfoDescriptor . outputPath ) ;
644
+ } ,
645
+ ( device : Mobile . IDevice ) => {
646
+ const liveSyncProcessInfo = this . liveSyncProcessesInfo [ projectData . projectDir ] ;
647
+ return liveSyncProcessInfo && _ . some ( liveSyncProcessInfo . deviceDescriptors , deviceDescriptor => deviceDescriptor . identifier === device . deviceInfo . identifier ) ;
648
+ }
649
+ ) ;
650
+ } catch ( err ) {
651
+ const allErrors = ( < Mobile . IDevicesOperationError > err ) . allErrors ;
652
+
653
+ if ( allErrors && _ . isArray ( allErrors ) ) {
654
+ for ( const deviceError of allErrors ) {
655
+ this . $logger . warn ( `Unable to apply changes for device: ${ deviceError . deviceIdentifier } . Error is: ${ deviceError . message } .` ) ;
656
+
657
+ this . emit ( LiveSyncEvents . liveSyncError , {
658
+ error : deviceError ,
659
+ deviceIdentifier : deviceError . deviceIdentifier ,
660
+ projectDir : projectData . projectDir ,
661
+ applicationIdentifier : projectData . projectId
662
+ } ) ;
663
+
664
+ await this . stopLiveSync ( projectData . projectDir , [ deviceError . deviceIdentifier ] , { shouldAwaitAllActions : false } ) ;
665
+ }
626
666
}
627
667
}
628
668
}
629
- }
630
- } ) ;
669
+ } ) ;
670
+ }
631
671
} , 250 ) ;
632
672
633
673
this . liveSyncProcessesInfo [ liveSyncData . projectDir ] . timer = timeoutTimer ;
@@ -683,6 +723,11 @@ export class LiveSyncService extends EventEmitter implements IDebugLiveSyncServi
683
723
this . liveSyncProcessesInfo [ liveSyncData . projectDir ] . timer = timeoutTimer ;
684
724
685
725
this . $processService . attachToProcessExitSignals ( this , ( ) => {
726
+ if ( liveSyncData . syncToPreviewApp ) {
727
+ // Do not await here, we are in process exit's handler.
728
+ this . $previewAppLiveSyncService . stopLiveSync ( ) ;
729
+ }
730
+
686
731
_ . keys ( this . liveSyncProcessesInfo ) . forEach ( projectDir => {
687
732
// Do not await here, we are in process exit's handler.
688
733
/* tslint:disable:no-floating-promises */
0 commit comments