From e8b67eb024fca9fc72faa0215a396a9550799849 Mon Sep 17 00:00:00 2001 From: fisker Cheung Date: Mon, 17 Jan 2022 17:56:43 +0800 Subject: [PATCH 1/3] Add failed test --- test.js | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/test.js b/test.js index f403623..f52d377 100644 --- a/test.js +++ b/test.js @@ -425,3 +425,23 @@ test('don\'t throw when specifying a non-existing cwd directory - sync', t => { t.is(actual.length, 0); } }); + +test('unique when using objectMode option', async t => { + const patterns = ['a.tmp', '*.tmp']; + const options = {cwd, objectMode: true}; + const isUnique = result => [...new Set(result)].length === result.length; + + const syncResult = globbySync(patterns, options).map(({path}) => path); + t.true(isUnique(syncResult)); + + const result = await globby(patterns, options); + t.deepEqual(result.map(({path}) => path), syncResult); + + // TODO: Use `Array.fromAsync` when Node.js supports it + const streamResult = []; + for await (const {path} of globbyStream(patterns, options)) { + streamResult.push(path); + } + + t.deepEqual(streamResult, syncResult); +}); From 883958585ce48117916858e7e43eb3bacd481d5e Mon Sep 17 00:00:00 2001 From: fisker Cheung Date: Mon, 17 Jan 2022 18:18:27 +0800 Subject: [PATCH 2/3] Fix --- index.js | 29 +++++++++++++++++++---------- stream-utils.js | 10 +++++++--- 2 files changed, 26 insertions(+), 13 deletions(-) diff --git a/index.js b/index.js index 3a6ac08..643aeec 100644 --- a/index.js +++ b/index.js @@ -35,6 +35,19 @@ const checkCwdOption = options => { }; const getPathString = fastGlobResult => fastGlobResult.path || fastGlobResult; +const unionFastGlobResults = (results, filter) => + results + .flat() + .filter((fastGlobResult, index, results) => { + if (filter(fastGlobResult)) { + return false; + } + + const path = getPathString(fastGlobResult); + const firstIndex = results.findIndex(fastGlobResult => getPathString(fastGlobResult) === path); + + return index === firstIndex; + }); export const generateGlobTasks = (patterns, taskOptions) => { patterns = arrayUnion([patterns].flat()); @@ -150,9 +163,9 @@ export const globby = async (patterns, options = {}) => { }; const [filter, tasks] = await Promise.all([getFilter(options), getTasks()]); - const paths = await Promise.all(tasks.map(task => fastGlob(task.pattern, task.options))); + const results = await Promise.all(tasks.map(task => fastGlob(task.pattern, task.options))); - return arrayUnion(...paths).filter(path_ => !filter(path_)); + return unionFastGlobResults(results, filter); }; export const globbySync = (patterns, options = {}) => { @@ -165,13 +178,9 @@ export const globbySync = (patterns, options = {}) => { } const filter = getFilterSync(options); + const results = tasks.map(task => fastGlob.sync(task.pattern, task.options)); - let matches = []; - for (const task of tasks) { - matches = arrayUnion(matches, fastGlob.sync(task.pattern, task.options)); - } - - return matches.filter(path_ => !filter(path_)); + return unionFastGlobResults(results, filter); }; export const globbyStream = (patterns, options = {}) => { @@ -184,8 +193,8 @@ export const globbyStream = (patterns, options = {}) => { } const filter = getFilterSync(options); - const filterStream = new FilterStream(p => !filter(p)); - const uniqueStream = new UniqueStream(); + const filterStream = new FilterStream(fastGlobResult => !filter(fastGlobResult)); + const uniqueStream = new UniqueStream(fastGlobResult => getPathString(fastGlobResult)); return merge2(tasks.map(task => fastGlob.stream(task.pattern, task.options))) .pipe(filterStream) diff --git a/stream-utils.js b/stream-utils.js index 91a99bb..86c3779 100644 --- a/stream-utils.js +++ b/stream-utils.js @@ -24,15 +24,19 @@ export class FilterStream extends ObjectTransform { } export class UniqueStream extends ObjectTransform { - constructor() { + constructor(uniqueBy) { super(); + this._uniqueBy = uniqueBy; this._pushed = new Set(); } _transform(data, encoding, callback) { - if (!this._pushed.has(data)) { + const {_uniqueBy: uniqueBy, _pushed: pushed} = this; + const key = uniqueBy(data); + + if (!pushed.has(key)) { this.push(data); - this._pushed.add(data); + pushed.add(key); } callback(); From 1e62b3ef0f4b8e3a63e7903a993cbde2071242de Mon Sep 17 00:00:00 2001 From: fisker Cheung Date: Mon, 17 Jan 2022 18:28:09 +0800 Subject: [PATCH 3/3] Minor tweak --- index.js | 31 ++++++++++++++++++------------- stream-utils.js | 12 ++++++------ 2 files changed, 24 insertions(+), 19 deletions(-) diff --git a/index.js b/index.js index 643aeec..253846c 100644 --- a/index.js +++ b/index.js @@ -35,19 +35,24 @@ const checkCwdOption = options => { }; const getPathString = fastGlobResult => fastGlobResult.path || fastGlobResult; -const unionFastGlobResults = (results, filter) => - results - .flat() - .filter((fastGlobResult, index, results) => { - if (filter(fastGlobResult)) { - return false; - } - - const path = getPathString(fastGlobResult); - const firstIndex = results.findIndex(fastGlobResult => getPathString(fastGlobResult) === path); - - return index === firstIndex; - }); +const unionFastGlobResults = (results, filter) => { + const seen = new Set(); + + return results.flat().filter(fastGlobResult => { + if (filter(fastGlobResult)) { + return false; + } + + const value = getPathString(fastGlobResult); + if (seen.has(value)) { + return false; + } + + seen.add(value); + + return true; + }); +}; export const generateGlobTasks = (patterns, taskOptions) => { patterns = arrayUnion([patterns].flat()); diff --git a/stream-utils.js b/stream-utils.js index 86c3779..2f64be2 100644 --- a/stream-utils.js +++ b/stream-utils.js @@ -24,19 +24,19 @@ export class FilterStream extends ObjectTransform { } export class UniqueStream extends ObjectTransform { - constructor(uniqueBy) { + constructor(comparator) { super(); - this._uniqueBy = uniqueBy; + this._comparator = comparator; this._pushed = new Set(); } _transform(data, encoding, callback) { - const {_uniqueBy: uniqueBy, _pushed: pushed} = this; - const key = uniqueBy(data); + const {_comparator: comparator, _pushed: pushed} = this; + const value = comparator(data); - if (!pushed.has(key)) { + if (!pushed.has(value)) { this.push(data); - pushed.add(key); + pushed.add(value); } callback();