diff --git a/README.md b/README.md index e1e1b0a..cda32ef 100644 --- a/README.md +++ b/README.md @@ -87,10 +87,24 @@ Options: Instances of `{path}` or `{event}` within the command will be replaced by the corresponding values from the chokidar event. - -d, --debounce Debounce timeout in ms for executing command - [default: 400] - -t, --throttle Throttle timeout in ms for executing command - [default: 0] + -d, --debounce Delays command execution until after specified ms have + elapsed since the last time the debounced command was + executed [default: 400] + --debounce-leading Specify executing on the leading edge of the timeout + [boolean] [default: false] + --debounce-max-wait The maximum time command is allowed to be delayed + before it is executed + --debounce-trailing Specify executing on the trailing edge of the timeout + [boolean] [default: true] + -t, --throttle Only execute command at most once per every specified + ms. Note: If leading and trailing options are true, + command is executed on the trailing edge of the + timeout only if the the throttled command is invoked + more than once during the timeout [default: 0] + --throttle-leading Specify executing on the leading edge of the timeout + [boolean] [default: true] + --throttle-trailing Specify executing on the trailing edge of the timeout + [boolean] [default: true] -s, --follow-symlinks When not set, only the symlinks themselves will be watched for changes instead of following the link references and bubbling events through the links path @@ -106,10 +120,10 @@ Options: of fs.watch. This might lead to high CPU utilization. It is typically necessary to set this to true to successfully watch files over a network, and it may be - necessary to successfully watch files in other non- - standard situations [boolean] [default: false] - --poll-interval Interval of file system polling. Effective when -- - polling is set [default: 100] + necessary to successfully watch files in other + non-standard situations [boolean] [default: false] + --poll-interval Interval of file system polling. Effective when + --polling is set [default: 100] --poll-interval-binary Interval of file system polling for binary files. Effective when --polling is set [default: 300] --verbose When set, output is more verbose and human readable. diff --git a/index.js b/index.js index e638668..2d1418f 100755 --- a/index.js +++ b/index.js @@ -16,7 +16,12 @@ var EVENT_DESCRIPTIONS = { var defaultOpts = { debounce: 400, + debounceLeading: false, + debounceMaxWait: undefined, + debounceTrailing: true, throttle: 0, + throttleLeading: true, + throttleTrailing: true, followSymlinks: false, ignore: null, polling: false, @@ -54,15 +59,44 @@ var argv = require('yargs') .option('d', { alias: 'debounce', default: defaultOpts.debounce, - describe: 'Debounce timeout in ms for executing command', + describe: 'Delays command execution until after specified ms have ' + + 'elapsed since the last time the debounced command was executed', type: 'number' }) + .option('debounce-leading', { + default: defaultOpts.debounceLeading, + describe: 'Specify executing on the leading edge of the timeout', + type: 'boolean' + }) + .option('debounce-max-wait', { + default: defaultOpts.debounceMaxWait, + describe: 'The maximum time command is allowed to be delayed before it is executed', + type: 'number' + }) + .option('debounce-trailing', { + default: defaultOpts.debounceTrailing, + describe: 'Specify executing on the trailing edge of the timeout', + type: 'boolean' + }) .option('t', { alias: 'throttle', default: defaultOpts.throttle, - describe: 'Throttle timeout in ms for executing command', + describe: 'Only execute command at most once per every specified ms. ' + + 'Note: If leading and trailing options are true, command is ' + + 'executed on the trailing edge of the timeout only if the the ' + + 'throttled command is invoked more than once during the timeout', type: 'number' }) + .option('throttle-leading', { + default: defaultOpts.throttleLeading, + describe: 'Specify executing on the leading edge of the timeout', + type: 'boolean' + }) + .option('throttle-trailing', { + default: defaultOpts.throttleTrailing, + describe: 'Specify executing on the trailing edge of the timeout', + type: 'boolean' + }) .option('s', { alias: 'follow-symlinks', default: defaultOpts.followSymlinks, @@ -139,8 +173,14 @@ function startWatching(opts) { var chokidarOpts = createChokidarOpts(opts); var watcher = chokidar.watch(opts.patterns, chokidarOpts); - var throttledRun = _.throttle(run, opts.throttle); - var debouncedRun = _.debounce(throttledRun, opts.debounce); + var throttledRun = _.throttle(run, opts.throttle, { + leading: opts.throttleLeading, + trailing: opts.throttleTrailing + }); + + var debounceOpts = createDebounceOpts(opts); + var debouncedRun = _.debounce(throttledRun, opts.debounce, debounceOpts); + watcher.on('all', function(event, path) { var description = EVENT_DESCRIPTIONS[event] + ':'; @@ -191,6 +231,17 @@ function createChokidarOpts(opts) { return chokidarOpts; } +function createDebounceOpts(opts) { + var debounceOpts = { + leading: opts.debounceLeading, + trailing: opts.debounceTrailing + }; + + if (opts.debounceMaxWait) debounceOpts.maxWait = opts.debounceMaxWait; + + return debounceOpts; +} + // Takes string or array of strings function _resolveIgnoreOpt(ignoreOpt) { if (!ignoreOpt) {