@@ -33,8 +33,10 @@ async function _create(stubs) {
3333 *@type {Promise<any> | undefined }
3434 */
3535let running ;
36- /**@type {Map<string, string> } Paths and contents of the currently loaded file stubs */
37- let current = stubs_to_map ( stubs ) ;
36+
37+ /** Paths and contents of the currently loaded file stubs */
38+ let current_stubs = stubs_to_map ( stubs ) ;
39+
3840/**@type {boolean } Track whether there was an error from vite dev server */
3941let vite_error = false ;
4042
@@ -150,22 +152,35 @@ async function _create(stubs) {
150152running = new Promise ( ( fulfil ) => ( resolve = fulfil ) ) ;
151153vite_error = false ;
152154
153- const old = current ;
154- const new_stubs = stubs . filter (
155- ( stub ) => stub . type !== 'file' || old . get ( stub . name ) !== stub . contents
156- ) ;
157- current = stubs_to_map ( stubs ) ;
155+ let added_new_file = false ;
156+
157+ /**@type {import('$lib/types').Stub[] } */
158+ const to_write = [ ] ;
158159
159160for ( const stub of stubs ) {
160161if ( stub . type === 'file' ) {
161- old . delete ( stub . name ) ;
162+ const current = /**@type {import('$lib/types').FileStub } */ ( current_stubs . get ( stub . name ) ) ;
163+
164+ if ( current ?. contents !== stub . contents ) {
165+ to_write . push ( stub ) ;
166+ }
167+
168+ if ( ! current ) added_new_file = true ;
169+ } else {
170+ // always add directories, otherwise convert_stubs_to_tree will fail
171+ to_write . push ( stub ) ;
162172}
173+
174+ current_stubs . delete ( stub . name ) ;
163175}
164176
177+ const to_delete = Array . from ( current_stubs . keys ( ) ) ;
178+ current_stubs = stubs_to_map ( stubs ) ;
179+
165180// For some reason, server-ready is fired again when the vite dev server is restarted.
166181// We need to wait for it to finish before we can continue, else we might
167182// request files from Vite before it's ready, leading to a timeout.
168- const will_restart = will_restart_vite_dev_server ( new_stubs ) ;
183+ const will_restart = will_restart_vite_dev_server ( to_write ) ;
169184const promise = will_restart
170185?new Promise ( ( fulfil , reject ) => {
171186const error_unsub = vm . on ( 'error' , ( error ) => {
@@ -188,19 +203,19 @@ async function _create(stubs) {
188203} )
189204:Promise . resolve ( ) ;
190205
191- for ( const file of old . keys ( ) ) {
206+ for ( const file of to_delete ) {
192207await vm . fs . rm ( file , { force :true , recursive :true } ) ;
193208}
194209
195- await vm . loadFiles ( convert_stubs_to_tree ( new_stubs ) ) ;
210+ await vm . loadFiles ( convert_stubs_to_tree ( to_write ) ) ;
196211await promise ;
197212await new Promise ( ( f ) => setTimeout ( f , 200 ) ) ; // wait for chokidar
198213
199214resolve ( ) ;
200215
201216// Also trigger a reload of the iframe in case new files were added / old ones deleted,
202217// because that can result in a broken UI state
203- return will_restart || vite_error || ! ! old . size || ! ! new_stubs . length ;
218+ return will_restart || vite_error || to_delete . length > 0 || added_new_file ;
204219}
205220
206221/**
@@ -237,7 +252,7 @@ async function _create(stubs) {
237252
238253await vm . loadFiles ( root ) ;
239254
240- stubs_to_map ( stubs , current ) ;
255+ stubs_to_map ( stubs , current_stubs ) ;
241256
242257await new Promise ( ( f ) => setTimeout ( f , 200 ) ) ; // wait for chokidar
243258
@@ -319,13 +334,11 @@ function to_file(stub) {
319334
320335/**
321336 *@param {import('$lib/types').Stub[] } stubs
322- *@returns {Map<string,string > }
337+ *@returns {Map<string,import('$lib/types').Stub > }
323338 */
324339function stubs_to_map ( stubs , map = new Map ( ) ) {
325340for ( const stub of stubs ) {
326- if ( stub . type === 'file' ) {
327- map . set ( stub . name , stub . contents ) ;
328- }
341+ map . set ( stub . name , stub ) ;
329342}
330343return map ;
331344}