Skip to content

Commit f8f3413

Browse files
committed
fix: sync all files when the app state does not support HOT updates in order to avoid multiple HMR syncs after restart
1 parent d938c80 commit f8f3413

File tree

3 files changed

+24
-25
lines changed

3 files changed

+24
-25
lines changed

lib/controllers/run-controller.ts

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -144,10 +144,10 @@ export class RunController extends EventEmitter implements IRunController {
144144
return this.$liveSyncProcessDataService.getDeviceDescriptors(data.projectDir);
145145
}
146146

147-
protected async refreshApplication(projectData: IProjectData, liveSyncResultInfo: ILiveSyncResultInfo, filesChangeEventData: IFilesChangeEventData, deviceDescriptor: ILiveSyncDeviceDescriptor): Promise<IRestartApplicationInfo> {
147+
protected async refreshApplication(projectData: IProjectData, liveSyncResultInfo: ILiveSyncResultInfo, filesChangeEventData: IFilesChangeEventData, deviceDescriptor: ILiveSyncDeviceDescriptor, fullSyncAction?: () => Promise<void>): Promise<IRestartApplicationInfo> {
148148
const result = deviceDescriptor.debuggingEnabled ?
149149
await this.refreshApplicationWithDebug(projectData, liveSyncResultInfo, filesChangeEventData, deviceDescriptor) :
150-
await this.refreshApplicationWithoutDebug(projectData, liveSyncResultInfo, filesChangeEventData, deviceDescriptor);
150+
await this.refreshApplicationWithoutDebug(projectData, liveSyncResultInfo, filesChangeEventData, deviceDescriptor, undefined, fullSyncAction);
151151

152152
const device = liveSyncResultInfo.deviceAppData.device;
153153

@@ -181,14 +181,15 @@ export class RunController extends EventEmitter implements IRunController {
181181
}
182182

183183
@performanceLog()
184-
protected async refreshApplicationWithoutDebug(projectData: IProjectData, liveSyncResultInfo: ILiveSyncResultInfo, filesChangeEventData: IFilesChangeEventData, deviceDescriptor: ILiveSyncDeviceDescriptor, settings?: IRefreshApplicationSettings): Promise<IRestartApplicationInfo> {
184+
protected async refreshApplicationWithoutDebug(projectData: IProjectData, liveSyncResultInfo: ILiveSyncResultInfo, filesChangeEventData: IFilesChangeEventData, deviceDescriptor: ILiveSyncDeviceDescriptor, settings?: IRefreshApplicationSettings, fullSyncAction?: () => Promise<void>): Promise<IRestartApplicationInfo> {
185185
const result = { didRestart: false };
186186
const platform = liveSyncResultInfo.deviceAppData.platform;
187187
const applicationIdentifier = projectData.projectIdentifiers[platform.toLowerCase()];
188188
const platformLiveSyncService = this.$liveSyncServiceResolver.resolveLiveSyncService(platform);
189189

190190
try {
191-
let shouldRestart = filesChangeEventData && (filesChangeEventData.hasNativeChanges || !filesChangeEventData.hasOnlyHotUpdateFiles);
191+
const isFullSync = filesChangeEventData && (filesChangeEventData.hasNativeChanges || !filesChangeEventData.hasOnlyHotUpdateFiles);
192+
let shouldRestart = isFullSync;
192193
if (!shouldRestart) {
193194
shouldRestart = await platformLiveSyncService.shouldRestart(projectData, liveSyncResultInfo);
194195
}
@@ -197,6 +198,12 @@ export class RunController extends EventEmitter implements IRunController {
197198
shouldRestart = !await platformLiveSyncService.tryRefreshApplication(projectData, liveSyncResultInfo);
198199
}
199200

201+
if (!isFullSync && shouldRestart && fullSyncAction) {
202+
this.$logger.trace(`Syncing all files as the current app state does not support hot updates.`);
203+
liveSyncResultInfo.didRecover = true;
204+
await fullSyncAction();
205+
}
206+
200207
if (shouldRestart) {
201208
this.emit(DEBUGGER_DETACHED_EVENT_NAME, { deviceIdentifier: liveSyncResultInfo.deviceAppData.device.deviceInfo.identifier });
202209
await platformLiveSyncService.restartApplication(projectData, liveSyncResultInfo);
@@ -393,16 +400,21 @@ export class RunController extends EventEmitter implements IRunController {
393400
}
394401

395402
const watchAction = async (): Promise<void> => {
396-
let liveSyncResultInfo = await platformLiveSyncService.liveSyncWatchAction(device, watchInfo);
397-
await this.refreshApplication(projectData, liveSyncResultInfo, data, deviceDescriptor);
403+
const liveSyncResultInfo = await platformLiveSyncService.liveSyncWatchAction(device, watchInfo);
404+
const fullSyncAction = async () => {
405+
watchInfo.filesToSync = allAppFiles;
406+
const fullLiveSyncResultInfo = await platformLiveSyncService.liveSyncWatchAction(device, watchInfo);
407+
// IMPORTANT: keep the same instance as we rely on side effects
408+
_.assign(liveSyncResultInfo, fullLiveSyncResultInfo);
409+
};
410+
411+
await this.refreshApplication(projectData, liveSyncResultInfo, data, deviceDescriptor, fullSyncAction);
398412

399413
if (!liveSyncResultInfo.didRecover && isInHMRMode) {
400414
const status = await this.$hmrStatusService.getHmrStatus(device.deviceInfo.identifier, data.hmrData.hash);
401415
// error or timeout
402416
if (status !== HmrConstants.HMR_SUCCESS_STATUS) {
403-
watchInfo.filesToSync = data.hmrData.fallbackFiles;
404-
liveSyncResultInfo = await platformLiveSyncService.liveSyncWatchAction(device, watchInfo);
405-
// We want to force a restart of the application.
417+
await fullSyncAction();
406418
liveSyncResultInfo.isFullSync = true;
407419
await this.refreshApplication(projectData, liveSyncResultInfo, data, deviceDescriptor);
408420
}

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

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -25,21 +25,6 @@ export class AndroidLiveSyncService extends PlatformLiveSyncServiceBase implemen
2525

2626
@performanceLog()
2727
public async liveSyncWatchAction(device: Mobile.IDevice, liveSyncInfo: ILiveSyncWatchInfo): Promise<IAndroidLiveSyncResultInfo> {
28-
let result = await this.liveSyncWatchActionCore(device, liveSyncInfo);
29-
30-
// When we use hmr, there is only one case when result.didRefresh is false.
31-
// This is the case when the app has crashed and is in ErrorActivity.
32-
// As the app might not have time to apply the patches, we will send the whole bundle.js(fallbackFiles)
33-
if (liveSyncInfo.useHotModuleReload && !result.didRefresh && liveSyncInfo.hmrData && liveSyncInfo.hmrData.hash) {
34-
liveSyncInfo.filesToSync = liveSyncInfo.hmrData.fallbackFiles;
35-
result = await this.liveSyncWatchActionCore(device, liveSyncInfo);
36-
result.didRecover = true;
37-
}
38-
39-
return result;
40-
}
41-
42-
private async liveSyncWatchActionCore(device: Mobile.IDevice, liveSyncInfo: ILiveSyncWatchInfo): Promise<IAndroidLiveSyncResultInfo> {
4328
const liveSyncResult = await super.liveSyncWatchAction(device, liveSyncInfo);
4429
const result = await this.finalizeSync(device, liveSyncInfo.projectData, liveSyncResult);
4530

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ export class IOSDeviceLiveSyncService extends DeviceLiveSyncServiceBase implemen
7676
shouldRestart = true;
7777
} else {
7878
const canExecuteFastSync = this.canExecuteFastSyncForPaths(liveSyncInfo, localToDevicePaths, projectData, deviceAppData.platform);
79-
const isRefreshConnectionSetup = this.canRefreshWithNotification(projectData, liveSyncInfo) || (!this.device.isOnlyWiFiConnected && await this.setupSocketIfNeeded(projectData));
79+
const isRefreshConnectionSetup = this.canRefreshWithNotification(projectData, liveSyncInfo) || (!this.device.isOnlyWiFiConnected && this.socket);
8080
if (!canExecuteFastSync || !isRefreshConnectionSetup) {
8181
shouldRestart = true;
8282
}
@@ -137,6 +137,8 @@ export class IOSDeviceLiveSyncService extends DeviceLiveSyncServiceBase implemen
137137
waitForDebugger: liveSyncInfo.waitForDebugger,
138138
projectDir: projectData.projectDir
139139
});
140+
// enable HOT updates
141+
await this.setupSocketIfNeeded(projectData);
140142
}
141143

142144
private async reloadPage(): Promise<void> {

0 commit comments

Comments
 (0)