From 7d4f742645058f5adea0e1312cb3e9bbbf552634 Mon Sep 17 00:00:00 2001 From: rosen-vladimirov Date: Mon, 1 Jul 2019 13:37:24 +0300 Subject: [PATCH 1/3] fix: remove debug qr code message --- lib/services/livesync/playground/preview-qr-code-service.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/lib/services/livesync/playground/preview-qr-code-service.ts b/lib/services/livesync/playground/preview-qr-code-service.ts index 3da28180c1..2609a2cd55 100644 --- a/lib/services/livesync/playground/preview-qr-code-service.ts +++ b/lib/services/livesync/playground/preview-qr-code-service.ts @@ -44,8 +44,6 @@ export class PreviewQrCodeService implements IPreviewQrCodeService { const qrCodeUrl = this.$previewSdkService.getQrCodeUrl(options); const url = await this.getShortenUrl(qrCodeUrl); - this.$logger.info("======== qrCodeUrl ======== ", qrCodeUrl); - this.$logger.info(); const message = `${EOL} Generating qrcode for url ${url}.`; this.$logger.trace(message); From 83609a332a9ae0ef75d49c009a09d7307ce28aa7 Mon Sep 17 00:00:00 2001 From: rosen-vladimirov Date: Mon, 1 Jul 2019 13:45:55 +0300 Subject: [PATCH 2/3] fix: do not start multiple watchers In some cases (for example `tns preview` and scan QR code simultaneously with several devices) we start multiple watchers per platform. We should always have single watcher per platform (one from webpack and one native in fact). --- lib/controllers/prepare-controller.ts | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/lib/controllers/prepare-controller.ts b/lib/controllers/prepare-controller.ts index 52c1eec584..87a9d62098 100644 --- a/lib/controllers/prepare-controller.ts +++ b/lib/controllers/prepare-controller.ts @@ -80,24 +80,24 @@ export class PrepareController extends EventEmitter { nativeFilesWatcher: null, webpackCompilerProcess: null }; - } + await this.startJSWatcherWithPrepare(platformData, projectData, prepareData); // -> start watcher + initial compilation + const hasNativeChanges = await this.startNativeWatcherWithPrepare(platformData, projectData, prepareData); // -> start watcher + initial prepare + const result = { platform: platformData.platformNameLowerCase, hasNativeChanges }; - await this.startJSWatcherWithPrepare(platformData, projectData, prepareData); // -> start watcher + initial compilation - const hasNativeChanges = await this.startNativeWatcherWithPrepare(platformData, projectData, prepareData); // -> start watcher + initial prepare + const hasPersistedDataWithNativeChanges = this.persistedData.find(data => data.platform === result.platform && data.hasNativeChanges); + if (hasPersistedDataWithNativeChanges) { + result.hasNativeChanges = true; + } - const result = { platform: platformData.platformNameLowerCase, hasNativeChanges }; - const hasPersistedDataWithNativeChanges = this.persistedData.find(data => data.platform === result.platform && data.hasNativeChanges); - if (hasPersistedDataWithNativeChanges) { - result.hasNativeChanges = true; - } + // TODO: Do not persist this in `this` context. Also it should be per platform. + this.isInitialPrepareReady = true; - this.isInitialPrepareReady = true; + if (this.persistedData && this.persistedData.length) { + this.emitPrepareEvent({ files: [], hasOnlyHotUpdateFiles: false, hasNativeChanges: result.hasNativeChanges, hmrData: null, platform: platformData.platformNameLowerCase }); + } - if (this.persistedData && this.persistedData.length) { - this.emitPrepareEvent({ files: [], hasOnlyHotUpdateFiles: false, hasNativeChanges: result.hasNativeChanges, hmrData: null, platform: platformData.platformNameLowerCase }); + return result; } - - return result; } private async startJSWatcherWithPrepare(platformData: IPlatformData, projectData: IProjectData, prepareData: IPrepareData): Promise { From d6af7bff74f88e3e923efdd22290018d0e86467a Mon Sep 17 00:00:00 2001 From: rosen-vladimirov Date: Mon, 1 Jul 2019 13:57:26 +0300 Subject: [PATCH 3/3] fix: handle preview initial sync once per device Handle preview initial sync once per device (in some cases PubNub reports the device multiple times). Also prepare all the files once per platform, not per each device. --- lib/controllers/preview-app-controller.ts | 33 +++++++++++++++-------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/lib/controllers/preview-app-controller.ts b/lib/controllers/preview-app-controller.ts index 9cf26564d8..c1883a76bf 100644 --- a/lib/controllers/preview-app-controller.ts +++ b/lib/controllers/preview-app-controller.ts @@ -9,7 +9,8 @@ import { PrepareDataService } from "../services/prepare-data-service"; import { PreviewAppLiveSyncEvents } from "../services/livesync/playground/preview-app-constants"; export class PreviewAppController extends EventEmitter implements IPreviewAppController { - private deviceInitializationPromise: IDictionary> = {}; + private deviceInitializationPromise: IDictionary = {}; + private platformPrepareHandlers: IDictionary = {}; private promise = Promise.resolve(); constructor( @@ -49,9 +50,14 @@ export class PreviewAppController extends EventEmitter implements IPreviewAppCon } if (this.deviceInitializationPromise[device.id]) { - return this.deviceInitializationPromise[device.id]; + // In some cases devices are reported several times during initialization. + // In case we are already preparing the sending of initial files, disregard consecutive requests for initial files + // until we send the files we are currently preparing. + return null; } + this.deviceInitializationPromise[device.id] = true; + if (device.uniqueId) { await this.$analyticsService.trackEventActionInGoogleAnalytics({ action: TrackActionNames.PreviewAppData, @@ -68,20 +74,25 @@ export class PreviewAppController extends EventEmitter implements IPreviewAppCon await this.$previewAppPluginsService.comparePluginsOnDevice(data, device); - this.$prepareController.on(PREPARE_READY_EVENT_NAME, async currentPrepareData => { - await this.handlePrepareReadyEvent(data, currentPrepareData.hmrData, currentPrepareData.files, device.platform); - }); + if (!this.platformPrepareHandlers[device.platform]) { + // TODO: Unset this property once the preview operation for this platform is stopped + this.platformPrepareHandlers[device.platform] = true; + + // TODO: Remove the handler once the preview operation for this platform is stopped + this.$prepareController.on(PREPARE_READY_EVENT_NAME, async currentPrepareData => { + await this.handlePrepareReadyEvent(data, currentPrepareData.hmrData, currentPrepareData.files, device.platform); + }); - if (!data.env) { data.env = { }; } + } + + data.env = data.env || {}; data.env.externals = this.$previewAppPluginsService.getExternalPlugins(device); - const prepareData = this.$prepareDataService.getPrepareData(data.projectDir, device.platform.toLowerCase(), { ...data, nativePrepare: { skipNativePrepare: true }, watch: true }); + const prepareData = this.$prepareDataService.getPrepareData(data.projectDir, device.platform.toLowerCase(), { ...data, nativePrepare: { skipNativePrepare: true }, watch: true }); await this.$prepareController.prepare(prepareData); - this.deviceInitializationPromise[device.id] = this.getInitialFilesForPlatformSafe(data, device.platform); - try { - const payloads = await this.deviceInitializationPromise[device.id]; + const payloads = await this.getInitialFilesForPlatformSafe(data, device.platform); return payloads; } finally { this.deviceInitializationPromise[device.id] = null; @@ -116,7 +127,7 @@ export class PreviewAppController extends EventEmitter implements IPreviewAppCon if (status === HmrConstants.HMR_ERROR_STATUS) { const originalUseHotModuleReload = data.useHotModuleReload; data.useHotModuleReload = false; - await this.syncFilesForPlatformSafe(data, { filesToSync: platformHmrData.fallbackFiles }, platform, previewDevice.id ); + await this.syncFilesForPlatformSafe(data, { filesToSync: platformHmrData.fallbackFiles }, platform, previewDevice.id); data.useHotModuleReload = originalUseHotModuleReload; } }));