@@ -123,8 +123,60 @@ public void PumpTimers()
123123 private const string InspectorMarker = "ns-inspector" ;
124124 private const string DebugBreakMarker = "ns-debugbreak" ;
125125 private const string DebuggerStartedMarker = "ns-debugger-started" ;
126+ // The CLI writes LiveSyncMarker after syncing files into app\ (webpack HMR), but only
127+ // while LiveSyncReadyMarker says this host is watching for it.
128+ private const string LiveSyncMarker = "ns-livesync" ;
129+ private const string LiveSyncReadyMarker = "ns-livesync-ready" ;
126130
127131 private bool _waitForDebugger ;
132+ private FileSystemWatcher _liveSyncWatcher ;
133+
134+ /// Applies CLI file syncs while the app runs, by calling global.__onLiveSync() on the UI
135+ /// thread, as the Android and iOS runtimes do after a LiveSync.
136+ public void WatchLiveSync ( Microsoft . UI . Dispatching . DispatcherQueue dispatcherQueue )
137+ {
138+ if ( ! _initialized || _liveSyncWatcher != null || dispatcherQueue == null ) return ;
139+ try
140+ {
141+ DeleteMarker ( LiveSyncMarker ) ;
142+ var watcher = new FileSystemWatcher ( LocalFolderPath , LiveSyncMarker )
143+ {
144+ NotifyFilter = NotifyFilters . FileName | NotifyFilters . LastWrite ,
145+ } ;
146+ FileSystemEventHandler onMarker = ( _ , _ ) => dispatcherQueue . TryEnqueue ( ApplyLiveSync ) ;
147+ watcher . Created += onMarker ;
148+ watcher . Changed += onMarker ;
149+ watcher . EnableRaisingEvents = true ;
150+ _liveSyncWatcher = watcher ;
151+ WriteMarker ( LiveSyncReadyMarker , "" ) ;
152+ }
153+ catch ( Exception ex )
154+ {
155+ System . Diagnostics . Debug . WriteLine ( $ "[NativeScript LiveSync] Watch failed: { ex . Message } ") ;
156+ }
157+ }
158+
159+ private void ApplyLiveSync ( )
160+ {
161+ // One write raises several events; the first one consumes the marker.
162+ if ( ! _initialized || ! ConsumeMarker ( LiveSyncMarker ) ) return ;
163+ try
164+ {
165+ runtime_runscript ( _runtime , "typeof __onLiveSync === 'function' && __onLiveSync();" , "ns-livesync.js" ) ;
166+ }
167+ catch ( Exception ex )
168+ {
169+ System . Diagnostics . Debug . WriteLine ( $ "[NativeScript LiveSync] Apply failed: { ex . Message } ") ;
170+ }
171+ }
172+
173+ private void StopWatchingLiveSync ( )
174+ {
175+ if ( _liveSyncWatcher == null ) return ;
176+ _liveSyncWatcher . Dispose ( ) ;
177+ _liveSyncWatcher = null ;
178+ DeleteMarker ( LiveSyncReadyMarker ) ;
179+ }
128180
129181 public string DevtoolsFrontendUrl { get ; private set ; }
130182
@@ -235,6 +287,7 @@ public void Initialize()
235287 }
236288 catch { }
237289 DeleteMarker ( DebuggerStartedMarker ) ;
290+ DeleteMarker ( LiveSyncReadyMarker ) ;
238291 var debugBreak = ConsumeMarker ( DebugBreakMarker ) ;
239292 if ( ConsumeMarker ( InspectorMarker ) || debugBreak )
240293 {
@@ -476,6 +529,9 @@ public string GetLastJsError()
476529 public void Dispose ( )
477530 {
478531 if ( ! _initialized ) return ;
532+ #if DEBUG
533+ StopWatchingLiveSync ( ) ;
534+ #endif
479535 runtime_deinit ( _runtime ) ;
480536 _runtime = 0 ;
481537 _initialized = false ;
0 commit comments