Skip to content

Commit ed42427

Browse files
authored
Merge pull request #4766 from NativeScript/fatme/fix-native-sync
fix: fix native change during livesync
2 parents 6b185be + 7441082 commit ed42427

File tree

4 files changed

+59
-72
lines changed

4 files changed

+59
-72
lines changed

lib/controllers/run-controller.ts

+48-63
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,16 @@ export class RunController extends EventEmitter implements IRunController {
124124
await this.refreshApplicationWithDebug(projectData, liveSyncResultInfo, filesChangeEventData, deviceDescriptor, settings) :
125125
await this.refreshApplicationWithoutDebug(projectData, liveSyncResultInfo, filesChangeEventData, deviceDescriptor, settings);
126126

127+
const device = liveSyncResultInfo.deviceAppData.device;
128+
129+
this.emitCore(RunOnDeviceEvents.runOnDeviceExecuted, {
130+
projectDir: projectData.projectDir,
131+
deviceIdentifier: device.deviceInfo.identifier,
132+
applicationIdentifier: projectData.projectIdentifiers[device.deviceInfo.platform.toLowerCase()],
133+
syncedFiles: liveSyncResultInfo.modifiedFilesData.map(m => m.getLocalPath()),
134+
isFullSync: liveSyncResultInfo.isFullSync
135+
});
136+
127137
return result;
128138
}
129139

@@ -282,14 +292,6 @@ export class RunController extends EventEmitter implements IRunController {
282292

283293
await this.refreshApplication(projectData, liveSyncResultInfo, null, deviceDescriptor);
284294

285-
this.emitCore(RunOnDeviceEvents.runOnDeviceExecuted, {
286-
projectDir: projectData.projectDir,
287-
deviceIdentifier: device.deviceInfo.identifier,
288-
applicationIdentifier: projectData.projectIdentifiers[device.deviceInfo.platform.toLowerCase()],
289-
syncedFiles: liveSyncResultInfo.modifiedFilesData.map(m => m.getLocalPath()),
290-
isFullSync: liveSyncResultInfo.isFullSync
291-
});
292-
293295
this.$logger.info(`Successfully synced application ${liveSyncResultInfo.deviceAppData.appIdentifier} on device ${liveSyncResultInfo.deviceAppData.device.deviceInfo.identifier}.`);
294296

295297
this.emitCore(RunOnDeviceEvents.runOnDeviceStarted, {
@@ -327,81 +329,64 @@ export class RunController extends EventEmitter implements IRunController {
327329
});
328330

329331
try {
330-
if (data.hasNativeChanges) {
331-
const rebuiltInfo = this.rebuiltInformation[platformData.platformNameLowerCase] && (this.$mobileHelper.isAndroidPlatform(platformData.platformNameLowerCase) || this.rebuiltInformation[platformData.platformNameLowerCase].isEmulator === device.isEmulator);
332-
if (!rebuiltInfo) {
333-
await this.$prepareNativePlatformService.prepareNativePlatform(platformData, projectData, prepareData);
334-
await deviceDescriptor.buildAction();
335-
this.rebuiltInformation[platformData.platformNameLowerCase] = { isEmulator: device.isEmulator, platform: platformData.platformNameLowerCase, packageFilePath: null };
336-
}
337-
338-
await this.$deviceInstallAppService.installOnDevice(device, deviceDescriptor.buildData, this.rebuiltInformation[platformData.platformNameLowerCase].packageFilePath);
339-
}
340-
341-
const isInHMRMode = liveSyncInfo.useHotModuleReload && data.hmrData && data.hmrData.hash;
342-
if (isInHMRMode) {
343-
this.$hmrStatusService.watchHmrStatus(device.deviceInfo.identifier, data.hmrData.hash);
344-
}
345-
346332
const platformLiveSyncService = this.$liveSyncServiceResolver.resolveLiveSyncService(device.deviceInfo.platform);
347333
const watchInfo = {
348334
liveSyncDeviceData: deviceDescriptor,
349335
projectData,
350336
filesToRemove: <any>[],
351337
filesToSync: data.files,
352-
isReinstalled: false,
353338
hmrData: data.hmrData,
354339
useHotModuleReload: liveSyncInfo.useHotModuleReload,
355340
force: liveSyncInfo.force,
356341
connectTimeout: 1000
357342
};
358-
let liveSyncResultInfo = await platformLiveSyncService.liveSyncWatchAction(device, watchInfo);
343+
const deviceAppData = await platformLiveSyncService.getAppData(_.merge({ device, watch: true }, watchInfo));
359344

360-
await this.refreshApplication(projectData, liveSyncResultInfo, data, deviceDescriptor);
345+
if (data.hasNativeChanges) {
346+
const rebuiltInfo = this.rebuiltInformation[platformData.platformNameLowerCase] && (this.$mobileHelper.isAndroidPlatform(platformData.platformNameLowerCase) || this.rebuiltInformation[platformData.platformNameLowerCase].isEmulator === device.isEmulator);
347+
if (!rebuiltInfo) {
348+
await this.$prepareNativePlatformService.prepareNativePlatform(platformData, projectData, prepareData);
349+
await deviceDescriptor.buildAction();
350+
this.rebuiltInformation[platformData.platformNameLowerCase] = { isEmulator: device.isEmulator, platform: platformData.platformNameLowerCase, packageFilePath: null };
351+
}
361352

362-
this.emitCore(RunOnDeviceEvents.runOnDeviceExecuted, {
363-
projectDir: projectData.projectDir,
364-
deviceIdentifier: device.deviceInfo.identifier,
365-
applicationIdentifier: projectData.projectIdentifiers[device.deviceInfo.platform.toLowerCase()],
366-
syncedFiles: liveSyncResultInfo.modifiedFilesData.map(m => m.getLocalPath()),
367-
isFullSync: liveSyncResultInfo.isFullSync
368-
});
353+
await this.$deviceInstallAppService.installOnDevice(device, deviceDescriptor.buildData, this.rebuiltInformation[platformData.platformNameLowerCase].packageFilePath);
354+
await platformLiveSyncService.syncAfterInstall(device, watchInfo);
355+
await platformLiveSyncService.restartApplication(projectData, { deviceAppData, modifiedFilesData: [], isFullSync: false, useHotModuleReload: liveSyncInfo.useHotModuleReload });
356+
} else {
357+
const isInHMRMode = liveSyncInfo.useHotModuleReload && data.hmrData && data.hmrData.hash;
358+
if (isInHMRMode) {
359+
this.$hmrStatusService.watchHmrStatus(device.deviceInfo.identifier, data.hmrData.hash);
360+
}
369361

370-
if (!liveSyncResultInfo.didRecover && isInHMRMode) {
371-
const status = await this.$hmrStatusService.getHmrStatus(device.deviceInfo.identifier, data.hmrData.hash);
372-
if (status === HmrConstants.HMR_ERROR_STATUS) {
373-
watchInfo.filesToSync = data.hmrData.fallbackFiles;
374-
liveSyncResultInfo = await platformLiveSyncService.liveSyncWatchAction(device, watchInfo);
375-
// We want to force a restart of the application.
376-
liveSyncResultInfo.isFullSync = true;
377-
await this.refreshApplication(projectData, liveSyncResultInfo, data, deviceDescriptor);
378-
379-
this.emitCore(RunOnDeviceEvents.runOnDeviceExecuted, {
380-
projectDir: projectData.projectDir,
381-
deviceIdentifier: device.deviceInfo.identifier,
382-
applicationIdentifier: projectData.projectIdentifiers[device.deviceInfo.platform.toLowerCase()],
383-
syncedFiles: liveSyncResultInfo.modifiedFilesData.map(m => m.getLocalPath()),
384-
isFullSync: liveSyncResultInfo.isFullSync
385-
});
362+
let liveSyncResultInfo = await platformLiveSyncService.liveSyncWatchAction(device, watchInfo);
363+
364+
if (!liveSyncResultInfo.didRecover && isInHMRMode) {
365+
const status = await this.$hmrStatusService.getHmrStatus(device.deviceInfo.identifier, data.hmrData.hash);
366+
if (status === HmrConstants.HMR_ERROR_STATUS) {
367+
watchInfo.filesToSync = data.hmrData.fallbackFiles;
368+
liveSyncResultInfo = await platformLiveSyncService.liveSyncWatchAction(device, watchInfo);
369+
// We want to force a restart of the application.
370+
liveSyncResultInfo.isFullSync = true;
371+
await this.refreshApplication(projectData, liveSyncResultInfo, data, deviceDescriptor);
372+
}
386373
}
374+
375+
await this.refreshApplication(projectData, liveSyncResultInfo, data, deviceDescriptor);
387376
}
388377

389-
this.$logger.info(`Successfully synced application ${liveSyncResultInfo.deviceAppData.appIdentifier} on device ${liveSyncResultInfo.deviceAppData.device.deviceInfo.identifier}.`);
378+
this.$logger.info(`Successfully synced application ${deviceAppData.appIdentifier} on device ${device.deviceInfo.identifier}.`);
390379
} catch (err) {
391-
const allErrors = (<Mobile.IDevicesOperationError>err).allErrors;
380+
this.$logger.warn(`Unable to apply changes for device: ${device.deviceInfo.identifier}. Error is: ${err && err.message}.`);
392381

393-
if (allErrors && _.isArray(allErrors)) {
394-
for (const deviceError of allErrors) {
395-
this.$logger.warn(`Unable to apply changes for device: ${deviceError.deviceIdentifier}. Error is: ${deviceError.message}.`);
382+
this.emitCore(RunOnDeviceEvents.runOnDeviceError, {
383+
projectDir: projectData.projectDir,
384+
deviceIdentifier: device.deviceInfo.identifier,
385+
applicationIdentifier: projectData.projectIdentifiers[device.deviceInfo.platform.toLowerCase()],
386+
error: err,
387+
});
396388

397-
this.emitCore(RunOnDeviceEvents.runOnDeviceError, {
398-
projectDir: projectData.projectDir,
399-
deviceIdentifier: device.deviceInfo.identifier,
400-
applicationIdentifier: projectData.projectIdentifiers[device.deviceInfo.platform.toLowerCase()],
401-
error: err,
402-
});
403-
}
404-
}
389+
await this.stop({ projectDir: projectData.projectDir, deviceIdentifiers: [device.deviceInfo.identifier] });
405390
}
406391
};
407392

lib/definitions/livesync.d.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,6 @@ declare global {
210210
interface ILiveSyncWatchInfo extends IProjectDataComposition, IHasUseHotModuleReloadOption, IConnectTimeoutOption {
211211
filesToRemove: string[];
212212
filesToSync: string[];
213-
isReinstalled: boolean;
214213
liveSyncDeviceData: ILiveSyncDeviceDescriptor;
215214
hmrData: IPlatformHmrData;
216215
force?: boolean;
@@ -250,6 +249,8 @@ declare global {
250249
restartApplication(projectData: IProjectData, liveSyncInfo: ILiveSyncResultInfo): Promise<void>;
251250
shouldRestart(projectData: IProjectData, liveSyncInfo: ILiveSyncResultInfo): Promise<boolean>;
252251
getDeviceLiveSyncService(device: Mobile.IDevice, projectData: IProjectData): INativeScriptDeviceLiveSyncService;
252+
getAppData(syncInfo: IFullSyncInfo): Promise<Mobile.IDeviceAppData>;
253+
syncAfterInstall(device: Mobile.IDevice, liveSyncInfo: ILiveSyncWatchInfo): Promise<void>;
253254
}
254255

255256
interface IRestartApplicationInfo {

lib/services/livesync/ios-livesync-service.ts

+3-6
Original file line numberDiff line numberDiff line change
@@ -55,19 +55,16 @@ export class IOSLiveSyncService extends PlatformLiveSyncServiceBase implements I
5555
};
5656
}
5757

58-
@performanceLog()
59-
public liveSyncWatchAction(device: Mobile.IDevice, liveSyncInfo: ILiveSyncWatchInfo): Promise<ILiveSyncResultInfo> {
60-
if (liveSyncInfo.isReinstalled) {
58+
public async syncAfterInstall(device: Mobile.IDevice, liveSyncInfo: ILiveSyncWatchInfo): Promise<void> {
59+
if (!device.isEmulator) {
6160
// In this case we should execute fullsync because iOS Runtime requires the full content of app dir to be extracted in the root of sync dir.
62-
return this.fullSync({
61+
await this.fullSync({
6362
projectData: liveSyncInfo.projectData,
6463
device,
6564
liveSyncDeviceData: liveSyncInfo.liveSyncDeviceData,
6665
watch: true,
6766
useHotModuleReload: liveSyncInfo.useHotModuleReload
6867
});
69-
} else {
70-
return super.liveSyncWatchAction(device, liveSyncInfo);
7168
}
7269
}
7370

lib/services/livesync/platform-livesync-service-base.ts

+6-2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import * as path from "path";
22
import * as util from "util";
33
import { APP_FOLDER_NAME } from "../../constants";
44
import { getHash } from "../../common/helpers";
5+
import { performanceLog } from "../../common/decorators";
56

67
export abstract class PlatformLiveSyncServiceBase {
78
private _deviceLiveSyncServicesCache: IDictionary<INativeScriptDeviceLiveSyncService> = {};
@@ -32,6 +33,8 @@ export abstract class PlatformLiveSyncServiceBase {
3233
return shouldRestart;
3334
}
3435

36+
public async syncAfterInstall(device: Mobile.IDevice, liveSyncInfo: ILiveSyncWatchInfo): Promise<void> { /* intentionally left blank */ }
37+
3538
public async restartApplication(projectData: IProjectData, liveSyncInfo: ILiveSyncResultInfo): Promise<void> {
3639
const deviceLiveSyncService = this.getDeviceLiveSyncService(liveSyncInfo.deviceAppData.device, projectData);
3740
this.$logger.info(`Restarting application on device ${liveSyncInfo.deviceAppData.device.deviceInfo.identifier}...`);
@@ -72,6 +75,7 @@ export abstract class PlatformLiveSyncServiceBase {
7275
};
7376
}
7477

78+
@performanceLog()
7579
public async liveSyncWatchAction(device: Mobile.IDevice, liveSyncInfo: ILiveSyncWatchInfo): Promise<ILiveSyncResultInfo> {
7680
const projectData = liveSyncInfo.projectData;
7781
const deviceLiveSyncService = this.getDeviceLiveSyncService(device, projectData);
@@ -122,7 +126,7 @@ export abstract class PlatformLiveSyncServiceBase {
122126

123127
return {
124128
modifiedFilesData: modifiedLocalToDevicePaths,
125-
isFullSync: liveSyncInfo.isReinstalled,
129+
isFullSync: false,
126130
deviceAppData,
127131
useHotModuleReload: liveSyncInfo.useHotModuleReload
128132
};
@@ -141,7 +145,7 @@ export abstract class PlatformLiveSyncServiceBase {
141145
return transferredFiles;
142146
}
143147

144-
protected async getAppData(syncInfo: IFullSyncInfo): Promise<Mobile.IDeviceAppData> {
148+
public async getAppData(syncInfo: IFullSyncInfo): Promise<Mobile.IDeviceAppData> {
145149
const platform = syncInfo.device.deviceInfo.platform.toLowerCase();
146150
const appIdentifier = syncInfo.projectData.projectIdentifiers[platform];
147151
const deviceProjectRootOptions: IDeviceProjectRootOptions = _.assign({ appIdentifier }, syncInfo);

0 commit comments

Comments
 (0)