1
1
import * as path from "path" ;
2
- import { FilePayload , Device , FilesPayload } from "nativescript-preview-sdk" ;
3
- import { PreviewSdkEventNames } from "./preview-app-constants" ;
4
- import { APP_FOLDER_NAME , APP_RESOURCES_FOLDER_NAME , TNS_MODULES_FOLDER_NAME } from "../../../constants" ;
2
+ import { Device , FilesPayload } from "nativescript-preview-sdk" ;
3
+ import { APP_RESOURCES_FOLDER_NAME , APP_FOLDER_NAME } from "../../../constants" ;
5
4
import { HmrConstants } from "../../../common/constants" ;
6
- const isTextOrBinary = require ( 'istextorbinary' ) ;
7
-
8
- interface ISyncFilesOptions {
9
- filesToSync ?: string [ ] ;
10
- filesToRemove ?: string [ ] ;
11
- isInitialSync ?: boolean ;
12
- skipPrepare ?: boolean ;
13
- useHotModuleReload ?: boolean ;
14
- deviceId ?: string ;
15
- }
16
5
17
6
export class PreviewAppLiveSyncService implements IPreviewAppLiveSyncService {
18
- private excludedFileExtensions = [ ".ts" , ".sass" , ".scss" , ".less" ] ;
19
- private excludedFiles = [ ".DS_Store" ] ;
7
+
20
8
private deviceInitializationPromise : IDictionary < Promise < FilesPayload > > = { } ;
21
9
22
- constructor ( private $fs : IFileSystem ,
10
+ constructor (
23
11
private $errors : IErrors ,
24
12
private $hooksService : IHooksService ,
25
13
private $logger : ILogger ,
26
- private $platformService : IPlatformService ,
27
14
private $platformsData : IPlatformsData ,
28
15
private $projectDataService : IProjectDataService ,
29
16
private $previewSdkService : IPreviewSdkService ,
17
+ private $previewAppFilesService : IPreviewAppFilesService ,
30
18
private $previewAppPluginsService : IPreviewAppPluginsService ,
31
19
private $previewDevicesService : IPreviewDevicesService ,
32
- private $projectFilesManager : IProjectFilesManager ,
33
20
private $hmrStatusService : IHmrStatusService ,
34
- private $projectFilesProvider : IProjectFilesProvider ) { }
21
+ ) { }
35
22
36
23
public async initialize ( data : IPreviewAppLiveSyncData ) : Promise < void > {
37
24
await this . $previewSdkService . initialize ( async ( device : Device ) => {
@@ -65,8 +52,9 @@ export class PreviewAppLiveSyncService implements IPreviewAppLiveSyncService {
65
52
. map ( device => device . platform )
66
53
. uniq ( )
67
54
. value ( ) ;
55
+
68
56
for ( const platform of platforms ) {
69
- await this . syncFilesForPlatformSafe ( data , platform , { filesToSync, filesToRemove, useHotModuleReload : data . useHotModuleReload } ) ;
57
+ await this . syncFilesForPlatformSafe ( data , { filesToSync, filesToRemove } , platform ) ;
70
58
}
71
59
}
72
60
@@ -78,7 +66,7 @@ export class PreviewAppLiveSyncService implements IPreviewAppLiveSyncService {
78
66
const hookArgs = this . getHookArgs ( data , device ) ;
79
67
await this . $hooksService . executeBeforeHooks ( "preview-sync" , { hookArgs } ) ;
80
68
await this . $previewAppPluginsService . comparePluginsOnDevice ( data , device ) ;
81
- const payloads = await this . syncFilesForPlatformSafe ( data , device . platform , { isInitialSync : true , useHotModuleReload : data . useHotModuleReload } ) ;
69
+ const payloads = await this . syncInitialFilesForPlatformSafe ( data , device . platform ) ;
82
70
return payloads ;
83
71
}
84
72
@@ -106,14 +94,55 @@ export class PreviewAppLiveSyncService implements IPreviewAppLiveSyncService {
106
94
return result ;
107
95
}
108
96
97
+ private async syncInitialFilesForPlatformSafe ( data : IPreviewAppLiveSyncData , platform : string ) : Promise < FilesPayload > {
98
+ this . $logger . info ( `Start syncing changes for platform ${ platform } .` ) ;
99
+
100
+ try {
101
+ const payloads = this . $previewAppFilesService . getInitialFilesPayload ( data , platform ) ;
102
+ this . $logger . info ( `Successfully synced changes for platform ${ platform } .` ) ;
103
+ return payloads ;
104
+ } catch ( err ) {
105
+ this . $logger . warn ( `Unable to apply changes for platform ${ platform } . Error is: ${ err } , ${ JSON . stringify ( err , null , 2 ) } .` ) ;
106
+ }
107
+ }
108
+
109
+ private async syncFilesForPlatformSafe ( data : IPreviewAppLiveSyncData , filesData : IPreviewAppFilesData , platform : string , deviceId ?: string ) : Promise < FilesPayload > {
110
+ this . $logger . info ( `Start syncing changes for platform ${ platform } .` ) ;
111
+
112
+ try {
113
+ const payloads = this . $previewAppFilesService . getFilesPayload ( data , filesData , platform ) ;
114
+ await this . $previewSdkService . applyChanges ( payloads ) ;
115
+ this . $logger . info ( `Successfully synced ${ payloads . files . map ( filePayload => filePayload . file . yellow ) } for platform ${ platform } .` ) ;
116
+ return payloads ;
117
+ } catch ( err ) {
118
+ this . $logger . warn ( `Unable to apply changes for platform ${ platform } . Error is: ${ err } , ${ JSON . stringify ( err , null , 2 ) } .` ) ;
119
+ }
120
+ }
121
+
109
122
private async onWebpackCompilationComplete ( data : IPreviewAppLiveSyncData , hmrData : IDictionary < IPlatformHmrData > , filesToSyncMap : IDictionary < string [ ] > , promise : Promise < FilesPayload > , platform : string ) {
110
123
await promise
111
124
. then ( async ( ) => {
112
125
const currentHmrData = _ . cloneDeep ( hmrData ) ;
113
126
const platformHmrData = currentHmrData [ platform ] || < any > { } ;
114
- const filesToSync = _ . cloneDeep ( filesToSyncMap [ platform ] ) ;
115
- // We don't need to prepare when webpack emits changed files. We just need to send a message to pubnub.
116
- promise = this . syncFilesForPlatformSafe ( data , platform , { filesToSync, skipPrepare : true , useHotModuleReload : data . useHotModuleReload } ) ;
127
+ const projectData = this . $projectDataService . getProjectData ( data . projectDir ) ;
128
+ const platformData = this . $platformsData . getPlatformData ( platform , projectData ) ;
129
+ const clonedFiles = _ . cloneDeep ( filesToSyncMap [ platform ] ) ;
130
+ const filesToSync = _ . map ( clonedFiles , fileToSync => {
131
+ const result = path . join ( platformData . appDestinationDirectoryPath , APP_FOLDER_NAME , path . relative ( projectData . getAppDirectoryPath ( ) , fileToSync ) ) ;
132
+ console . log ( result ) ;
133
+ return result ;
134
+ } ) ;
135
+
136
+ // console.log("####### FILES TO SYNC!!!!!!! %%%%%%%% ", filesToSync, data.projectDir, platformData);
137
+ // console.log("####### appDestinationDirectoryPath!!!! ", platformData.appDestinationDirectoryPath);
138
+ // console.log("hjfjdjgdfjgjfgjgj !!!!! ", projectData.getAppDirectoryPath());
139
+
140
+ // filesToSync = filesToSync.map(fileToSync => {
141
+ // console.log("appDestinationDirectoryPath !!!! ", platformData.appDestinationDirectoryPath);
142
+ // console.log("relative path!!!!!", path.relative(projectData.getAppDirectoryPath(), fileToSync));
143
+ // return result;
144
+ // });
145
+ promise = this . syncFilesForPlatformSafe ( data , { filesToSync } , platform ) ;
117
146
await promise ;
118
147
119
148
if ( data . useHotModuleReload && platformHmrData . hash ) {
@@ -122,123 +151,18 @@ export class PreviewAppLiveSyncService implements IPreviewAppLiveSyncService {
122
151
await Promise . all ( _ . map ( devices , async ( previewDevice : Device ) => {
123
152
const status = await this . $hmrStatusService . getHmrStatus ( previewDevice . id , platformHmrData . hash ) ;
124
153
if ( status === HmrConstants . HMR_ERROR_STATUS ) {
125
- await this . syncFilesForPlatformSafe ( data , platform , { filesToSync : platformHmrData . fallbackFiles , useHotModuleReload : false , deviceId : previewDevice . id } ) ;
154
+ // TODO: SET useHotModuleReload: false,
155
+ await this . syncFilesForPlatformSafe ( data , { filesToSync : platformHmrData . fallbackFiles } , platform , previewDevice . id ) ;
126
156
}
127
157
} ) ) ;
128
158
}
129
159
} ) ;
130
160
filesToSyncMap [ platform ] = [ ] ;
131
161
}
132
162
133
- private async syncFilesForPlatformSafe ( data : IPreviewAppLiveSyncData , platform : string , opts ?: ISyncFilesOptions ) : Promise < FilesPayload > {
134
- this . $logger . info ( `Start syncing changes for platform ${ platform } .` ) ;
135
-
136
- opts = opts || { } ;
137
- let payloads = null ;
138
-
139
- try {
140
- const { env, projectDir } = data ;
141
- const projectData = this . $projectDataService . getProjectData ( projectDir ) ;
142
- const platformData = this . $platformsData . getPlatformData ( platform , projectData ) ;
143
-
144
- if ( ! opts . skipPrepare ) {
145
- await this . preparePlatform ( platform , data , env , projectData ) ;
146
- }
147
-
148
- if ( opts . isInitialSync ) {
149
- const platformsAppFolderPath = path . join ( platformData . appDestinationDirectoryPath , APP_FOLDER_NAME ) ;
150
- opts . filesToSync = this . $projectFilesManager . getProjectFiles ( platformsAppFolderPath ) ;
151
- payloads = this . getFilesPayload ( platformData , projectData , opts ) ;
152
- this . $logger . info ( `Successfully synced changes for platform ${ platform } .` ) ;
153
- } else {
154
- opts . filesToSync = _ . map ( opts . filesToSync , file => this . $projectFilesProvider . mapFilePath ( file , platformData . normalizedPlatformName , projectData ) ) ;
155
- payloads = this . getFilesPayload ( platformData , projectData , opts ) ;
156
- await this . $previewSdkService . applyChanges ( payloads ) ;
157
- this . $logger . info ( `Successfully synced ${ payloads . files . map ( filePayload => filePayload . file . yellow ) } for platform ${ platform } .` ) ;
158
- }
159
-
160
- return payloads ;
161
- } catch ( err ) {
162
- this . $logger . warn ( `Unable to apply changes for platform ${ platform } . Error is: ${ err } , ${ JSON . stringify ( err , null , 2 ) } .` ) ;
163
- }
164
- }
165
-
166
- private getFilesPayload ( platformData : IPlatformData , projectData : IProjectData , opts ?: ISyncFilesOptions ) : FilesPayload {
167
- const { filesToSync, filesToRemove, deviceId } = opts ;
168
-
169
- const filesToTransfer = filesToSync
170
- . filter ( file => file . indexOf ( TNS_MODULES_FOLDER_NAME ) === - 1 )
171
- . filter ( file => file . indexOf ( APP_RESOURCES_FOLDER_NAME ) === - 1 )
172
- . filter ( file => ! _ . includes ( this . excludedFiles , path . basename ( file ) ) )
173
- . filter ( file => ! _ . includes ( this . excludedFileExtensions , path . extname ( file ) ) ) ;
174
-
175
- this . $logger . trace ( `Transferring ${ filesToTransfer . join ( "\n" ) } .` ) ;
176
-
177
- const payloadsToSync = filesToTransfer . map ( file => this . createFilePayload ( file , platformData , projectData , PreviewSdkEventNames . CHANGE_EVENT_NAME ) ) ;
178
- const payloadsToRemove = _ . map ( filesToRemove , file => this . createFilePayload ( file , platformData , projectData , PreviewSdkEventNames . UNLINK_EVENT_NAME ) ) ;
179
- const payloads = payloadsToSync . concat ( payloadsToRemove ) ;
180
-
181
- const hmrMode = opts . useHotModuleReload ? 1 : 0 ;
182
- return { files : payloads , platform : platformData . normalizedPlatformName . toLowerCase ( ) , hmrMode, deviceId } ;
183
- }
184
-
185
- private async preparePlatform ( platform : string , data : IPreviewAppLiveSyncData , env : Object , projectData : IProjectData ) : Promise < void > {
186
- const appFilesUpdaterOptions = {
187
- bundle : data . bundle ,
188
- useHotModuleReload : data . useHotModuleReload ,
189
- release : false
190
- } ;
191
- const nativePrepare = { skipNativePrepare : true } ;
192
- const config = < IPlatformOptions > { } ;
193
- const platformTemplate = < string > null ;
194
- const prepareInfo = {
195
- platform,
196
- appFilesUpdaterOptions,
197
- env,
198
- projectData,
199
- nativePrepare,
200
- config,
201
- platformTemplate,
202
- skipCopyTnsModules : true ,
203
- skipCopyAppResourcesFiles : true
204
- } ;
205
- await this . $platformService . preparePlatform ( prepareInfo ) ;
206
- }
207
-
208
163
private showWarningsForNativeFiles ( files : string [ ] ) : void {
209
164
_ . filter ( files , file => file . indexOf ( APP_RESOURCES_FOLDER_NAME ) > - 1 )
210
165
. 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.` ) ) ;
211
166
}
212
-
213
- private createFilePayload ( file : string , platformData : IPlatformData , projectData : IProjectData , event : string ) : FilePayload {
214
- const projectFileInfo = this . $projectFilesProvider . getProjectFileInfo ( file , platformData . normalizedPlatformName , null ) ;
215
- const binary = isTextOrBinary . isBinarySync ( file ) ;
216
- let fileContents = "" ;
217
- let filePath = "" ;
218
-
219
- if ( event === PreviewSdkEventNames . CHANGE_EVENT_NAME ) {
220
- const relativePath = path . relative ( path . join ( platformData . appDestinationDirectoryPath , APP_FOLDER_NAME ) , file ) ;
221
- filePath = path . join ( path . dirname ( relativePath ) , projectFileInfo . onDeviceFileName ) ;
222
-
223
- if ( binary ) {
224
- const bitmap = < string > this . $fs . readFile ( file ) ;
225
- const base64 = Buffer . from ( bitmap ) . toString ( 'base64' ) ;
226
- fileContents = base64 ;
227
- } else {
228
- fileContents = this . $fs . readText ( path . join ( path . dirname ( projectFileInfo . filePath ) , projectFileInfo . onDeviceFileName ) ) ;
229
- }
230
- } else if ( event === PreviewSdkEventNames . UNLINK_EVENT_NAME ) {
231
- filePath = path . relative ( path . join ( projectData . projectDir , APP_FOLDER_NAME ) , file ) ;
232
- }
233
-
234
- const filePayload = {
235
- event,
236
- file : filePath ,
237
- binary,
238
- fileContents
239
- } ;
240
-
241
- return filePayload ;
242
- }
243
167
}
244
168
$injector . register ( "previewAppLiveSyncService" , PreviewAppLiveSyncService ) ;
0 commit comments