graphmatch 1.0.0 → 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/types.d.ts +4 -1
- package/dist/utils.d.ts +1 -2
- package/dist/utils.js +46 -15
- package/package.json +1 -4
- package/asd.js +0 -81
package/dist/types.d.ts
CHANGED
package/dist/utils.d.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import type { Node } from './types.js';
|
|
2
2
|
declare const getNodeFlags: (node: Node) => string;
|
|
3
3
|
declare const getNodeSource: (node: Node, partial: boolean) => string;
|
|
4
|
-
|
|
5
|
-
export { getNodeFlags, getNodeSource, visitNode };
|
|
4
|
+
export { getNodeFlags, getNodeSource };
|
package/dist/utils.js
CHANGED
|
@@ -1,27 +1,49 @@
|
|
|
1
1
|
/* IMPORT */
|
|
2
2
|
/* MAIN */
|
|
3
|
+
const getNodes = (node) => {
|
|
4
|
+
const nodes = new Set();
|
|
5
|
+
const queue = [node];
|
|
6
|
+
for (let i = 0; i < queue.length; i++) {
|
|
7
|
+
const node = queue[i];
|
|
8
|
+
if (nodes.has(node))
|
|
9
|
+
continue;
|
|
10
|
+
nodes.add(node);
|
|
11
|
+
const { children } = node;
|
|
12
|
+
if (!children?.length)
|
|
13
|
+
continue;
|
|
14
|
+
for (let ci = 0, cl = children.length; ci < cl; ci++) {
|
|
15
|
+
queue.push(children[ci]);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
return Array.from(nodes);
|
|
19
|
+
};
|
|
3
20
|
const getNodeFlags = (node) => {
|
|
4
21
|
let flags = '';
|
|
5
|
-
|
|
22
|
+
const nodes = getNodes(node);
|
|
23
|
+
for (let i = 0, l = nodes.length; i < l; i++) { // From root to leaves
|
|
24
|
+
const node = nodes[i];
|
|
6
25
|
if (!node.regex)
|
|
7
|
-
|
|
26
|
+
continue;
|
|
8
27
|
const nodeFlags = node.regex.flags;
|
|
9
28
|
flags || (flags = nodeFlags);
|
|
10
|
-
if (flags
|
|
11
|
-
|
|
12
|
-
}
|
|
13
|
-
}
|
|
29
|
+
if (flags === nodeFlags)
|
|
30
|
+
continue;
|
|
31
|
+
throw new Error(`Inconsistent RegExp flags used: "${flags}" and "${nodeFlags}"`);
|
|
32
|
+
}
|
|
14
33
|
return flags;
|
|
15
34
|
};
|
|
16
|
-
const
|
|
35
|
+
const getNodeSourceWithCache = (node, partial, cache) => {
|
|
36
|
+
const cached = cache.get(node);
|
|
37
|
+
if (cached !== undefined)
|
|
38
|
+
return cached;
|
|
17
39
|
let source = '';
|
|
18
40
|
if (node.regex) {
|
|
19
41
|
source += partial ? '(?:$|' : '';
|
|
20
42
|
source += node.regex.source;
|
|
21
43
|
}
|
|
22
44
|
if (node.children?.length) {
|
|
23
|
-
const children = node.children.map(node =>
|
|
24
|
-
if (children
|
|
45
|
+
const children = uniq(node.children.map(node => getNodeSourceWithCache(node, partial, cache)).filter(Boolean));
|
|
46
|
+
if (children?.length) {
|
|
25
47
|
const needsWrapperGroup = (children.length > 1) || (partial && !source.length);
|
|
26
48
|
source += needsWrapperGroup ? partial ? '(?:$|' : '(?:' : '';
|
|
27
49
|
source += children.join('|');
|
|
@@ -31,13 +53,22 @@ const getNodeSource = (node, partial) => {
|
|
|
31
53
|
if (node.regex) {
|
|
32
54
|
source += partial ? ')' : '';
|
|
33
55
|
}
|
|
56
|
+
cache.set(node, source);
|
|
34
57
|
return source;
|
|
35
58
|
};
|
|
36
|
-
const
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
59
|
+
const getNodeSource = (node, partial) => {
|
|
60
|
+
const cache = new Map();
|
|
61
|
+
const nodes = getNodes(node);
|
|
62
|
+
for (let i = nodes.length - 1; i >= 0; i--) { // From leaves to root
|
|
63
|
+
const source = getNodeSourceWithCache(nodes[i], partial, cache);
|
|
64
|
+
if (i > 0)
|
|
65
|
+
continue;
|
|
66
|
+
return source;
|
|
67
|
+
}
|
|
68
|
+
return '';
|
|
69
|
+
};
|
|
70
|
+
const uniq = (values) => {
|
|
71
|
+
return Array.from(new Set(values));
|
|
41
72
|
};
|
|
42
73
|
/* EXPORT */
|
|
43
|
-
export { getNodeFlags, getNodeSource
|
|
74
|
+
export { getNodeFlags, getNodeSource };
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "graphmatch",
|
|
3
3
|
"repository": "github:fabiospampinato/graphmatch",
|
|
4
4
|
"description": "A low-level utility for matching a string against a directed acyclic graph of regexes.",
|
|
5
|
-
"version": "1.0.
|
|
5
|
+
"version": "1.0.2",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"main": "dist/index.js",
|
|
8
8
|
"exports": "./dist/index.js",
|
|
@@ -29,8 +29,5 @@
|
|
|
29
29
|
"fava": "^0.3.5",
|
|
30
30
|
"tsex": "^4.0.2",
|
|
31
31
|
"typescript": "^5.9.3"
|
|
32
|
-
},
|
|
33
|
-
"dependencies": {
|
|
34
|
-
"lodash": "^4.17.21"
|
|
35
32
|
}
|
|
36
33
|
}
|
package/asd.js
DELETED
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
import graphmatch from './dist/index.js';
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
const GRAPH = {
|
|
6
|
-
regex: /foo/,
|
|
7
|
-
children: [
|
|
8
|
-
{
|
|
9
|
-
regex: /\//,
|
|
10
|
-
children: [
|
|
11
|
-
{
|
|
12
|
-
regex: /bar/,
|
|
13
|
-
children: [
|
|
14
|
-
{
|
|
15
|
-
regex: /\//,
|
|
16
|
-
children: [
|
|
17
|
-
{
|
|
18
|
-
regex: /qux/
|
|
19
|
-
}
|
|
20
|
-
]
|
|
21
|
-
}
|
|
22
|
-
]
|
|
23
|
-
},
|
|
24
|
-
{
|
|
25
|
-
regex: /baz/,
|
|
26
|
-
children: [
|
|
27
|
-
{
|
|
28
|
-
regex: /\//,
|
|
29
|
-
children: [
|
|
30
|
-
{
|
|
31
|
-
regex: /qux/
|
|
32
|
-
}
|
|
33
|
-
]
|
|
34
|
-
}
|
|
35
|
-
]
|
|
36
|
-
}
|
|
37
|
-
]
|
|
38
|
-
}
|
|
39
|
-
]
|
|
40
|
-
};
|
|
41
|
-
|
|
42
|
-
// Let's now match against the graph, fully
|
|
43
|
-
|
|
44
|
-
console.log ('1.');
|
|
45
|
-
|
|
46
|
-
console.log ( graphmatch ( GRAPH, 'foo/bar/qux' ) ); // => true
|
|
47
|
-
console.log ( graphmatch ( GRAPH, 'foo/baz/qux' ) ); // => true
|
|
48
|
-
|
|
49
|
-
console.log ( graphmatch ( GRAPH, 'foo/bar/whoops' ) ); // => false
|
|
50
|
-
console.log ( graphmatch ( GRAPH, 'foo/baz' ) ); // => false
|
|
51
|
-
|
|
52
|
-
// Let's now match against the graph, partially
|
|
53
|
-
// A partial match happens when any matching node in the graph reaches the end of the string
|
|
54
|
-
|
|
55
|
-
console.log ('2.');
|
|
56
|
-
|
|
57
|
-
console.log ( graphmatch ( GRAPH, 'foo/bar/qux', { partial: true } ) ); // => true
|
|
58
|
-
console.log ( graphmatch ( GRAPH, 'foo/bar/', { partial: true } ) ); // => true
|
|
59
|
-
console.log ( graphmatch ( GRAPH, 'foo/bar', { partial: true } ) ); // => true
|
|
60
|
-
console.log ( graphmatch ( GRAPH, 'foo/', { partial: true } ) ); // => true
|
|
61
|
-
console.log ( graphmatch ( GRAPH, 'foo', { partial: true } ) ); // => true
|
|
62
|
-
|
|
63
|
-
console.log ( graphmatch ( GRAPH, 'foo/bar/whoops', { partial: true } ) ); // => false
|
|
64
|
-
console.log ( graphmatch ( GRAPH, 'foo/barsomething', { partial: true } ) ); // => false
|
|
65
|
-
console.log ( graphmatch ( GRAPH, 'bar', { partial: true } ) ); // => false
|
|
66
|
-
|
|
67
|
-
// Let's now compile the whole graph to a single regex
|
|
68
|
-
// This is useful if you expect to match against the graph multiple times
|
|
69
|
-
// It's faster to compile the graph once and match against it multiple times
|
|
70
|
-
|
|
71
|
-
console.log ('3.');
|
|
72
|
-
|
|
73
|
-
const fullRe = graphmatch.compile ( GRAPH ); // => RegExp
|
|
74
|
-
|
|
75
|
-
console.log ( fullRe.test ( 'foo/bar/qux' ) ); // => true
|
|
76
|
-
console.log ( fullRe.test ( 'foo/bar' ) ); // => false
|
|
77
|
-
|
|
78
|
-
const partialRe = graphmatch.compile ( GRAPH, { partial: true } ); // => RegExp
|
|
79
|
-
|
|
80
|
-
console.log ( partialRe.test ( 'foo/bar/qux' ) ); // => true
|
|
81
|
-
console.log ( partialRe.test ( 'foo/bar' ) ); // => true
|