@@ -33,8 +33,10 @@ async function _create(stubs) {
33
33
* @type {Promise<any> | undefined }
34
34
*/
35
35
let 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
+
38
40
/** @type {boolean } Track whether there was an error from vite dev server */
39
41
let vite_error = false ;
40
42
@@ -150,22 +152,35 @@ async function _create(stubs) {
150
152
running = new Promise ( ( fulfil ) => ( resolve = fulfil ) ) ;
151
153
vite_error = false ;
152
154
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 = [ ] ;
158
159
159
160
for ( const stub of stubs ) {
160
161
if ( 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 ) ;
162
172
}
173
+
174
+ current_stubs . delete ( stub . name ) ;
163
175
}
164
176
177
+ const to_delete = Array . from ( current_stubs . keys ( ) ) ;
178
+ current_stubs = stubs_to_map ( stubs ) ;
179
+
165
180
// For some reason, server-ready is fired again when the vite dev server is restarted.
166
181
// We need to wait for it to finish before we can continue, else we might
167
182
// 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 ) ;
169
184
const promise = will_restart
170
185
? new Promise ( ( fulfil , reject ) => {
171
186
const error_unsub = vm . on ( 'error' , ( error ) => {
@@ -188,19 +203,19 @@ async function _create(stubs) {
188
203
} )
189
204
: Promise . resolve ( ) ;
190
205
191
- for ( const file of old . keys ( ) ) {
206
+ for ( const file of to_delete ) {
192
207
await vm . fs . rm ( file , { force : true , recursive : true } ) ;
193
208
}
194
209
195
- await vm . loadFiles ( convert_stubs_to_tree ( new_stubs ) ) ;
210
+ await vm . loadFiles ( convert_stubs_to_tree ( to_write ) ) ;
196
211
await promise ;
197
212
await new Promise ( ( f ) => setTimeout ( f , 200 ) ) ; // wait for chokidar
198
213
199
214
resolve ( ) ;
200
215
201
216
// Also trigger a reload of the iframe in case new files were added / old ones deleted,
202
217
// 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 ;
204
219
}
205
220
206
221
/**
@@ -237,7 +252,7 @@ async function _create(stubs) {
237
252
238
253
await vm . loadFiles ( root ) ;
239
254
240
- stubs_to_map ( stubs , current ) ;
255
+ stubs_to_map ( stubs , current_stubs ) ;
241
256
242
257
await new Promise ( ( f ) => setTimeout ( f , 200 ) ) ; // wait for chokidar
243
258
@@ -319,13 +334,11 @@ function to_file(stub) {
319
334
320
335
/**
321
336
* @param {import('$lib/types').Stub[] } stubs
322
- * @returns {Map<string, string > }
337
+ * @returns {Map<string, import('$lib/types').Stub > }
323
338
*/
324
339
function stubs_to_map ( stubs , map = new Map ( ) ) {
325
340
for ( const stub of stubs ) {
326
- if ( stub . type === 'file' ) {
327
- map . set ( stub . name , stub . contents ) ;
328
- }
341
+ map . set ( stub . name , stub ) ;
329
342
}
330
343
return map ;
331
344
}
0 commit comments