()
| 566 | } |
| 567 | |
| 568 | function startWatching(): void { |
| 569 | const file = getConfigFilePath() |
| 570 | watcher?.close().catch(() => {}) |
| 571 | watcher = chokidar.watch(file, { |
| 572 | ignoreInitial: true, |
| 573 | awaitWriteFinish: { stabilityThreshold: 150, pollInterval: 50 } |
| 574 | }) |
| 575 | const handle = debounce(() => { |
| 576 | void (async () => { |
| 577 | const res = await readConfigFile() |
| 578 | if (!res) return |
| 579 | // Our own writes (and no-op saves) match lastKnownText — skip them so we |
| 580 | // never feed our writes back into the renderer. Also skip a stale read of |
| 581 | // any recent own-write the watcher observed out of order, so it can't |
| 582 | // clobber the in-memory cache with an older serialized state. |
| 583 | if (res.text === lastKnownText || ownWrites.has(res.text)) return |
| 584 | cache = res.portable |
| 585 | lastKnownText = res.text |
| 586 | onChangeCb?.({ ...cache }) |
| 587 | })() |
| 588 | }, WATCH_DEBOUNCE_MS) |
| 589 | watcher.on('add', handle).on('change', handle) |
| 590 | // Intentionally ignore 'unlink': a deleted config shouldn't wipe the live |
| 591 | // settings; the next save recreates the file from the in-memory cache. |
| 592 | } |
| 593 | |
| 594 | /** |
| 595 | * Load the config from disk and begin watching it. Must run before the first |
no test coverage detected