-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathapi-search.js
75 lines (69 loc) · 2.05 KB
/
api-search.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
/** This Webworker performs search on the API structure
*
* It can be used as follows:
*
* ```javascript
* var apiSearch = new Worker("<path to this file>");
* apiSearch.postMessage({
* "type": "setup",
* "search": "<search term>",
* "docs": <docs API>
* });
* ```
*
* It posts a few different messages to its parent:
*
* ```json
* {
* "type": "entityResult",
* "package": <parent package>,
* "entity": <entity>
* }
*
* {
* "type": "memberResult",
* "package": <parent package>,
* "parent": <parent entity>,
* "member": <entity>
* }
* ```
*/
onmessage = function({ data: { docs, search } }) {
const regexForTerm = (query) => {
const escaped = query.replace(/([\.\*\+\?\|\(\)\[\]\\])/g, '\\$1');
if (query.toLowerCase() != query) {
// Regexp that matches CamelCase subbits: "BiSe" is
// "[a-z]*Bi[a-z]*Se" and matches "BitSet", "ABitSet", ...
return new RegExp(escaped.replace(/([A-Z])/g,"[a-z]*$1"));
}
// if query is all lower case make a normal case insensitive search
return new RegExp(escaped, "i");
};
const searchRegex = regexForTerm(search);
const filterPackages = (entity) => !["val", "def", "type", "package"].includes(entity.kind);
const messageParentIfMatches = (parent) => (entity) => {
const fullName = entity.path.join('.');
if (searchRegex.test(fullName)) {
postMessage({
type: "entityResult",
package: parent,
entity
});
}
entity.members.forEach((member) => {
if (searchRegex.test(member.name)) {
postMessage({
type: "memberResult",
package: parent,
parent: entity,
member
});
}
});
};
docs.forEach((pack) => {
pack.members
.filter(filterPackages)
.forEach(messageParentIfMatches(pack));
});
};