trueicon 0.3.0 → 0.3.1
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/search/search.d.ts +12 -3
- package/dist/search/search.js +34 -14
- package/dist/search/search.js.map +1 -1
- package/package.json +1 -1
package/dist/search/search.d.ts
CHANGED
|
@@ -15,7 +15,11 @@ export interface SearchOptions {
|
|
|
15
15
|
}
|
|
16
16
|
export interface SearchResult {
|
|
17
17
|
record: IconRecord;
|
|
18
|
-
/**
|
|
18
|
+
/**
|
|
19
|
+
* Best per-token Fuse.js score: 0 is a perfect match, 1 is no match. For
|
|
20
|
+
* multi-word queries this is the score of the closest-matching token; see
|
|
21
|
+
* {@link searchIcons} for how coverage across tokens breaks ties.
|
|
22
|
+
*/
|
|
19
23
|
score: number;
|
|
20
24
|
}
|
|
21
25
|
/** Reads index.json and meta.json from an index directory written by writeIndex. */
|
|
@@ -24,7 +28,12 @@ export declare function loadIndex(cacheDir: string): Promise<LoadedIndex>;
|
|
|
24
28
|
export declare function indexNeedsRebuild(meta: IndexMeta, synonyms: Synonyms): boolean;
|
|
25
29
|
/**
|
|
26
30
|
* Filters records by provider/style/set exactly, then ranks them against the query with Fuse.js.
|
|
27
|
-
*
|
|
28
|
-
*
|
|
31
|
+
*
|
|
32
|
+
* Multi-word queries are searched token by token. A record is a candidate when it matches
|
|
33
|
+
* at least one token; ranking is by the best per-token score first, then by how many tokens
|
|
34
|
+
* matched, then by the mean matched score. Requiring every token to match (a hard AND) was
|
|
35
|
+
* tried and rejected: on real indexes it excludes the right icons whenever one token is a
|
|
36
|
+
* near-synonym absent from the index ("can" vs keywords trash/delete/bin), while unrelated
|
|
37
|
+
* icons slip through on loose fuzzy matches of every token ("kanban" ~= "can").
|
|
29
38
|
*/
|
|
30
39
|
export declare function searchIcons(records: readonly IconRecord[], query: string, options?: SearchOptions): SearchResult[];
|
package/dist/search/search.js
CHANGED
|
@@ -32,8 +32,13 @@ function matches(value, filter) {
|
|
|
32
32
|
}
|
|
33
33
|
/**
|
|
34
34
|
* Filters records by provider/style/set exactly, then ranks them against the query with Fuse.js.
|
|
35
|
-
*
|
|
36
|
-
*
|
|
35
|
+
*
|
|
36
|
+
* Multi-word queries are searched token by token. A record is a candidate when it matches
|
|
37
|
+
* at least one token; ranking is by the best per-token score first, then by how many tokens
|
|
38
|
+
* matched, then by the mean matched score. Requiring every token to match (a hard AND) was
|
|
39
|
+
* tried and rejected: on real indexes it excludes the right icons whenever one token is a
|
|
40
|
+
* near-synonym absent from the index ("can" vs keywords trash/delete/bin), while unrelated
|
|
41
|
+
* icons slip through on loose fuzzy matches of every token ("kanban" ~= "can").
|
|
37
42
|
*/
|
|
38
43
|
export function searchIcons(records, query, options = {}) {
|
|
39
44
|
const tokens = query.trim().split(/\s+/).filter(Boolean);
|
|
@@ -42,18 +47,33 @@ export function searchIcons(records, query, options = {}) {
|
|
|
42
47
|
const { provider, style, set, limit } = options;
|
|
43
48
|
const filtered = records.filter((r) => matches(r.provider, provider) && matches(r.style, style) && matches(r.set, set));
|
|
44
49
|
const fuse = new Fuse(filtered, FUSE_OPTIONS);
|
|
45
|
-
const
|
|
46
|
-
const
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
50
|
+
const stats = new Map();
|
|
51
|
+
for (const token of tokens) {
|
|
52
|
+
for (const result of fuse.search(token)) {
|
|
53
|
+
const score = result.score ?? 0;
|
|
54
|
+
const st = stats.get(result.item);
|
|
55
|
+
if (st) {
|
|
56
|
+
st.matched += 1;
|
|
57
|
+
st.total += score;
|
|
58
|
+
if (score < st.best)
|
|
59
|
+
st.best = score;
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
stats.set(result.item, { best: score, matched: 1, total: score });
|
|
63
|
+
}
|
|
64
|
+
}
|
|
55
65
|
}
|
|
56
|
-
|
|
57
|
-
|
|
66
|
+
// Sort is stable, so full ties keep token order: matches for earlier query
|
|
67
|
+
// tokens were inserted first and stay ahead.
|
|
68
|
+
const ranked = [...stats]
|
|
69
|
+
.map(([record, st]) => ({
|
|
70
|
+
record,
|
|
71
|
+
score: st.best,
|
|
72
|
+
matched: st.matched,
|
|
73
|
+
mean: st.total / st.matched,
|
|
74
|
+
}))
|
|
75
|
+
.sort((a, b) => a.score - b.score || b.matched - a.matched || a.mean - b.mean)
|
|
76
|
+
.map(({ record, score }) => ({ record, score }));
|
|
77
|
+
return limit === undefined ? ranked : ranked.slice(0, Math.max(0, limit));
|
|
58
78
|
}
|
|
59
79
|
//# sourceMappingURL=search.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"search.js","sourceRoot":"","sources":["../../src/search/search.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,IAA2B,MAAM,SAAS,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"search.js","sourceRoot":"","sources":["../../src/search/search.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "trueicon",
|
|
3
3
|
"mcpName": "io.github.manikumarkv/trueicon",
|
|
4
|
-
"version": "0.3.
|
|
4
|
+
"version": "0.3.1",
|
|
5
5
|
"description": "MCP server that lets AI coding assistants search the icon packages actually installed in your project.",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"author": "manikumarkv",
|