-
-
Notifications
You must be signed in to change notification settings - Fork 7
/
index.js
78 lines (64 loc) · 1.83 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
import functionTimeout, {isTimeoutError} from 'function-timeout';
import timeSpan from 'time-span';
const resultToMatch = result => ({
match: result[0],
index: result.index,
groups: result.slice(1),
namedGroups: result.groups ?? {},
input: result.input,
});
const context = {};
export function isMatch(regex, string, {timeout} = {}) {
try {
return functionTimeout(() => structuredClone(regex).test(string), {timeout, context})();
} catch (error) {
if (isTimeoutError(error)) {
return false;
}
throw error;
}
}
export function firstMatch(regex, string, {timeout} = {}) {
try {
const result = functionTimeout(() => structuredClone(regex).exec(string), {timeout, context})();
if (result === null) {
return;
}
return resultToMatch(result);
} catch (error) {
if (isTimeoutError(error)) {
return;
}
throw error;
}
}
export function matches(regex, string, {timeout = Number.POSITIVE_INFINITY, matchTimeout = Number.POSITIVE_INFINITY} = {}) {
if (!regex.global) {
throw new Error('The regex must have the global flag, otherwise, use `firstMatch()` instead');
}
return {
* [Symbol.iterator]() {
try {
const matches = string.matchAll(regex); // The regex is only executed when iterated over.
while (true) {
// `matches.next` must be called within an arrow function so that it doesn't loose its context.
const nextMatch = functionTimeout(() => matches.next(), {
context,
timeout: (timeout !== Number.POSITIVE_INFINITY || matchTimeout !== Number.POSITIVE_INFINITY) ? Math.min(timeout, matchTimeout) : undefined,
});
const end = timeSpan();
const {value, done} = nextMatch();
timeout -= Math.ceil(end());
if (done) {
break;
}
yield resultToMatch(value);
}
} catch (error) {
if (!isTimeoutError(error)) {
throw error;
}
}
},
};
}