@stapel/search-react 0.11.0 → 0.12.0
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/CHANGELOG.md +120 -0
- package/MODULE.md +111 -0
- package/README.md +42 -0
- package/dist/api/generated/schema.d.ts +60 -6
- package/dist/api/generated/schema.d.ts.map +1 -1
- package/dist/api/searchApi.d.ts +13 -6
- package/dist/api/searchApi.d.ts.map +1 -1
- package/dist/api/searchApi.js.map +1 -1
- package/dist/api/types.d.ts +107 -1
- package/dist/api/types.d.ts.map +1 -1
- package/dist/api/types.js +29 -0
- package/dist/api/types.js.map +1 -1
- package/dist/default/FacetPanelPane.d.ts +13 -2
- package/dist/default/FacetPanelPane.d.ts.map +1 -1
- package/dist/default/FacetPanelPane.js +3 -1
- package/dist/default/FacetPanelPane.js.map +1 -1
- package/dist/default/FilterChips.d.ts +88 -3
- package/dist/default/FilterChips.d.ts.map +1 -1
- package/dist/default/FilterChips.js +161 -13
- package/dist/default/FilterChips.js.map +1 -1
- package/dist/default/LocationSummaryLine.d.ts.map +1 -1
- package/dist/default/LocationSummaryLine.js +1 -1
- package/dist/default/LocationSummaryLine.js.map +1 -1
- package/dist/default/SearchBox.d.ts.map +1 -1
- package/dist/default/SearchBox.js +74 -4
- package/dist/default/SearchBox.js.map +1 -1
- package/dist/default/SearchPage.d.ts +29 -1
- package/dist/default/SearchPage.d.ts.map +1 -1
- package/dist/default/SearchPage.js +25 -10
- package/dist/default/SearchPage.js.map +1 -1
- package/dist/default/SearchResultsPane.d.ts +22 -0
- package/dist/default/SearchResultsPane.d.ts.map +1 -1
- package/dist/default/SearchResultsPane.js +2 -2
- package/dist/default/SearchResultsPane.js.map +1 -1
- package/dist/default/SortSelect.d.ts +23 -0
- package/dist/default/SortSelect.d.ts.map +1 -1
- package/dist/default/SortSelect.js +29 -9
- package/dist/default/SortSelect.js.map +1 -1
- package/dist/default/index.d.ts +2 -2
- package/dist/default/index.d.ts.map +1 -1
- package/dist/default/index.js +1 -1
- package/dist/default/index.js.map +1 -1
- package/dist/headless/FacetPanel.d.ts +10 -0
- package/dist/headless/FacetPanel.d.ts.map +1 -1
- package/dist/headless/FacetPanel.js +9 -1
- package/dist/headless/FacetPanel.js.map +1 -1
- package/dist/headless/useFacetLabels.d.ts +39 -0
- package/dist/headless/useFacetLabels.d.ts.map +1 -0
- package/dist/headless/useFacetLabels.js +129 -0
- package/dist/headless/useFacetLabels.js.map +1 -0
- package/dist/headless/useSearchBox.d.ts +71 -0
- package/dist/headless/useSearchBox.d.ts.map +1 -1
- package/dist/headless/useSearchBox.js +67 -2
- package/dist/headless/useSearchBox.js.map +1 -1
- package/dist/i18n/es.d.ts.map +1 -1
- package/dist/i18n/es.js +7 -0
- package/dist/i18n/es.js.map +1 -1
- package/dist/i18n/keys.d.ts +45 -0
- package/dist/i18n/keys.d.ts.map +1 -1
- package/dist/i18n/keys.js +54 -0
- package/dist/i18n/keys.js.map +1 -1
- package/dist/i18n/ru.d.ts.map +1 -1
- package/dist/i18n/ru.js +9 -0
- package/dist/i18n/ru.js.map +1 -1
- package/dist/index.d.ts +6 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -3
- package/dist/index.js.map +1 -1
- package/dist/model/queries.d.ts +6 -5
- package/dist/model/queries.d.ts.map +1 -1
- package/dist/model/queries.js +4 -3
- package/dist/model/queries.js.map +1 -1
- package/dist/model/queryKeys.d.ts +12 -0
- package/dist/model/queryKeys.d.ts.map +1 -1
- package/dist/model/queryKeys.js +7 -0
- package/dist/model/queryKeys.js.map +1 -1
- package/dist/nav/manifest.d.ts +21 -0
- package/dist/nav/manifest.d.ts.map +1 -1
- package/dist/nav/manifest.js +3 -2
- package/dist/nav/manifest.js.map +1 -1
- package/dist/state/facets.d.ts +56 -15
- package/dist/state/facets.d.ts.map +1 -1
- package/dist/state/facets.js +101 -27
- package/dist/state/facets.js.map +1 -1
- package/llms.txt +2 -2
- package/manifest.json +22 -2
- package/nav-manifest.json +4 -3
- package/package.json +11 -11
- package/src/analytics/generated/events.json +1 -1
- package/src/api/generated/schema.ts +60 -6
- package/src/api/searchApi.ts +13 -6
- package/src/api/types.ts +115 -1
- package/src/default/FacetPanelPane.tsx +16 -2
- package/src/default/FilterChips.tsx +285 -38
- package/src/default/LocationSummaryLine.tsx +6 -1
- package/src/default/SearchBox.tsx +134 -6
- package/src/default/SearchPage.tsx +79 -5
- package/src/default/SearchResultsPane.tsx +48 -11
- package/src/default/SortSelect.tsx +70 -9
- package/src/default/index.ts +10 -2
- package/src/headless/FacetPanel.tsx +20 -1
- package/src/headless/useFacetLabels.ts +172 -0
- package/src/headless/useSearchBox.ts +132 -5
- package/src/i18n/es.ts +8 -0
- package/src/i18n/keys.ts +56 -0
- package/src/i18n/ru.ts +10 -0
- package/src/index.ts +21 -3
- package/src/model/queries.ts +6 -5
- package/src/model/queryKeys.ts +23 -0
- package/src/nav/manifest.ts +24 -2
- package/src/state/facets.ts +123 -39
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,125 @@
|
|
|
1
1
|
# @stapel/search-react
|
|
2
2
|
|
|
3
|
+
## 0.12.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 8d1e20f: The phone dock stops truncating its labels, stops covering the footer, and the
|
|
8
|
+
phone SERP gets a one-line toolbar instead of four stacked rows.
|
|
9
|
+
|
|
10
|
+
**A compact label for a compact chrome.** `NavEntry.shortLabelKey` (core) is an
|
|
11
|
+
optional second i18n key a manifest declares when its menu label cannot fit a
|
|
12
|
+
dock cell. A five-item dock at 390px gives each destination about ten
|
|
13
|
+
characters, and a label written for a menu row ellipsizes mid-word — a
|
|
14
|
+
destination a person has to guess at, which is the one thing a dock must not
|
|
15
|
+
produce. A key and not a length hint, because which words survive the cut is a
|
|
16
|
+
translator's judgement: the useful short form of "Post a listing" is the verb,
|
|
17
|
+
of "My listings" the noun, and no truncation rule finds either. `resolveNav`
|
|
18
|
+
carries it through, `<NavDock>` prints it and keeps the LONG label as the
|
|
19
|
+
link's accessible name; `listings-react` declares one for `compose` and `mine`.
|
|
20
|
+
The dock also drops its inter-cell gap and one inset step — 24px given back to
|
|
21
|
+
five labels — and `scripts/gen-nav-manifest.mjs` validates the new field.
|
|
22
|
+
|
|
23
|
+
**The clearance belongs to the page, not the content.** The island is fixed
|
|
24
|
+
over the last thing on the page, and the last thing is the footer. Reserving
|
|
25
|
+
`DOCK_CLEARANCE` on `<Layout.Content>` cleared the final card and left the
|
|
26
|
+
footer's legal links permanently under the island. `<PublicShell>` reserves it
|
|
27
|
+
on the page column instead, and only when `dockRenders(nav)` says an island
|
|
28
|
+
will actually be drawn — a one-entry nav used to get a strip of empty page
|
|
29
|
+
under a dock nobody rendered.
|
|
30
|
+
|
|
31
|
+
**A phone toolbar that is one row.** `<SearchResultsPane header="compact">`
|
|
32
|
+
gives the toolbar its own line and puts the count directly above the cards as
|
|
33
|
+
their caption, with the heading visually hidden but still in the document
|
|
34
|
+
outline; the banner shape (heading | count + toolbar) is unchanged and
|
|
35
|
+
remains the default. `<SortSelect compact>` drops the caption and the 200px
|
|
36
|
+
floor so the control shares a row, and moves the blocked `distance` option's
|
|
37
|
+
REASON into the option's own label — on a phone, where that refusal is most
|
|
38
|
+
common, a separate reason row costs a band of viewport above the first result.
|
|
39
|
+
`<FilterChips>` takes `geoChip={false}` for a surface that already states the
|
|
40
|
+
location above it (the phone SERP mounts `<LocationSummaryLine>`, and the two
|
|
41
|
+
together asked about one filter twice), and renders NOTHING when it would be a
|
|
42
|
+
row of one button — a free-text query has no category, so the server returns no
|
|
43
|
+
facet plan, and the row was a lone circle floating between two working filter
|
|
44
|
+
affordances. `<LocationSummaryLine>` says "Filters", not "All filters": that
|
|
45
|
+
end of the row shares 390px with a place name.
|
|
46
|
+
|
|
47
|
+
**Tiles say which category they are.** `<CategoryTileGrid>` draws the
|
|
48
|
+
category's own initial where art is missing, instead of a muted disc. A live
|
|
49
|
+
catalogue put nine identical grey discs on one landing — every category there
|
|
50
|
+
carries an empty `carousel_icon`, which is the state every catalogue is in
|
|
51
|
+
until somebody uploads art — and a grid of them reads as nine images still
|
|
52
|
+
loading. A letter cannot be mistaken for a pending image, and every tile
|
|
53
|
+
differs from every other.
|
|
54
|
+
|
|
55
|
+
**`visuallyHidden`** (tokens-antd `/skin`) is the fleet's one off-screen-but-
|
|
56
|
+
announced style. It was written twice before, in `calendar-react` and
|
|
57
|
+
`search-react`, and the two disagreed on `clip-path` versus the deprecated
|
|
58
|
+
`clip`; both now import it.
|
|
59
|
+
|
|
60
|
+
- aa79a97: The result list gets a chip row a person can use, chips that print copy, a
|
|
61
|
+
category narrowing, and a search box that can reach a category.
|
|
62
|
+
|
|
63
|
+
**A facet a person cannot filter by is not a chip.** `FACETABLE_FEATURE_TYPES`
|
|
64
|
+
/ `isFacetableFeature` decide from the category's own schema — the select
|
|
65
|
+
family, `bool`, and `attributes-react`'s own `VOCABULARY_BACKED_TYPES`,
|
|
66
|
+
imported rather than retyped. `imei` and `video_file_url` leave both the chip
|
|
67
|
+
row and the panel. Two edges are held on purpose: a group with NO feature def
|
|
68
|
+
is KEPT (the schema slot is optional, and treating silence as "not facetable"
|
|
69
|
+
would empty the row for every host that never threaded it), and a slug the URL
|
|
70
|
+
already filters on is kept whatever its type, or a shared link would narrow a
|
|
71
|
+
search with nothing on screen to widen it again.
|
|
72
|
+
|
|
73
|
+
**The row's leading edge is the filters people use.** `orderChipFilters` sorts
|
|
74
|
+
applied-first, then by band: core ranges (`facet_meta.core_ranges`), then
|
|
75
|
+
counted facet groups, then the category's numeric attributes. A live
|
|
76
|
+
classified deployment led with battery health and four delivery dimensions;
|
|
77
|
+
it now leads with category, price, condition and brand. Nothing is deleted —
|
|
78
|
+
`facet_meta.skipped` means the counter hit its field cap, not that the axis
|
|
79
|
+
is unfilterable, and `r.<slug>` still answers for a skipped slug, so removing
|
|
80
|
+
one on that signal would delete a working filter on a capacity report.
|
|
81
|
+
|
|
82
|
+
**A chip prints copy, not a storage slug.** Precedence, now answer-first:
|
|
83
|
+
`facet_labels` (the server saw the write-time snapshot) → the def's inline
|
|
84
|
+
`options` → the host's `resolveFacetLabels` → the raw value. The host seam is
|
|
85
|
+
batched per group through `useQueries`, cached, deduplicated across the three
|
|
86
|
+
components that read the panel, and given the query's own `AbortSignal`; it is
|
|
87
|
+
asked only about values nothing else named and cannot overwrite one that was.
|
|
88
|
+
A value nothing resolves keeps printing itself — a chip that silently drops an
|
|
89
|
+
option is worse than one showing a slug.
|
|
90
|
+
|
|
91
|
+
**A category narrowing on the row.** `renderCategoryFilter` and the new
|
|
92
|
+
`categoryLabel` reach `<FilterChips>` as the LEADING chip, opening the same
|
|
93
|
+
sheet every other chip does. There is no category facet on any server and the
|
|
94
|
+
index has no read path for one, so nothing here synthesizes counts. `hasChips`
|
|
95
|
+
now renders a row holding only the category chip and still renders nothing for
|
|
96
|
+
a row holding only the sliders circle.
|
|
97
|
+
|
|
98
|
+
**The search box offers CATEGORIES.** stapel-search 0.7.0's `/suggest` answers
|
|
99
|
+
a destination per row — the full ancestor path, the live count behind it, and
|
|
100
|
+
a `category` string to pass verbatim to `/query`. `useSearchBox` surfaces
|
|
101
|
+
`categories`, `categoriesUnavailable`, `categoryCountsUnknown` and
|
|
102
|
+
`chooseCategory`, and `<SearchBox>` draws them as a labelled group above the
|
|
103
|
+
term suggestions, each row printing the whole trail (which is what tells three
|
|
104
|
+
same-named leaves apart) and its counted sentence. Choosing one clears the
|
|
105
|
+
query text: keeping it would land the person on that section intersected with
|
|
106
|
+
a title search for the word that found it, which is fewer results than the
|
|
107
|
+
number they just tapped. A zero-count row is dropped — an empty section is a
|
|
108
|
+
dead end dressed as a destination — except under `category_rollup`, where the
|
|
109
|
+
zeroes mean the ancestry never arrived and it is the NUMBERS that are omitted.
|
|
110
|
+
`SuggestAnswer` deliberately widens the generated response type, whose fields
|
|
111
|
+
are all required: a pair typed against it would compile while reading
|
|
112
|
+
`undefined` from a field the compiler swore was there. An older server that
|
|
113
|
+
sends no `categories` key, and one that reports `category_suggestions` in
|
|
114
|
+
`degraded`, both draw no group at all — never an empty one, and nothing
|
|
115
|
+
anywhere says the catalogue has no matches.
|
|
116
|
+
|
|
117
|
+
**Nav labels.** `search.results` stopped borrowing `search.results.title` from
|
|
118
|
+
the results heading: one key was carrying the name of a DESTINATION and the
|
|
119
|
+
name of a LIST, and they diverge the moment the destination is a tab.
|
|
120
|
+
`search.nav.results` / `search.nav.ranking` are the nav's own, and the
|
|
121
|
+
disclosure entry declares a `shortLabelKey` for a phone dock.
|
|
122
|
+
|
|
3
123
|
## 0.11.0
|
|
4
124
|
|
|
5
125
|
### Minor Changes
|
package/MODULE.md
CHANGED
|
@@ -126,6 +126,117 @@ carries facet values as index TERMS (strings), so `facetOptionLabel` coerces
|
|
|
126
126
|
back into the shape each type's formatter expects: `select` is a list even for
|
|
127
127
|
one value, `date` is a Unix timestamp integer, `int`/`float` are numbers.
|
|
128
128
|
|
|
129
|
+
## The search box reaches the catalogue
|
|
130
|
+
|
|
131
|
+
Until stapel-search 0.7.0 `/suggest` answered title prefixes only, so typing a
|
|
132
|
+
word that names a SECTION answered listing titles and nothing else — the search
|
|
133
|
+
field could not reach a category at all. 0.7.0 makes the answer two-part and
|
|
134
|
+
`categories` is the primary half:
|
|
135
|
+
|
|
136
|
+
| field | what it is |
|
|
137
|
+
|---|---|
|
|
138
|
+
| `path` | display names root→leaf — the only thing telling three same-named leaves apart |
|
|
139
|
+
| `category` | the ancestry as ids joined with `/`, to pass VERBATIM as the `category` parameter |
|
|
140
|
+
| `count` | live listings under it, descendants included — the number the SERP reports |
|
|
141
|
+
| `id` / `slug` / `name` / `depth` / `match` | identity, and how the name matched (informational; ranking is by `count`) |
|
|
142
|
+
|
|
143
|
+
`useSearchBox` surfaces them as `categories`, and `<SearchBox>` draws them as
|
|
144
|
+
their own labelled group ABOVE the terms, each row printing the path and the
|
|
145
|
+
count (a plural family — Russian needs four endings). Selecting one calls
|
|
146
|
+
`chooseCategory`, which writes `{ q: "", category: entry.category }` in ONE
|
|
147
|
+
patch: the server's own joined string, never a path the client reassembled, and
|
|
148
|
+
the text goes with it because the row quoted the section's count and the
|
|
149
|
+
destination has to show that count rather than the section intersected with a
|
|
150
|
+
title search.
|
|
151
|
+
|
|
152
|
+
Three honesty rules ride along:
|
|
153
|
+
|
|
154
|
+
- **absent key ⇒ today's behaviour.** Every member of `SuggestAnswer` but
|
|
155
|
+
`backend` is optional. The generated `SuggestResponse` declares 0.7.0's five
|
|
156
|
+
new fields required, which is true of one server and false of the others a
|
|
157
|
+
storefront is deployed against.
|
|
158
|
+
- **`degraded: ["category_suggestions"]` ⇒ no group at all.** An empty group
|
|
159
|
+
under a heading is the box claiming the catalogue has no such section — a
|
|
160
|
+
claim the answer never made. Not a banner either: the reader is mid-word and
|
|
161
|
+
a missing provider is the operator's business.
|
|
162
|
+
- **`degraded: ["category_rollup"]` ⇒ rows without numbers.** Every count reads
|
|
163
|
+
`0` because the ancestry never arrived, so the counts are dropped and the
|
|
164
|
+
destinations kept. Outside that case a `count: 0` row is filtered out: the
|
|
165
|
+
server really does return empty sections, and following one is a dead end
|
|
166
|
+
dressed as a destination.
|
|
167
|
+
|
|
168
|
+
## Which counted slugs are filters, and who names their values
|
|
169
|
+
|
|
170
|
+
The facet plan is derived from the leaf category's feature defs and the counter
|
|
171
|
+
counts what is indexed, so a real classified answer carries `imei` and
|
|
172
|
+
`video_file_url` beside `condition` and `vendor`. Neither is a filter: an
|
|
173
|
+
identifier is unique per document and a URL is free text, and a chip offering
|
|
174
|
+
one IMEI with a count of one crowds a 390px row.
|
|
175
|
+
|
|
176
|
+
`FACETABLE_FEATURE_TYPES` is the verdict, read by value TYPE from the same
|
|
177
|
+
`categoryFeatures` schema everything else here reads — the select family, the
|
|
178
|
+
vocabulary-backed family (`VOCABULARY_BACKED_TYPES`, imported rather than
|
|
179
|
+
retyped) and `bool`. Two rules keep it honest:
|
|
180
|
+
|
|
181
|
+
- a slug with **no feature def** is KEPT. `categoryFeatures` is optional, a
|
|
182
|
+
feature can be retired after the write that indexed it, and answering "not
|
|
183
|
+
facetable" for silence would empty the row for every host that never threaded
|
|
184
|
+
the schema through;
|
|
185
|
+
- a slug the **URL already filters on** is KEPT whatever the schema now says,
|
|
186
|
+
or a link narrows the search with nothing on screen to widen it.
|
|
187
|
+
|
|
188
|
+
Captions have four sources, in this order, and none of them invents one:
|
|
189
|
+
|
|
190
|
+
1. the answer's `facet_labels` (stapel-search 0.4.0+) — the server saw the
|
|
191
|
+
write-time snapshot;
|
|
192
|
+
2. the feature def's inline `options` table;
|
|
193
|
+
3. **`resolveFacetLabels`** — a host seam, `(slug, feature, values[]) →
|
|
194
|
+
Promise<{value: caption}>`, batched per group, cached, given the query's own
|
|
195
|
+
`AbortSignal`. It exists because a `ref_select` config carries a POINTER to a
|
|
196
|
+
vocabulary (`optionsRef`) and no options, and reading that vocabulary is the
|
|
197
|
+
host's business, not a search package's;
|
|
198
|
+
4. the raw value — a value nobody names keeps printing itself rather than
|
|
199
|
+
disappearing, because a chip that silently drops an option is worse than one
|
|
200
|
+
showing a slug.
|
|
201
|
+
|
|
202
|
+
Set on `<SearchPage>`, it reaches both filter surfaces: the desktop panel and
|
|
203
|
+
the phone chip row read one `useFacetPanel`, so they cannot print two words for
|
|
204
|
+
one value.
|
|
205
|
+
|
|
206
|
+
## The chip row's order is the row's product
|
|
207
|
+
|
|
208
|
+
At 390px about four chips fit before the fold. On a live phone category the
|
|
209
|
+
first seven were battery health, four parcel dimensions and two wholesale
|
|
210
|
+
counts — numeric attributes the category happens to declare, drawn ahead of the
|
|
211
|
+
price, the condition and the vendor.
|
|
212
|
+
|
|
213
|
+
That is an ordering defect and it is fixed as one. Nothing in a feature def
|
|
214
|
+
separates `akb` from `weight_for_delivery`, and the next category's `int`
|
|
215
|
+
attribute is `mileage`, so `orderChipFilters` re-ranks and deletes nothing:
|
|
216
|
+
|
|
217
|
+
1. the category chip, then the location chip — the two host-slot filters;
|
|
218
|
+
2. everything APPLIED, in band order — a constraint you set must be reachable
|
|
219
|
+
without a flick;
|
|
220
|
+
3. then, unapplied: **core range axes** (`facet_meta.core_ranges`, the server
|
|
221
|
+
declaring an axis that exists for every document), **counted facet groups**
|
|
222
|
+
(the server counted them for this search and each carries its remaining
|
|
223
|
+
counts), then **the category's numeric attributes**, which nothing ranks.
|
|
224
|
+
|
|
225
|
+
The sort is stable, so an authored option order survives to the row. Deleting
|
|
226
|
+
band 3 was considered and rejected: the only server signal that names a slug is
|
|
227
|
+
`facet_meta.skipped`, and that means the counter hit `MAX_FACET_FIELDS` — not
|
|
228
|
+
that a person cannot filter by it. `r.<slug>` still answers for a skipped slug.
|
|
229
|
+
|
|
230
|
+
## The chip row's leading chip is the category
|
|
231
|
+
|
|
232
|
+
There is no category facet on the server and no read path for one, so nothing
|
|
233
|
+
here synthesizes counts. What the SERP offers instead is a narrowing: the host's
|
|
234
|
+
`renderCategoryFilter` — the same slot the panel takes — becomes the FIRST chip
|
|
235
|
+
of the phone row, opening in the same sheet as every other chip, labelled with
|
|
236
|
+
`categoryLabel` (or the path's last segment) when the search is narrowed and
|
|
237
|
+
with the filter's own name when it is not. A host that fills no such slot gets
|
|
238
|
+
the row exactly as it was.
|
|
239
|
+
|
|
129
240
|
## Honesty flags are not decoration
|
|
130
241
|
|
|
131
242
|
Four independent signals, all surfaced:
|
package/README.md
CHANGED
|
@@ -83,6 +83,20 @@ two members, shaped exactly like react-router's `useSearchParams()`. `./router`
|
|
|
83
83
|
ships that binding; a Next.js app, a hash router or a plain `URLSearchParams` in
|
|
84
84
|
a test satisfy the same seam.
|
|
85
85
|
|
|
86
|
+
## The search box reaches the catalogue, not only the titles
|
|
87
|
+
|
|
88
|
+
`GET /suggest` (stapel-search 0.7.0) answers CATEGORIES as well as title
|
|
89
|
+
prefixes, so typing a section's name offers the section. `<SearchBox>` draws
|
|
90
|
+
them as their own group above the terms — each row the ancestor path plus its
|
|
91
|
+
live listing count, which is the only way to tell three same-named leaves
|
|
92
|
+
apart — and selecting one narrows the SERP using the server's own `category`
|
|
93
|
+
string, verbatim.
|
|
94
|
+
|
|
95
|
+
An older server sends no `categories` key and the box behaves exactly as it
|
|
96
|
+
did. When the answer says `degraded: ["category_suggestions"]` the group is
|
|
97
|
+
absent rather than empty: an empty group under a heading would claim the
|
|
98
|
+
catalogue has no such section.
|
|
99
|
+
|
|
86
100
|
## Facets are drill-down, and the panel says so
|
|
87
101
|
|
|
88
102
|
Each facet is counted over the candidates **with its own filter removed**
|
|
@@ -99,6 +113,34 @@ category's feature schema. Hand that schema in and the options read as words:
|
|
|
99
113
|
|
|
100
114
|
Without it, options read as raw index terms. Never as blanks.
|
|
101
115
|
|
|
116
|
+
That schema also decides **which counted slugs are filters at all**: a plan
|
|
117
|
+
derived from a category counts what is indexed, so a real answer carries `imei`
|
|
118
|
+
and `video_file_url` beside `condition` and `vendor`. Only the bounded option
|
|
119
|
+
types (`FACETABLE_FEATURE_TYPES`) get a chip. A slug with no feature def is
|
|
120
|
+
kept — silence is not a verdict — and so is any slug the URL already filters on,
|
|
121
|
+
so a link can always be widened again.
|
|
122
|
+
|
|
123
|
+
A `ref_select` facet carries a POINTER to a vocabulary and no options, and a
|
|
124
|
+
server older than stapel-search 0.4.0 sends no `facet_labels` to cover for it.
|
|
125
|
+
`resolveFacetLabels` is the host seam that names those values — batched per
|
|
126
|
+
group, cached, aborted on supersession:
|
|
127
|
+
|
|
128
|
+
```tsx
|
|
129
|
+
<SearchPage
|
|
130
|
+
categoryFeatures={features}
|
|
131
|
+
resolveFacetLabels={async ({ slug, feature, values }, { signal }) =>
|
|
132
|
+
await vocabulary.captions(feature, values, { signal })
|
|
133
|
+
}
|
|
134
|
+
renderCategoryFilter={(slot) => <CategoryPickerField {...slot} />}
|
|
135
|
+
categoryLabel={currentCategory?.name}
|
|
136
|
+
/>
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
Precedence is `facet_labels` → the schema's inline `options` → this resolver →
|
|
140
|
+
the raw value; a value nobody names keeps printing itself. `renderCategoryFilter`
|
|
141
|
+
also becomes the leading chip of the phone filter row, which is where the
|
|
142
|
+
catalogue's deeper levels are chosen on a result list.
|
|
143
|
+
|
|
102
144
|
## What the server admits, the screen repeats
|
|
103
145
|
|
|
104
146
|
| The envelope says | The page says |
|
|
@@ -99,13 +99,24 @@ export interface paths {
|
|
|
99
99
|
cookie?: never;
|
|
100
100
|
};
|
|
101
101
|
/**
|
|
102
|
-
*
|
|
103
|
-
* @description ``GET /search/api/v1/suggest`` —
|
|
102
|
+
* Type-ahead: category paths with live counts, plus title prefixes
|
|
103
|
+
* @description ``GET /search/api/v1/suggest`` — what to offer under the search box.
|
|
104
104
|
*
|
|
105
|
-
*
|
|
105
|
+
* ``categories`` is the primary half: each row is a destination with its
|
|
106
|
+
* full ancestor path and the number of listings a buyer would actually
|
|
107
|
+
* see there, ranked by that number. ``terms`` is the title-prefix half.
|
|
108
|
+
*
|
|
109
|
+
* Neither comes from a query log: no query log is kept, which is a privacy
|
|
106
110
|
* decision before it is a product one, and on day one there would be
|
|
107
111
|
* nothing in it anyway.
|
|
108
112
|
*
|
|
113
|
+
* The answer is public, identical for every reader and requested on every
|
|
114
|
+
* keystroke, so it carries ``Cache-Control: public`` and an ``ETag``. This
|
|
115
|
+
* is the module's first conditional read — ``query`` has none, because a
|
|
116
|
+
* SERP answer embeds ``took_ms`` and a cursor and would revalidate to a
|
|
117
|
+
* miss every time. Here the payload is deliberately free of anything that
|
|
118
|
+
* varies with the clock.
|
|
119
|
+
*
|
|
109
120
|
* **Permissions:** `AllowAny`
|
|
110
121
|
*/
|
|
111
122
|
get: operations["search_api_v1_suggest_retrieve"];
|
|
@@ -121,6 +132,30 @@ export interface paths {
|
|
|
121
132
|
export type webhooks = Record<string, never>;
|
|
122
133
|
export interface components {
|
|
123
134
|
schemas: {
|
|
135
|
+
/** @description One destination in the dropdown, ready to render and ready to follow. */
|
|
136
|
+
CategorySuggestion: {
|
|
137
|
+
/** @description Category id. */
|
|
138
|
+
id: number;
|
|
139
|
+
/** @description Category slug. */
|
|
140
|
+
slug: string;
|
|
141
|
+
/** @description The category's own display name. */
|
|
142
|
+
name: string;
|
|
143
|
+
/** @description Display names root->leaf, e.g. ['Мужская одежда', 'Шорты']. This is what distinguishes three categories that share a name. */
|
|
144
|
+
path: string[];
|
|
145
|
+
/** @description The ancestry as ids joined with '/'. Pass it verbatim as the `category` parameter of /query — do not re-join path segments yourself. */
|
|
146
|
+
category: string;
|
|
147
|
+
/** @description Live listings a buyer would see under this category, descendants included — the same number the SERP reports for it. */
|
|
148
|
+
count: number;
|
|
149
|
+
/** @description Number of segments in `path`. */
|
|
150
|
+
depth: number;
|
|
151
|
+
/**
|
|
152
|
+
* @description How the name matched. Informational; ranking is by `count`.
|
|
153
|
+
*
|
|
154
|
+
* * `prefix` - prefix
|
|
155
|
+
* * `substring` - substring
|
|
156
|
+
*/
|
|
157
|
+
match: components["schemas"]["MatchEnum"];
|
|
158
|
+
};
|
|
124
159
|
/** @description Captions for one slug's option codes. */
|
|
125
160
|
FacetLabels: {
|
|
126
161
|
/** @description True when `values` holds translation KEYS to run through the catalogue; false when it holds literal captions. The reader cannot tell by looking — `b.apple` and `Б/у` are both strings. */
|
|
@@ -152,6 +187,12 @@ export interface components {
|
|
|
152
187
|
lag_seconds?: number | null;
|
|
153
188
|
stale_reason?: string;
|
|
154
189
|
};
|
|
190
|
+
/**
|
|
191
|
+
* @description * `prefix` - prefix
|
|
192
|
+
* * `substring` - substring
|
|
193
|
+
* @enum {string}
|
|
194
|
+
*/
|
|
195
|
+
MatchEnum: "prefix" | "substring";
|
|
155
196
|
/** @description The P2B Art. 5 disclosure, generated from the scorer registry. */
|
|
156
197
|
RankingResponse: {
|
|
157
198
|
doc_type: string;
|
|
@@ -239,7 +280,16 @@ export interface components {
|
|
|
239
280
|
took_ms: number;
|
|
240
281
|
};
|
|
241
282
|
SuggestResponse: {
|
|
283
|
+
/** @description Destinations, ranked by live listing count desc, then depth, then name. */
|
|
284
|
+
categories: components["schemas"]["CategorySuggestion"][];
|
|
285
|
+
/** @description Title prefixes from the index. */
|
|
286
|
+
terms: string[];
|
|
287
|
+
/** @description Deprecated alias of `terms`, kept for one minor. */
|
|
242
288
|
items: string[];
|
|
289
|
+
/** @description Which dictionary answered — the same resolution /query reports. */
|
|
290
|
+
language: string;
|
|
291
|
+
/** @description What this answer could not do: `category_suggestions` (no provider for category names), `category_rollup` (no ancestry, so counts would read 0). */
|
|
292
|
+
degraded: string[];
|
|
243
293
|
backend: string;
|
|
244
294
|
};
|
|
245
295
|
};
|
|
@@ -369,11 +419,15 @@ export interface operations {
|
|
|
369
419
|
};
|
|
370
420
|
search_api_v1_suggest_retrieve: {
|
|
371
421
|
parameters: {
|
|
372
|
-
query
|
|
422
|
+
query?: {
|
|
423
|
+
/** @description Language of the query: picks the dictionary, so «shorty» reaches «шорты». Falls back to Accept-Language, then DEFAULT_LANGUAGE. */
|
|
424
|
+
lang?: string;
|
|
425
|
+
/** @description Rows per half. Capped by MAX_SUGGEST_LIMIT. */
|
|
373
426
|
limit?: number;
|
|
374
|
-
/** @description
|
|
427
|
+
/** @description What the buyer has typed so far. */
|
|
375
428
|
q?: string;
|
|
376
|
-
type
|
|
429
|
+
/** @description Registered doc_type. Optional when exactly one type is registered — a type-ahead should not have to name the only corpus there is. */
|
|
430
|
+
type?: string;
|
|
377
431
|
};
|
|
378
432
|
header?: never;
|
|
379
433
|
path?: never;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../../src/api/generated/schema.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,KAAK;IAClB,uBAAuB,EAAE;QACrB,UAAU,EAAE;YACR,KAAK,CAAC,EAAE,KAAK,CAAC;YACd,MAAM,CAAC,EAAE,KAAK,CAAC;YACf,IAAI,CAAC,EAAE,KAAK,CAAC;YACb,MAAM,CAAC,EAAE,KAAK,CAAC;SAClB,CAAC;QACF;;;;;WAKG;QACH,GAAG,EAAE,UAAU,CAAC,+BAA+B,CAAC,CAAC;QACjD,GAAG,CAAC,EAAE,KAAK,CAAC;QACZ,IAAI,CAAC,EAAE,KAAK,CAAC;QACb,MAAM,CAAC,EAAE,KAAK,CAAC;QACf,OAAO,CAAC,EAAE,KAAK,CAAC;QAChB,IAAI,CAAC,EAAE,KAAK,CAAC;QACb,KAAK,CAAC,EAAE,KAAK,CAAC;QACd,KAAK,CAAC,EAAE,KAAK,CAAC;KACjB,CAAC;IACF,sBAAsB,EAAE;QACpB,UAAU,EAAE;YACR,KAAK,CAAC,EAAE,KAAK,CAAC;YACd,MAAM,CAAC,EAAE,KAAK,CAAC;YACf,IAAI,CAAC,EAAE,KAAK,CAAC;YACb,MAAM,CAAC,EAAE,KAAK,CAAC;SAClB,CAAC;QACF;;;;;WAKG;QACH,GAAG,EAAE,UAAU,CAAC,8BAA8B,CAAC,CAAC;QAChD,GAAG,CAAC,EAAE,KAAK,CAAC;QACZ,IAAI,CAAC,EAAE,KAAK,CAAC;QACb,MAAM,CAAC,EAAE,KAAK,CAAC;QACf,OAAO,CAAC,EAAE,KAAK,CAAC;QAChB,IAAI,CAAC,EAAE,KAAK,CAAC;QACb,KAAK,CAAC,EAAE,KAAK,CAAC;QACd,KAAK,CAAC,EAAE,KAAK,CAAC;KACjB,CAAC;IACF,wBAAwB,EAAE;QACtB,UAAU,EAAE;YACR,KAAK,CAAC,EAAE,KAAK,CAAC;YACd,MAAM,CAAC,EAAE,KAAK,CAAC;YACf,IAAI,CAAC,EAAE,KAAK,CAAC;YACb,MAAM,CAAC,EAAE,KAAK,CAAC;SAClB,CAAC;QACF;;;;;;;;;WASG;QACH,GAAG,EAAE,UAAU,CAAC,gCAAgC,CAAC,CAAC;QAClD,GAAG,CAAC,EAAE,KAAK,CAAC;QACZ,IAAI,CAAC,EAAE,KAAK,CAAC;QACb,MAAM,CAAC,EAAE,KAAK,CAAC;QACf,OAAO,CAAC,EAAE,KAAK,CAAC;QAChB,IAAI,CAAC,EAAE,KAAK,CAAC;QACb,KAAK,CAAC,EAAE,KAAK,CAAC;QACd,KAAK,CAAC,EAAE,KAAK,CAAC;KACjB,CAAC;IACF,wBAAwB,EAAE;QACtB,UAAU,EAAE;YACR,KAAK,CAAC,EAAE,KAAK,CAAC;YACd,MAAM,CAAC,EAAE,KAAK,CAAC;YACf,IAAI,CAAC,EAAE,KAAK,CAAC;YACb,MAAM,CAAC,EAAE,KAAK,CAAC;SAClB,CAAC;QACF,GAAG,CAAC,EAAE,KAAK,CAAC;QACZ,GAAG,CAAC,EAAE,KAAK,CAAC;QACZ;;;;;WAKG;QACH,IAAI,EAAE,UAAU,CAAC,8BAA8B,CAAC,CAAC;QACjD,MAAM,CAAC,EAAE,KAAK,CAAC;QACf,OAAO,CAAC,EAAE,KAAK,CAAC;QAChB,IAAI,CAAC,EAAE,KAAK,CAAC;QACb,KAAK,CAAC,EAAE,KAAK,CAAC;QACd,KAAK,CAAC,EAAE,KAAK,CAAC;KACjB,CAAC;IACF,wBAAwB,EAAE;QACtB,UAAU,EAAE;YACR,KAAK,CAAC,EAAE,KAAK,CAAC;YACd,MAAM,CAAC,EAAE,KAAK,CAAC;YACf,IAAI,CAAC,EAAE,KAAK,CAAC;YACb,MAAM,CAAC,EAAE,KAAK,CAAC;SAClB,CAAC;QACF
|
|
1
|
+
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../../src/api/generated/schema.ts"],"names":[],"mappings":"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"}
|
package/dist/api/searchApi.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { StapelClient } from "@stapel/core";
|
|
2
|
-
import type { RankingResponse, SearchQueryState, SearchResponse,
|
|
2
|
+
import type { RankingResponse, SearchQueryState, SearchResponse, SuggestAnswer, SuggestParams } from "./types.js";
|
|
3
3
|
/**
|
|
4
4
|
* The pair's typed operation surface — one method per stapel-search endpoint a
|
|
5
5
|
* storefront may call, bound to the injected {@link StapelClient} (the
|
|
@@ -43,14 +43,21 @@ export interface SearchApi {
|
|
|
43
43
|
readonly signal?: AbortSignal;
|
|
44
44
|
}): Promise<SearchResponse>;
|
|
45
45
|
/**
|
|
46
|
-
*
|
|
47
|
-
*
|
|
48
|
-
*
|
|
49
|
-
*
|
|
46
|
+
* What to offer under the search box: CATEGORIES first, then title-prefix
|
|
47
|
+
* terms (stapel-search 0.7.0).
|
|
48
|
+
*
|
|
49
|
+
* Neither half comes from a query log — the module keeps none, which is a
|
|
50
|
+
* privacy decision before it is a product one — so every suggestion is a
|
|
51
|
+
* destination or a search that has results.
|
|
52
|
+
*
|
|
53
|
+
* Typed as {@link SuggestAnswer} rather than as the generated
|
|
54
|
+
* `SuggestResponse`: a build regenerated against a pre-0.7.0 schema would
|
|
55
|
+
* otherwise hide the categories half from the compiler. See that type for
|
|
56
|
+
* why every member but `backend` is optional.
|
|
50
57
|
*/
|
|
51
58
|
suggest(params: SuggestParams, options?: {
|
|
52
59
|
readonly signal?: AbortSignal;
|
|
53
|
-
}): Promise<
|
|
60
|
+
}): Promise<SuggestAnswer>;
|
|
54
61
|
/**
|
|
55
62
|
* The P2B Art. 5 ranking disclosure for a doc type: which parameters rank
|
|
56
63
|
* results, their weights, and — per parameter — whether the configured
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"searchApi.d.ts","sourceRoot":"","sources":["../../src/api/searchApi.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,KAAK,EACV,eAAe,EACf,gBAAgB,EAChB,cAAc,EACd,aAAa,EACb,
|
|
1
|
+
{"version":3,"file":"searchApi.d.ts","sourceRoot":"","sources":["../../src/api/searchApi.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,KAAK,EACV,eAAe,EACf,gBAAgB,EAChB,cAAc,EACd,aAAa,EACb,aAAa,EACd,MAAM,YAAY,CAAC;AAEpB;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC;IAE9B;;;;;;;;;;;;OAYG;IACH,KAAK,CACH,KAAK,EAAE,gBAAgB,EACvB,OAAO,CAAC,EAAE;QAAE,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAA;KAAE,GAC1C,OAAO,CAAC,cAAc,CAAC,CAAC;IAE3B;;;;;;;;;;;;OAYG;IACH,OAAO,CACL,MAAM,EAAE,aAAa,EACrB,OAAO,CAAC,EAAE;QAAE,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAA;KAAE,GAC1C,OAAO,CAAC,aAAa,CAAC,CAAC;IAE1B;;;;;;OAMG;IACH,OAAO,CACL,IAAI,CAAC,EAAE,MAAM,EACb,OAAO,CAAC,EAAE;QAAE,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAA;KAAE,GAC1C,OAAO,CAAC,eAAe,CAAC,CAAC;CAC7B;AAED;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,gBAAgB,GACtB,MAAM,CACP,MAAM,EACN,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,GAAG,SAAS,CAAC,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,EAAE,CAC/E,CA+CA;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,YAAY,GAAG,SAAS,CA0B/D"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"searchApi.js","sourceRoot":"","sources":["../../src/api/searchApi.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"searchApi.js","sourceRoot":"","sources":["../../src/api/searchApi.ts"],"names":[],"mappings":"AAqFA;;;;;;;;;GASG;AACH,MAAM,UAAU,iBAAiB,CAC/B,KAAuB;IAKvB,MAAM,KAAK,GAOP,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC;IAEzB,IAAI,KAAK,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC;QAAE,KAAK,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC;IAC7C,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS;QAAE,KAAK,CAAC,MAAM,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC;IACzD,IAAI,KAAK,CAAC,QAAQ,KAAK,SAAS;QAAE,KAAK,CAAC,UAAU,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC;IACrE,IAAI,KAAK,CAAC,KAAK,KAAK,SAAS;QAAE,KAAK,CAAC,OAAO,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC;IAE5D,KAAK,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC;QAC3D,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC;YAAE,KAAK,CAAC,KAAK,IAAI,EAAE,CAAC,GAAG,MAAM,CAAC;IACrD,CAAC;IACD,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC;QACzD,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS,IAAI,KAAK,CAAC,EAAE,KAAK,SAAS;YAAE,SAAS;QACjE,KAAK,CAAC,KAAK,IAAI,EAAE,CAAC,GAAG,GAAG,KAAK,CAAC,IAAI,IAAI,EAAE,KAAK,KAAK,CAAC,EAAE,IAAI,EAAE,EAAE,CAAC;IAChE,CAAC;IAED,IAAI,KAAK,CAAC,GAAG,KAAK,SAAS,EAAE,CAAC;QAC5B,IAAI,KAAK,CAAC,GAAG,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;YAC9B,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,KAAK,CAAC,GAAG,CAAC;YACrD,KAAK,CAAC,MAAM,CAAC,GAAG,GAAG,MAAM,IAAI,MAAM,IAAI,MAAM,IAAI,MAAM,EAAE,CAAC;QAC5D,CAAC;aAAM,CAAC;YACN,KAAK,CAAC,KAAK,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC;YAC7B,KAAK,CAAC,KAAK,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC;YAC7B,IAAI,KAAK,CAAC,GAAG,CAAC,QAAQ,KAAK,SAAS,EAAE,CAAC;gBACrC,KAAK,CAAC,WAAW,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC;YAC1C,CAAC;QACH,CAAC;IACH,CAAC;IAED,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS;QAAE,KAAK,CAAC,MAAM,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC;IACzD,IAAI,KAAK,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;QAC/B,KAAK,CAAC,QAAQ,CAAC,GAAG,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC;YAC3C,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC;YACxB,CAAC,CAAE,KAAK,CAAC,MAAiB,CAAC;IAC/B,CAAC;IACD,IAAI,KAAK,CAAC,MAAM,KAAK,SAAS;QAAE,KAAK,CAAC,QAAQ,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC;IAC/D,IAAI,KAAK,CAAC,SAAS,KAAK,SAAS;QAAE,KAAK,CAAC,WAAW,CAAC,GAAG,KAAK,CAAC,SAAS,CAAC;IACxE,IAAI,KAAK,CAAC,KAAK,KAAK,SAAS;QAAE,KAAK,CAAC,OAAO,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC;IAE5D,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,MAAoB;IAClD,OAAO;QACL,MAAM;QAEN,KAAK,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE,CACxB,MAAM,CAAC,GAAG,CAAC,QAAQ,EAAE;YACnB,KAAK,EAAE,iBAAiB,CAAC,KAAK,CAAC;YAC/B,GAAG,CAAC,OAAO,EAAE,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACrE,CAAC;QAEJ,OAAO,EAAE,CAAC,MAAM,EAAE,OAAO,EAAE,EAAE,CAC3B,MAAM,CAAC,GAAG,CAAC,UAAU,EAAE;YACrB,KAAK,EAAE;gBACL,IAAI,EAAE,MAAM,CAAC,IAAI;gBACjB,GAAG,CAAC,MAAM,CAAC,CAAC,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBAClD,GAAG,CAAC,MAAM,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aAC/D;YACD,GAAG,CAAC,OAAO,EAAE,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACrE,CAAC;QAEJ,OAAO,EAAE,CAAC,IAAI,EAAE,OAAO,EAAE,EAAE,CACzB,MAAM,CAAC,GAAG,CAAC,UAAU,EAAE;YACrB,KAAK,EAAE,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE;YACzC,GAAG,CAAC,OAAO,EAAE,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACrE,CAAC;KACL,CAAC;AACJ,CAAC"}
|
package/dist/api/types.d.ts
CHANGED
|
@@ -20,8 +20,114 @@ export type SearchItem = Schemas["SearchItem"];
|
|
|
20
20
|
/** The honesty block beside the counts: `approximate`, `candidates`,
|
|
21
21
|
* `counted`, `skipped`. Rendered, never swallowed (spec §4.2). */
|
|
22
22
|
export type FacetMeta = Schemas["FacetMeta"];
|
|
23
|
-
/** `GET /suggest` 200. */
|
|
23
|
+
/** `GET /suggest` 200, as the CURRENT generated schema describes it. */
|
|
24
24
|
export type SuggestResponse = Schemas["SuggestResponse"];
|
|
25
|
+
/**
|
|
26
|
+
* How a category's name matched the typed prefix. Informational — the server
|
|
27
|
+
* ranks by `count`, never by this.
|
|
28
|
+
*/
|
|
29
|
+
export type SuggestCategoryMatch = "prefix" | "substring";
|
|
30
|
+
/**
|
|
31
|
+
* One CATEGORY the type-ahead offers: a destination, not a search term.
|
|
32
|
+
*
|
|
33
|
+
* A classified's search box is a navigation control before it is a text
|
|
34
|
+
* filter. "Shorts" is not one destination but three — men's, women's,
|
|
35
|
+
* children's — and the only things that let a buyer pick between them are the
|
|
36
|
+
* ancestor path and how many live listings sit behind each. Both are here,
|
|
37
|
+
* and neither can be computed on the client: the count is one aggregate over
|
|
38
|
+
* the index, and a client-side matcher over a fetched tree would have the
|
|
39
|
+
* names and no numbers.
|
|
40
|
+
*/
|
|
41
|
+
export interface SuggestCategory {
|
|
42
|
+
readonly id: number;
|
|
43
|
+
readonly slug: string;
|
|
44
|
+
/** The category's own display name. */
|
|
45
|
+
readonly name: string;
|
|
46
|
+
/**
|
|
47
|
+
* Display names root→leaf, e.g. `["Menswear", "Shorts"]` — this is what
|
|
48
|
+
* distinguishes three categories sharing a name, and it is what a row has
|
|
49
|
+
* to print.
|
|
50
|
+
*/
|
|
51
|
+
readonly path: readonly string[];
|
|
52
|
+
/**
|
|
53
|
+
* The ancestry as ids joined with `/`, ready to pass VERBATIM as the
|
|
54
|
+
* `category` parameter of `/query`.
|
|
55
|
+
*
|
|
56
|
+
* The server serves the joined string rather than only the segments
|
|
57
|
+
* precisely so that a client cannot invent a different join and silently
|
|
58
|
+
* miss — so nothing in this pair rebuilds it from {@link path} or
|
|
59
|
+
* {@link slug}.
|
|
60
|
+
*/
|
|
61
|
+
readonly category: string;
|
|
62
|
+
/**
|
|
63
|
+
* Live listings a buyer would see under this category, descendants
|
|
64
|
+
* included — the same number the SERP reports for it.
|
|
65
|
+
*/
|
|
66
|
+
readonly count: number;
|
|
67
|
+
/** Number of segments in {@link path}. */
|
|
68
|
+
readonly depth: number;
|
|
69
|
+
readonly match: SuggestCategoryMatch;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* The `/suggest` answer this pair actually reads.
|
|
73
|
+
*
|
|
74
|
+
* GENERATOR NOTE, and the reason this is not `Schemas["SuggestResponse"]`:
|
|
75
|
+
* the generated type describes ONE server. stapel-search 0.7.0 made the answer
|
|
76
|
+
* three-part — `categories`, `terms`, and `items` as a deprecated alias of
|
|
77
|
+
* `terms` — plus `language` and `degraded`, and declares all five REQUIRED,
|
|
78
|
+
* which is true of a 0.7.0 answer and false of every answer sent by the
|
|
79
|
+
* servers a storefront is also deployed against.
|
|
80
|
+
*
|
|
81
|
+
* Every member but `backend` is therefore OPTIONAL here, which is not
|
|
82
|
+
* sloppiness but the deployment story: a storefront ships against whichever
|
|
83
|
+
* server is actually running, an older one sends no `categories` key at all,
|
|
84
|
+
* and "the key is absent" has to read as "this server offers no destinations"
|
|
85
|
+
* rather than as a crash or as an empty group under a heading. A pair typed
|
|
86
|
+
* against the required-field version would compile while reading `undefined`
|
|
87
|
+
* from a field the compiler swore was there.
|
|
88
|
+
*/
|
|
89
|
+
export interface SuggestAnswer {
|
|
90
|
+
readonly backend: string;
|
|
91
|
+
/** Destinations, ranked by live listing count desc, then depth, then name. */
|
|
92
|
+
readonly categories?: readonly SuggestCategory[];
|
|
93
|
+
/** Title prefixes from the index. */
|
|
94
|
+
readonly terms?: readonly string[];
|
|
95
|
+
/** Deprecated alias of {@link terms}, and the only half a pre-0.7.0 server
|
|
96
|
+
* sends. Read through {@link suggestTerms}, never directly. */
|
|
97
|
+
readonly items?: readonly string[];
|
|
98
|
+
/** Which dictionary answered — the same resolution `/query` reports. */
|
|
99
|
+
readonly language?: string;
|
|
100
|
+
/** What this answer could not do — see {@link SUGGEST_DEGRADED_CATEGORIES}
|
|
101
|
+
* and {@link SUGGEST_DEGRADED_ROLLUP}. */
|
|
102
|
+
readonly degraded?: readonly string[];
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* The suggest answer had NO category provider, so the categories half is
|
|
106
|
+
* empty for a reason that is not "nothing matched".
|
|
107
|
+
*
|
|
108
|
+
* A dropdown has no room for a sentence about a provider being down, and the
|
|
109
|
+
* person reading it is mid-word. So the group is ABSENT rather than empty —
|
|
110
|
+
* an empty group under a heading is the box claiming the catalogue has no
|
|
111
|
+
* section by that name, which is a different and untrue statement.
|
|
112
|
+
*/
|
|
113
|
+
export declare const SUGGEST_DEGRADED_CATEGORIES = "category_suggestions";
|
|
114
|
+
/**
|
|
115
|
+
* Ancestry never arrived, so every stored path is one segment long and every
|
|
116
|
+
* count would read `0`.
|
|
117
|
+
*
|
|
118
|
+
* The rows are still destinations and still worth offering; their COUNTS are
|
|
119
|
+
* the part that is not an answer, so a surface drops the number rather than
|
|
120
|
+
* printing a catalogue of zeros.
|
|
121
|
+
*/
|
|
122
|
+
export declare const SUGGEST_DEGRADED_ROLLUP = "category_rollup";
|
|
123
|
+
/**
|
|
124
|
+
* The term half of a suggest answer, from whichever key this server sends.
|
|
125
|
+
*
|
|
126
|
+
* `terms` is 0.7.0's name and `items` is the deprecated alias kept for one
|
|
127
|
+
* minor; a client that read only one of them would go blank against half the
|
|
128
|
+
* servers in the fleet.
|
|
129
|
+
*/
|
|
130
|
+
export declare function suggestTerms(answer: SuggestAnswer | undefined): readonly string[];
|
|
25
131
|
/** `GET /ranking` 200 — the P2B Art. 5 disclosure. */
|
|
26
132
|
export type RankingResponse = Schemas["RankingResponse"];
|
|
27
133
|
/** One ranking parameter of the disclosure. */
|
package/dist/api/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/api/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAExD,4EAA4E;AAC5E,MAAM,MAAM,OAAO,GAAG,UAAU,CAAC,SAAS,CAAC,CAAC;AAE5C,6CAA6C;AAC7C,MAAM,MAAM,cAAc,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC;AAEvD;;0EAE0E;AAC1E,MAAM,MAAM,UAAU,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;AAE/C;kEACkE;AAClE,MAAM,MAAM,SAAS,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;AAE7C,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/api/types.ts"],"names":[],"mappings":"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"}
|