@fluid-topics/ft-search-context 1.2.21 → 1.2.22
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/build/ft-search-context.light.js +6 -6
- package/build/ft-search-context.min.js +17 -17
- package/build/store/FtSearchStateManager.d.ts +11 -7
- package/build/store/FtSearchStateManager.js +26 -39
- package/build/store/utils/FtSearchService.d.ts +4 -1
- package/build/store/utils/FtSearchService.js +34 -3
- package/package.json +4 -4
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { FtSearchPageState } from "./model";
|
|
2
|
-
import { FtReduxStore } from "@fluid-topics/ft-wc-utils";
|
|
2
|
+
import { FtReduxStore, ReduxWatcher } from "@fluid-topics/ft-wc-utils";
|
|
3
3
|
import { FtSearchPageStateReducers } from "./redux";
|
|
4
|
-
import { FtDateFilterTypeKeys, FtMetadataFilter, FtPublicClusterSortCriterion, FtSearchRequest, FtSearchScope, FtSearchSortCriterion, FtVirtualField } from "@fluid-topics/public-api";
|
|
4
|
+
import { FtDateFilterTypeKeys, FtMetadataFilter, FtPublicClusterSortCriterion, FtSearchRequest, FtSearchScope, FtSearchSortCriterion, FtSuggestRequest, FtVirtualField } from "@fluid-topics/public-api";
|
|
5
5
|
import { FtSearchService } from "./utils/FtSearchService";
|
|
6
6
|
export declare const searchInDocumentTitlesOnlySelector: (s: FtSearchPageState) => boolean;
|
|
7
7
|
export declare class ClearAllFiltersEvent extends Event {
|
|
@@ -9,12 +9,14 @@ export declare class ClearAllFiltersEvent extends Event {
|
|
|
9
9
|
constructor();
|
|
10
10
|
}
|
|
11
11
|
export declare class FtSearchStateManager {
|
|
12
|
-
store: FtReduxStore<FtSearchPageState, FtSearchPageStateReducers>;
|
|
12
|
+
readonly store: FtReduxStore<FtSearchPageState, FtSearchPageStateReducers>;
|
|
13
13
|
static build(id: string, service?: FtSearchService): FtSearchStateManager;
|
|
14
|
-
service: FtSearchService;
|
|
14
|
+
readonly service: FtSearchService;
|
|
15
15
|
errorHandler?: (e: Error) => void;
|
|
16
16
|
ignoreEmptyQuery: boolean;
|
|
17
17
|
openExternalDocumentInNewTab: boolean;
|
|
18
|
+
protected readonly searchWatcher: ReduxWatcher<FtSearchPageState, FtSearchRequest>;
|
|
19
|
+
protected readonly suggestWatcher: ReduxWatcher<FtSearchPageState, FtSuggestRequest>;
|
|
18
20
|
constructor(store: FtReduxStore<FtSearchPageState, FtSearchPageStateReducers>, service?: FtSearchService);
|
|
19
21
|
initService(): Promise<boolean>;
|
|
20
22
|
setQuery(query: string): void;
|
|
@@ -49,11 +51,13 @@ export declare class FtSearchStateManager {
|
|
|
49
51
|
private localesDebouncer;
|
|
50
52
|
updateLocales(): Promise<boolean>;
|
|
51
53
|
private searchDebouncer;
|
|
52
|
-
launchSearch()
|
|
53
|
-
private
|
|
54
|
-
launchSuggest(): Promise<boolean>;
|
|
54
|
+
launchSearch: (request?: FtSearchRequest) => Promise<boolean>;
|
|
55
|
+
private buildSearchRequest;
|
|
55
56
|
private cancelableSearch;
|
|
56
57
|
private fetchSearchData;
|
|
58
|
+
private suggestDebouncer;
|
|
59
|
+
launchSuggest: (request?: FtSuggestRequest) => Promise<boolean>;
|
|
60
|
+
private buildSuggestRequest;
|
|
57
61
|
private cancelableSuggest;
|
|
58
62
|
private fetchSuggestData;
|
|
59
63
|
clear(): void;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { cancelable, CanceledPromiseError, Debouncer } from "@fluid-topics/ft-wc-utils";
|
|
1
|
+
import { cancelable, CanceledPromiseError, Debouncer, watch } from "@fluid-topics/ft-wc-utils";
|
|
2
2
|
import { createSearchPageStore } from "./redux";
|
|
3
3
|
import { FtSearchScope, FtVirtualField } from "@fluid-topics/public-api";
|
|
4
4
|
import { FtSearchService } from "./utils/FtSearchService";
|
|
@@ -21,13 +21,36 @@ export class FtSearchStateManager {
|
|
|
21
21
|
this.openExternalDocumentInNewTab = false;
|
|
22
22
|
this.localesDebouncer = new Debouncer(10);
|
|
23
23
|
this.searchDebouncer = new Debouncer(100);
|
|
24
|
+
this.launchSearch = (request) => {
|
|
25
|
+
return this.searchDebouncer.run(() => this.fetchSearchData(request !== null && request !== void 0 ? request : this.buildSearchRequest(this.store.getState())));
|
|
26
|
+
};
|
|
27
|
+
this.buildSearchRequest = (state) => {
|
|
28
|
+
return {
|
|
29
|
+
...state.request,
|
|
30
|
+
facets: this.facetIds.map(id => ({ id })),
|
|
31
|
+
};
|
|
32
|
+
};
|
|
24
33
|
this.suggestDebouncer = new Debouncer(300);
|
|
34
|
+
this.launchSuggest = (request) => {
|
|
35
|
+
return this.suggestDebouncer.run(() => this.fetchSuggestData(request !== null && request !== void 0 ? request : this.buildSuggestRequest(this.store.getState())));
|
|
36
|
+
};
|
|
37
|
+
this.buildSuggestRequest = (state) => {
|
|
38
|
+
return {
|
|
39
|
+
input: state.liveQuery,
|
|
40
|
+
metadataFilters: state.request.metadataFilters,
|
|
41
|
+
sort: state.request.sort,
|
|
42
|
+
contentLocale: state.request.contentLocale,
|
|
43
|
+
scope: state.request.scope,
|
|
44
|
+
};
|
|
45
|
+
};
|
|
25
46
|
this.service = service !== null && service !== void 0 ? service : new FtSearchService();
|
|
26
47
|
this.service.cache.addEventListener("clear-cache", (e) => {
|
|
27
48
|
if (e.detail.clearedKeys.includes("available-locales")) {
|
|
28
49
|
this.updateLocales();
|
|
29
50
|
}
|
|
30
51
|
});
|
|
52
|
+
this.searchWatcher = watch(store, this.buildSearchRequest, this.launchSearch);
|
|
53
|
+
this.suggestWatcher = watch(store, this.buildSuggestRequest, this.launchSuggest);
|
|
31
54
|
}
|
|
32
55
|
async initService() {
|
|
33
56
|
this.updateLocales();
|
|
@@ -37,7 +60,6 @@ export class FtSearchStateManager {
|
|
|
37
60
|
this.store.actions.setRequestQuery(query);
|
|
38
61
|
this.store.actions.liveQuery(query);
|
|
39
62
|
this.store.actions.setPageNumber(1);
|
|
40
|
-
this.launchSearch();
|
|
41
63
|
}
|
|
42
64
|
setContentLocale(contentLocale) {
|
|
43
65
|
var _a;
|
|
@@ -53,36 +75,29 @@ export class FtSearchStateManager {
|
|
|
53
75
|
this.store.actions.setRequestContentLocale(contentLocale);
|
|
54
76
|
this.store.actions.setPageNumber(1);
|
|
55
77
|
this.store.actions.setRequestFilters([]);
|
|
56
|
-
this.launchSearch();
|
|
57
78
|
}
|
|
58
79
|
return contentLocale;
|
|
59
80
|
}
|
|
60
81
|
forceContentLocale(contentLocale) {
|
|
61
82
|
this.store.actions.setRequestContentLocale(contentLocale);
|
|
62
|
-
this.launchSearch();
|
|
63
83
|
}
|
|
64
84
|
setPageSize(pageSize) {
|
|
65
85
|
this.store.actions.setPageSize(pageSize);
|
|
66
|
-
this.launchSearch();
|
|
67
86
|
}
|
|
68
87
|
setPageNumber(pageNumber) {
|
|
69
88
|
this.store.actions.setPageNumber(pageNumber);
|
|
70
|
-
this.launchSearch();
|
|
71
89
|
}
|
|
72
90
|
setSort(sort) {
|
|
73
91
|
this.store.actions.setRequestSort(sort);
|
|
74
92
|
this.store.actions.setPageNumber(1);
|
|
75
|
-
this.launchSearch();
|
|
76
93
|
}
|
|
77
94
|
setFilters(filters) {
|
|
78
95
|
const cleanFilters = filters.filter(f => !f.valueFilter || f.valueFilter.values.length > 0);
|
|
79
96
|
this.store.actions.setRequestFilters(cleanFilters);
|
|
80
97
|
this.store.actions.setPageNumber(1);
|
|
81
|
-
this.launchSearch();
|
|
82
98
|
}
|
|
83
99
|
setClusterSortCriterion(criterions) {
|
|
84
100
|
this.store.actions.setRequestClusterSortCriterion(criterions);
|
|
85
|
-
this.launchSearch();
|
|
86
101
|
}
|
|
87
102
|
setSearchInDocumentTitlesOnly(searchInDocumentTitleOnly) {
|
|
88
103
|
if (searchInDocumentTitleOnly) {
|
|
@@ -93,11 +108,9 @@ export class FtSearchStateManager {
|
|
|
93
108
|
this.store.actions.setRequestVirtualField(FtVirtualField.EVERYWHERE);
|
|
94
109
|
this.store.actions.setRequestScope(FtSearchScope.DEFAULT);
|
|
95
110
|
}
|
|
96
|
-
this.launchSearch();
|
|
97
111
|
}
|
|
98
112
|
setVirtualField(virtualField) {
|
|
99
113
|
this.store.actions.setRequestVirtualField(virtualField);
|
|
100
|
-
this.launchSearch();
|
|
101
114
|
}
|
|
102
115
|
get searchInDocumentTitlesOnly() {
|
|
103
116
|
return searchInDocumentTitlesOnlySelector(this.store.getState());
|
|
@@ -109,7 +122,6 @@ export class FtSearchStateManager {
|
|
|
109
122
|
}
|
|
110
123
|
addFacet(id) {
|
|
111
124
|
this.facetIds = [...this.facetIds, id];
|
|
112
|
-
this.launchSearch();
|
|
113
125
|
}
|
|
114
126
|
replaceFacet(oldId, newId) {
|
|
115
127
|
let facetIds = this.facetIds.filter(id => id != oldId);
|
|
@@ -117,7 +129,6 @@ export class FtSearchStateManager {
|
|
|
117
129
|
facetIds.push(newId);
|
|
118
130
|
}
|
|
119
131
|
this.facetIds = facetIds;
|
|
120
|
-
this.launchSearch();
|
|
121
132
|
}
|
|
122
133
|
get facetIds() {
|
|
123
134
|
var _a;
|
|
@@ -203,7 +214,6 @@ export class FtSearchStateManager {
|
|
|
203
214
|
}
|
|
204
215
|
setLiveQuery(query) {
|
|
205
216
|
this.store.actions.liveQuery(query);
|
|
206
|
-
this.launchSuggest();
|
|
207
217
|
}
|
|
208
218
|
setRequest(request) {
|
|
209
219
|
this.store.actions.setRequest({
|
|
@@ -212,18 +222,15 @@ export class FtSearchStateManager {
|
|
|
212
222
|
});
|
|
213
223
|
this.store.actions.liveQuery(request.query);
|
|
214
224
|
this.store.actions.setPageNumber(1);
|
|
215
|
-
this.launchSearch();
|
|
216
225
|
}
|
|
217
226
|
setScope(scope) {
|
|
218
227
|
this.store.actions.setRequestScope(scope);
|
|
219
|
-
this.launchSearch();
|
|
220
228
|
}
|
|
221
229
|
setOtherQueryParams(params) {
|
|
222
230
|
this.store.actions.setOtherQueryParams(params);
|
|
223
231
|
}
|
|
224
232
|
setIgnoreEmptyQuery(ignoreEmptyQuery) {
|
|
225
233
|
this.ignoreEmptyQuery = ignoreEmptyQuery;
|
|
226
|
-
this.launchSearch();
|
|
227
234
|
}
|
|
228
235
|
setOpenExternalDocumentInNewTab(openExternalDocumentInNewTab) {
|
|
229
236
|
this.openExternalDocumentInNewTab = openExternalDocumentInNewTab;
|
|
@@ -231,21 +238,10 @@ export class FtSearchStateManager {
|
|
|
231
238
|
updateLocales() {
|
|
232
239
|
return this.localesDebouncer.run(async () => this.store.actions.locales((await this.service.getAvailableSearchLocales()).contentLocales));
|
|
233
240
|
}
|
|
234
|
-
|
|
235
|
-
this.launchSuggest();
|
|
236
|
-
return this.searchDebouncer.run(() => this.fetchSearchData());
|
|
237
|
-
}
|
|
238
|
-
launchSuggest() {
|
|
239
|
-
return this.suggestDebouncer.run(() => this.fetchSuggestData());
|
|
240
|
-
}
|
|
241
|
-
async fetchSearchData() {
|
|
241
|
+
async fetchSearchData(request) {
|
|
242
242
|
var _a, _b;
|
|
243
243
|
try {
|
|
244
244
|
(_a = this.cancelableSearch) === null || _a === void 0 ? void 0 : _a.cancel();
|
|
245
|
-
let request = {
|
|
246
|
-
...this.store.getState().request,
|
|
247
|
-
facets: this.facetIds.map(id => ({ id })),
|
|
248
|
-
};
|
|
249
245
|
this.store.actions.paging(undefined);
|
|
250
246
|
if (this.ignoreEmptyQuery && request.query.length == 0) {
|
|
251
247
|
this.store.actions.results(undefined);
|
|
@@ -273,18 +269,9 @@ export class FtSearchStateManager {
|
|
|
273
269
|
}
|
|
274
270
|
}
|
|
275
271
|
}
|
|
276
|
-
async fetchSuggestData() {
|
|
272
|
+
async fetchSuggestData(request) {
|
|
277
273
|
var _a;
|
|
278
274
|
try {
|
|
279
|
-
const searchState = this.store.getState();
|
|
280
|
-
const searchRequest = searchState.request;
|
|
281
|
-
const request = {
|
|
282
|
-
input: searchState.liveQuery,
|
|
283
|
-
metadataFilters: searchRequest.metadataFilters,
|
|
284
|
-
sort: searchRequest.sort,
|
|
285
|
-
contentLocale: searchRequest.contentLocale,
|
|
286
|
-
scope: searchRequest.scope,
|
|
287
|
-
};
|
|
288
275
|
(_a = this.cancelableSuggest) === null || _a === void 0 ? void 0 : _a.cancel();
|
|
289
276
|
this.cancelableSuggest = cancelable(this.service.launchSuggest(request));
|
|
290
277
|
let results = await this.cancelableSuggest;
|
|
@@ -1,8 +1,11 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type FluidTopicsApi, FtSearchLocales, FtSearchRequest, FtSearchResults, FtSuggestRequest, FtSuggestResults } from "@fluid-topics/public-api";
|
|
2
2
|
import { FtServiceWithCache } from "@fluid-topics/ft-app-context";
|
|
3
3
|
export declare class FtSearchService extends FtServiceWithCache {
|
|
4
|
+
constructor(overrideApi?: FluidTopicsApi);
|
|
4
5
|
launchSearch(request: FtSearchRequest): Promise<FtSearchResults>;
|
|
5
6
|
launchSuggest(request: FtSuggestRequest): Promise<FtSuggestResults>;
|
|
6
7
|
getAvailableSearchLocales(): Promise<FtSearchLocales>;
|
|
8
|
+
private sortFilters;
|
|
9
|
+
private sortObjectFields;
|
|
7
10
|
hash(object: any): string;
|
|
8
11
|
}
|
|
@@ -1,15 +1,46 @@
|
|
|
1
1
|
import { FtServiceWithCache } from "@fluid-topics/ft-app-context";
|
|
2
2
|
export class FtSearchService extends FtServiceWithCache {
|
|
3
|
+
constructor(overrideApi) {
|
|
4
|
+
super(true, overrideApi);
|
|
5
|
+
this.sortObjectFields = (_, value) => {
|
|
6
|
+
if (typeof value !== "object" || value == null || Array.isArray(value)) {
|
|
7
|
+
return value;
|
|
8
|
+
}
|
|
9
|
+
return Object.fromEntries(Object.entries(value)
|
|
10
|
+
.sort(([ka], [kb]) => ka.localeCompare(kb)));
|
|
11
|
+
};
|
|
12
|
+
}
|
|
3
13
|
async launchSearch(request) {
|
|
4
|
-
|
|
14
|
+
const sortedRequest = {
|
|
15
|
+
...request,
|
|
16
|
+
metadataFilters: this.sortFilters(request.metadataFilters),
|
|
17
|
+
facets: [...request.facets].sort((a, b) => a.id.localeCompare(b.id)),
|
|
18
|
+
};
|
|
19
|
+
return this.cache.get(this.hash(sortedRequest), async () => (await this.awaitApi).search(request), 2 * 60 * 1000);
|
|
5
20
|
}
|
|
6
21
|
async launchSuggest(request) {
|
|
7
|
-
|
|
22
|
+
const sortedRequest = {
|
|
23
|
+
...request,
|
|
24
|
+
metadataFilters: this.sortFilters(request.metadataFilters)
|
|
25
|
+
};
|
|
26
|
+
return this.cache.get(this.hash(sortedRequest), async () => (await this.awaitApi).getSuggestions(request), 2 * 60 * 1000);
|
|
8
27
|
}
|
|
9
28
|
async getAvailableSearchLocales() {
|
|
10
29
|
return this.cache.get("available-locales", async () => (await this.awaitApi).getAvailableSearchLocales());
|
|
11
30
|
}
|
|
31
|
+
sortFilters(filters) {
|
|
32
|
+
return filters
|
|
33
|
+
.map(f => f.valueFilter == null ? f : {
|
|
34
|
+
...f,
|
|
35
|
+
valueFilter: {
|
|
36
|
+
...f.valueFilter,
|
|
37
|
+
values: f.valueFilter.values.sort((a, b) => a.localeCompare(b))
|
|
38
|
+
}
|
|
39
|
+
})
|
|
40
|
+
.sort((a, b) => a.key.localeCompare(b.key));
|
|
41
|
+
}
|
|
12
42
|
hash(object) {
|
|
13
|
-
return
|
|
43
|
+
return String(Array.from(JSON.stringify(object, this.sortObjectFields))
|
|
44
|
+
.reduce((hash, char) => 0 | (31 * hash + char.charCodeAt(0)), 0));
|
|
14
45
|
}
|
|
15
46
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fluid-topics/ft-search-context",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.22",
|
|
4
4
|
"description": "Context block for integrated search components",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"Lit"
|
|
@@ -19,12 +19,12 @@
|
|
|
19
19
|
"url": "ssh://git@scm.mrs.antidot.net:2222/fluidtopics/ft-web-components.git"
|
|
20
20
|
},
|
|
21
21
|
"dependencies": {
|
|
22
|
-
"@fluid-topics/ft-app-context": "1.2.
|
|
23
|
-
"@fluid-topics/ft-wc-utils": "1.2.
|
|
22
|
+
"@fluid-topics/ft-app-context": "1.2.22",
|
|
23
|
+
"@fluid-topics/ft-wc-utils": "1.2.22",
|
|
24
24
|
"lit": "3.1.0"
|
|
25
25
|
},
|
|
26
26
|
"devDependencies": {
|
|
27
27
|
"@fluid-topics/public-api": "1.0.82"
|
|
28
28
|
},
|
|
29
|
-
"gitHead": "
|
|
29
|
+
"gitHead": "29f6269b3af8af4c82f5ab2228d52b493ac3ddea"
|
|
30
30
|
}
|