@inseefr/lunatic 3.12.1 → 3.12.3
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/components/Dropdown/Dropdown.js +1 -2
- package/components/Dropdown/Dropdown.js.map +1 -1
- package/components/Dropdown/Dropdown.spec.js +13 -5
- package/components/Dropdown/Dropdown.spec.js.map +1 -1
- package/components/Suggester/CustomSuggester.d.ts +6 -0
- package/components/Suggester/CustomSuggester.js +1 -1
- package/components/Suggester/CustomSuggester.js.map +1 -1
- package/components/shared/Combobox/Combobox.js +5 -6
- package/components/shared/Combobox/Combobox.js.map +1 -1
- package/components/shared/Combobox/ComboboxType.d.ts +1 -0
- package/components/shared/Combobox/Panel/ComboboxOption.d.ts +1 -0
- package/components/shared/Combobox/Panel/ComboboxOption.js +4 -4
- package/components/shared/Combobox/Panel/ComboboxOption.js.map +1 -1
- package/components/shared/Combobox/Panel/ComboboxOption.spec.js +18 -5
- package/components/shared/Combobox/Panel/ComboboxOption.spec.js.map +1 -1
- package/components/shared/Combobox/Panel/ComboboxPanel.d.ts +1 -1
- package/components/shared/Combobox/Panel/ComboboxPanel.js +2 -2
- package/components/shared/Combobox/Panel/ComboboxPanel.js.map +1 -1
- package/components/type.d.ts +6 -0
- package/esm/components/Dropdown/Dropdown.js +1 -2
- package/esm/components/Dropdown/Dropdown.js.map +1 -1
- package/esm/components/Dropdown/Dropdown.spec.js +14 -6
- package/esm/components/Dropdown/Dropdown.spec.js.map +1 -1
- package/esm/components/Suggester/CustomSuggester.d.ts +6 -0
- package/esm/components/Suggester/CustomSuggester.js +1 -1
- package/esm/components/Suggester/CustomSuggester.js.map +1 -1
- package/esm/components/shared/Combobox/Combobox.js +5 -6
- package/esm/components/shared/Combobox/Combobox.js.map +1 -1
- package/esm/components/shared/Combobox/ComboboxType.d.ts +1 -0
- package/esm/components/shared/Combobox/Panel/ComboboxOption.d.ts +1 -0
- package/esm/components/shared/Combobox/Panel/ComboboxOption.js +5 -5
- package/esm/components/shared/Combobox/Panel/ComboboxOption.js.map +1 -1
- package/esm/components/shared/Combobox/Panel/ComboboxOption.spec.js +18 -5
- package/esm/components/shared/Combobox/Panel/ComboboxOption.spec.js.map +1 -1
- package/esm/components/shared/Combobox/Panel/ComboboxPanel.d.ts +1 -1
- package/esm/components/shared/Combobox/Panel/ComboboxPanel.js +2 -2
- package/esm/components/shared/Combobox/Panel/ComboboxPanel.js.map +1 -1
- package/esm/components/type.d.ts +6 -0
- package/esm/utils/search/SearchMiniSearch.spec.js +16 -1
- package/esm/utils/search/SearchMiniSearch.spec.js.map +1 -1
- package/esm/utils/search/SearchMinisearch.js +26 -1
- package/esm/utils/search/SearchMinisearch.js.map +1 -1
- package/esm/utils/search/tokenizer.js +1 -14
- package/esm/utils/search/tokenizer.js.map +1 -1
- package/esm/utils/search/utils.d.ts +7 -0
- package/esm/utils/search/utils.js +15 -0
- package/esm/utils/search/utils.js.map +1 -0
- package/package.json +8 -8
- package/src/components/Dropdown/Dropdown.spec.tsx +22 -6
- package/src/components/Dropdown/Dropdown.tsx +1 -2
- package/src/components/Dropdown/__snapshots__/Dropdown.spec.tsx.snap +2 -2
- package/src/components/Suggester/CustomSuggester.tsx +7 -0
- package/src/components/shared/Combobox/Combobox.tsx +5 -4
- package/src/components/shared/Combobox/ComboboxType.ts +1 -0
- package/src/components/shared/Combobox/Panel/ComboboxOption.spec.tsx +27 -5
- package/src/components/shared/Combobox/Panel/ComboboxOption.tsx +10 -6
- package/src/components/shared/Combobox/Panel/ComboboxPanel.tsx +3 -1
- package/src/components/type.ts +6 -0
- package/src/utils/search/SearchMiniSearch.spec.ts +21 -1
- package/src/utils/search/SearchMinisearch.ts +34 -1
- package/src/utils/search/tokenizer.ts +1 -15
- package/src/utils/search/utils.ts +14 -0
- package/tsconfig.build.tsbuildinfo +1 -1
- package/utils/search/SearchMiniSearch.spec.js +15 -1
- package/utils/search/SearchMiniSearch.spec.js.map +1 -1
- package/utils/search/SearchMinisearch.js +26 -1
- package/utils/search/SearchMinisearch.js.map +1 -1
- package/utils/search/tokenizer.js +6 -19
- package/utils/search/tokenizer.js.map +1 -1
- package/utils/search/utils.d.ts +7 -0
- package/utils/search/utils.js +19 -0
- package/utils/search/utils.js.map +1 -0
- package/components/Dropdown/renderer/SimpleOptionRenderer.d.ts +0 -7
- package/components/Dropdown/renderer/SimpleOptionRenderer.js +0 -16
- package/components/Dropdown/renderer/SimpleOptionRenderer.js.map +0 -1
- package/esm/components/Dropdown/renderer/SimpleOptionRenderer.d.ts +0 -7
- package/esm/components/Dropdown/renderer/SimpleOptionRenderer.js +0 -10
- package/esm/components/Dropdown/renderer/SimpleOptionRenderer.js.map +0 -1
- package/src/components/Dropdown/renderer/SimpleOptionRenderer.tsx +0 -26
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { describe, it, expect, vi, beforeAll, afterEach } from 'vitest';
|
|
2
2
|
import { SearchMinisearch } from './SearchMinisearch';
|
|
3
|
+
import { applyMelauto } from './melauto';
|
|
3
4
|
|
|
4
5
|
vi.mock('minisearch', () => {
|
|
5
6
|
return {
|
|
@@ -24,7 +25,13 @@ describe('SearchMinisearch', () => {
|
|
|
24
25
|
beforeAll(() => {
|
|
25
26
|
searchInstance = new SearchMinisearch({
|
|
26
27
|
name: 'test-suggester',
|
|
27
|
-
fields: [
|
|
28
|
+
fields: [
|
|
29
|
+
{ name: 'id' },
|
|
30
|
+
{
|
|
31
|
+
name: 'label',
|
|
32
|
+
synonyms: { accueil: ['ACCEUIL', 'ACUEIL'] },
|
|
33
|
+
},
|
|
34
|
+
],
|
|
28
35
|
queryParser: {
|
|
29
36
|
type: 'tokenized',
|
|
30
37
|
params: { language: 'English', pattern: '\\w+', min: 1 },
|
|
@@ -55,4 +62,17 @@ describe('SearchMinisearch', () => {
|
|
|
55
62
|
|
|
56
63
|
expect(searchInstance.db?.addAll).not.toHaveBeenCalled();
|
|
57
64
|
});
|
|
65
|
+
|
|
66
|
+
it('should expand query synonyms before melauto sorting', async () => {
|
|
67
|
+
await searchInstance.index(mockData);
|
|
68
|
+
(searchInstance.db?.search as any).mockReturnValue(mockData);
|
|
69
|
+
vi.mocked(applyMelauto).mockReturnValue(mockData as any);
|
|
70
|
+
|
|
71
|
+
await searchInstance.search('agent acceuil');
|
|
72
|
+
|
|
73
|
+
expect(applyMelauto).toHaveBeenCalledWith(
|
|
74
|
+
'agent acceuil accueil',
|
|
75
|
+
mockData
|
|
76
|
+
);
|
|
77
|
+
});
|
|
58
78
|
});
|
|
@@ -6,6 +6,39 @@ import type {
|
|
|
6
6
|
import { applyMelauto } from './melauto';
|
|
7
7
|
import MiniSearch from 'minisearch';
|
|
8
8
|
import { tokenizer } from './tokenizer';
|
|
9
|
+
import { normalizeStr } from './utils';
|
|
10
|
+
|
|
11
|
+
function getMelautoQuery(query: string, info: SearchInfo) {
|
|
12
|
+
const tokens = tokenizer(info)(query);
|
|
13
|
+
|
|
14
|
+
// existing query tokens (already tokenized/normalized by tokenizer).
|
|
15
|
+
const expandedTokens = new Set(tokens);
|
|
16
|
+
|
|
17
|
+
// add synonyms to keep melauto ranking.
|
|
18
|
+
for (const field of info.fields) {
|
|
19
|
+
if (!field.synonyms) {
|
|
20
|
+
continue;
|
|
21
|
+
}
|
|
22
|
+
for (const source in field.synonyms) {
|
|
23
|
+
const normalizedSource = normalizeStr(source);
|
|
24
|
+
const normalizedSynonyms = field.synonyms[source].map((synonym) =>
|
|
25
|
+
normalizeStr(synonym)
|
|
26
|
+
);
|
|
27
|
+
|
|
28
|
+
// source -> synonyms
|
|
29
|
+
if (expandedTokens.has(normalizedSource)) {
|
|
30
|
+
normalizedSynonyms.forEach((synonym) => expandedTokens.add(synonym));
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// synonym -> source
|
|
34
|
+
if (normalizedSynonyms.some((synonym) => expandedTokens.has(synonym))) {
|
|
35
|
+
expandedTokens.add(normalizedSource);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return Array.from(expandedTokens).join(' ');
|
|
41
|
+
}
|
|
9
42
|
|
|
10
43
|
export class SearchMinisearch<T extends IndexEntry>
|
|
11
44
|
implements SearchInterface<T>
|
|
@@ -45,7 +78,7 @@ export class SearchMinisearch<T extends IndexEntry>
|
|
|
45
78
|
}) as any as T[];
|
|
46
79
|
|
|
47
80
|
// Apply melauto to classify results
|
|
48
|
-
data = applyMelauto(q, data);
|
|
81
|
+
data = applyMelauto(getMelautoQuery(q, this.info), data);
|
|
49
82
|
|
|
50
83
|
data = data.slice(0, this.info.max);
|
|
51
84
|
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { SearchInfo } from './SearchInterface';
|
|
2
2
|
import type { ItemOf } from '../../type.utils';
|
|
3
|
+
import { normalizeStr } from './utils';
|
|
3
4
|
|
|
4
5
|
/**
|
|
5
6
|
* Generates a tokenize method.
|
|
@@ -76,21 +77,6 @@ export const tokenizeIndex = (
|
|
|
76
77
|
);
|
|
77
78
|
};
|
|
78
79
|
|
|
79
|
-
/**
|
|
80
|
-
* Normalize a string
|
|
81
|
-
* - Remove accent (é => e, à => a)
|
|
82
|
-
* - remove ligatures (æ => ae, , Æ => ae, œ => oe, Œ => oe)
|
|
83
|
-
* - Lowercase
|
|
84
|
-
*/
|
|
85
|
-
const normalizeStr = (str: string) => {
|
|
86
|
-
return str
|
|
87
|
-
.toLowerCase()
|
|
88
|
-
.replaceAll('œ', 'oe')
|
|
89
|
-
.replaceAll('æ', 'ae')
|
|
90
|
-
.normalize('NFD')
|
|
91
|
-
.replace(/[\u0300-\u036f]/g, '');
|
|
92
|
-
};
|
|
93
|
-
|
|
94
80
|
/**
|
|
95
81
|
* remove from a string all the words that are included in a stopwords list
|
|
96
82
|
*/
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Normalize a string
|
|
3
|
+
* - Remove accent (é => e, à => a)
|
|
4
|
+
* - remove ligatures (æ => ae, , Æ => ae, œ => oe, Œ => oe)
|
|
5
|
+
* - Lowercase
|
|
6
|
+
*/
|
|
7
|
+
export const normalizeStr = (str: string) => {
|
|
8
|
+
return str
|
|
9
|
+
.toLowerCase()
|
|
10
|
+
.replaceAll('œ', 'oe')
|
|
11
|
+
.replaceAll('æ', 'ae')
|
|
12
|
+
.normalize('NFD')
|
|
13
|
+
.replace(/[\u0300-\u036f]/g, '');
|
|
14
|
+
};
|