@findlane/browser 0.3.0 → 0.4.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/index.d.ts
CHANGED
|
@@ -8,9 +8,12 @@ export type SearchRequest = {
|
|
|
8
8
|
/** Facets (also in `facets`) counted without the filter on their own field, so a list of choices
|
|
9
9
|
* keeps its other values, with counts, after one is chosen. */
|
|
10
10
|
disjunctiveFacets?: string[];
|
|
11
|
+
/** Number fields (up to eight) whose smallest and largest values across the matches to return in
|
|
12
|
+
* `facetStats`, such as a price slider's bounds. Each field's own filter is left out. */
|
|
13
|
+
facetStats?: string[];
|
|
11
14
|
/** Hits per request: 1–50 (default 20). */
|
|
12
15
|
limit?: number;
|
|
13
|
-
/** Up to
|
|
16
|
+
/** Up to 5,000. */
|
|
14
17
|
offset?: number;
|
|
15
18
|
attributesToRetrieve?: string[];
|
|
16
19
|
/** "page" (default) counts only the returned page when a query matches more; "exact" counts every match. */
|
|
@@ -37,6 +40,12 @@ export type SearchResponse<T> = {
|
|
|
37
40
|
totalRelation?: "eq" | "gte";
|
|
38
41
|
hasMore?: boolean;
|
|
39
42
|
facets: Record<string, Record<string, number>>;
|
|
43
|
+
/** With `facetStats`: each field's smallest and largest value across the matches, without the field's
|
|
44
|
+
* own filter. A field no match has is left out. */
|
|
45
|
+
facetStats?: Record<string, {
|
|
46
|
+
min: number;
|
|
47
|
+
max: number;
|
|
48
|
+
}>;
|
|
40
49
|
tookMs: number;
|
|
41
50
|
sort?: string;
|
|
42
51
|
/** With the index's `didYouMean` setting: the query with the words typo tolerance corrected, when the
|
package/dist/react/cache.js
CHANGED
|
@@ -12,7 +12,7 @@ export function searchKey(request) {
|
|
|
12
12
|
for (const [key, value] of Object.entries(defaults))
|
|
13
13
|
if (normal[key] === value)
|
|
14
14
|
delete normal[key];
|
|
15
|
-
for (const key of ["facets", "disjunctiveFacets"]) {
|
|
15
|
+
for (const key of ["facets", "disjunctiveFacets", "facetStats"]) {
|
|
16
16
|
const list = normal[key];
|
|
17
17
|
if (Array.isArray(list))
|
|
18
18
|
normal[key] = list.length ? [...list].sort() : undefined;
|
|
@@ -72,9 +72,13 @@ export type Range = {
|
|
|
72
72
|
gte?: number | string;
|
|
73
73
|
lte?: number | string;
|
|
74
74
|
};
|
|
75
|
-
/** A number or date range filter. List the field in `filterFields` to keep it in the URL
|
|
75
|
+
/** A number or date range filter. List the field in `filterFields` to keep it in the URL, and in
|
|
76
|
+
* `facetStats` for `min` and `max`: the smallest and largest values across the matches, without
|
|
77
|
+
* this range, such as a slider's bounds. */
|
|
76
78
|
export declare function useRange(field: string): {
|
|
77
79
|
range: Range | undefined;
|
|
80
|
+
min: number | undefined;
|
|
81
|
+
max: number | undefined;
|
|
78
82
|
/** Leave a bound out (or empty) for no limit on that side. */
|
|
79
83
|
setRange: (range: Range | undefined) => void;
|
|
80
84
|
clear: () => void;
|
|
@@ -110,7 +114,7 @@ export declare function useLoadMore(): {
|
|
|
110
114
|
shown: number;
|
|
111
115
|
total: number;
|
|
112
116
|
};
|
|
113
|
-
/** Numbered pages, from 0. The API returns hits up to the
|
|
117
|
+
/** Numbered pages, from 0. The API returns hits up to the 5,000th offset, so pages stop there. */
|
|
114
118
|
export declare function usePagination(): {
|
|
115
119
|
page: number;
|
|
116
120
|
pages: number;
|
|
@@ -142,12 +142,17 @@ export function useRefinementList(field) {
|
|
|
142
142
|
clear: () => store.update(withRefinement(field, [])),
|
|
143
143
|
};
|
|
144
144
|
}
|
|
145
|
-
/** A number or date range filter. List the field in `filterFields` to keep it in the URL
|
|
145
|
+
/** A number or date range filter. List the field in `filterFields` to keep it in the URL, and in
|
|
146
|
+
* `facetStats` for `min` and `max`: the smallest and largest values across the matches, without
|
|
147
|
+
* this range, such as a slider's bounds. */
|
|
146
148
|
export function useRange(field) {
|
|
147
|
-
const [{ state }, store] = useSnapshot();
|
|
149
|
+
const [{ state, results }, store] = useSnapshot();
|
|
148
150
|
const value = state.filters[field];
|
|
151
|
+
const stats = results?.response.facetStats?.[field];
|
|
149
152
|
return {
|
|
150
153
|
range: isRange(value) ? value : undefined,
|
|
154
|
+
min: stats?.min,
|
|
155
|
+
max: stats?.max,
|
|
151
156
|
/** Leave a bound out (or empty) for no limit on that side. */
|
|
152
157
|
setRange: (range) => {
|
|
153
158
|
const bounds = Object.entries(range ?? {}).filter(([, bound]) => bound !== undefined && bound !== "");
|
|
@@ -203,7 +208,7 @@ export function useLoadMore() {
|
|
|
203
208
|
total: results?.response.total ?? 0,
|
|
204
209
|
};
|
|
205
210
|
}
|
|
206
|
-
/** Numbered pages, from 0. The API returns hits up to the
|
|
211
|
+
/** Numbered pages, from 0. The API returns hits up to the 5,000th offset, so pages stop there. */
|
|
207
212
|
export function usePagination() {
|
|
208
213
|
const [{ state, results }, store] = useSnapshot();
|
|
209
214
|
const pageSize = store.settings.pageSize ?? 20;
|
package/dist/react/state.d.ts
CHANGED
|
@@ -18,6 +18,9 @@ export type SearchConfig = {
|
|
|
18
18
|
facets?: string[];
|
|
19
19
|
/** Fields that useRange and useToggle filter, so the URL can carry them. */
|
|
20
20
|
filterFields?: string[];
|
|
21
|
+
/** Number fields whose smallest and largest values across the matches useRange returns as `min`
|
|
22
|
+
* and `max`, such as a price slider's bounds. */
|
|
23
|
+
facetStats?: string[];
|
|
21
24
|
/** Filters always applied, such as `{ published: true }`. They aren't shown as refinements. */
|
|
22
25
|
filters?: Record<string, unknown>;
|
|
23
26
|
/** Hits per page: 1–50 (default 20). */
|
|
@@ -30,7 +33,7 @@ export type SearchConfig = {
|
|
|
30
33
|
};
|
|
31
34
|
export declare const emptyState: SearchState;
|
|
32
35
|
/** The API's largest offset. */
|
|
33
|
-
export declare const maxOffset =
|
|
36
|
+
export declare const maxOffset = 5000;
|
|
34
37
|
/** The request behind a state. A facet with selections is counted without them
|
|
35
38
|
* (`disjunctiveFacets`), so its other values stay listed and can be added. */
|
|
36
39
|
export declare function planSearch(config: SearchConfig, state: SearchState): SearchRequest;
|
package/dist/react/state.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export const emptyState = { q: "", refinements: {}, filters: {}, page: 0 };
|
|
2
2
|
/** The API's largest offset. */
|
|
3
|
-
export const maxOffset =
|
|
3
|
+
export const maxOffset = 5000;
|
|
4
4
|
/** The request behind a state. A facet with selections is counted without them
|
|
5
5
|
* (`disjunctiveFacets`), so its other values stay listed and can be added. */
|
|
6
6
|
export function planSearch(config, state) {
|
|
@@ -19,6 +19,7 @@ export function planSearch(config, state) {
|
|
|
19
19
|
...(Object.keys(filters).length ? { filters } : {}),
|
|
20
20
|
...(facets.length ? { facets } : {}),
|
|
21
21
|
...(disjunctive.length ? { disjunctiveFacets: disjunctive } : {}),
|
|
22
|
+
...(config.facetStats?.length ? { facetStats: config.facetStats } : {}),
|
|
22
23
|
limit: pageSize,
|
|
23
24
|
...(state.page > 0 ? { offset: Math.min(state.page * pageSize, maxOffset) } : {}),
|
|
24
25
|
...(config.fields ? { attributesToRetrieve: config.fields } : {}),
|
package/dist/react/store.js
CHANGED
|
@@ -116,7 +116,7 @@ export class SearchStore {
|
|
|
116
116
|
const { results, loadingMore, pending } = this.snapshot;
|
|
117
117
|
if (!results?.hasMore || loadingMore || pending)
|
|
118
118
|
return;
|
|
119
|
-
const { facets: _, disjunctiveFacets: __, facetMode: ___, ...request } = results.request;
|
|
119
|
+
const { facets: _, disjunctiveFacets: __, facetMode: ___, facetStats: ____, ...request } = results.request;
|
|
120
120
|
const offset = (request.offset ?? 0) + results.hits.length;
|
|
121
121
|
const run = this.run;
|
|
122
122
|
this.set({ loadingMore: true });
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@findlane/browser",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.1",
|
|
4
4
|
"description": "Findlane browser SDK: fast, typo-tolerant public search from the browser with an index's public ID, plus React hooks and components.",
|
|
5
5
|
"keywords": ["findlane", "search", "full-text search", "typo tolerance", "instant search", "ecommerce search", "browser", "react", "autocomplete"],
|
|
6
6
|
"license": "MIT",
|