Skip to content

Commit ca2a342

Browse files
committed
feat: respect removed files on preview command
1 parent 5c3f893 commit ca2a342

File tree

5 files changed

+81
-77
lines changed

5 files changed

+81
-77
lines changed

lib/definitions/preview-app-livesync.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { FilePayload, Device, FilesPayload } from "nativescript-preview-sdk";
33
declare global {
44
interface IPreviewAppLiveSyncService {
55
initialize(data: IPreviewAppLiveSyncData): void;
6-
syncFiles(data: IPreviewAppLiveSyncData, filesToSync: string[]): Promise<void>;
6+
syncFiles(data: IPreviewAppLiveSyncData, filesToSync: string[], filesToRemove: string[]): Promise<void>;
77
stopLiveSync(): Promise<void>;
88
}
99

lib/services/livesync/livesync-service.ts

Lines changed: 16 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -588,9 +588,15 @@ export class LiveSyncService extends EventEmitter implements IDebugLiveSyncServi
588588

589589
const startSyncFilesTimeout = (platform?: string) => {
590590
timeoutTimer = setTimeout(async () => {
591-
if (liveSyncData.syncToPreviewApp) {
592-
await this.addActionToChain(projectData.projectDir, async () => {
593-
if (filesToSync.length || filesToRemove.length) {
591+
if (filesToSync.length || filesToRemove.length) {
592+
const currentFilesToSync = _.cloneDeep(filesToSync);
593+
filesToSync.splice(0, filesToSync.length);
594+
595+
const currentFilesToRemove = _.cloneDeep(filesToRemove);
596+
filesToRemove = [];
597+
598+
if (liveSyncData.syncToPreviewApp) {
599+
await this.addActionToChain(projectData.projectDir, async () => {
594600
await this.$previewAppLiveSyncService.syncFiles({
595601
appFilesUpdaterOptions: {
596602
bundle: liveSyncData.bundle,
@@ -599,22 +605,12 @@ export class LiveSyncService extends EventEmitter implements IDebugLiveSyncServi
599605
},
600606
env: liveSyncData.env,
601607
projectDir: projectData.projectDir
602-
}, filesToSync);
603-
filesToSync = [];
604-
filesToRemove = [];
605-
}
606-
});
607-
} else {
608-
// Push actions to the queue, do not start them simultaneously
609-
await this.addActionToChain(projectData.projectDir, async () => {
610-
if (filesToSync.length || filesToRemove.length) {
608+
}, currentFilesToSync, currentFilesToRemove);
609+
});
610+
} else {
611+
// Push actions to the queue, do not start them simultaneously
612+
await this.addActionToChain(projectData.projectDir, async () => {
611613
try {
612-
const currentFilesToSync = _.cloneDeep(filesToSync);
613-
filesToSync.splice(0, filesToSync.length);
614-
615-
const currentFilesToRemove = _.cloneDeep(filesToRemove);
616-
filesToRemove = [];
617-
618614
const allModifiedFiles = [].concat(currentFilesToSync).concat(currentFilesToRemove);
619615

620616
const preparedPlatforms: string[] = [];
@@ -681,8 +677,8 @@ export class LiveSyncService extends EventEmitter implements IDebugLiveSyncServi
681677
}
682678
}
683679
}
684-
}
685-
});
680+
});
681+
}
686682
}
687683
}, 250);
688684

lib/services/livesync/playground/preview-app-constants.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
export class PreviewSdkEventNames {
22
public static CHANGE_EVENT_NAME = "change";
3+
public static UNLINK_EVENT_NAME = "unlink";
34
}
45

56
export class PubnubKeys {

lib/services/livesync/playground/preview-app-livesync-service.ts

Lines changed: 62 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,9 @@ export class PreviewAppLiveSyncService implements IPreviewAppLiveSyncService {
4646
let promise = Promise.resolve<FilesPayload>(null);
4747
const startSyncFilesTimeout = async (platform: string) => {
4848
await promise
49-
.then(async () => {
50-
const projectData = this.$projectDataService.getProjectData(data.projectDir);
51-
promise = this.applyChanges(this.$platformsData.getPlatformData(platform, projectData), projectData, filesToSyncMap[platform]);
49+
.then(async () => {
50+
// We don't need to prepare when webpack emits changed files. We just need to send a message to pubnub.
51+
promise = this.syncFilesForPlatformSafe(data, platform, { filesToSync: filesToSyncMap[platform], skipPrepare: true });
5252
await promise;
5353
});
5454
filesToSyncMap[platform] = [];
@@ -67,13 +67,12 @@ export class PreviewAppLiveSyncService implements IPreviewAppLiveSyncService {
6767
}
6868
});
6969
await this.$previewAppPluginsService.comparePluginsOnDevice(data, device);
70-
const payloads = await this.syncFilesForPlatformSafe(data, device.platform);
71-
payloads.deviceId = device.id;
70+
const payloads = await this.syncFilesForPlatformSafe(data, device.platform, { isInitialSync: true });
7271
return payloads;
7372
}
7473

75-
public async syncFiles(data: IPreviewAppLiveSyncData, files?: string[]): Promise<void> {
76-
this.showWarningsForNativeFiles(files);
74+
public async syncFiles(data: IPreviewAppLiveSyncData, filesToSync: string[], filesToRemove: string[]): Promise<void> {
75+
this.showWarningsForNativeFiles(filesToSync);
7776

7877
for (const device of this.$previewSdkService.connectedDevices) {
7978
await this.$previewAppPluginsService.comparePluginsOnDevice(data, device);
@@ -85,83 +84,60 @@ export class PreviewAppLiveSyncService implements IPreviewAppLiveSyncService {
8584
.value();
8685

8786
for (const platform of platforms) {
88-
await this.syncFilesForPlatformSafe(data, platform, files);
87+
await this.syncFilesForPlatformSafe(data, platform, { filesToSync, filesToRemove });
8988
}
9089
}
9190

9291
public async stopLiveSync(): Promise<void> {
9392
this.$previewSdkService.stop();
9493
}
9594

96-
private async syncFilesForPlatformSafe(data: IPreviewAppLiveSyncData, platform: string, files?: string[]): Promise<FilesPayload> {
95+
private async syncFilesForPlatformSafe(data: IPreviewAppLiveSyncData, platform: string, opts?: { filesToSync?: string[], filesToRemove?: string[], isInitialSync?: boolean, skipPrepare?: boolean }): Promise<FilesPayload> {
9796
this.$logger.info(`Start syncing changes for platform ${platform}.`);
9897

98+
opts = opts || {};
99+
const { filesToSync, filesToRemove } = opts;
100+
let payloads = null;
101+
99102
try {
100103
const { appFilesUpdaterOptions, env, projectDir } = data;
101104
const projectData = this.$projectDataService.getProjectData(projectDir);
102105
const platformData = this.$platformsData.getPlatformData(platform, projectData);
103-
await this.preparePlatform(platform, appFilesUpdaterOptions, env, projectData);
104106

105-
let result: FilesPayload = null;
106-
if (files && files.length) {
107-
result = await this.applyChanges(platformData, projectData, files);
108-
this.$logger.info(`Successfully synced ${result.files.map(filePayload => filePayload.file.yellow)} for platform ${platform}.`);
109-
} else {
110-
result = await this.getFilesPayload(platformData, projectData);
107+
if (!opts.skipPrepare) {
108+
await this.preparePlatform(platform, appFilesUpdaterOptions, env, projectData);
109+
}
110+
111+
if (opts.isInitialSync) {
112+
const platformsAppFolderPath = path.join(platformData.appDestinationDirectoryPath, APP_FOLDER_NAME);
113+
const files = this.$projectFilesManager.getProjectFiles(platformsAppFolderPath);
114+
payloads = this.getFilesPayload(platformData, projectData, files);
111115
this.$logger.info(`Successfully synced changes for platform ${platform}.`);
116+
} else {
117+
const files = _.map(filesToSync, file => this.$projectFilesProvider.mapFilePath(file, platformData.normalizedPlatformName, projectData));
118+
payloads = this.getFilesPayload(platformData, projectData, files, filesToRemove);
119+
await this.$previewSdkService.applyChanges(payloads);
120+
this.$logger.info(`Successfully synced ${payloads.files.map(filePayload => filePayload.file.yellow)} for platform ${platform}.`);
112121
}
113122

114-
return result;
123+
return payloads;
115124
} catch (err) {
116125
this.$logger.warn(`Unable to apply changes for platform ${platform}. Error is: ${err}, ${JSON.stringify(err, null, 2)}.`);
117126
}
118127
}
119128

120-
private async applyChanges(platformData: IPlatformData, projectData: IProjectData, files: string[]): Promise<FilesPayload> {
121-
const payloads = this.getFilesPayload(platformData, projectData, _(files).uniq().value());
122-
await this.$previewSdkService.applyChanges(payloads);
123-
124-
return payloads;
125-
}
126-
127-
private getFilesPayload(platformData: IPlatformData, projectData: IProjectData, files?: string[]): FilesPayload {
128-
const platformsAppFolderPath = path.join(platformData.appDestinationDirectoryPath, APP_FOLDER_NAME);
129-
130-
if (files && files.length) {
131-
files = files.map(file => this.$projectFilesProvider.mapFilePath(file, platformData.normalizedPlatformName, projectData));
132-
} else {
133-
files = this.$projectFilesManager.getProjectFiles(platformsAppFolderPath);
134-
}
135-
136-
const filesToTransfer = files
129+
private getFilesPayload(platformData: IPlatformData, projectData: IProjectData, filesToSync?: string[], filesToRemove?: string[]): FilesPayload {
130+
const filesToTransfer = filesToSync
137131
.filter(file => file.indexOf(TNS_MODULES_FOLDER_NAME) === -1)
138132
.filter(file => file.indexOf(APP_RESOURCES_FOLDER_NAME) === -1)
139133
.filter(file => !_.includes(this.excludedFiles, path.basename(file)))
140134
.filter(file => !_.includes(this.excludedFileExtensions, path.extname(file)));
141135

142136
this.$logger.trace(`Transferring ${filesToTransfer.join("\n")}.`);
143137

144-
const payloads = filesToTransfer
145-
.map(file => {
146-
const projectFileInfo = this.$projectFilesProvider.getProjectFileInfo(file, platformData.normalizedPlatformName, null);
147-
const relativePath = path.relative(platformsAppFolderPath, file);
148-
const filePayload: FilePayload = {
149-
event: PreviewSdkEventNames.CHANGE_EVENT_NAME,
150-
file: path.join(path.dirname(relativePath), projectFileInfo.onDeviceFileName),
151-
binary: isTextOrBinary.isBinarySync(file),
152-
fileContents: ""
153-
};
154-
155-
if (filePayload.binary) {
156-
const bitmap = <string>this.$fs.readFile(file);
157-
const base64 = Buffer.from(bitmap).toString('base64');
158-
filePayload.fileContents = base64;
159-
} else {
160-
filePayload.fileContents = this.$fs.readText(path.join(path.dirname(projectFileInfo.filePath), projectFileInfo.onDeviceFileName));
161-
}
162-
163-
return filePayload;
164-
});
138+
const payloadsToSync = filesToTransfer.map(file => this.createFilePayload(file, platformData, projectData, PreviewSdkEventNames.CHANGE_EVENT_NAME));
139+
const payloadsToRemove = _.map(filesToRemove, file => this.createFilePayload(file, platformData, projectData, PreviewSdkEventNames.UNLINK_EVENT_NAME));
140+
const payloads = payloadsToSync.concat(payloadsToRemove);
165141

166142
return { files: payloads, platform: platformData.normalizedPlatformName.toLowerCase() };
167143
}
@@ -188,5 +164,36 @@ export class PreviewAppLiveSyncService implements IPreviewAppLiveSyncService {
188164
_.filter(files, file => file.indexOf(APP_RESOURCES_FOLDER_NAME) > -1)
189165
.forEach(file => this.$logger.warn(`Unable to apply changes from ${APP_RESOURCES_FOLDER_NAME} folder. You need to build your application in order to make changes in ${APP_RESOURCES_FOLDER_NAME} folder.`));
190166
}
167+
168+
private createFilePayload(file: string, platformData: IPlatformData, projectData: IProjectData, event: string): FilePayload {
169+
const projectFileInfo = this.$projectFilesProvider.getProjectFileInfo(file, platformData.normalizedPlatformName, null);
170+
const binary = isTextOrBinary.isBinarySync(file);
171+
let fileContents = "";
172+
let filePath = "";
173+
174+
if (event === PreviewSdkEventNames.CHANGE_EVENT_NAME) {
175+
const relativePath = path.relative(path.join(platformData.appDestinationDirectoryPath, APP_FOLDER_NAME), file);
176+
filePath = path.join(path.dirname(relativePath), projectFileInfo.onDeviceFileName);
177+
178+
if (binary) {
179+
const bitmap = <string>this.$fs.readFile(file);
180+
const base64 = Buffer.from(bitmap).toString('base64');
181+
fileContents = base64;
182+
} else {
183+
fileContents = this.$fs.readText(path.join(path.dirname(projectFileInfo.filePath), projectFileInfo.onDeviceFileName));
184+
}
185+
} else if (event === PreviewSdkEventNames.UNLINK_EVENT_NAME) {
186+
filePath = path.relative(path.join(projectData.projectDir, APP_FOLDER_NAME), file);
187+
}
188+
189+
const filePayload = {
190+
event,
191+
file: filePath,
192+
binary,
193+
fileContents
194+
};
195+
196+
return filePayload;
197+
}
191198
}
192199
$injector.register("previewAppLiveSyncService", PreviewAppLiveSyncService);

test/services/playground/preview-app-livesync-service.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,7 @@ async function syncFiles(input?: IActInput) {
197197
await previewSdkService.getInitialFiles(deviceMockData);
198198
}
199199

200-
await previewAppLiveSyncService.syncFiles(syncFilesMockData, projectFiles);
200+
await previewAppLiveSyncService.syncFiles(syncFilesMockData, projectFiles, []);
201201
}
202202

203203
async function assert(expectedFiles: string[], options?: IAssertOptions) {

0 commit comments

Comments
 (0)