From 704d9f65289c7c8718d7753a9e2c9909f71da844 Mon Sep 17 00:00:00 2001 From: Simon Knott Date: Tue, 17 Oct 2023 11:50:57 +0200 Subject: [PATCH 1/2] fix: don't swallow file changes when a lot of them come in --- src/utils/command-helpers.mjs | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/src/utils/command-helpers.mjs b/src/utils/command-helpers.mjs index 3146b85bda0..b20de549783 100644 --- a/src/utils/command-helpers.mjs +++ b/src/utils/command-helpers.mjs @@ -9,7 +9,6 @@ import { Chalk } from 'chalk' import chokidar from 'chokidar' import decache from 'decache' import WSL from 'is-wsl' -import debounce from 'lodash/debounce.js' import terminalLink from 'terminal-link' import { clearSpinner, startSpinner } from '../lib/spinner.mjs' @@ -225,8 +224,6 @@ export const normalizeConfig = (config) => { return publishOrigin === 'default' ? { ...config, build } : config } -const DEBOUNCE_WAIT = 100 - /** * Adds a file watcher to a path or set of paths and debounces the events. * @@ -234,9 +231,9 @@ const DEBOUNCE_WAIT = 100 * @param {Object} opts * @param {number} [opts.depth] * @param {Array} [opts.ignored] - * @param {() => any} [opts.onAdd] - * @param {() => any} [opts.onChange] - * @param {() => any} [opts.onUnlink] + * @param {(path: string) => any} [opts.onAdd] + * @param {(path: string) => any} [opts.onChange] + * @param {(path: string) => any} [opts.onUnlink] */ export const watchDebounced = async ( target, @@ -247,22 +244,18 @@ export const watchDebounced = async ( await once(watcher, 'ready') - const debouncedOnChange = debounce(onChange, DEBOUNCE_WAIT) - const debouncedOnUnlink = debounce(onUnlink, DEBOUNCE_WAIT) - const debouncedOnAdd = debounce(onAdd, DEBOUNCE_WAIT) - watcher .on('change', (path) => { decache(path) - debouncedOnChange(path) + onChange(path) }) .on('unlink', (path) => { decache(path) - debouncedOnUnlink(path) + onUnlink(path) }) .on('add', (path) => { decache(path) - debouncedOnAdd(path) + onAdd(path) }) return watcher From fe7150a019810759a57bf5a9770ec485931ac371 Mon Sep 17 00:00:00 2001 From: Simon Knott Date: Tue, 17 Oct 2023 12:12:50 +0200 Subject: [PATCH 2/2] fix: reintroduce debounce, but collect paths --- src/lib/edge-functions/registry.mjs | 13 ++++++----- src/utils/command-helpers.mjs | 35 ++++++++++++++++++++++++----- 2 files changed, 37 insertions(+), 11 deletions(-) diff --git a/src/lib/edge-functions/registry.mjs b/src/lib/edge-functions/registry.mjs index a4cf38683ce..664d1373e74 100644 --- a/src/lib/edge-functions/registry.mjs +++ b/src/lib/edge-functions/registry.mjs @@ -269,12 +269,15 @@ export class EdgeFunctionsRegistry { } /** - * @param {string} path + * @param {string[]} paths * @returns {Promise} */ - async #handleFileChange(path) { + async #handleFileChange(paths) { const matchingFunctions = new Set( - [this.#functionPaths.get(path), ...(this.#dependencyPaths.get(path) || [])].filter(Boolean), + [ + ...paths.map((path) => this.#functionPaths.get(path)), + ...paths.flatMap((path) => this.#dependencyPaths.get(path)), + ].filter(Boolean), ) // If the file is not associated with any function, there's no point in @@ -285,7 +288,7 @@ export class EdgeFunctionsRegistry { return } - const reason = this.#debug ? ` because ${chalk.underline(path)} has changed` : '' + const reason = this.#debug ? ` because ${chalk.underline(paths.join(','))} has changed` : '' log(`${NETLIFYDEVLOG} ${chalk.magenta('Reloading')} edge functions${reason}...`) @@ -548,7 +551,7 @@ export class EdgeFunctionsRegistry { const watcher = await watchDebounced(directory, { ignored, onAdd: () => this.#checkForAddedOrDeletedFunctions(), - onChange: (path) => this.#handleFileChange(path), + onChange: (paths) => this.#handleFileChange(paths), onUnlink: () => this.#checkForAddedOrDeletedFunctions(), }) diff --git a/src/utils/command-helpers.mjs b/src/utils/command-helpers.mjs index b20de549783..5bd68dd71e9 100644 --- a/src/utils/command-helpers.mjs +++ b/src/utils/command-helpers.mjs @@ -9,6 +9,7 @@ import { Chalk } from 'chalk' import chokidar from 'chokidar' import decache from 'decache' import WSL from 'is-wsl' +import debounce from 'lodash/debounce.js' import terminalLink from 'terminal-link' import { clearSpinner, startSpinner } from '../lib/spinner.mjs' @@ -224,6 +225,8 @@ export const normalizeConfig = (config) => { return publishOrigin === 'default' ? { ...config, build } : config } +const DEBOUNCE_WAIT = 100 + /** * Adds a file watcher to a path or set of paths and debounces the events. * @@ -231,9 +234,9 @@ export const normalizeConfig = (config) => { * @param {Object} opts * @param {number} [opts.depth] * @param {Array} [opts.ignored] - * @param {(path: string) => any} [opts.onAdd] - * @param {(path: string) => any} [opts.onChange] - * @param {(path: string) => any} [opts.onUnlink] + * @param {(paths: string[]) => any} [opts.onAdd] + * @param {(paths: string[]) => any} [opts.onChange] + * @param {(paths: string[]) => any} [opts.onUnlink] */ export const watchDebounced = async ( target, @@ -244,18 +247,38 @@ export const watchDebounced = async ( await once(watcher, 'ready') + let onChangeQueue = [] + let onAddQueue = [] + let onUnlinkQueue = [] + + const debouncedOnChange = debounce(() => { + onChange(onChangeQueue) + onChangeQueue = [] + }, DEBOUNCE_WAIT) + const debouncedOnAdd = debounce(() => { + onAdd(onAddQueue) + onAddQueue = [] + }, DEBOUNCE_WAIT) + const debouncedOnUnlink = debounce(() => { + onUnlink(onUnlinkQueue) + onUnlinkQueue = [] + }, DEBOUNCE_WAIT) + watcher .on('change', (path) => { decache(path) - onChange(path) + onChangeQueue.push(path) + debouncedOnChange() }) .on('unlink', (path) => { decache(path) - onUnlink(path) + onUnlinkQueue.push(path) + debouncedOnUnlink() }) .on('add', (path) => { decache(path) - onAdd(path) + onAddQueue.push(path) + debouncedOnAdd() }) return watcher