Skip to content

Commit 13c16ef

Browse files
authored
Merge pull request #26 from soukand/abort_controller
AbortController support
2 parents 2be4958 + a8f646f commit 13c16ef

14 files changed

+146
-25
lines changed

README.md

Lines changed: 55 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@
22

33
![fuzzball.js logo](fuzzballlogo.jpg "feed me strings!")
44
==========
5-
Easy to use and powerful fuzzy string matching.
5+
Easy to use and powerful fuzzy string matching.
66

77
Mostly a JavaScript port of the [TheFuzz](https://github.com/seatgeek/thefuzz) (formerly fuzzywuzzy) Python library, with some additional features like token similarity sorting and wildcard support.
88

9-
Demo <a href="https://nol13.github.io/fuzzball.js" target="_blank">here</a> comparing some of the different scorers/options. Auto-generated API Docs <a href="https://github.com/nol13/fuzzball.js/blob/master/jsdocs/fuzzball.md" target="_blank">here</a>.
9+
Demo <a href="https://nol13.github.io/fuzzball.js" target="_blank">here</a> comparing some of the different scorers/options. Auto-generated API Docs <a href="https://github.com/nol13/fuzzball.js/blob/master/jsdocs/fuzzball.md" target="_blank">here</a>.
1010

1111
# Contents
1212
* [Installation](#installation)
@@ -73,7 +73,7 @@ fuzz.extract("mr. harry hood", choices, options);
7373
[ 'Mr. Henry Hood', 85, 2 ],
7474
[ 'Mr. Minor', 40, 1 ] ]
7575
76-
/**
76+
/**
7777
* Set options.returnObjects = true to get back
7878
* an array of {choice, score, key} objects instead of tuples
7979
*/
@@ -89,9 +89,21 @@ options.cancelToken = cancelToken;
8989
fuzz.extractAsPromised("gonna get canceled", choices, options)
9090
.then(res => {/* do stuff */})
9191
.catch((e) => {
92-
if (e.message === 'canceled') console.log('I got canceled!')
92+
if (e.message === 'canceled') console.log('I got canceled!')
9393
});
9494
cancelToken.canceled = true;
95+
96+
// or use AbortController to cancel search
97+
const abortController = new AbortController();
98+
99+
options.abortController = abortController;
100+
fuzz.extractAsPromised("gonna get canceled", choices, options)
101+
.then(res => {/* do stuff */})
102+
.catch((e) => {
103+
if (e.message === 'aborted') console.log('Search was aborted!')
104+
});
105+
106+
abortController.abort();
95107
```
96108
97109
**Simple Ratio**
@@ -102,7 +114,7 @@ fuzz.ratio("this is a test", "This is a test!");
102114
100
103115
```
104116
105-
**Partial Ratio**
117+
**Partial Ratio**
106118
107119
Highest scoring substring of the longer string vs. the shorter string.
108120
@@ -122,18 +134,18 @@ fuzz.token_sort_ratio("fuzzy wuzzy was a bear", "wuzzy fuzzy was a bear");
122134
100
123135
```
124136
125-
**Token Set Ratio**
137+
**Token Set Ratio**
126138
127139
Highest of 3 scores comparing the set intersection, intersection + difference 1 to 2, and intersection + difference 2 to 1.
128140
```js
129141
fuzz.token_sort_ratio("fuzzy was a bear", "fuzzy fuzzy was a bear");
130142
84
131-
fuzz.token_set_ratio("fuzzy was a bear", "fuzzy fuzzy was a bear");
143+
fuzz.token_set_ratio("fuzzy was a bear", "fuzzy fuzzy was a bear");
132144
100
133145
```
134146
If you set options.trySimple to true it will add the simple ratio to the token_set_ratio test suite as well. This can help smooth out occational irregularities in how much differences in the first letter of a token will get penalized.
135147
136-
**Token Similarity Sort Ratio**
148+
**Token Similarity Sort Ratio**
137149
138150
Instead of sorting alphabetically, tokens will be sorted by similarity to the smaller set. Useful if the matching token may have a different first letter, but performs a bit slower. You can also use similarity sorting when calculating token_set_ratio by setting sortBySimilarity to true.
139151
@@ -200,7 +212,7 @@ fuzz.ratio("this is ä test", "this is a test", options);
200212
100
201213
```
202214
203-
If your strings contain code points beyond the basic multilingual plane (BMP), set **astral** to true. If your strings contain astral symbols and this is not set, those symbols will be treated as multiple characters and the ratio will be off a bit. (This will have some impact on performance, which is why it is turned off by default.)
215+
If your strings contain code points beyond the basic multilingual plane (BMP), set **astral** to true. If your strings contain astral symbols and this is not set, those symbols will be treated as multiple characters and the ratio will be off a bit. (This will have some impact on performance, which is why it is turned off by default.)
204216
205217
```js
206218
options = {astral: true};
@@ -211,7 +223,7 @@ fuzz.ratio("ab🐴c", "ab🐴d", options);
211223
212224
When astral is true it will also normalize your strings before scoring, as long as String.prototype.normalize exists in your environment, but will not attempt to polyfill. (So if you need to compare unnormalized strings in IE, normalize separately) You can set the **normalize** option to false if you want different representations not to match, but is true by default.
213225
214-
### Batch Extract
226+
### Batch Extract
215227
Search list of choices for top results.
216228
217229
###### fuzz.extract(query, choices, options);
@@ -318,16 +330,45 @@ results = fuzz.extract(query, choices, options);
318330
319331
### Async and Cancellation
320332
321-
When using extractAsPromised or extractAsync, create a new object with a 'canceled' property to use as a cancel token. For performance, by default only every 256th loop will be async, but set asyncLoopOffset to change. It is most likely not worth changing this.
333+
When using extractAsPromised or extractAsync, you might want to cancel the action before it has finished.
334+
It can be done using `CancelToken` or `AbortController`.
335+
336+
For performance, by default only every 256th loop will be async, but set `asyncLoopOffset` to change. It is most likely not worth changing this.
337+
338+
**AbortController**
339+
340+
[AbortController](https://developer.mozilla.org/en-US/docs/Web/API/AbortController) is present in modern browsers and from node version `15+`. It is currently a standard way how to cancel running operations.
322341
323342
```js
324-
let cancelToken = {canceled: false};
343+
// or use AbortController to cancel search
344+
const abortController = new AbortController();
345+
346+
options.abortController = abortController;
347+
options.asyncLoopOffset = 64;
348+
349+
fuzz.extractAsPromised("gonna get aborted", choices, options)
350+
.then(res => {/* do stuff */})
351+
.catch((e) => {
352+
if (e.message === 'aborted') console.log('I got aborted!')
353+
});
354+
355+
abortController.abort();
356+
```
357+
358+
**CancelToken**
359+
360+
For older browsers and node versions you can use cancel token. It is an in
361+
362+
```js
363+
let cancelToken = { canceled: false };
364+
325365
options.cancelToken = cancelToken;
326366
options.asyncLoopOffset = 64;
367+
327368
fuzz.extractAsPromised("gonna get canceled", choices, options)
328369
.then(res => {/* do stuff */})
329370
.catch((e) => {
330-
if (e.message === 'canceled') console.log('I got canceled!')
371+
if (e.message === 'canceled') console.log('I got canceled!')
331372
});
332373
333374
// ...
@@ -476,4 +517,4 @@ Thanks to dvisg and voidevector on reddit for .d.ts feedback.
476517
477518
### Contributions
478519
479-
Pull requests welcome.
520+
Pull requests welcome.

dist/esm/fuzzball.esm.min.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/fuzzball.umd.min.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

fuzzball.d.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,13 @@ interface FuzzballExtractBaseOptions extends FuzzballBaseOptions {
6767
sortBySimilarity?: boolean
6868
}
6969

70+
interface AbortController {
71+
/**
72+
* If extract has been aborted;
73+
*/
74+
signal: { aborted: boolean }
75+
}
76+
7077
interface CancellationToken {
7178
/**
7279
* If extract has been canceled;
@@ -89,6 +96,10 @@ export interface FuzzballExtractObjectOptions extends FuzzballExtractBaseOptions
8996
}
9097

9198
export interface FuzzballAsyncExtractOptions extends FuzzballExtractOptions {
99+
/**
100+
* Track if extract has been aborted
101+
*/
102+
abortController?: AbortController;
92103
/**
93104
* Track if extract has been canceled
94105
*/
@@ -100,6 +111,10 @@ export interface FuzzballAsyncExtractOptions extends FuzzballExtractOptions {
100111
}
101112

102113
export interface FuzzballAsyncExtractObjectOptions extends FuzzballExtractObjectOptions {
114+
/**
115+
* Track if extract has been aborted
116+
*/
117+
abortController?: AbortController;
103118
/**
104119
* Track if extract has been canceled;
105120
*/

fuzzball.js

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -511,11 +511,18 @@
511511
* @param {boolean} [options_p.sortBySimilarity] - sort tokens by similarity to each other before combining instead of alphabetically
512512
* @param {string} [options_p.wildcards] - characters that will be used as wildcards if provided
513513
* @param {boolean} [options_p.returnObjects] - return array of object instead of array of tuples; default false
514+
* @param {Object} [options_p.abortController] - track abortion
514515
* @param {Object} [options_p.cancelToken] - track cancellation
515516
* @param {number} [options_p.asyncLoopOffset] - number of rows to run in between every async loop iteration, default 256
516517
* @param {function} callback - node style callback (err, arrayOfResults)
517518
*/
518519
var options = clone_and_set_option_defaults(options_p);
520+
521+
var abortController;
522+
if (typeof options_p.abortController === "object") {
523+
abortController = options_p.abortController;
524+
}
525+
519526
var cancelToken;
520527
if (typeof options_p.cancelToken === "object") {
521528
cancelToken = options_p.cancelToken;
@@ -646,6 +653,11 @@
646653
}
647654
}
648655

656+
if (abortController && abortController.signal.aborted === true) {
657+
callback(new Error("aborted"));
658+
return;
659+
}
660+
649661
if (cancelToken && cancelToken.canceled === true) {
650662
callback(new Error("canceled"));
651663
return;
@@ -742,7 +754,7 @@
742754
}
743755
}
744756
}
745-
757+
746758
return charCounts;
747759
}
748760

jsdocs/fuzzball.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,7 @@ Return the top scoring items from an array (or assoc array) of choices
280280
| [options_p.sortBySimilarity] | <code>boolean</code> | sort tokens by similarity to each other before combining instead of alphabetically |
281281
| [options_p.wildcards] | <code>string</code> | characters that will be used as wildcards if provided |
282282
| [options_p.returnObjects] | <code>boolean</code> | return array of object instead of array of tuples; default false |
283+
| [options_p.abortController] | <code>Object</code> | track abortion |
283284
| [options_p.cancelToken] | <code>Object</code> | track cancellation |
284285
| [options_p.asyncLoopOffset] | <code>number</code> | number of rows to run in between every async loop iteration, default 256 |
285286
| callback | <code>function</code> | node style callback (err, arrayOfResults) |

lite/esm/fuzzball_lite.esm.min.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

lite/fuzzball_lite.d.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,13 @@ interface FuzzballExtractBaseOptions extends FuzzballBaseOptions {
5959
cutoff?: number;
6060
}
6161

62+
interface AbortController {
63+
/**
64+
* If extract has been aborted;
65+
*/
66+
signal: { aborted: boolean }
67+
}
68+
6269
interface CancellationToken {
6370
/**
6471
* If extract has been canceled;
@@ -81,6 +88,10 @@ export interface FuzzballExtractObjectOptions extends FuzzballExtractBaseOptions
8188
}
8289

8390
export interface FuzzballAsyncExtractOptions extends FuzzballExtractOptions {
91+
/**
92+
* Track if extract has been aborted
93+
*/
94+
abortController?: AbortController;
8495
/**
8596
* Track if extract has been canceled
8697
*/
@@ -92,6 +103,10 @@ export interface FuzzballAsyncExtractOptions extends FuzzballExtractOptions {
92103
}
93104

94105
export interface FuzzballAsyncExtractObjectOptions extends FuzzballExtractObjectOptions {
106+
/**
107+
* Track if extract has been aborted
108+
*/
109+
abortController?: AbortController;
95110
/**
96111
* Track if extract has been canceled;
97112
*/

lite/fuzzball_lite.js

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828

2929
var processing = require('../lib/process.js')(clone_and_set_option_defaults, Array.isArray, QRatio, extract);
3030
var dedupe = processing.dedupe;
31-
31+
3232
/** Mostly follows after python fuzzywuzzy, https://github.com/seatgeek/fuzzywuzzy */
3333

3434

@@ -292,12 +292,18 @@
292292
* @param {boolean} [options_p.trySimple] - try simple/partial ratio as part of (parial_)token_set_ratio test suite
293293
* @param {string} [options_p.wildcards] - characters that will be used as wildcards if provided
294294
* @param {boolean} [options_p.returnObjects] - return array of object instead of array of tuples; default false
295+
* @param {Object} [options_p.abortController] - track abortion
295296
* @param {Object} [options_p.cancelToken] - track cancellation
296297
* @param {number} [options_p.asyncLoopOffset] - number of rows to run in between every async loop iteration, default 256
297298
* @param {function} callback - node style callback (err, arrayOfResults)
298299
*/
299300
var options = clone_and_set_option_defaults(options_p);
300301

302+
var abortController;
303+
if (typeof options_p.abortController === "object") {
304+
abortController = options_p.abortController;
305+
}
306+
301307
var cancelToken;
302308
if (typeof options_p.cancelToken === "object") {
303309
cancelToken = options_p.cancelToken;
@@ -428,6 +434,11 @@
428434
}
429435
}
430436

437+
if (abortController && abortController.signal.aborted === true) {
438+
callback(new Error("aborted"));
439+
return;
440+
}
441+
431442
if (cancelToken && cancelToken.canceled === true) {
432443
callback(new Error("canceled"));
433444
return;
@@ -476,7 +487,7 @@
476487
var sorted_2to1 = diff2to1.sort().join(" ");
477488
var combined_1to2 = sorted_sect + " " + sorted_1to2;
478489
var combined_2to1 = sorted_sect + " " + sorted_2to1;
479-
490+
480491
sorted_sect = sorted_sect.trim();
481492
combined_1to2 = combined_1to2.trim();
482493
combined_2to1 = combined_2to1.trim();

lite/fuzzball_lite.umd.min.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)