@datawheel/bespoke 0.3.7 → 0.3.8
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/index.js +13 -11
- package/dist/server.js +41 -9
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -3888,13 +3888,14 @@ function BespokeSearch({
|
|
|
3888
3888
|
};
|
|
3889
3889
|
const inputRef = useRef();
|
|
3890
3890
|
const containerRef = useClickOutside(doClose);
|
|
3891
|
+
const searchLimit = autocompleteProps?.searchConfig?.searchLimit ?? 10;
|
|
3891
3892
|
const doSearch = () => {
|
|
3892
3893
|
setLoading(true);
|
|
3893
3894
|
const params = {
|
|
3894
3895
|
query: debouncedQuery,
|
|
3895
3896
|
format: "profiles",
|
|
3896
3897
|
locale,
|
|
3897
|
-
limit:
|
|
3898
|
+
limit: searchLimit,
|
|
3898
3899
|
visible: true,
|
|
3899
3900
|
includes: true,
|
|
3900
3901
|
noImage: false,
|
|
@@ -3936,10 +3937,10 @@ function BespokeSearch({
|
|
|
3936
3937
|
});
|
|
3937
3938
|
};
|
|
3938
3939
|
useEffect(() => {
|
|
3939
|
-
if (initialized && debouncedQuery.length
|
|
3940
|
+
if (initialized && debouncedQuery.length >= (autocompleteProps.searchConfig?.queryThreshold ?? 0)) {
|
|
3940
3941
|
doSearch();
|
|
3941
3942
|
}
|
|
3942
|
-
}, [debouncedQuery]);
|
|
3943
|
+
}, [initialized, debouncedQuery, autocompleteProps.searchConfig?.queryThreshold]);
|
|
3943
3944
|
useEffect(() => {
|
|
3944
3945
|
cancel();
|
|
3945
3946
|
if (inputRef.current && visible) {
|
|
@@ -3952,13 +3953,6 @@ function BespokeSearch({
|
|
|
3952
3953
|
setInitialized(true);
|
|
3953
3954
|
}
|
|
3954
3955
|
}, [visible]);
|
|
3955
|
-
const acConfig = {
|
|
3956
|
-
placeholder: "Search",
|
|
3957
|
-
size: "md",
|
|
3958
|
-
icon: /* @__PURE__ */ jsx(IconSearch, {}),
|
|
3959
|
-
...autocompleteProps,
|
|
3960
|
-
data: results
|
|
3961
|
-
};
|
|
3962
3956
|
const onItemSubmit = (item) => {
|
|
3963
3957
|
setVisible(false);
|
|
3964
3958
|
if (callback) {
|
|
@@ -3973,6 +3967,14 @@ function BespokeSearch({
|
|
|
3973
3967
|
setQuery(searchTerm);
|
|
3974
3968
|
}
|
|
3975
3969
|
};
|
|
3970
|
+
const { searchConfig: _, ...finalAutocompleteProps } = autocompleteProps;
|
|
3971
|
+
const acConfig = {
|
|
3972
|
+
placeholder: "Search",
|
|
3973
|
+
size: "md",
|
|
3974
|
+
icon: /* @__PURE__ */ jsx(IconSearch, {}),
|
|
3975
|
+
...finalAutocompleteProps,
|
|
3976
|
+
data: results
|
|
3977
|
+
};
|
|
3976
3978
|
const autocompleteElement = /* @__PURE__ */ jsx(
|
|
3977
3979
|
Autocomplete,
|
|
3978
3980
|
{
|
|
@@ -3982,7 +3984,7 @@ function BespokeSearch({
|
|
|
3982
3984
|
onChange,
|
|
3983
3985
|
filter: () => true,
|
|
3984
3986
|
disabled: (loading || redirecting) && !initialized,
|
|
3985
|
-
limit:
|
|
3987
|
+
limit: searchLimit,
|
|
3986
3988
|
maxDropdownHeight: 250,
|
|
3987
3989
|
rightSection: /* @__PURE__ */ jsx(Group, { spacing: 0, position: "right", children: loading ? /* @__PURE__ */ jsx(Loader, { size: 20 }) : /* @__PURE__ */ jsx(Fragment, {}) }),
|
|
3988
3990
|
rightSectionWidth: 50,
|
package/dist/server.js
CHANGED
|
@@ -1707,6 +1707,12 @@ function readMemberImageFactory(db) {
|
|
|
1707
1707
|
}
|
|
1708
1708
|
}
|
|
1709
1709
|
}
|
|
1710
|
+
function sanitizeQuery(str) {
|
|
1711
|
+
if (!str)
|
|
1712
|
+
return "";
|
|
1713
|
+
return strip(str.toLowerCase(), " ").replace(/\s\s+/g, " ");
|
|
1714
|
+
}
|
|
1715
|
+
var sanitizeQuery_default = sanitizeQuery;
|
|
1710
1716
|
lunrStemmer(lunr);
|
|
1711
1717
|
var whitelist = [
|
|
1712
1718
|
"ar",
|
|
@@ -1787,21 +1793,23 @@ async function newSearchIndex(db) {
|
|
|
1787
1793
|
if (locale && locale !== "en")
|
|
1788
1794
|
this.use(lunr[locale]);
|
|
1789
1795
|
this.ref("content_id");
|
|
1790
|
-
this.field("id");
|
|
1791
|
-
this.field("
|
|
1792
|
-
this.field("
|
|
1796
|
+
this.field("id", { boost: 4 });
|
|
1797
|
+
this.field("keywords", { boost: 3 });
|
|
1798
|
+
this.field("searchTerms", { boost: 2 });
|
|
1793
1799
|
this.field("attributes");
|
|
1794
1800
|
this.pipeline.reset();
|
|
1795
1801
|
this.searchPipeline.reset();
|
|
1796
1802
|
results.forEach((result) => {
|
|
1797
1803
|
const content = result.contentByLocale.find((d) => d.locale === locale);
|
|
1798
1804
|
if (content) {
|
|
1805
|
+
const searchTerms = sanitizeQuery_default(content.name);
|
|
1799
1806
|
const payload = {
|
|
1800
1807
|
id: result.id,
|
|
1801
1808
|
content_id: result.content_id,
|
|
1802
1809
|
name: content.name,
|
|
1803
1810
|
keywords: content.keywords,
|
|
1804
|
-
attributes: content.attributes
|
|
1811
|
+
attributes: content.attributes,
|
|
1812
|
+
searchTerms
|
|
1805
1813
|
};
|
|
1806
1814
|
this.add(payload, { boost: result.zvalue });
|
|
1807
1815
|
}
|
|
@@ -1825,6 +1833,7 @@ function dbSearchMemberFactory(db) {
|
|
|
1825
1833
|
async function searchMember2(params) {
|
|
1826
1834
|
const searchIndexByLocale = await search_default2(db);
|
|
1827
1835
|
let resultsIds = [];
|
|
1836
|
+
let resultsScores = [];
|
|
1828
1837
|
const {
|
|
1829
1838
|
query,
|
|
1830
1839
|
locale,
|
|
@@ -1841,11 +1850,10 @@ function dbSearchMemberFactory(db) {
|
|
|
1841
1850
|
direction = "ASC"
|
|
1842
1851
|
} = params;
|
|
1843
1852
|
if (query && query !== "" && searchIndexByLocale[locale]) {
|
|
1844
|
-
const terms = query
|
|
1845
|
-
return `+${d}~2*`;
|
|
1846
|
-
}).join(" ");
|
|
1853
|
+
const terms = sanitizeQuery_default(query).replace(/([A-z]{2,})/g, (txt) => `+${txt}`).replace(/(.)$/g, (txt) => `${txt}*`);
|
|
1847
1854
|
const lunrResults = searchIndexByLocale[locale].index.search(terms);
|
|
1848
1855
|
resultsIds = lunrResults.map((d) => parseInt(d.ref, 10));
|
|
1856
|
+
resultsScores = lunrResults.reduce((obj, d) => (obj[d.ref] = d.score, obj), {});
|
|
1849
1857
|
}
|
|
1850
1858
|
const whereClause = {
|
|
1851
1859
|
...visible ? { visible } : {},
|
|
@@ -1910,6 +1918,29 @@ function dbSearchMemberFactory(db) {
|
|
|
1910
1918
|
});
|
|
1911
1919
|
}
|
|
1912
1920
|
const resultFormatter = format === "nested" ? nestedFormatter : plainFormatter;
|
|
1921
|
+
const formattedResults = results.map(resultFormatter);
|
|
1922
|
+
if (format !== "nested") {
|
|
1923
|
+
formattedResults.forEach((d) => {
|
|
1924
|
+
const { name, keywords, score = 0, zvalue } = d;
|
|
1925
|
+
if (name) {
|
|
1926
|
+
const cleanName = sanitizeQuery_default(name);
|
|
1927
|
+
let scoreMod = score;
|
|
1928
|
+
const diffMod = query.length / cleanName.length;
|
|
1929
|
+
const matchingStartChars = cleanName.split("").reduce((str, c, i) => {
|
|
1930
|
+
if (str === query.slice(0, i), query.charAt(i) === c)
|
|
1931
|
+
str += c;
|
|
1932
|
+
return str;
|
|
1933
|
+
}, "").length;
|
|
1934
|
+
if (cleanName === query || keywords && keywords.includes(query))
|
|
1935
|
+
scoreMod = 1e6;
|
|
1936
|
+
else if (cleanName.startsWith(query))
|
|
1937
|
+
scoreMod *= 20 * diffMod;
|
|
1938
|
+
else if (matchingStartChars)
|
|
1939
|
+
scoreMod *= matchingStartChars * diffMod;
|
|
1940
|
+
d.zvalue = scoreMod * 2 + zvalue;
|
|
1941
|
+
}
|
|
1942
|
+
});
|
|
1943
|
+
}
|
|
1913
1944
|
return {
|
|
1914
1945
|
meta: {
|
|
1915
1946
|
origin: "lunr",
|
|
@@ -1917,7 +1948,7 @@ function dbSearchMemberFactory(db) {
|
|
|
1917
1948
|
Object.entries(params).map((entry) => [entry[0], stripHTML(entry[1])])
|
|
1918
1949
|
)
|
|
1919
1950
|
},
|
|
1920
|
-
results:
|
|
1951
|
+
results: formattedResults
|
|
1921
1952
|
};
|
|
1922
1953
|
function nestedFormatter(item) {
|
|
1923
1954
|
return item.toJSON();
|
|
@@ -1929,7 +1960,8 @@ function dbSearchMemberFactory(db) {
|
|
|
1929
1960
|
locale: localizedItem.locale,
|
|
1930
1961
|
name: localizedItem.name,
|
|
1931
1962
|
attributes: localizedItem.attributes,
|
|
1932
|
-
keywords: localizedItem.keywords
|
|
1963
|
+
keywords: localizedItem.keywords,
|
|
1964
|
+
score: resultsScores[item.content_id]
|
|
1933
1965
|
};
|
|
1934
1966
|
}
|
|
1935
1967
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@datawheel/bespoke",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.8",
|
|
4
4
|
"description": "Content management system for creating automated data reports",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": {
|
|
@@ -73,7 +73,7 @@
|
|
|
73
73
|
"d3plus-export": "^1.3.0",
|
|
74
74
|
"d3plus-format": "^1.2.4",
|
|
75
75
|
"d3plus-react": "^1.3.3",
|
|
76
|
-
"d3plus-text": "^1.2.
|
|
76
|
+
"d3plus-text": "^1.2.4",
|
|
77
77
|
"d3plus-viz": "^1.3.3",
|
|
78
78
|
"dom-parser": "^0.1.6",
|
|
79
79
|
"fast-glob": "^3.2.12",
|