@stapel/search-react 0.25.0 → 0.27.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.
Files changed (81) hide show
  1. package/CHANGELOG.md +50 -0
  2. package/MODULE.md +21 -9
  3. package/README.md +79 -18
  4. package/dist/api/generated/schema.d.ts +18 -3
  5. package/dist/api/generated/schema.d.ts.map +1 -1
  6. package/dist/api/types.d.ts +39 -4
  7. package/dist/api/types.d.ts.map +1 -1
  8. package/dist/api/types.js.map +1 -1
  9. package/dist/default/FacetGroupControl.d.ts +20 -13
  10. package/dist/default/FacetGroupControl.d.ts.map +1 -1
  11. package/dist/default/FacetGroupControl.js +29 -21
  12. package/dist/default/FacetGroupControl.js.map +1 -1
  13. package/dist/default/FacetPanelPane.d.ts +28 -11
  14. package/dist/default/FacetPanelPane.d.ts.map +1 -1
  15. package/dist/default/FacetPanelPane.js +53 -24
  16. package/dist/default/FacetPanelPane.js.map +1 -1
  17. package/dist/default/SearchPage.d.ts +27 -0
  18. package/dist/default/SearchPage.d.ts.map +1 -1
  19. package/dist/default/SearchPage.js +21 -8
  20. package/dist/default/SearchPage.js.map +1 -1
  21. package/dist/headless/SearchStateProvider.d.ts +12 -2
  22. package/dist/headless/SearchStateProvider.d.ts.map +1 -1
  23. package/dist/headless/SearchStateProvider.js +58 -6
  24. package/dist/headless/SearchStateProvider.js.map +1 -1
  25. package/dist/i18n/es.d.ts.map +1 -1
  26. package/dist/i18n/es.js +0 -2
  27. package/dist/i18n/es.js.map +1 -1
  28. package/dist/i18n/generated/errors.es.gen.d.ts.map +1 -1
  29. package/dist/i18n/generated/errors.es.gen.js +1 -0
  30. package/dist/i18n/generated/errors.es.gen.js.map +1 -1
  31. package/dist/i18n/generated/errors.gen.d.ts +6 -0
  32. package/dist/i18n/generated/errors.gen.d.ts.map +1 -1
  33. package/dist/i18n/generated/errors.gen.js +3 -0
  34. package/dist/i18n/generated/errors.gen.js.map +1 -1
  35. package/dist/i18n/generated/errors.ru.gen.d.ts.map +1 -1
  36. package/dist/i18n/generated/errors.ru.gen.js +1 -0
  37. package/dist/i18n/generated/errors.ru.gen.js.map +1 -1
  38. package/dist/i18n/keys.d.ts +13 -11
  39. package/dist/i18n/keys.d.ts.map +1 -1
  40. package/dist/i18n/keys.js +13 -14
  41. package/dist/i18n/keys.js.map +1 -1
  42. package/dist/i18n/ru.d.ts.map +1 -1
  43. package/dist/i18n/ru.js +0 -4
  44. package/dist/i18n/ru.js.map +1 -1
  45. package/dist/index.d.ts +4 -4
  46. package/dist/index.d.ts.map +1 -1
  47. package/dist/index.js +3 -3
  48. package/dist/index.js.map +1 -1
  49. package/dist/model/queries.d.ts.map +1 -1
  50. package/dist/model/queries.js +9 -1
  51. package/dist/model/queries.js.map +1 -1
  52. package/dist/state/facets.d.ts +62 -11
  53. package/dist/state/facets.d.ts.map +1 -1
  54. package/dist/state/facets.js +141 -29
  55. package/dist/state/facets.js.map +1 -1
  56. package/dist/state/urlState.d.ts +77 -2
  57. package/dist/state/urlState.d.ts.map +1 -1
  58. package/dist/state/urlState.js +80 -6
  59. package/dist/state/urlState.js.map +1 -1
  60. package/llms.txt +3 -2
  61. package/manifest.json +18 -4
  62. package/nav-manifest.json +1 -1
  63. package/package.json +9 -9
  64. package/src/analytics/generated/events.json +1 -1
  65. package/src/api/generated/schema.ts +18 -3
  66. package/src/api/types.ts +42 -4
  67. package/src/default/FacetGroupControl.tsx +27 -23
  68. package/src/default/FacetPanelPane.tsx +81 -33
  69. package/src/default/SearchPage.tsx +55 -6
  70. package/src/headless/SearchStateProvider.tsx +94 -4
  71. package/src/i18n/es.ts +0 -4
  72. package/src/i18n/generated/errors.es.gen.ts +1 -0
  73. package/src/i18n/generated/errors.gen.ts +3 -0
  74. package/src/i18n/generated/errors.json +9 -0
  75. package/src/i18n/generated/errors.ru.gen.ts +1 -0
  76. package/src/i18n/keys.ts +13 -16
  77. package/src/i18n/ru.ts +0 -8
  78. package/src/index.ts +13 -1
  79. package/src/model/queries.ts +11 -1
  80. package/src/state/facets.ts +173 -30
  81. package/src/state/urlState.ts +137 -5
@@ -19,6 +19,72 @@ export const SEARCH_PARAM = {
19
19
  export const FILTER_PREFIX = "f.";
20
20
  /** Prefix of a range filter parameter (`r.price=100..500`). */
21
21
  export const RANGE_PREFIX = "r.";
22
+ /** No short keys — a pre-0.14.4 server, or a query with no category scope. */
23
+ export const EMPTY_FACET_KEYS = { write: {}, read: {} };
24
+ /**
25
+ * Normalize `{slug: url_key}` into the two directions, refusing anything
26
+ * ambiguous.
27
+ *
28
+ * The server already applies these rules; they are applied again here because
29
+ * this codec cannot verify which server answered, and the cost of getting it
30
+ * wrong is a filter that reads back as a different filter. A short form is
31
+ * used only when it is:
32
+ *
33
+ * - not a real slug of the same answer — `f.make` in a scope declaring both
34
+ * `make` and `make_ref_select` is the feature CALLED `make`, and the other
35
+ * one keeps its full slug (the server's own rule, stated the same way);
36
+ * - claimed by exactly one slug. Two slugs shortening to one key means
37
+ * neither may use it: a collision keeps the slug on both sides.
38
+ */
39
+ export function buildFacetKeyMap(declared) {
40
+ const slugs = Object.keys(declared);
41
+ const real = new Set(slugs);
42
+ const claims = new Map();
43
+ for (const slug of slugs) {
44
+ const key = declared[slug];
45
+ if (typeof key !== "string" || key.length === 0 || key === slug)
46
+ continue;
47
+ claims.set(key, (claims.get(key) ?? 0) + 1);
48
+ }
49
+ const write = {};
50
+ const read = {};
51
+ for (const slug of slugs) {
52
+ const key = declared[slug];
53
+ if (typeof key !== "string" ||
54
+ key.length === 0 ||
55
+ key === slug ||
56
+ real.has(key) ||
57
+ claims.get(key) !== 1) {
58
+ continue;
59
+ }
60
+ write[slug] = key;
61
+ read[key] = slug;
62
+ }
63
+ // A real slug always wins, whatever some other group shortened to. Written
64
+ // last so it overwrites a short form that collided with it.
65
+ for (const slug of slugs)
66
+ read[slug] = slug;
67
+ return { write, read };
68
+ }
69
+ /** {@link buildFacetKeyMap} over an answer's `facet_labels`. */
70
+ export function facetKeyMapFromLabels(labels) {
71
+ if (labels === undefined)
72
+ return EMPTY_FACET_KEYS;
73
+ const declared = {};
74
+ for (const [slug, entry] of Object.entries(labels))
75
+ declared[slug] = entry.url_key;
76
+ return buildFacetKeyMap(declared);
77
+ }
78
+ /** The slug an address key names. Unknown keys pass through unchanged — the
79
+ * server resolves what it recognises and 400s on what it does not, and a
80
+ * codec that dropped the key would lose a filter the answer can still honour. */
81
+ export function facetSlugForKey(key, keys) {
82
+ return keys?.read[key] ?? key;
83
+ }
84
+ /** The address key a slug is written as. The slug itself when there is none. */
85
+ export function facetKeyForSlug(slug, keys) {
86
+ return keys?.write[slug] ?? slug;
87
+ }
22
88
  const ISSUE_KEY = {
23
89
  not_a_number: "search.url.issue.not_a_number",
24
90
  geo_incomplete: "search.url.issue.geo_incomplete",
@@ -132,8 +198,11 @@ export function parseSearchState(params, options) {
132
198
  if (key.startsWith(FILTER_PREFIX) && key.length > FILTER_PREFIX.length) {
133
199
  // `getAll` is the whole point: a repeated key is OR within the slug.
134
200
  const values = params.getAll(key).filter((v) => v.length > 0);
135
- if (values.length > 0)
136
- filters[key.slice(FILTER_PREFIX.length)] = values;
201
+ if (values.length === 0)
202
+ continue;
203
+ // Both forms read: `f.make` and `f.make_ref_select` land on one slug.
204
+ const slug = facetSlugForKey(key.slice(FILTER_PREFIX.length), options.facetKeys);
205
+ filters[slug] = [...(filters[slug] ?? []), ...values];
137
206
  continue;
138
207
  }
139
208
  if (key.startsWith(RANGE_PREFIX) && key.length > RANGE_PREFIX.length) {
@@ -151,7 +220,7 @@ export function parseSearchState(params, options) {
151
220
  const to = raw.slice(separator + 2);
152
221
  if (from.length === 0 && to.length === 0)
153
222
  continue;
154
- ranges[key.slice(RANGE_PREFIX.length)] = {
223
+ ranges[facetSlugForKey(key.slice(RANGE_PREFIX.length), options.facetKeys)] = {
155
224
  ...(from.length > 0 ? { from } : {}),
156
225
  ...(to.length > 0 ? { to } : {}),
157
226
  };
@@ -200,8 +269,12 @@ function optional(key, value) {
200
269
  * is copied through untouched, so a host's own `?ref=`/`utm_*` survives a
201
270
  * facet click. Every parameter it DOES own is rewritten from the state, so a
202
271
  * removed filter actually leaves the URL instead of lingering as a stale key.
272
+ *
273
+ * `keys` is the answer's short-key map: a filter is written as its
274
+ * `url_key` when the answer states one and as its slug otherwise, so the two
275
+ * halves of a round trip agree without either side chopping at a string.
203
276
  */
204
- export function writeSearchState(state, base) {
277
+ export function writeSearchState(state, base, keys) {
205
278
  const next = new URLSearchParams();
206
279
  if (base !== undefined) {
207
280
  for (const key of new Set(base.keys())) {
@@ -221,8 +294,9 @@ export function writeSearchState(state, base) {
221
294
  if (state.owner !== undefined)
222
295
  next.set(SEARCH_PARAM.owner, state.owner);
223
296
  for (const slug of Object.keys(state.filters).sort()) {
297
+ const key = facetKeyForSlug(slug, keys);
224
298
  for (const value of state.filters[slug] ?? []) {
225
- next.append(`${FILTER_PREFIX}${slug}`, value);
299
+ next.append(`${FILTER_PREFIX}${key}`, value);
226
300
  }
227
301
  }
228
302
  for (const slug of Object.keys(state.ranges).sort()) {
@@ -231,7 +305,7 @@ export function writeSearchState(state, base) {
231
305
  continue;
232
306
  if (range.from === undefined && range.to === undefined)
233
307
  continue;
234
- next.set(`${RANGE_PREFIX}${slug}`, `${range.from ?? ""}..${range.to ?? ""}`);
308
+ next.set(`${RANGE_PREFIX}${facetKeyForSlug(slug, keys)}`, `${range.from ?? ""}..${range.to ?? ""}`);
235
309
  }
236
310
  if (state.geo !== undefined) {
237
311
  if (state.geo.kind === "bbox") {
@@ -1 +1 @@
1
- {"version":3,"file":"urlState.js","sourceRoot":"","sources":["../../src/state/urlState.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"urlState.js","sourceRoot":"","sources":["../../src/state/urlState.ts"],"names":[],"mappings":"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"}
package/llms.txt CHANGED
@@ -1,4 +1,4 @@
1
- # @stapel/search-react 0.25.0
1
+ # @stapel/search-react 0.27.0
2
2
 
3
3
  Headless React flow pair for stapel-search (contract >=0.14 <0.15) — business + state, zero visual opinion.
4
4
  Built on @stapel/core: typed client + StapelApiError envelope, auth token refresh,
@@ -33,7 +33,7 @@ Paths are relative to `/search/api/v1/`.
33
33
  - useSuggest (query) → suggest
34
34
 
35
35
  ## Errors (render t(code, params); UX from remediation)
36
- 54 keys (full catalog: manifest.json §errors). By remediation: fix_input 26 · retry 15 · verify 5 · wait_and_retry 5 · contact_support 2 · reauthenticate 1.
36
+ 55 keys (full catalog: manifest.json §errors). By remediation: fix_input 27 · retry 15 · verify 5 · wait_and_retry 5 · contact_support 2 · reauthenticate 1.
37
37
  Param-bearing keys (interpolation slots matter):
38
38
  - error.400.field.blank [400] → fix_input {field}
39
39
  - error.400.field.does_not_exist [400] → fix_input {field}
@@ -50,6 +50,7 @@ Param-bearing keys (interpolation slots matter):
50
50
  - error.400.search_bad_range [400] → fix_input {slug,reason}
51
51
  - error.400.search_too_many_facets [400] → fix_input {limit}
52
52
  - error.400.search_too_many_ranges [400] → fix_input {limit}
53
+ - error.400.search_unknown_category [400] → fix_input {category}
53
54
  - error.400.search_unknown_doc_type [400] → fix_input {doc_type}
54
55
  - error.400.search_unknown_sort [400] → fix_input {sort}
55
56
  - error.400.search_window_exceeded [400] → fix_input {window}
package/manifest.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$generated": "by scripts/gen-manifest.mjs — do not edit; drift-gated (pnpm gen:manifest:check)",
3
3
  "package": "@stapel/search-react",
4
- "version": "0.25.0",
4
+ "version": "0.27.0",
5
5
  "backend": {
6
6
  "module": "stapel-search",
7
7
  "contract": ">=0.14 <0.15"
@@ -234,6 +234,13 @@
234
234
  ],
235
235
  "remediation": "fix_input"
236
236
  },
237
+ "error.400.search_unknown_category": {
238
+ "status": 400,
239
+ "params": [
240
+ "category"
241
+ ],
242
+ "remediation": "fix_input"
243
+ },
237
244
  "error.400.search_unknown_doc_type": {
238
245
  "status": 400,
239
246
  "params": [
@@ -741,6 +748,7 @@
741
748
  "error.400.search_sort_needs_center",
742
749
  "error.400.search_too_many_facets",
743
750
  "error.400.search_too_many_ranges",
751
+ "error.400.search_unknown_category",
744
752
  "error.400.search_unknown_doc_type",
745
753
  "error.400.search_unknown_sort",
746
754
  "error.400.search_window_exceeded",
@@ -830,9 +838,6 @@
830
838
  "search.facets.show_less",
831
839
  "search.facets.skipped",
832
840
  "search.facets.title",
833
- "search.facets.withheld",
834
- "search.facets.withheld.one",
835
- "search.facets.withheld.other",
836
841
  "search.filters.all",
837
842
  "search.filters.applied_label",
838
843
  "search.filters.apply",
@@ -936,6 +941,7 @@
936
941
  ],
937
942
  "exports": {
938
943
  "runtime": [
944
+ "EMPTY_FACET_KEYS",
939
945
  "FACETABLE_FEATURE_TYPES",
940
946
  "FACET_PLAN_EVIDENCE",
941
947
  "FILTER_PREFIX",
@@ -971,6 +977,7 @@
971
977
  "SearchStateProvider",
972
978
  "activeFilterCount",
973
979
  "buildFacetGroups",
980
+ "buildFacetKeyMap",
974
981
  "buildRangeGroups",
975
982
  "clearFilters",
976
983
  "consonantKey",
@@ -985,7 +992,11 @@
985
992
  "explainSearchError",
986
993
  "facetGroupHasEvidence",
987
994
  "facetGroupIsDrawable",
995
+ "facetGroupIsVocabularyBacked",
996
+ "facetKeyForSlug",
997
+ "facetKeyMapFromLabels",
988
998
  "facetOptionLabel",
999
+ "facetSlugForKey",
989
1000
  "isCountNuanceOnly",
990
1001
  "isFacetableFeature",
991
1002
  "isRangeFeature",
@@ -1011,9 +1022,11 @@
1011
1022
  "translitKey",
1012
1023
  "translitPrefixMatch",
1013
1024
  "useAppliedSort",
1025
+ "useFacetKeys",
1014
1026
  "useFacetPanel",
1015
1027
  "useHostFacetLabels",
1016
1028
  "useOtherCategories",
1029
+ "usePublishFacetKeys",
1017
1030
  "useRankingDisclosure",
1018
1031
  "useSearchAnalytics",
1019
1032
  "useSearchApi",
@@ -1031,6 +1044,7 @@
1031
1044
  "CreateSearchRuntimeOptions",
1032
1045
  "FacetCategoryCount",
1033
1046
  "FacetGroup",
1047
+ "FacetKeyMap",
1034
1048
  "FacetLabelRequest",
1035
1049
  "FacetLabelResolver",
1036
1050
  "FacetLabelSource",
package/nav-manifest.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "package": "@stapel/search-react",
3
- "version": "0.25.0",
3
+ "version": "0.27.0",
4
4
  "entries": [
5
5
  {
6
6
  "id": "search.results",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stapel/search-react",
3
- "version": "0.25.0",
3
+ "version": "0.27.0",
4
4
  "description": "Headless React pair for stapel-search: a typed query client, TanStack Query hooks, and a URL-first state codec that makes a search shareable by construction (filters, ranges, geo, sort and the keyset cursor all live in the query string). Drill-down facets rendered with their remaining counts and with the server's own honesty flags — approximate, skipped, degraded — never swallowed; keyset pagination with the window refusal named; DSA Art. 26 `promoted` marking carried into every card slot and the P2B Art. 5 ranking disclosure exposed as data. Zero visual opinion in the main entry; an opt-in /default subpath ships the antd skin, and /router binds the codec to react-router's useSearchParams.",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -52,14 +52,14 @@
52
52
  ],
53
53
  "size-limit": [
54
54
  {
55
- "name": "index — the headless pair (client + hooks + URL codec + facet model incl. the facetability rule, the label-source order, the across-alphabets prefix matcher, the SCHEMA-order comparator that puts a category's required axes first and the bounded-integer picker list): no antd, no react-router. Raised 12 → 12.5 KB for the rail-order comparator, the shared drawability predicate (one rule for the rail and the chip row) and the picker bounds. Raised 12.5 → 13 KB for `useOtherCategories`, which reads the sections an answer is made of out of `facet_meta.categories` — the read that replaced a storefront's second request",
55
+ "name": "index — the headless pair (client + hooks + URL codec + facet model incl. the facetability rule, the label-source order, the across-alphabets prefix matcher, the SCHEMA-order comparator that puts a category's required axes first and the bounded-integer picker list): no antd, no react-router. Raised 12 → 12.5 KB for the rail-order comparator, the shared drawability predicate (one rule for the rail and the chip row) and the picker bounds. Raised 12.5 → 13 KB for `useOtherCategories`, which reads the sections an answer is made of out of `facet_meta.categories` — the read that replaced a storefront's second request, then 13 → 13.5 KB for the SHORT FEATURE KEYS: the two-direction `url_key` map (built with the server's own collision rules, so an ambiguous short form keeps the slug on both sides), its publication seam from the answer up to the state provider, and the vocabulary-backed predicate the drawability rule and the dictionary shape now share",
56
56
  "path": "dist/index.js",
57
- "limit": "13 KB"
57
+ "limit": "13.5 KB"
58
58
  },
59
59
  {
60
- "name": "default — the antd skin (query box + a typeahead that offers CATEGORY destinations with their live counts, filters incl. ranges/geo/category slots + the phone chip row with its leading category chip and the location summary row + the rail's evidence-ranked disclosure groups, panel search and sticky count/clear footer, results incl. the view switch, the card photo GALLERY as a SkinCarousel strip, the empty state's derived exits, ranking, the dictionary control for a vocabulary facet, the popular-values block, the partition row in both its chip and segmented variants, the select-style dictionary FIELD the desktop rail opens, the from/to pickers a bounded integer axis draws and the rail's own scrollbar sheet) must stay out of the main bundle. Raised 24.5 → 25.5 KB for those four controls, then 25.5 → 26.25 KB for the chip row's APPLIED mode — one chip per applied value and per numeric bound, each removing that one constraint beside a rail that is already on screen (a storefront was carrying its own copy of it), then 26.25 → 27 KB for the \"search in other categories\" LINE — which is a net deletion on the page that mounts it, replacing a full-width block of one row per section that arrived after the results and pushed them",
60
+ "name": "default — the antd skin (query box + a typeahead that offers CATEGORY destinations with their live counts, filters incl. ranges/geo/category slots + the phone chip row with its leading category chip and the location summary row + the rail's evidence-ranked disclosure groups, panel search and sticky count/clear footer, results incl. the view switch, the card photo GALLERY as a SkinCarousel strip, the empty state's derived exits, ranking, the dictionary control for a vocabulary facet, the popular-values block, the partition row in both its chip and segmented variants, the select-style dictionary FIELD the desktop rail opens, the from/to pickers a bounded integer axis draws and the rail's own scrollbar sheet) must stay out of the main bundle. Raised 24.5 → 25.5 KB for those four controls, then 25.5 → 26.25 KB for the chip row's APPLIED mode — one chip per applied value and per numeric bound, each removing that one constraint beside a rail that is already on screen (a storefront was carrying its own copy of it), then 26.25 → 27 KB for the \"search in other categories\" LINE — which is a net deletion on the page that mounts it, replacing a full-width block of one row per section that arrived after the results and pushed them, then 27 → 27.75 KB for the two frames the page now tells apart: the dictionary FIELD reaching `<SearchPage>` at all (per-layout default, field in the rail and inline in the sheet) and the footer bar being static in a column and sticky in a sheet, where it used to be pinned over the last two groups everywhere",
61
61
  "path": "dist/default/index.js",
62
- "limit": "27 KB"
62
+ "limit": "27.75 KB"
63
63
  },
64
64
  {
65
65
  "name": "router — the react-router binding is opt-in; the main entry must never pull a router",
@@ -115,12 +115,12 @@
115
115
  "size-limit": "^11.2.0",
116
116
  "typescript": "^5.8.3",
117
117
  "vitest": "^3.2.4",
118
- "@stapel/attributes-react": "^0.15.0",
119
- "@stapel/core": "^0.25.0",
120
- "@stapel/image": "^0.4.2",
118
+ "@stapel/core": "^0.25.1",
119
+ "@stapel/attributes-react": "^0.16.0",
121
120
  "@stapel/showcase": "^0.3.0",
121
+ "@stapel/image": "^0.4.2",
122
122
  "@stapel/tokens": "^0.7.0",
123
- "@stapel/tokens-antd": "^0.16.1"
123
+ "@stapel/tokens-antd": "^0.17.0"
124
124
  },
125
125
  "engines": {
126
126
  "node": ">=22"
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$generated": "by scripts/gen-events.mjs — do not edit; drift-gated (pnpm gen:events:check)",
3
3
  "package": "@stapel/search-react",
4
- "version": "0.25.0",
4
+ "version": "0.27.0",
5
5
  "defined": [],
6
6
  "flows": []
7
7
  }
@@ -148,6 +148,13 @@ export interface components {
148
148
  */
149
149
  radius_km?: number;
150
150
  };
151
+ /** @description The queried category in both forms an address can carry. */
152
+ CategoryResolved: {
153
+ /** @description The slash-joined ID path this answer actually filtered on — what to send back as `category`. `category=` accepts an id, an id path, a slug, a slug path and any mix, so the string the caller sent is not necessarily this one: `avtomobili` and `141/avtomobili` both answer `141/151`. */
154
+ path: string;
155
+ /** @description The same node as slug segments, root->leaf — what a readable URL is built from (`/c/avtomobili`). `null`, never partial, when any segment has no slug: half a slug path builds a wrong address and a client cannot see that by looking. `null` here with `category_names` in `degraded[]` means the names provider was unreachable, not that the node has no slug. */
156
+ slugs: string[] | null;
157
+ };
151
158
  /** @description One destination in the dropdown, ready to render and ready to follow. */
152
159
  CategorySuggestion: {
153
160
  /** @description Category id. A `listings`-graded row derives it from the path's leaf segment. */
@@ -209,8 +216,14 @@ export interface components {
209
216
  /** @description True when this filter actually narrowed the answer. A false one still contributed to each row's `match_count`. */
210
217
  applied: boolean;
211
218
  };
212
- /** @description Captions for one slug's option codes. */
219
+ /** @description The heading for one facet group, plus captions for its option codes. */
213
220
  FacetLabels: {
221
+ /** @description The feature definition's own name — the HEADING above this group's buckets. `null` when the definition carries no name: a client renders the slug only as a dev-mode fallback, because a raw slug in a heading is not a caption, and this field is how it can tell that case from a name the server has. */
222
+ label: string | null;
223
+ /** @description True when `label` is a translation KEY (`FeatureDef.translate` is `all` or `title`), false when it is literal text. Same question as `translatable`, one level up. */
224
+ label_translatable: boolean;
225
+ /** @description What to call this group in the address: `f.<url_key>` and `r.<url_key>`. The slug without the importer type suffix (`_select`, `_ref_select`, `_int`, `_bool`, `_string`) where that stays unambiguous among the features of the category in scope, and the slug itself otherwise — and always when the query names no category. Derived per request, never stored: the slug remains the feature's identity, and both forms are accepted inside the scope. */
226
+ url_key: string;
214
227
  /** @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. */
215
228
  translatable: boolean;
216
229
  values: {
@@ -347,6 +360,8 @@ export interface components {
347
360
  /** @description The query envelope: AnchorPagination's keys, plus what search owes. */
348
361
  SearchResponse: {
349
362
  items: components["schemas"]["SearchItem"][];
363
+ /** @description The category this answer filtered on, in both addressable forms. `null` when the query named no category. */
364
+ category_resolved: components["schemas"]["CategoryResolved"] | null;
350
365
  /** @description Per-band counts in render order — `nearby` («Объявления поблизости») then `all` («Все объявления»). Present only under `geo_mode=rank`; empty when no centre was given. The rows themselves carry `band`; this is the summary a heading needs. The top-level `count` remains the WHOLE matching total, never the nearby one. */
351
366
  bands?: components["schemas"]["BandSummary"][];
352
367
  /** @description What the query's words became. Absent entirely while QUERY_UNDERSTANDING is off or `qu=off` was sent. */
@@ -357,7 +372,7 @@ export interface components {
357
372
  [key: string]: number;
358
373
  };
359
374
  };
360
- /** @description {slug: {translatable, values: {value: caption}}} for slugs whose options are inline in the category schema. Absent for a vocabulary-backed slug: its level lives outside the schema and the plan will not invent a caption it has not read. */
375
+ /** @description {slug: {label, label_translatable, url_key, translatable, values: {value: caption}}} — one entry for EVERY group in `facets`. `url_key` is the group's key in the address. `label` is the group's heading and is null when the definition has no name; `values` is empty for a slug whose options are not inline in the category schema and whose vocabulary resolved nothing, because this module will not invent a caption it has not read. */
361
376
  facet_labels: {
362
377
  [key: string]: components["schemas"]["FacetLabels"];
363
378
  };
@@ -428,7 +443,7 @@ export interface operations {
428
443
  anchor?: string;
429
444
  /** @description minLat,minLon,maxLat,maxLon. minLon > maxLon means the box crosses +/-180. For an anonymous caller the rectangle is grown OUTWARD to whole ~1.1km cells of the public geo grid, so it can only ever ask about the area a public card publishes: a box EXCLUDES rows, and halving one around a listing would otherwise converge on the seller's pin in a few dozen requests. */
430
445
  bbox?: string;
431
- /** @description root/leaf path; a prefix filter, so a parent finds its descendants. */
446
+ /** @description root/leaf path; a prefix filter, so a parent finds its descendants. Segments are node IDS or SLUGS, in any mix: a bare node id is resolved to that node's full path (`166` == `141/151/166`), and a slug is a whole address on its own because slugs are globally unique (`avtomobili` == `transport/avtomobili` == `141/151`). The form that answered is echoed in `category_resolved`. A segment no category has is a 400, never an empty answer. */
432
447
  category?: string;
433
448
  /** @description next | prev. */
434
449
  direction?: string;
package/src/api/types.ts CHANGED
@@ -24,11 +24,17 @@ export type Schemas = components["schemas"];
24
24
  * slug either; ABSENT is a server too old to send one, and both read the same
25
25
  * way here (fall through to the schema).
26
26
  *
27
- * WHAT THE GENERATOR LOST: the field is newer than this pair's pinned
28
- * `schema.json`, so it is declared here as optional-and-nullable rather than
29
- * regenerated into a shape a deployed older server does not send.
27
+ * WHY IT IS NOT THE GENERATED SHAPE: stapel-search 0.14.5's `schema.json`
28
+ * declares this field REQUIRED, but the contract this pair announces is
29
+ * `>=0.14 <0.15`, and a 0.14.0 server inside that range sends no `label` at
30
+ * all. The generated member is therefore `Omit`ted and re-declared here as
31
+ * optional-and-nullable — a type must not promise a field a server the pair
32
+ * says it supports does not send.
30
33
  */
31
- export type FacetLabels = Schemas["FacetLabels"] & {
34
+ export type FacetLabels = Omit<
35
+ Schemas["FacetLabels"],
36
+ "label" | "label_translatable" | "url_key"
37
+ > & {
32
38
  readonly label?: string | null;
33
39
  /**
34
40
  * Whether {@link label} is a translation KEY rather than a caption, the way
@@ -43,6 +49,38 @@ export type FacetLabels = Schemas["FacetLabels"] & {
43
49
  * fixture captured from the wire is not a type error.
44
50
  */
45
51
  readonly label_translatable?: boolean;
52
+ /**
53
+ * What this group is called IN THE ADDRESS: `f.<url_key>`, `r.<url_key>`.
54
+ *
55
+ * The slug minus the type suffix an importer mints (`_select`,
56
+ * `_ref_select`, `_int`, `_bool`, `_string`) where dropping it stays
57
+ * unambiguous among the features of the category in scope, and the slug
58
+ * itself otherwise — and always when the query names no category
59
+ * (stapel-search 0.14.4+, `facets.url_keys`). Derived per request, never
60
+ * stored: the slug remains the feature's identity and both forms are
61
+ * accepted inside the scope, which is what lets a client write the short
62
+ * one without a migration behind it.
63
+ *
64
+ * WHY IT IS NOT THE GENERATED SHAPE: 0.14.5 declares it REQUIRED, and the
65
+ * announced contract is `>=0.14 <0.15` — a 0.14.0 server in that range
66
+ * states no `url_key`, and the codec's whole point is that such a link
67
+ * still works. `Omit`ted from the generated member and re-declared
68
+ * optional here. Measured on a live answer 2026-09-04:
69
+ * `make_ref_select` → `make`, `fuel_type_ref_select` → `fuel_type`,
70
+ * `model` → `model`.
71
+ */
72
+ readonly url_key?: string | null;
73
+ /**
74
+ * The vocabulary this group's values are drawn from, when the server names
75
+ * one.
76
+ *
77
+ * The one fact that decides whether an axis is a DICTIONARY rather than a
78
+ * list, and the client's second-best source for it: the first is the
79
+ * category schema's own `optionsRef`, which a host that threaded no schema
80
+ * does not have. Absent on every server that does not state it — absence
81
+ * is not "inline", it is "unsaid", and the schema is asked next.
82
+ */
83
+ readonly vocabulary?: string | null;
46
84
  };
47
85
 
48
86
  /** `facet_labels` as a whole: `{slug: {label, translatable, values}}`. */
@@ -67,12 +67,9 @@ import type { CSSProperties, ReactElement } from "react";
67
67
  import { Button, Checkbox, Flex, Input, Typography } from "antd";
68
68
  import { useT } from "@stapel/core";
69
69
  import { controls, cssVar, radii, spacing } from "@stapel/tokens";
70
- import {
71
- VOCABULARY_BACKED_TYPES,
72
- featureConfig,
73
- featureType,
74
- } from "@stapel/attributes-react";
70
+ import { featureConfig, featureType } from "@stapel/attributes-react";
75
71
  import type { FeatureDef } from "@stapel/attributes-react";
72
+ import { facetGroupIsVocabularyBacked } from "../state/facets.js";
76
73
  import type { FacetGroup, FacetOption } from "../state/facets.js";
77
74
  import { translitPrefixMatch } from "../state/translit.js";
78
75
  import { SEARCH_I18N_KEYS } from "../i18n/keys.js";
@@ -147,14 +144,21 @@ function singleChoice(feature: FeatureDef | undefined): boolean {
147
144
  }
148
145
 
149
146
  /**
150
- * Is this group a DICTIONARY — a vocabulary's level, too long to scroll?
147
+ * Is this group a DICTIONARY — an axis whose values live in a vocabulary?
151
148
  *
152
- * Two ways to be one, because the schema is an optional slot and the live
153
- * case is the one where it is empty:
149
+ * Two ways to be one, and only the second one counts anything:
154
150
  *
155
- * - the def types the slug `ref_select`/`ref_hierarchical_select`, i.e. its
156
- * config is a POINTER into a vocabulary and there was never an option
157
- * table to draw;
151
+ * - the axis is VOCABULARY-BACKED (`facetGroupIsVocabularyBacked`): the def
152
+ * types it `ref_select`/`ref_hierarchical_select`, so its config is a
153
+ * POINTER and there was never an option table to draw — or there is no def
154
+ * and the answer named the vocabulary itself. **However many buckets came
155
+ * back.** This threshold used to be counted against the answer's evidence,
156
+ * and on a stand holding three cars the make axis has three buckets, drew
157
+ * three checkboxes, and hid the other four hundred makes behind nothing at
158
+ * all: the founder's "what if there are hundreds of options" is a question about the DICTIONARY,
159
+ * and the dictionary is large whether or not this leaf has stock. The
160
+ * field is also the only control that can search values the answer never
161
+ * enumerated, which is exactly the case a thin stand produces;
158
162
  * - there is NO def at all and the answer came back with more values than a
159
163
  * fold. At a live classified's cars branch the storefront passed an empty
160
164
  * feature list, so the 418 makes arrived as an unnamed, untyped group of
@@ -162,20 +166,20 @@ function singleChoice(feature: FeatureDef | undefined): boolean {
162
166
  * answers that, and refusing to draw one because the schema is missing
163
167
  * punishes the buyer for the wiring.
164
168
  *
165
- * Either way it takes more than {@link FACET_DICTIONARY_THRESHOLD} EVIDENCE
166
- * buckets values the answer actually counted. A zero-filled option table or
167
- * a schema-only tail is a list a person can already read, and a box over it
168
- * would search for values no document carries.
169
+ * An INLINE option set is never one, whatever its length: a `select` carries
170
+ * its own table, that table is the whole of the axis, and a small one
171
+ * (≤ {@link FACET_DICTIONARY_THRESHOLD} options) is a list a person reads at
172
+ * a glance rather than types into.
169
173
  */
170
174
  export function isDictionaryFacet(group: FacetGroup): boolean {
175
+ if (facetGroupIsVocabularyBacked(group)) return true;
176
+ // A typed def that is not vocabulary-backed carries its options inline:
177
+ // checkboxes or pills, however many there are.
178
+ if (group.feature !== undefined) return false;
171
179
  const buckets = group.options.filter(
172
180
  (option) => option.count !== null && option.count > 0
173
181
  ).length;
174
- if (buckets <= FACET_DICTIONARY_THRESHOLD) return false;
175
- const feature = group.feature;
176
- if (feature === undefined) return true;
177
- const type = featureType(feature);
178
- return type !== undefined && VOCABULARY_BACKED_TYPES.includes(type);
182
+ return buckets > FACET_DICTIONARY_THRESHOLD;
179
183
  }
180
184
 
181
185
  /**
@@ -189,9 +193,9 @@ export function isDictionaryFacet(group: FacetGroup): boolean {
189
193
  * `maxSelected: 1` over a 418-value vocabulary, so "pick one" won and the
190
194
  * control it produced was four hundred pills in a 280px rail — a wall
191
195
  * with a different border radius. Above the fold the shape a person needs
192
- * is a search box, whether or not they may tick two; below it,
193
- * single-choice still means pills, because `isDictionaryFacet` requires
194
- * more than {@link FACET_DICTIONARY_THRESHOLD} counted buckets;
196
+ * is a search box, whether or not they may tick two. A single-choice axis
197
+ * with an INLINE option table still means pills, because a dictionary is
198
+ * now about where the values live and not about how many came back;
195
199
  * - and a dictionary is a dictionary before it is a checkbox list, because
196
200
  * the checkbox list is the shape it was drawn as when nobody could pick a
197
201
  * make.