fix: editing config.yaml with vscode produced empty file for an instant

Massimo Melina committed Jan 28, 2023 at 00:30 UTC 7c7ba587eb0be53aa81618c3d4c5b9c6bd69ac0b
1 file changed +13 -19
src/watchLoad.ts
+13 -19
@@ -14,10 +14,10 @@ interface WatchLoadReturn { unwatch:WatchLoadCanceller, save:WriteFile }
14 export function watchLoad(path:string, parser:(data:any)=>void|Promise<void>, { failedOnFirstAttempt }:Options={}): WatchLoadReturn {
15 let doing = false
16 let watcher: FSWatcher | undefined
17 - const debounced = debounceAsync(load, 500, { leading: true })
17 + const debounced = debounceAsync(load, 500, { maxWait: 1000 })
18 let retry: NodeJS.Timeout
19 let saving: Promise<unknown> | undefined
20 - let lastStats: any
20 + let last: string | undefined
21 init().then(ok => ok || failedOnFirstAttempt?.())
22 return {
23 unwatch(){
@@ -49,24 +49,18 @@ export function watchLoad(path:string, parser:(data:any)=>void|Promise<void>, {
49 async function load(){
50 if (doing) return
51 doing = true
52 - let data: any
52 try {
54 - try { // I've seen watch() firing 'change' without any change, so we'll check if any change is detectable before going on
55 - const stats = await fs.stat(path)
56 - if (stats.mtimeMs === lastStats?.mtimeMs) return
57 - lastStats = stats
58 -
59 - data = await readFileBusy(path)
60 - console.debug('loaded', path)
61 - }
62 - catch (e: any) {
63 - if (e.code === 'EPERM')
64 - console.error("missing permissions on file", path) // warn user, who could be clueless about this problem
65 - return // ignore read errors
66 - }
67 - if (path.endsWith('.yaml'))
68 - data = yaml.parse(data)
69 - await parser(data)
53 + const text = await readFileBusy(path)
54 + if (text === last)
55 + return
56 + last = text
57 + console.debug('loaded', path)
58 + const parsed = path.endsWith('.yaml') ? yaml.parse(text) : text
59 + await parser(parsed)
60 + }
61 + catch (e: any) { // ignore read errors
62 + if (e.code === 'EPERM')
63 + console.error("missing permissions on file", path) // warn user, who could be clueless about this problem
64 }
65 finally {
66 doing = false