Skip to content

Commit add840f

Browse files
committed
Send special message if we live sync javascript file and the liveEdit option is on
1 parent 7282118 commit add840f

6 files changed

+130
-82
lines changed

lib/common

Submodule common updated 1 file

lib/declarations.ts

+1
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ interface IOptions extends ICommonOptions {
100100
teamId: string;
101101
rebuild: boolean;
102102
syncAllFiles: boolean;
103+
liveEdit: boolean;
103104
}
104105

105106
interface IInitService {

lib/options.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,8 @@ export class Options extends commonOptionsLibPath.OptionsBase {
3838
all: {type: OptionType.Boolean },
3939
teamId: { type: OptionType.String },
4040
rebuild: { type: OptionType.Boolean, default: true },
41-
syncAllFiles: { type: OptionType.Boolean }
41+
syncAllFiles: { type: OptionType.Boolean },
42+
liveEdit: { type: OptionType.Boolean }
4243
},
4344
path.join($hostInfo.isWindows ? process.env.AppData : path.join(osenv.home(), ".local/share"), ".nativescript-cli"),
4445
$errors, $staticConfig);

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

+16-6
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
import {DeviceAndroidDebugBridge} from "../../common/mobile/android/device-android-debug-bridge";
22
import {AndroidDeviceHashService} from "../../common/mobile/android/android-device-hash-service";
3-
import {DeviceLiveSyncServiceBase} from "./device-livesync-service-base";
43
import Future = require("fibers/future");
54
import * as helpers from "../../common/helpers";
65
import * as path from "path";
76
import * as net from "net";
87

9-
class AndroidLiveSyncService extends DeviceLiveSyncServiceBase<Mobile.IAndroidDevice> implements IDeviceLiveSyncService {
8+
class AndroidLiveSyncService implements IDeviceLiveSyncService {
109
private static BACKEND_PORT = 18182;
10+
private device: Mobile.IAndroidDevice;
1111

1212
constructor(_device: Mobile.IDevice,
1313
private $fs: IFileSystem,
@@ -16,15 +16,25 @@ class AndroidLiveSyncService extends DeviceLiveSyncServiceBase<Mobile.IAndroidDe
1616
private $injector: IInjector,
1717
private $projectData: IProjectData,
1818
private $androidDebugService: IDebugService,
19-
$liveSyncProvider: ILiveSyncProvider) {
20-
super(_device, $liveSyncProvider);
19+
private $liveSyncProvider: ILiveSyncProvider) {
20+
this.device = <Mobile.IAndroidDevice>(_device);
2121
}
2222

2323
public get debugService(): IDebugService {
2424
return this.$androidDebugService;
2525
}
2626

27-
public restartApplication(deviceAppData: Mobile.IDeviceAppData): IFuture<void> {
27+
public refreshApplication(deviceAppData: Mobile.IDeviceAppData, localToDevicePaths: Mobile.ILocalToDevicePathData[], forceExecuteFullSync: boolean): IFuture<void> {
28+
let canExecuteFastSync = !forceExecuteFullSync && !_.some(localToDevicePaths, (localToDevicePath:any) => !this.$liveSyncProvider.canExecuteFastSync(localToDevicePath.getLocalPath(), deviceAppData.platform));
29+
30+
if (canExecuteFastSync) {
31+
return this.reloadPage(deviceAppData, localToDevicePaths);
32+
}
33+
34+
return this.restartApplication(deviceAppData);
35+
}
36+
37+
private restartApplication(deviceAppData: Mobile.IDeviceAppData): IFuture<void> {
2838
return (() => {
2939
this.device.adb.executeShellCommand(["chmod", "777", deviceAppData.deviceProjectRootPath, `/data/local/tmp/${deviceAppData.appIdentifier}`]).wait();
3040

@@ -56,7 +66,7 @@ class AndroidLiveSyncService extends DeviceLiveSyncServiceBase<Mobile.IAndroidDe
5666
}).future<void>()();
5767
}
5868

59-
public reloadPage(deviceAppData: Mobile.IDeviceAppData): IFuture<void> {
69+
private reloadPage(deviceAppData: Mobile.IDeviceAppData, localToDevicePaths: Mobile.ILocalToDevicePathData[]): IFuture<void> {
6070
return (() => {
6171
this.device.adb.executeCommand(["forward", `tcp:${AndroidLiveSyncService.BACKEND_PORT.toString()}`, `localabstract:${deviceAppData.appIdentifier}-livesync`]).wait();
6272
this.sendPageReloadMessage().wait();

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

-21
This file was deleted.

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

+110-53
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
import {DeviceLiveSyncServiceBase} from "./device-livesync-service-base";
21
import * as helpers from "../../common/helpers";
32
import * as net from "net";
43

54
let currentPageReloadId = 0;
65

7-
class IOSLiveSyncService extends DeviceLiveSyncServiceBase<Mobile.IiOSDevice> implements IDeviceLiveSyncService {
6+
class IOSLiveSyncService implements IDeviceLiveSyncService {
87
private static BACKEND_PORT = 18181;
98
private socket: net.Socket;
9+
private device: Mobile.IiOSDevice;
1010

1111
constructor(_device: Mobile.IDevice,
1212
private $iOSSocketRequestExecutor: IiOSSocketRequestExecutor,
@@ -17,8 +17,9 @@ class IOSLiveSyncService extends DeviceLiveSyncServiceBase<Mobile.IiOSDevice> im
1717
private $options: IOptions,
1818
private $iOSDebugService: IDebugService,
1919
private $childProcess: IChildProcess,
20-
$liveSyncProvider: ILiveSyncProvider) {
21-
super(_device, $liveSyncProvider);
20+
private $fs: IFileSystem,
21+
private $liveSyncProvider: ILiveSyncProvider) {
22+
this.device = <Mobile.IiOSDevice>(_device);
2223
}
2324

2425
public get debugService(): IDebugService {
@@ -31,78 +32,140 @@ class IOSLiveSyncService extends DeviceLiveSyncServiceBase<Mobile.IiOSDevice> im
3132
}).future<boolean>()();
3233
}
3334

35+
private setupSocketIfNeeded(): IFuture<boolean> {
36+
return (() => {
37+
if (this.socket) {
38+
return true;
39+
}
40+
41+
let enableDebuggerMessage = `{ "method":"Debugger.enable","id":${++currentPageReloadId} }`;
42+
if (this.device.isEmulator) {
43+
this.$iOSEmulatorServices.postDarwinNotification(this.$iOSNotification.attachRequest).wait();
44+
try {
45+
this.socket = helpers.connectEventuallyUntilTimeout(() => net.connect(IOSLiveSyncService.BACKEND_PORT), 5000).wait();
46+
} catch (e) {
47+
this.$logger.warn(e);
48+
49+
return false;
50+
}
51+
} else {
52+
let timeout = 9000;
53+
this.$iOSSocketRequestExecutor.executeAttachRequest(this.device, timeout).wait();
54+
this.socket = this.device.connectToPort(IOSLiveSyncService.BACKEND_PORT);
55+
}
56+
57+
this.attachEventHandlers();
58+
this.sendMessage(enableDebuggerMessage);
59+
60+
return true;
61+
}).future<boolean>()();
62+
}
63+
3464
public removeFiles(appIdentifier: string, localToDevicePaths: Mobile.ILocalToDevicePathData[]): IFuture<void> {
3565
return (() => {
3666
_.each(localToDevicePaths, localToDevicePathData => this.device.fileSystem.deleteFile(localToDevicePathData.getDevicePath(), appIdentifier));
3767
}).future<void>()();
3868
}
3969

40-
protected restartApplication(deviceAppData: Mobile.IDeviceAppData): IFuture<void> {
70+
public refreshApplication(deviceAppData: Mobile.IDeviceAppData, localToDevicePaths: Mobile.ILocalToDevicePathData[], forceExecuteFullSync: boolean): IFuture<void> {
71+
return (() => {
72+
if (forceExecuteFullSync) {
73+
this.restartApplication(deviceAppData).wait();
74+
return;
75+
}
76+
let scriptFiles = _.filter(localToDevicePaths, localToDevicePath => _.endsWith(localToDevicePath.getDevicePath(), ".js"));
77+
let otherFiles = _.difference(localToDevicePaths, scriptFiles);
78+
let shouldRestart = _.some(otherFiles, (localToDevicePath: Mobile.ILocalToDevicePathData) => !this.$liveSyncProvider.canExecuteFastSync(localToDevicePath.getLocalPath(), deviceAppData.platform));
79+
80+
if (shouldRestart) {
81+
this.restartApplication(deviceAppData).wait();
82+
83+
return;
84+
}
85+
86+
if (!this.$options.liveEdit && scriptFiles.length) {
87+
this.restartApplication(deviceAppData).wait();
88+
89+
return;
90+
}
91+
92+
if (this.setupSocketIfNeeded().wait()) {
93+
this.liveEdit(scriptFiles);
94+
this.reloadPage(deviceAppData, otherFiles).wait();
95+
}
96+
}).future<void>()();
97+
}
98+
99+
private restartApplication(deviceAppData: Mobile.IDeviceAppData): IFuture<void> {
41100
let projectData: IProjectData = this.$injector.resolve("projectData");
42101
return this.device.applicationManager.restartApplication(deviceAppData.appIdentifier, projectData.projectName);
43102
}
44103

45-
protected reloadPage(deviceAppData: Mobile.IDeviceAppData): IFuture<void> {
104+
private reloadPage(deviceAppData: Mobile.IDeviceAppData, localToDevicePaths: Mobile.ILocalToDevicePathData[]): IFuture<void> {
46105
return (() => {
47-
let timeout = 9000;
48-
if (this.device.isEmulator) {
49-
if (!this.socket) {
50-
helpers.connectEventually(() => net.connect(IOSLiveSyncService.BACKEND_PORT), (socket: net.Socket) => {
51-
this.socket = socket;
52-
this.attachEventHandlersIfNecessary();
53-
this.sendPageReloadMessage();
54-
});
55-
} else {
56-
this.sendPageReloadMessage();
57-
}
58-
this.$iOSEmulatorServices.postDarwinNotification(this.$iOSNotification.attachRequest).wait();
59-
} else {
60-
if(!this.socket) {
61-
this.$iOSSocketRequestExecutor.executeAttachRequest(this.device, timeout).wait();
62-
this.socket = this.device.connectToPort(IOSLiveSyncService.BACKEND_PORT);
63-
this.attachEventHandlersIfNecessary();
64-
}
65-
this.sendPageReloadMessage();
106+
if (localToDevicePaths.length) {
107+
let message = JSON.stringify({
108+
method: "Page.reload",
109+
params: {
110+
ignoreCache: false
111+
},
112+
id: ++currentPageReloadId
113+
});
114+
115+
this.sendMessage(message);
66116
}
67117
}).future<void>()();
68118
}
69119

70-
private attachEventHandlersIfNecessary(): void {
71-
if(this.$options.watch) {
72-
this.attachProcessExitHandlers();
73-
this.attachSocketCloseEvent();
74-
}
120+
private liveEdit(localToDevicePaths: Mobile.ILocalToDevicePathData[]) {
121+
return (() => {
122+
_.each(localToDevicePaths, localToDevicePath => {
123+
let content = this.$fs.readFile(localToDevicePath.getLocalPath()).wait().toString();
124+
let message = JSON.stringify({
125+
method: "Debugger.setScriptSource",
126+
params: {
127+
scriptUrl: localToDevicePath.getDevicePath(),
128+
scriptSource: content
129+
},
130+
id: ++currentPageReloadId
131+
});
132+
133+
this.sendMessage(message);
134+
});
135+
}).future<void>()();
75136
}
76137

77-
private attachSocketCloseEvent(): void {
138+
private attachEventHandlers(): void {
139+
this.attachProcessExitHandlers();
140+
78141
this.socket.on("close", (hadError: boolean) => {
79142
this.$logger.trace(`Socket closed, hadError is ${hadError}.`);
80143
this.socket = null;
81144
});
145+
146+
this.socket.on("error", (error: any) => {
147+
this.$logger.trace(`Socket error received: ${error}`);
148+
});
149+
150+
this.socket.on("data", (data: NodeBuffer|string) => {
151+
this.$logger.trace(`Socket sent data: ${data.toString()}`);
152+
});
82153
}
83154

84-
private sendPageReloadMessage(): void {
155+
private sendMessage(message: string): void {
85156
try {
86-
this.sendPageReloadMessageCore();
87-
this.socket.on("data", (data: NodeBuffer|string) => {
88-
this.$logger.trace(`Socket sent data: ${data.toString()}`);
89-
this.destroySocketIfNecessary();
90-
});
157+
let length = Buffer.byteLength(message, "utf16le");
158+
let payload = new Buffer(length + 4);
159+
payload.writeInt32BE(length, 0);
160+
payload.write(message, 4, length, "utf16le");
161+
162+
this.socket.write(payload);
91163
} catch(err) {
92164
this.$logger.trace("Error while sending page reload:", err);
93-
this.destroySocketIfNecessary();
165+
this.destroySocket();
94166
}
95167
}
96168

97-
private sendPageReloadMessageCore(): void {
98-
let message = `{ "method":"Page.reload","params":{"ignoreCache":false},"id":${++currentPageReloadId} }`;
99-
let length = Buffer.byteLength(message, "utf16le");
100-
let payload = new Buffer(length + 4);
101-
payload.writeInt32BE(length, 0);
102-
payload.write(message, 4, length, "utf16le");
103-
this.socket.write(payload);
104-
}
105-
106169
private attachProcessExitHandlers(): void {
107170
process.on("exit", (exitCode: number) => {
108171
this.destroySocket();
@@ -118,12 +181,6 @@ class IOSLiveSyncService extends DeviceLiveSyncServiceBase<Mobile.IiOSDevice> im
118181
});
119182
}
120183

121-
private destroySocketIfNecessary(): void {
122-
if(!this.$options.watch) {
123-
this.destroySocket();
124-
}
125-
}
126-
127184
private destroySocket(): void {
128185
if(this.socket) {
129186
this.socket.destroy();

0 commit comments

Comments
 (0)