@rushstack/lookup-by-path 0.1.0
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/CHANGELOG.json +17 -0
- package/CHANGELOG.md +11 -0
- package/LICENSE +24 -0
- package/README.md +14 -0
- package/dist/lookup-by-path.d.ts +137 -0
- package/dist/tsdoc-metadata.json +11 -0
- package/lib/LookupByPath.d.ts +129 -0
- package/lib/LookupByPath.d.ts.map +1 -0
- package/lib/LookupByPath.js +219 -0
- package/lib/LookupByPath.js.map +1 -0
- package/lib/LookupByPath.test.d.ts +2 -0
- package/lib/LookupByPath.test.d.ts.map +1 -0
- package/lib/LookupByPath.test.js.map +1 -0
- package/lib/index.d.ts +8 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +8 -0
- package/lib/index.js.map +1 -0
- package/package.json +37 -0
package/CHANGELOG.json
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@rushstack/lookup-by-path",
|
|
3
|
+
"entries": [
|
|
4
|
+
{
|
|
5
|
+
"version": "0.1.0",
|
|
6
|
+
"tag": "@rushstack/lookup-by-path_v0.1.0",
|
|
7
|
+
"date": "Thu, 08 Aug 2024 22:08:25 GMT",
|
|
8
|
+
"comments": {
|
|
9
|
+
"minor": [
|
|
10
|
+
{
|
|
11
|
+
"comment": "Extract LookupByPath from @rushstack/rush-lib."
|
|
12
|
+
}
|
|
13
|
+
]
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
]
|
|
17
|
+
}
|
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# Change Log - @rushstack/lookup-by-path
|
|
2
|
+
|
|
3
|
+
This log was last generated on Thu, 08 Aug 2024 22:08:25 GMT and should not be manually modified.
|
|
4
|
+
|
|
5
|
+
## 0.1.0
|
|
6
|
+
Thu, 08 Aug 2024 22:08:25 GMT
|
|
7
|
+
|
|
8
|
+
### Minor changes
|
|
9
|
+
|
|
10
|
+
- Extract LookupByPath from @rushstack/rush-lib.
|
|
11
|
+
|
package/LICENSE
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
@rushstack/lookup-by-path
|
|
2
|
+
|
|
3
|
+
Copyright (c) Microsoft Corporation. All rights reserved.
|
|
4
|
+
|
|
5
|
+
MIT License
|
|
6
|
+
|
|
7
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
|
8
|
+
a copy of this software and associated documentation files (the
|
|
9
|
+
"Software"), to deal in the Software without restriction, including
|
|
10
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
|
11
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
|
12
|
+
permit persons to whom the Software is furnished to do so, subject to
|
|
13
|
+
the following conditions:
|
|
14
|
+
|
|
15
|
+
The above copyright notice and this permission notice shall be
|
|
16
|
+
included in all copies or substantial portions of the Software.
|
|
17
|
+
|
|
18
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
19
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
20
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
21
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
22
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
23
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
24
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# @rushstack/lookup-by-path
|
|
2
|
+
|
|
3
|
+
This library contains a strongly-typed implementation of of a [Trie](https://en.wikipedia.org/wiki/Trie) (a.k.a. prefix tree) data structure optimized for file paths and URLs.
|
|
4
|
+
|
|
5
|
+
This package is used by Rush to associate Git hashes with their nearest ancestor Rush project, for example.
|
|
6
|
+
|
|
7
|
+
## Links
|
|
8
|
+
|
|
9
|
+
- [CHANGELOG.md](
|
|
10
|
+
https://github.com/microsoft/rushstack/blob/main/libraries/lookup-by-path/CHANGELOG.md) - Find
|
|
11
|
+
out what's new in the latest version
|
|
12
|
+
- [API Reference](https://api.rushstack.io/pages/lookup-by-path/)
|
|
13
|
+
|
|
14
|
+
`@rushstack/lookup-by-path` is part of the [Rush Stack](https://rushstack.io/) family of projects.
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Strongly typed trie data structure for path and URL-like strings.
|
|
3
|
+
*
|
|
4
|
+
* @packageDocumentation
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Object containing both the matched item and the start index of the remainder of the query.
|
|
9
|
+
*
|
|
10
|
+
* @beta
|
|
11
|
+
*/
|
|
12
|
+
export declare interface IPrefixMatch<TItem> {
|
|
13
|
+
/**
|
|
14
|
+
* The item that matched the prefix
|
|
15
|
+
*/
|
|
16
|
+
value: TItem;
|
|
17
|
+
/**
|
|
18
|
+
* The index of the first character after the matched prefix
|
|
19
|
+
*/
|
|
20
|
+
index: number;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* This class is used to associate path-like-strings, such as those returned by `git` commands,
|
|
25
|
+
* with entities that correspond with ancestor folders, such as Rush Projects or npm packages.
|
|
26
|
+
*
|
|
27
|
+
* It is optimized for efficiently locating the nearest ancestor path with an associated value.
|
|
28
|
+
*
|
|
29
|
+
* It is implemented as a Trie (https://en.wikipedia.org/wiki/Trie) data structure, with each edge
|
|
30
|
+
* being a path segment.
|
|
31
|
+
*
|
|
32
|
+
* @example
|
|
33
|
+
* ```ts
|
|
34
|
+
* const trie = new LookupByPath([['foo', 1], ['bar', 2], ['foo/bar', 3]]);
|
|
35
|
+
* trie.findChildPath('foo'); // returns 1
|
|
36
|
+
* trie.findChildPath('foo/baz'); // returns 1
|
|
37
|
+
* trie.findChildPath('baz'); // returns undefined
|
|
38
|
+
* trie.findChildPath('foo/bar/baz'); returns 3
|
|
39
|
+
* trie.findChildPath('bar/foo/bar'); returns 2
|
|
40
|
+
* ```
|
|
41
|
+
* @beta
|
|
42
|
+
*/
|
|
43
|
+
export declare class LookupByPath<TItem> {
|
|
44
|
+
/**
|
|
45
|
+
* The delimiter used to split paths
|
|
46
|
+
*/
|
|
47
|
+
readonly delimiter: string;
|
|
48
|
+
/**
|
|
49
|
+
* The root node of the trie, corresponding to the path ''
|
|
50
|
+
*/
|
|
51
|
+
private readonly _root;
|
|
52
|
+
/**
|
|
53
|
+
* Constructs a new `LookupByPath`
|
|
54
|
+
*
|
|
55
|
+
* @param entries - Initial path-value pairs to populate the trie.
|
|
56
|
+
*/
|
|
57
|
+
constructor(entries?: Iterable<[string, TItem]>, delimiter?: string);
|
|
58
|
+
/**
|
|
59
|
+
* Iterates over the segments of a serialized path.
|
|
60
|
+
*
|
|
61
|
+
* @example
|
|
62
|
+
*
|
|
63
|
+
* `LookupByPath.iteratePathSegments('foo/bar/baz')` yields 'foo', 'bar', 'baz'
|
|
64
|
+
*
|
|
65
|
+
* `LookupByPath.iteratePathSegments('foo\\bar\\baz', '\\')` yields 'foo', 'bar', 'baz'
|
|
66
|
+
*/
|
|
67
|
+
static iteratePathSegments(serializedPath: string, delimiter?: string): Iterable<string>;
|
|
68
|
+
private static _iteratePrefixes;
|
|
69
|
+
/**
|
|
70
|
+
* Associates the value with the specified serialized path.
|
|
71
|
+
* If a value is already associated, will overwrite.
|
|
72
|
+
*
|
|
73
|
+
* @returns this, for chained calls
|
|
74
|
+
*/
|
|
75
|
+
setItem(serializedPath: string, value: TItem): this;
|
|
76
|
+
/**
|
|
77
|
+
* Associates the value with the specified path.
|
|
78
|
+
* If a value is already associated, will overwrite.
|
|
79
|
+
*
|
|
80
|
+
* @returns this, for chained calls
|
|
81
|
+
*/
|
|
82
|
+
setItemFromSegments(pathSegments: Iterable<string>, value: TItem): this;
|
|
83
|
+
/**
|
|
84
|
+
* Searches for the item associated with `childPath`, or the nearest ancestor of that path that
|
|
85
|
+
* has an associated item.
|
|
86
|
+
*
|
|
87
|
+
* @returns the found item, or `undefined` if no item was found
|
|
88
|
+
*
|
|
89
|
+
* @example
|
|
90
|
+
* ```ts
|
|
91
|
+
* const trie = new LookupByPath([['foo', 1], ['foo/bar', 2]]);
|
|
92
|
+
* trie.findChildPath('foo/baz'); // returns 1
|
|
93
|
+
* trie.findChildPath('foo/bar/baz'); // returns 2
|
|
94
|
+
* ```
|
|
95
|
+
*/
|
|
96
|
+
findChildPath(childPath: string): TItem | undefined;
|
|
97
|
+
/**
|
|
98
|
+
* Searches for the item for which the recorded prefix is the longest matching prefix of `query`.
|
|
99
|
+
* Obtains both the item and the length of the matched prefix, so that the remainder of the path can be
|
|
100
|
+
* extracted.
|
|
101
|
+
*
|
|
102
|
+
* @returns the found item and the length of the matched prefix, or `undefined` if no item was found
|
|
103
|
+
*
|
|
104
|
+
* @example
|
|
105
|
+
* ```ts
|
|
106
|
+
* const trie = new LookupByPath([['foo', 1], ['foo/bar', 2]]);
|
|
107
|
+
* trie.findLongestPrefixMatch('foo/baz'); // returns { item: 1, index: 3 }
|
|
108
|
+
* trie.findLongestPrefixMatch('foo/bar/baz'); // returns { item: 2, index: 7 }
|
|
109
|
+
* ```
|
|
110
|
+
*/
|
|
111
|
+
findLongestPrefixMatch(query: string): IPrefixMatch<TItem> | undefined;
|
|
112
|
+
/**
|
|
113
|
+
* Searches for the item associated with `childPathSegments`, or the nearest ancestor of that path that
|
|
114
|
+
* has an associated item.
|
|
115
|
+
*
|
|
116
|
+
* @returns the found item, or `undefined` if no item was found
|
|
117
|
+
*
|
|
118
|
+
* @example
|
|
119
|
+
* ```ts
|
|
120
|
+
* const trie = new LookupByPath([['foo', 1], ['foo/bar', 2]]);
|
|
121
|
+
* trie.findChildPathFromSegments(['foo', 'baz']); // returns 1
|
|
122
|
+
* trie.findChildPathFromSegments(['foo','bar', 'baz']); // returns 2
|
|
123
|
+
* ```
|
|
124
|
+
*/
|
|
125
|
+
findChildPathFromSegments(childPathSegments: Iterable<string>): TItem | undefined;
|
|
126
|
+
/**
|
|
127
|
+
* Iterates through progressively longer prefixes of a given string and returns as soon
|
|
128
|
+
* as the number of candidate items that match the prefix are 1 or 0.
|
|
129
|
+
*
|
|
130
|
+
* If a match is present, returns the matched itme and the length of the matched prefix.
|
|
131
|
+
*
|
|
132
|
+
* @returns the found item, or `undefined` if no item was found
|
|
133
|
+
*/
|
|
134
|
+
private _findLongestPrefixMatch;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
export { }
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
// This file is read by tools that parse documentation comments conforming to the TSDoc standard.
|
|
2
|
+
// It should be published with your NPM package. It should not be tracked by Git.
|
|
3
|
+
{
|
|
4
|
+
"tsdocVersion": "0.12",
|
|
5
|
+
"toolPackages": [
|
|
6
|
+
{
|
|
7
|
+
"packageName": "@microsoft/api-extractor",
|
|
8
|
+
"packageVersion": "7.47.5"
|
|
9
|
+
}
|
|
10
|
+
]
|
|
11
|
+
}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Object containing both the matched item and the start index of the remainder of the query.
|
|
3
|
+
*
|
|
4
|
+
* @beta
|
|
5
|
+
*/
|
|
6
|
+
export interface IPrefixMatch<TItem> {
|
|
7
|
+
/**
|
|
8
|
+
* The item that matched the prefix
|
|
9
|
+
*/
|
|
10
|
+
value: TItem;
|
|
11
|
+
/**
|
|
12
|
+
* The index of the first character after the matched prefix
|
|
13
|
+
*/
|
|
14
|
+
index: number;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* This class is used to associate path-like-strings, such as those returned by `git` commands,
|
|
18
|
+
* with entities that correspond with ancestor folders, such as Rush Projects or npm packages.
|
|
19
|
+
*
|
|
20
|
+
* It is optimized for efficiently locating the nearest ancestor path with an associated value.
|
|
21
|
+
*
|
|
22
|
+
* It is implemented as a Trie (https://en.wikipedia.org/wiki/Trie) data structure, with each edge
|
|
23
|
+
* being a path segment.
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* ```ts
|
|
27
|
+
* const trie = new LookupByPath([['foo', 1], ['bar', 2], ['foo/bar', 3]]);
|
|
28
|
+
* trie.findChildPath('foo'); // returns 1
|
|
29
|
+
* trie.findChildPath('foo/baz'); // returns 1
|
|
30
|
+
* trie.findChildPath('baz'); // returns undefined
|
|
31
|
+
* trie.findChildPath('foo/bar/baz'); returns 3
|
|
32
|
+
* trie.findChildPath('bar/foo/bar'); returns 2
|
|
33
|
+
* ```
|
|
34
|
+
* @beta
|
|
35
|
+
*/
|
|
36
|
+
export declare class LookupByPath<TItem> {
|
|
37
|
+
/**
|
|
38
|
+
* The delimiter used to split paths
|
|
39
|
+
*/
|
|
40
|
+
readonly delimiter: string;
|
|
41
|
+
/**
|
|
42
|
+
* The root node of the trie, corresponding to the path ''
|
|
43
|
+
*/
|
|
44
|
+
private readonly _root;
|
|
45
|
+
/**
|
|
46
|
+
* Constructs a new `LookupByPath`
|
|
47
|
+
*
|
|
48
|
+
* @param entries - Initial path-value pairs to populate the trie.
|
|
49
|
+
*/
|
|
50
|
+
constructor(entries?: Iterable<[string, TItem]>, delimiter?: string);
|
|
51
|
+
/**
|
|
52
|
+
* Iterates over the segments of a serialized path.
|
|
53
|
+
*
|
|
54
|
+
* @example
|
|
55
|
+
*
|
|
56
|
+
* `LookupByPath.iteratePathSegments('foo/bar/baz')` yields 'foo', 'bar', 'baz'
|
|
57
|
+
*
|
|
58
|
+
* `LookupByPath.iteratePathSegments('foo\\bar\\baz', '\\')` yields 'foo', 'bar', 'baz'
|
|
59
|
+
*/
|
|
60
|
+
static iteratePathSegments(serializedPath: string, delimiter?: string): Iterable<string>;
|
|
61
|
+
private static _iteratePrefixes;
|
|
62
|
+
/**
|
|
63
|
+
* Associates the value with the specified serialized path.
|
|
64
|
+
* If a value is already associated, will overwrite.
|
|
65
|
+
*
|
|
66
|
+
* @returns this, for chained calls
|
|
67
|
+
*/
|
|
68
|
+
setItem(serializedPath: string, value: TItem): this;
|
|
69
|
+
/**
|
|
70
|
+
* Associates the value with the specified path.
|
|
71
|
+
* If a value is already associated, will overwrite.
|
|
72
|
+
*
|
|
73
|
+
* @returns this, for chained calls
|
|
74
|
+
*/
|
|
75
|
+
setItemFromSegments(pathSegments: Iterable<string>, value: TItem): this;
|
|
76
|
+
/**
|
|
77
|
+
* Searches for the item associated with `childPath`, or the nearest ancestor of that path that
|
|
78
|
+
* has an associated item.
|
|
79
|
+
*
|
|
80
|
+
* @returns the found item, or `undefined` if no item was found
|
|
81
|
+
*
|
|
82
|
+
* @example
|
|
83
|
+
* ```ts
|
|
84
|
+
* const trie = new LookupByPath([['foo', 1], ['foo/bar', 2]]);
|
|
85
|
+
* trie.findChildPath('foo/baz'); // returns 1
|
|
86
|
+
* trie.findChildPath('foo/bar/baz'); // returns 2
|
|
87
|
+
* ```
|
|
88
|
+
*/
|
|
89
|
+
findChildPath(childPath: string): TItem | undefined;
|
|
90
|
+
/**
|
|
91
|
+
* Searches for the item for which the recorded prefix is the longest matching prefix of `query`.
|
|
92
|
+
* Obtains both the item and the length of the matched prefix, so that the remainder of the path can be
|
|
93
|
+
* extracted.
|
|
94
|
+
*
|
|
95
|
+
* @returns the found item and the length of the matched prefix, or `undefined` if no item was found
|
|
96
|
+
*
|
|
97
|
+
* @example
|
|
98
|
+
* ```ts
|
|
99
|
+
* const trie = new LookupByPath([['foo', 1], ['foo/bar', 2]]);
|
|
100
|
+
* trie.findLongestPrefixMatch('foo/baz'); // returns { item: 1, index: 3 }
|
|
101
|
+
* trie.findLongestPrefixMatch('foo/bar/baz'); // returns { item: 2, index: 7 }
|
|
102
|
+
* ```
|
|
103
|
+
*/
|
|
104
|
+
findLongestPrefixMatch(query: string): IPrefixMatch<TItem> | undefined;
|
|
105
|
+
/**
|
|
106
|
+
* Searches for the item associated with `childPathSegments`, or the nearest ancestor of that path that
|
|
107
|
+
* has an associated item.
|
|
108
|
+
*
|
|
109
|
+
* @returns the found item, or `undefined` if no item was found
|
|
110
|
+
*
|
|
111
|
+
* @example
|
|
112
|
+
* ```ts
|
|
113
|
+
* const trie = new LookupByPath([['foo', 1], ['foo/bar', 2]]);
|
|
114
|
+
* trie.findChildPathFromSegments(['foo', 'baz']); // returns 1
|
|
115
|
+
* trie.findChildPathFromSegments(['foo','bar', 'baz']); // returns 2
|
|
116
|
+
* ```
|
|
117
|
+
*/
|
|
118
|
+
findChildPathFromSegments(childPathSegments: Iterable<string>): TItem | undefined;
|
|
119
|
+
/**
|
|
120
|
+
* Iterates through progressively longer prefixes of a given string and returns as soon
|
|
121
|
+
* as the number of candidate items that match the prefix are 1 or 0.
|
|
122
|
+
*
|
|
123
|
+
* If a match is present, returns the matched itme and the length of the matched prefix.
|
|
124
|
+
*
|
|
125
|
+
* @returns the found item, or `undefined` if no item was found
|
|
126
|
+
*/
|
|
127
|
+
private _findLongestPrefixMatch;
|
|
128
|
+
}
|
|
129
|
+
//# sourceMappingURL=LookupByPath.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LookupByPath.d.ts","sourceRoot":"","sources":["../src/LookupByPath.ts"],"names":[],"mappings":"AA4BA;;;;GAIG;AACH,MAAM,WAAW,YAAY,CAAC,KAAK;IACjC;;OAEG;IACH,KAAK,EAAE,KAAK,CAAC;IACb;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,qBAAa,YAAY,CAAC,KAAK;IAC7B;;OAEG;IACH,SAAgB,SAAS,EAAE,MAAM,CAAC;IAClC;;OAEG;IACH,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAuB;IAE7C;;;;OAIG;gBACgB,OAAO,CAAC,EAAE,QAAQ,CAAC,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,EAAE,SAAS,CAAC,EAAE,MAAM;IAe1E;;;;;;;;OAQG;WACY,mBAAmB,CAAC,cAAc,EAAE,MAAM,EAAE,SAAS,GAAE,MAAY,GAAG,QAAQ,CAAC,MAAM,CAAC;IAMrG,OAAO,CAAC,MAAM,CAAE,gBAAgB;IA2BhC;;;;;OAKG;IACI,OAAO,CAAC,cAAc,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,GAAG,IAAI;IAI1D;;;;;OAKG;IACI,mBAAmB,CAAC,YAAY,EAAE,QAAQ,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,KAAK,GAAG,IAAI;IAuB9E;;;;;;;;;;;;OAYG;IACI,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,KAAK,GAAG,SAAS;IAI1D;;;;;;;;;;;;;OAaG;IACI,sBAAsB,CAAC,KAAK,EAAE,MAAM,GAAG,YAAY,CAAC,KAAK,CAAC,GAAG,SAAS;IAI7E;;;;;;;;;;;;OAYG;IACI,yBAAyB,CAAC,iBAAiB,EAAE,QAAQ,CAAC,MAAM,CAAC,GAAG,KAAK,GAAG,SAAS;IAqBxF;;;;;;;OAOG;IACH,OAAO,CAAC,uBAAuB;CA8BhC"}
|
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
|
|
3
|
+
// See LICENSE in the project root for license information.
|
|
4
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
5
|
+
exports.LookupByPath = void 0;
|
|
6
|
+
/**
|
|
7
|
+
* This class is used to associate path-like-strings, such as those returned by `git` commands,
|
|
8
|
+
* with entities that correspond with ancestor folders, such as Rush Projects or npm packages.
|
|
9
|
+
*
|
|
10
|
+
* It is optimized for efficiently locating the nearest ancestor path with an associated value.
|
|
11
|
+
*
|
|
12
|
+
* It is implemented as a Trie (https://en.wikipedia.org/wiki/Trie) data structure, with each edge
|
|
13
|
+
* being a path segment.
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```ts
|
|
17
|
+
* const trie = new LookupByPath([['foo', 1], ['bar', 2], ['foo/bar', 3]]);
|
|
18
|
+
* trie.findChildPath('foo'); // returns 1
|
|
19
|
+
* trie.findChildPath('foo/baz'); // returns 1
|
|
20
|
+
* trie.findChildPath('baz'); // returns undefined
|
|
21
|
+
* trie.findChildPath('foo/bar/baz'); returns 3
|
|
22
|
+
* trie.findChildPath('bar/foo/bar'); returns 2
|
|
23
|
+
* ```
|
|
24
|
+
* @beta
|
|
25
|
+
*/
|
|
26
|
+
class LookupByPath {
|
|
27
|
+
/**
|
|
28
|
+
* Constructs a new `LookupByPath`
|
|
29
|
+
*
|
|
30
|
+
* @param entries - Initial path-value pairs to populate the trie.
|
|
31
|
+
*/
|
|
32
|
+
constructor(entries, delimiter) {
|
|
33
|
+
this._root = {
|
|
34
|
+
value: undefined,
|
|
35
|
+
children: undefined
|
|
36
|
+
};
|
|
37
|
+
this.delimiter = delimiter !== null && delimiter !== void 0 ? delimiter : '/';
|
|
38
|
+
if (entries) {
|
|
39
|
+
for (const [path, item] of entries) {
|
|
40
|
+
this.setItem(path, item);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Iterates over the segments of a serialized path.
|
|
46
|
+
*
|
|
47
|
+
* @example
|
|
48
|
+
*
|
|
49
|
+
* `LookupByPath.iteratePathSegments('foo/bar/baz')` yields 'foo', 'bar', 'baz'
|
|
50
|
+
*
|
|
51
|
+
* `LookupByPath.iteratePathSegments('foo\\bar\\baz', '\\')` yields 'foo', 'bar', 'baz'
|
|
52
|
+
*/
|
|
53
|
+
static *iteratePathSegments(serializedPath, delimiter = '/') {
|
|
54
|
+
for (const prefixMatch of this._iteratePrefixes(serializedPath, delimiter)) {
|
|
55
|
+
yield prefixMatch.prefix;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
static *_iteratePrefixes(input, delimiter = '/') {
|
|
59
|
+
if (!input) {
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
let previousIndex = 0;
|
|
63
|
+
let nextIndex = input.indexOf(delimiter);
|
|
64
|
+
// Leading segments
|
|
65
|
+
while (nextIndex >= 0) {
|
|
66
|
+
yield {
|
|
67
|
+
prefix: input.slice(previousIndex, nextIndex),
|
|
68
|
+
index: nextIndex
|
|
69
|
+
};
|
|
70
|
+
previousIndex = nextIndex + 1;
|
|
71
|
+
nextIndex = input.indexOf(delimiter, previousIndex);
|
|
72
|
+
}
|
|
73
|
+
// Last segment
|
|
74
|
+
if (previousIndex < input.length) {
|
|
75
|
+
yield {
|
|
76
|
+
prefix: input.slice(previousIndex, input.length),
|
|
77
|
+
index: input.length
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Associates the value with the specified serialized path.
|
|
83
|
+
* If a value is already associated, will overwrite.
|
|
84
|
+
*
|
|
85
|
+
* @returns this, for chained calls
|
|
86
|
+
*/
|
|
87
|
+
setItem(serializedPath, value) {
|
|
88
|
+
return this.setItemFromSegments(LookupByPath.iteratePathSegments(serializedPath, this.delimiter), value);
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Associates the value with the specified path.
|
|
92
|
+
* If a value is already associated, will overwrite.
|
|
93
|
+
*
|
|
94
|
+
* @returns this, for chained calls
|
|
95
|
+
*/
|
|
96
|
+
setItemFromSegments(pathSegments, value) {
|
|
97
|
+
let node = this._root;
|
|
98
|
+
for (const segment of pathSegments) {
|
|
99
|
+
if (!node.children) {
|
|
100
|
+
node.children = new Map();
|
|
101
|
+
}
|
|
102
|
+
let child = node.children.get(segment);
|
|
103
|
+
if (!child) {
|
|
104
|
+
node.children.set(segment, (child = {
|
|
105
|
+
value: undefined,
|
|
106
|
+
children: undefined
|
|
107
|
+
}));
|
|
108
|
+
}
|
|
109
|
+
node = child;
|
|
110
|
+
}
|
|
111
|
+
node.value = value;
|
|
112
|
+
return this;
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Searches for the item associated with `childPath`, or the nearest ancestor of that path that
|
|
116
|
+
* has an associated item.
|
|
117
|
+
*
|
|
118
|
+
* @returns the found item, or `undefined` if no item was found
|
|
119
|
+
*
|
|
120
|
+
* @example
|
|
121
|
+
* ```ts
|
|
122
|
+
* const trie = new LookupByPath([['foo', 1], ['foo/bar', 2]]);
|
|
123
|
+
* trie.findChildPath('foo/baz'); // returns 1
|
|
124
|
+
* trie.findChildPath('foo/bar/baz'); // returns 2
|
|
125
|
+
* ```
|
|
126
|
+
*/
|
|
127
|
+
findChildPath(childPath) {
|
|
128
|
+
return this.findChildPathFromSegments(LookupByPath.iteratePathSegments(childPath, this.delimiter));
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Searches for the item for which the recorded prefix is the longest matching prefix of `query`.
|
|
132
|
+
* Obtains both the item and the length of the matched prefix, so that the remainder of the path can be
|
|
133
|
+
* extracted.
|
|
134
|
+
*
|
|
135
|
+
* @returns the found item and the length of the matched prefix, or `undefined` if no item was found
|
|
136
|
+
*
|
|
137
|
+
* @example
|
|
138
|
+
* ```ts
|
|
139
|
+
* const trie = new LookupByPath([['foo', 1], ['foo/bar', 2]]);
|
|
140
|
+
* trie.findLongestPrefixMatch('foo/baz'); // returns { item: 1, index: 3 }
|
|
141
|
+
* trie.findLongestPrefixMatch('foo/bar/baz'); // returns { item: 2, index: 7 }
|
|
142
|
+
* ```
|
|
143
|
+
*/
|
|
144
|
+
findLongestPrefixMatch(query) {
|
|
145
|
+
return this._findLongestPrefixMatch(LookupByPath._iteratePrefixes(query, this.delimiter));
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Searches for the item associated with `childPathSegments`, or the nearest ancestor of that path that
|
|
149
|
+
* has an associated item.
|
|
150
|
+
*
|
|
151
|
+
* @returns the found item, or `undefined` if no item was found
|
|
152
|
+
*
|
|
153
|
+
* @example
|
|
154
|
+
* ```ts
|
|
155
|
+
* const trie = new LookupByPath([['foo', 1], ['foo/bar', 2]]);
|
|
156
|
+
* trie.findChildPathFromSegments(['foo', 'baz']); // returns 1
|
|
157
|
+
* trie.findChildPathFromSegments(['foo','bar', 'baz']); // returns 2
|
|
158
|
+
* ```
|
|
159
|
+
*/
|
|
160
|
+
findChildPathFromSegments(childPathSegments) {
|
|
161
|
+
var _a;
|
|
162
|
+
let node = this._root;
|
|
163
|
+
let best = node.value;
|
|
164
|
+
// Trivial cases
|
|
165
|
+
if (node.children) {
|
|
166
|
+
for (const segment of childPathSegments) {
|
|
167
|
+
const child = node.children.get(segment);
|
|
168
|
+
if (!child) {
|
|
169
|
+
break;
|
|
170
|
+
}
|
|
171
|
+
node = child;
|
|
172
|
+
best = (_a = node.value) !== null && _a !== void 0 ? _a : best;
|
|
173
|
+
if (!node.children) {
|
|
174
|
+
break;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
return best;
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Iterates through progressively longer prefixes of a given string and returns as soon
|
|
182
|
+
* as the number of candidate items that match the prefix are 1 or 0.
|
|
183
|
+
*
|
|
184
|
+
* If a match is present, returns the matched itme and the length of the matched prefix.
|
|
185
|
+
*
|
|
186
|
+
* @returns the found item, or `undefined` if no item was found
|
|
187
|
+
*/
|
|
188
|
+
_findLongestPrefixMatch(prefixes) {
|
|
189
|
+
let node = this._root;
|
|
190
|
+
let best = node.value
|
|
191
|
+
? {
|
|
192
|
+
value: node.value,
|
|
193
|
+
index: 0
|
|
194
|
+
}
|
|
195
|
+
: undefined;
|
|
196
|
+
// Trivial cases
|
|
197
|
+
if (node.children) {
|
|
198
|
+
for (const { prefix: hash, index } of prefixes) {
|
|
199
|
+
const child = node.children.get(hash);
|
|
200
|
+
if (!child) {
|
|
201
|
+
break;
|
|
202
|
+
}
|
|
203
|
+
node = child;
|
|
204
|
+
if (node.value !== undefined) {
|
|
205
|
+
best = {
|
|
206
|
+
value: node.value,
|
|
207
|
+
index
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
if (!node.children) {
|
|
211
|
+
break;
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
return best;
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
exports.LookupByPath = LookupByPath;
|
|
219
|
+
//# sourceMappingURL=LookupByPath.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LookupByPath.js","sourceRoot":"","sources":["../src/LookupByPath.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.\n// See LICENSE in the project root for license information.\n\n/**\n * A node in the path trie used in LookupByPath\n */\ninterface IPathTrieNode<TItem> {\n /**\n * The value that exactly matches the current relative path\n */\n value: TItem | undefined;\n /**\n * Child nodes by subfolder\n */\n children: Map<string, IPathTrieNode<TItem>> | undefined;\n}\n\ninterface IPrefixEntry {\n /**\n * The prefix that was matched\n */\n prefix: string;\n /**\n * The index of the first character after the matched prefix\n */\n index: number;\n}\n\n/**\n * Object containing both the matched item and the start index of the remainder of the query.\n *\n * @beta\n */\nexport interface IPrefixMatch<TItem> {\n /**\n * The item that matched the prefix\n */\n value: TItem;\n /**\n * The index of the first character after the matched prefix\n */\n index: number;\n}\n\n/**\n * This class is used to associate path-like-strings, such as those returned by `git` commands,\n * with entities that correspond with ancestor folders, such as Rush Projects or npm packages.\n *\n * It is optimized for efficiently locating the nearest ancestor path with an associated value.\n *\n * It is implemented as a Trie (https://en.wikipedia.org/wiki/Trie) data structure, with each edge\n * being a path segment.\n *\n * @example\n * ```ts\n * const trie = new LookupByPath([['foo', 1], ['bar', 2], ['foo/bar', 3]]);\n * trie.findChildPath('foo'); // returns 1\n * trie.findChildPath('foo/baz'); // returns 1\n * trie.findChildPath('baz'); // returns undefined\n * trie.findChildPath('foo/bar/baz'); returns 3\n * trie.findChildPath('bar/foo/bar'); returns 2\n * ```\n * @beta\n */\nexport class LookupByPath<TItem> {\n /**\n * The delimiter used to split paths\n */\n public readonly delimiter: string;\n /**\n * The root node of the trie, corresponding to the path ''\n */\n private readonly _root: IPathTrieNode<TItem>;\n\n /**\n * Constructs a new `LookupByPath`\n *\n * @param entries - Initial path-value pairs to populate the trie.\n */\n public constructor(entries?: Iterable<[string, TItem]>, delimiter?: string) {\n this._root = {\n value: undefined,\n children: undefined\n };\n\n this.delimiter = delimiter ?? '/';\n\n if (entries) {\n for (const [path, item] of entries) {\n this.setItem(path, item);\n }\n }\n }\n\n /**\n * Iterates over the segments of a serialized path.\n *\n * @example\n *\n * `LookupByPath.iteratePathSegments('foo/bar/baz')` yields 'foo', 'bar', 'baz'\n *\n * `LookupByPath.iteratePathSegments('foo\\\\bar\\\\baz', '\\\\')` yields 'foo', 'bar', 'baz'\n */\n public static *iteratePathSegments(serializedPath: string, delimiter: string = '/'): Iterable<string> {\n for (const prefixMatch of this._iteratePrefixes(serializedPath, delimiter)) {\n yield prefixMatch.prefix;\n }\n }\n\n private static *_iteratePrefixes(input: string, delimiter: string = '/'): Iterable<IPrefixEntry> {\n if (!input) {\n return;\n }\n\n let previousIndex: number = 0;\n let nextIndex: number = input.indexOf(delimiter);\n\n // Leading segments\n while (nextIndex >= 0) {\n yield {\n prefix: input.slice(previousIndex, nextIndex),\n index: nextIndex\n };\n previousIndex = nextIndex + 1;\n nextIndex = input.indexOf(delimiter, previousIndex);\n }\n\n // Last segment\n if (previousIndex < input.length) {\n yield {\n prefix: input.slice(previousIndex, input.length),\n index: input.length\n };\n }\n }\n\n /**\n * Associates the value with the specified serialized path.\n * If a value is already associated, will overwrite.\n *\n * @returns this, for chained calls\n */\n public setItem(serializedPath: string, value: TItem): this {\n return this.setItemFromSegments(LookupByPath.iteratePathSegments(serializedPath, this.delimiter), value);\n }\n\n /**\n * Associates the value with the specified path.\n * If a value is already associated, will overwrite.\n *\n * @returns this, for chained calls\n */\n public setItemFromSegments(pathSegments: Iterable<string>, value: TItem): this {\n let node: IPathTrieNode<TItem> = this._root;\n for (const segment of pathSegments) {\n if (!node.children) {\n node.children = new Map();\n }\n let child: IPathTrieNode<TItem> | undefined = node.children.get(segment);\n if (!child) {\n node.children.set(\n segment,\n (child = {\n value: undefined,\n children: undefined\n })\n );\n }\n node = child;\n }\n node.value = value;\n\n return this;\n }\n\n /**\n * Searches for the item associated with `childPath`, or the nearest ancestor of that path that\n * has an associated item.\n *\n * @returns the found item, or `undefined` if no item was found\n *\n * @example\n * ```ts\n * const trie = new LookupByPath([['foo', 1], ['foo/bar', 2]]);\n * trie.findChildPath('foo/baz'); // returns 1\n * trie.findChildPath('foo/bar/baz'); // returns 2\n * ```\n */\n public findChildPath(childPath: string): TItem | undefined {\n return this.findChildPathFromSegments(LookupByPath.iteratePathSegments(childPath, this.delimiter));\n }\n\n /**\n * Searches for the item for which the recorded prefix is the longest matching prefix of `query`.\n * Obtains both the item and the length of the matched prefix, so that the remainder of the path can be\n * extracted.\n *\n * @returns the found item and the length of the matched prefix, or `undefined` if no item was found\n *\n * @example\n * ```ts\n * const trie = new LookupByPath([['foo', 1], ['foo/bar', 2]]);\n * trie.findLongestPrefixMatch('foo/baz'); // returns { item: 1, index: 3 }\n * trie.findLongestPrefixMatch('foo/bar/baz'); // returns { item: 2, index: 7 }\n * ```\n */\n public findLongestPrefixMatch(query: string): IPrefixMatch<TItem> | undefined {\n return this._findLongestPrefixMatch(LookupByPath._iteratePrefixes(query, this.delimiter));\n }\n\n /**\n * Searches for the item associated with `childPathSegments`, or the nearest ancestor of that path that\n * has an associated item.\n *\n * @returns the found item, or `undefined` if no item was found\n *\n * @example\n * ```ts\n * const trie = new LookupByPath([['foo', 1], ['foo/bar', 2]]);\n * trie.findChildPathFromSegments(['foo', 'baz']); // returns 1\n * trie.findChildPathFromSegments(['foo','bar', 'baz']); // returns 2\n * ```\n */\n public findChildPathFromSegments(childPathSegments: Iterable<string>): TItem | undefined {\n let node: IPathTrieNode<TItem> = this._root;\n let best: TItem | undefined = node.value;\n // Trivial cases\n if (node.children) {\n for (const segment of childPathSegments) {\n const child: IPathTrieNode<TItem> | undefined = node.children.get(segment);\n if (!child) {\n break;\n }\n node = child;\n best = node.value ?? best;\n if (!node.children) {\n break;\n }\n }\n }\n\n return best;\n }\n\n /**\n * Iterates through progressively longer prefixes of a given string and returns as soon\n * as the number of candidate items that match the prefix are 1 or 0.\n *\n * If a match is present, returns the matched itme and the length of the matched prefix.\n *\n * @returns the found item, or `undefined` if no item was found\n */\n private _findLongestPrefixMatch(prefixes: Iterable<IPrefixEntry>): IPrefixMatch<TItem> | undefined {\n let node: IPathTrieNode<TItem> = this._root;\n let best: IPrefixMatch<TItem> | undefined = node.value\n ? {\n value: node.value,\n index: 0\n }\n : undefined;\n // Trivial cases\n if (node.children) {\n for (const { prefix: hash, index } of prefixes) {\n const child: IPathTrieNode<TItem> | undefined = node.children.get(hash);\n if (!child) {\n break;\n }\n node = child;\n if (node.value !== undefined) {\n best = {\n value: node.value,\n index\n };\n }\n if (!node.children) {\n break;\n }\n }\n }\n\n return best;\n }\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LookupByPath.test.d.ts","sourceRoot":"","sources":["../src/LookupByPath.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LookupByPath.test.js","sourceRoot":"","sources":["../src/LookupByPath.test.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.\n// See LICENSE in the project root for license information.\n\nimport { LookupByPath } from './LookupByPath';\n\ndescribe(LookupByPath.iteratePathSegments.name, () => {\n it('returns empty for an empty string', () => {\n const result = [...LookupByPath.iteratePathSegments('')];\n expect(result.length).toEqual(0);\n });\n it('returns the only segment of a trival string', () => {\n const result = [...LookupByPath.iteratePathSegments('foo')];\n expect(result).toEqual(['foo']);\n });\n it('treats backslashes as ordinary characters, per POSIX', () => {\n const result = [...LookupByPath.iteratePathSegments('foo\\\\bar\\\\baz')];\n expect(result).toEqual(['foo\\\\bar\\\\baz']);\n });\n it('iterates segments', () => {\n const result = [...LookupByPath.iteratePathSegments('foo/bar/baz')];\n expect(result).toEqual(['foo', 'bar', 'baz']);\n });\n it('returns correct last single character segment', () => {\n const result = [...LookupByPath.iteratePathSegments('foo/a')];\n expect(result).toEqual(['foo', 'a']);\n });\n});\n\ndescribe(LookupByPath.prototype.findChildPath.name, () => {\n it('returns empty for an empty tree', () => {\n expect(new LookupByPath().findChildPath('foo')).toEqual(undefined);\n });\n it('returns the matching node for a trivial tree', () => {\n expect(new LookupByPath([['foo', 1]]).findChildPath('foo')).toEqual(1);\n });\n it('returns the matching node for a single-layer tree', () => {\n const tree: LookupByPath<number> = new LookupByPath([\n ['foo', 1],\n ['bar', 2],\n ['baz', 3]\n ]);\n\n expect(tree.findChildPath('foo')).toEqual(1);\n expect(tree.findChildPath('bar')).toEqual(2);\n expect(tree.findChildPath('baz')).toEqual(3);\n expect(tree.findChildPath('buzz')).toEqual(undefined);\n });\n it('returns the matching parent for multi-layer queries', () => {\n const tree: LookupByPath<number> = new LookupByPath([\n ['foo', 1],\n ['bar', 2],\n ['baz', 3]\n ]);\n\n expect(tree.findChildPath('foo/bar')).toEqual(1);\n expect(tree.findChildPath('bar/baz')).toEqual(2);\n expect(tree.findChildPath('baz/foo')).toEqual(3);\n expect(tree.findChildPath('foo/foo')).toEqual(1);\n });\n it('returns the matching parent for multi-layer queries in multi-layer trees', () => {\n const tree: LookupByPath<number> = new LookupByPath([\n ['foo', 1],\n ['bar', 2],\n ['baz', 3],\n ['foo/bar', 4],\n ['foo/bar/baz', 5],\n ['baz/foo', 6],\n ['baz/baz/baz/baz', 7]\n ]);\n\n expect(tree.findChildPath('foo/foo')).toEqual(1);\n expect(tree.findChildPath('foo/bar\\\\baz')).toEqual(1);\n\n expect(tree.findChildPath('bar/baz')).toEqual(2);\n\n expect(tree.findChildPath('baz/bar')).toEqual(3);\n expect(tree.findChildPath('baz/baz')).toEqual(3);\n expect(tree.findChildPath('baz/baz/baz')).toEqual(3);\n\n expect(tree.findChildPath('foo/bar')).toEqual(4);\n expect(tree.findChildPath('foo/bar/foo')).toEqual(4);\n\n expect(tree.findChildPath('foo/bar/baz')).toEqual(5);\n expect(tree.findChildPath('foo/bar/baz/baz/baz/baz/baz')).toEqual(5);\n\n expect(tree.findChildPath('baz/foo/')).toEqual(6);\n\n expect(tree.findChildPath('baz/baz/baz/baz')).toEqual(7);\n\n expect(tree.findChildPath('')).toEqual(undefined);\n expect(tree.findChildPath('foofoo')).toEqual(undefined);\n expect(tree.findChildPath('foo\\\\bar\\\\baz')).toEqual(undefined);\n });\n it('handles custom delimiters', () => {\n const tree: LookupByPath<number> = new LookupByPath(\n [\n ['foo,bar', 1],\n ['foo/bar', 2]\n ],\n ','\n );\n\n expect(tree.findChildPath('foo/bar,baz')).toEqual(2);\n expect(tree.findChildPath('foo,bar/baz')).toEqual(undefined);\n expect(tree.findChildPathFromSegments(['foo', 'bar', 'baz'])).toEqual(1);\n });\n});\n\ndescribe(LookupByPath.prototype.findLongestPrefixMatch.name, () => {\n it('returns empty for an empty tree', () => {\n expect(new LookupByPath().findLongestPrefixMatch('foo')).toEqual(undefined);\n });\n it('returns the matching node for a trivial tree', () => {\n expect(new LookupByPath([['foo', 1]]).findLongestPrefixMatch('foo')).toEqual({ value: 1, index: 3 });\n });\n it('returns the matching node for a single-layer tree', () => {\n const tree: LookupByPath<number> = new LookupByPath([\n ['foo', 1],\n ['barbar', 2],\n ['baz', 3]\n ]);\n\n expect(tree.findLongestPrefixMatch('foo')).toEqual({ value: 1, index: 3 });\n expect(tree.findLongestPrefixMatch('barbar')).toEqual({ value: 2, index: 6 });\n expect(tree.findLongestPrefixMatch('baz')).toEqual({ value: 3, index: 3 });\n expect(tree.findLongestPrefixMatch('buzz')).toEqual(undefined);\n });\n it('returns the matching parent for multi-layer queries', () => {\n const tree: LookupByPath<number> = new LookupByPath([\n ['foo', 1],\n ['barbar', 2],\n ['baz', 3],\n ['foo/bar', 4]\n ]);\n\n expect(tree.findLongestPrefixMatch('foo/bar')).toEqual({ value: 4, index: 7 });\n expect(tree.findLongestPrefixMatch('barbar/baz')).toEqual({ value: 2, index: 6 });\n expect(tree.findLongestPrefixMatch('baz/foo')).toEqual({ value: 3, index: 3 });\n expect(tree.findLongestPrefixMatch('foo/foo')).toEqual({ value: 1, index: 3 });\n });\n});\n"]}
|
package/lib/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA;;;;GAIG;AAEH,YAAY,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC"}
|
package/lib/index.js
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
|
|
3
|
+
// See LICENSE in the project root for license information.
|
|
4
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
5
|
+
exports.LookupByPath = void 0;
|
|
6
|
+
var LookupByPath_1 = require("./LookupByPath");
|
|
7
|
+
Object.defineProperty(exports, "LookupByPath", { enumerable: true, get: function () { return LookupByPath_1.LookupByPath; } });
|
|
8
|
+
//# sourceMappingURL=index.js.map
|
package/lib/index.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA,4FAA4F;AAC5F,2DAA2D;;;AAS3D,+CAA8C;AAArC,4GAAA,YAAY,OAAA","sourcesContent":["// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.\n// See LICENSE in the project root for license information.\n\n/**\n * Strongly typed trie data structure for path and URL-like strings.\n *\n * @packageDocumentation\n */\n\nexport type { IPrefixMatch } from './LookupByPath';\nexport { LookupByPath } from './LookupByPath';\n"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@rushstack/lookup-by-path",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Strongly typed trie data structure for path and URL-like strings.",
|
|
5
|
+
"main": "lib/index.js",
|
|
6
|
+
"typings": "dist/lookup-by-path.d.ts",
|
|
7
|
+
"keywords": [
|
|
8
|
+
"trie",
|
|
9
|
+
"path",
|
|
10
|
+
"url",
|
|
11
|
+
"radix tree",
|
|
12
|
+
"prefix tree"
|
|
13
|
+
],
|
|
14
|
+
"license": "MIT",
|
|
15
|
+
"repository": {
|
|
16
|
+
"url": "https://github.com/microsoft/rushstack.git",
|
|
17
|
+
"type": "git",
|
|
18
|
+
"directory": "libraries/lookup-by-path"
|
|
19
|
+
},
|
|
20
|
+
"devDependencies": {
|
|
21
|
+
"@rushstack/heft": "0.66.25",
|
|
22
|
+
"local-node-rig": "1.0.0"
|
|
23
|
+
},
|
|
24
|
+
"peerDependencies": {
|
|
25
|
+
"@types/node": "*"
|
|
26
|
+
},
|
|
27
|
+
"peerDependenciesMeta": {
|
|
28
|
+
"@types/node": {
|
|
29
|
+
"optional": true
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
"scripts": {
|
|
33
|
+
"build": "heft build --clean",
|
|
34
|
+
"_phase:build": "heft run --only build -- --clean",
|
|
35
|
+
"_phase:test": "heft run --only test -- --clean"
|
|
36
|
+
}
|
|
37
|
+
}
|