@mailwoman/react 7.4.0 → 7.5.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/index.ts CHANGED
@@ -51,12 +51,15 @@ export type {
51
51
  CategoryRecord,
52
52
  LiveSearchState,
53
53
  LoadPOIRuntime,
54
+ POIBrandSubject,
55
+ POICategorySubject,
54
56
  POIExplorerResult,
55
57
  POILiveSearch,
56
58
  POILiveSearchResult,
57
59
  POIRuntime,
58
60
  POISearchHit,
59
61
  POISubject,
62
+ POISubjectBase,
60
63
  TaxonomyLookup,
61
64
  } from "./poi/types.ts"
62
65
  export { usePOISearch } from "./poi/usePOISearch.ts"
package/out/index.d.ts CHANGED
@@ -43,7 +43,7 @@ export type { QueryInputProps } from "./poi/QueryInput.tsx";
43
43
  export { formatDistance, loadPOIRuntime, POI_DEFAULT_TEXT, POI_PRESETS } from "./poi/runtime.ts";
44
44
  export { SubjectPanel } from "./poi/SubjectPanel.tsx";
45
45
  export type { SubjectPanelProps } from "./poi/SubjectPanel.tsx";
46
- export type { CategoryRecord, LiveSearchState, LoadPOIRuntime, POIExplorerResult, POILiveSearch, POILiveSearchResult, POIRuntime, POISearchHit, POISubject, TaxonomyLookup, } from "./poi/types.ts";
46
+ export type { CategoryRecord, LiveSearchState, LoadPOIRuntime, POIBrandSubject, POICategorySubject, POIExplorerResult, POILiveSearch, POILiveSearchResult, POIRuntime, POISearchHit, POISubject, POISubjectBase, TaxonomyLookup, } from "./poi/types.ts";
47
47
  export { usePOISearch } from "./poi/usePOISearch.ts";
48
48
  export type { UsePOISearch, UsePOISearchOptions } from "./poi/usePOISearch.ts";
49
49
  export { CandidatePicker } from "./pipeline/CandidatePicker.tsx";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"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"}
package/out/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,8EAA8E;AAC9E,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAyB,CAAA;AAEpD,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAyB,CAAA;AAEpD,OAAO,EAAE,EAAE,EAAE,MAAM,gBAAgB,CAAA;AAEnC,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAwB,CAAA;AAElD,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA+B,CAAA;AAEhE,OAAO,EAAE,WAAW,EAAE,MAAM,yBAA0B,CAAA;AAEtD,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAA;AAEvD,OAAO,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAA;AAEjE,8EAA8E;AAC9E,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAwB,CAAA;AAErD,OAAO,EAAE,gBAAgB,EAAE,MAAM,2BAA4B,CAAA;AAE7D,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAyB,CAAA;AAEvD,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAuB,CAAA;AAEnD,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAsB,CAAA;AAEjD,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAChG,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAwB,CAAA;AAcrD,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAA;AAGpD,8EAA8E;AAC9E,OAAO,EAAE,eAAe,EAAE,MAAM,+BAAgC,CAAA;AAEhE,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA+B,CAAA;AAE9D,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA+B,CAAA;AAE9D,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAA;AACtD,OAAO,EAAE,wBAAwB,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAA;AAClF,OAAO,EAAE,gBAAgB,EAAE,MAAM,gCAAiC,CAAA;AAElE,OAAO,EAAE,SAAS,EAAE,MAAM,yBAA0B,CAAA;AAEpD,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA8B,CAAA;AAa5D,OAAO,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,8EAA8E;AAC9E,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAyB,CAAA;AAEpD,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAyB,CAAA;AAEpD,OAAO,EAAE,EAAE,EAAE,MAAM,gBAAgB,CAAA;AAEnC,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAwB,CAAA;AAElD,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA+B,CAAA;AAEhE,OAAO,EAAE,WAAW,EAAE,MAAM,yBAA0B,CAAA;AAEtD,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAA;AAEvD,OAAO,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAA;AAEjE,8EAA8E;AAC9E,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAwB,CAAA;AAErD,OAAO,EAAE,gBAAgB,EAAE,MAAM,2BAA4B,CAAA;AAE7D,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAyB,CAAA;AAEvD,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAuB,CAAA;AAEnD,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAsB,CAAA;AAEjD,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAChG,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAwB,CAAA;AAiBrD,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAA;AAGpD,8EAA8E;AAC9E,OAAO,EAAE,eAAe,EAAE,MAAM,+BAAgC,CAAA;AAEhE,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA+B,CAAA;AAE9D,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA+B,CAAA;AAE9D,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAA;AACtD,OAAO,EAAE,wBAAwB,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAA;AAClF,OAAO,EAAE,gBAAgB,EAAE,MAAM,gCAAiC,CAAA;AAElE,OAAO,EAAE,SAAS,EAAE,MAAM,yBAA0B,CAAA;AAEpD,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA8B,CAAA;AAa5D,OAAO,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAA"}
@@ -10,12 +10,12 @@
10
10
  import type { ReactNode } from "react";
11
11
  import type { LiveSearchState } from "./types.ts";
12
12
  export interface LiveResultsBlockProps {
13
- /** Category label for empty-state copy ("No hospital results near …"). */
14
- categoryLabel: string;
13
+ /** Subject label for empty-state copy — a category ("No hospital results near …") or a brand ("No chevron results …"). */
14
+ subjectLabel: string;
15
15
  /** The location anchor the search runs against (empty ⇒ the button is disabled with a hint). */
16
16
  anchor: string;
17
17
  state: LiveSearchState;
18
18
  onSearch: () => void;
19
19
  }
20
- export declare function LiveResultsBlock({ categoryLabel, anchor, state, onSearch }: LiveResultsBlockProps): ReactNode;
20
+ export declare function LiveResultsBlock({ subjectLabel, anchor, state, onSearch }: LiveResultsBlockProps): ReactNode;
21
21
  //# sourceMappingURL=LiveResultsBlock.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"LiveResultsBlock.d.ts","sourceRoot":"","sources":["../../poi/LiveResultsBlock.tsx"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAGtC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AAEjD,MAAM,WAAW,qBAAqB;IACrC,0EAA0E;IAC1E,aAAa,EAAE,MAAM,CAAA;IACrB,gGAAgG;IAChG,MAAM,EAAE,MAAM,CAAA;IACd,KAAK,EAAE,eAAe,CAAA;IACtB,QAAQ,EAAE,MAAM,IAAI,CAAA;CACpB;AAED,wBAAgB,gBAAgB,CAAC,EAAE,aAAa,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,qBAAqB,GAAG,SAAS,CA6C7G"}
1
+ {"version":3,"file":"LiveResultsBlock.d.ts","sourceRoot":"","sources":["../../poi/LiveResultsBlock.tsx"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAGtC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AAEjD,MAAM,WAAW,qBAAqB;IACrC,0HAA0H;IAC1H,YAAY,EAAE,MAAM,CAAA;IACpB,gGAAgG;IAChG,MAAM,EAAE,MAAM,CAAA;IACd,KAAK,EAAE,eAAe,CAAA;IACtB,QAAQ,EAAE,MAAM,IAAI,CAAA;CACpB;AAED,wBAAgB,gBAAgB,CAAC,EAAE,YAAY,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,qBAAqB,GAAG,SAAS,CA6C5G"}
@@ -1,7 +1,7 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
2
  import { formatDistance } from "./runtime.js";
3
- export function LiveResultsBlock({ categoryLabel, anchor, state, onSearch }) {
3
+ export function LiveResultsBlock({ subjectLabel, anchor, state, onSearch }) {
4
4
  const hasAnchor = anchor.trim().length > 0;
5
- return (_jsxs("div", { className: "mw-live", children: [_jsxs("div", { className: "mw-panel__header", children: [_jsx("h3", { children: "Live results" }), _jsx("button", { type: "button", className: "mw-btn", onClick: onSearch, disabled: !hasAnchor || state.status === "loading", title: hasAnchor ? "Search the published poi.db layer" : 'Needs a location anchor (e.g. "near Springfield")', children: state.status === "loading" ? "Searching…" : "Search live" })] }), !hasAnchor ? (_jsx("p", { className: "mw-muted", children: "Add a location anchor (e.g. \"near Springfield\") to search live." })) : state.status === "error" ? (_jsx("p", { className: "mw-error", children: state.message })) : state.status === "success" ? (state.hits.length === 0 ? (_jsxs("p", { className: "mw-muted", children: ["No ", categoryLabel.toLowerCase(), " results near ", state.centerName, "."] })) : (_jsxs(_Fragment, { children: [_jsxs("p", { className: "mw-live__caption", children: ["Near ", state.centerName, ", ranked by distance:"] }), _jsx("ul", { className: "mw-live__results", children: state.hits.map((hit, i) => (_jsxs("li", { children: [_jsx("span", { className: "mw-live__name", children: hit.name }), _jsxs("span", { className: "mw-live__meta", children: [formatDistance(hit.distanceM), " \u00B7 ", hit.country] })] }, `${hit.name}-${i}`))) })] }))) : null] }));
5
+ return (_jsxs("div", { className: "mw-live", children: [_jsxs("div", { className: "mw-panel__header", children: [_jsx("h3", { children: "Live results" }), _jsx("button", { type: "button", className: "mw-btn", onClick: onSearch, disabled: !hasAnchor || state.status === "loading", title: hasAnchor ? "Search the published poi.db layer" : 'Needs a location anchor (e.g. "near Springfield")', children: state.status === "loading" ? "Searching…" : "Search live" })] }), !hasAnchor ? (_jsx("p", { className: "mw-muted", children: "Add a location anchor (e.g. \"near Springfield\") to search live." })) : state.status === "error" ? (_jsx("p", { className: "mw-error", children: state.message })) : state.status === "success" ? (state.hits.length === 0 ? (_jsxs("p", { className: "mw-muted", children: ["No ", subjectLabel.toLowerCase(), " results near ", state.centerName, "."] })) : (_jsxs(_Fragment, { children: [_jsxs("p", { className: "mw-live__caption", children: ["Near ", state.centerName, ", ranked by distance:"] }), _jsx("ul", { className: "mw-live__results", children: state.hits.map((hit, i) => (_jsxs("li", { children: [_jsx("span", { className: "mw-live__name", children: hit.name }), _jsxs("span", { className: "mw-live__meta", children: [formatDistance(hit.distanceM), " \u00B7 ", hit.country] })] }, `${hit.name}-${i}`))) })] }))) : null] }));
6
6
  }
7
7
  //# sourceMappingURL=LiveResultsBlock.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"LiveResultsBlock.js","sourceRoot":"","sources":["../../poi/LiveResultsBlock.tsx"],"names":[],"mappings":";AAYA,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AAY7C,MAAM,UAAU,gBAAgB,CAAC,EAAE,aAAa,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAyB;IACjG,MAAM,SAAS,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CAAA;IAE1C,OAAO,CACN,eAAK,SAAS,EAAC,SAAS,aACvB,eAAK,SAAS,EAAC,kBAAkB,aAChC,wCAAqB,EACrB,iBACC,IAAI,EAAC,QAAQ,EACb,SAAS,EAAC,QAAQ,EAClB,OAAO,EAAE,QAAQ,EACjB,QAAQ,EAAE,CAAC,SAAS,IAAI,KAAK,CAAC,MAAM,KAAK,SAAS,EAClD,KAAK,EAAE,SAAS,CAAC,CAAC,CAAC,mCAAmC,CAAC,CAAC,CAAC,mDAAmD,YAE3G,KAAK,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,aAAa,GAClD,IACJ,EAEL,CAAC,SAAS,CAAC,CAAC,CAAC,CACb,YAAG,SAAS,EAAC,UAAU,kFAAoE,CAC3F,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,CAC9B,YAAG,SAAS,EAAC,UAAU,YAAE,KAAK,CAAC,OAAO,GAAK,CAC3C,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,CAChC,KAAK,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,CACzB,aAAG,SAAS,EAAC,UAAU,oBAClB,aAAa,CAAC,WAAW,EAAE,oBAAgB,KAAK,CAAC,UAAU,SAC5D,CACJ,CAAC,CAAC,CAAC,CACH,8BACC,aAAG,SAAS,EAAC,kBAAkB,sBAAO,KAAK,CAAC,UAAU,6BAA0B,EAChF,aAAI,SAAS,EAAC,kBAAkB,YAC9B,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,CAC3B,yBACC,eAAM,SAAS,EAAC,eAAe,YAAE,GAAG,CAAC,IAAI,GAAQ,EACjD,gBAAM,SAAS,EAAC,eAAe,aAC7B,cAAc,CAAC,GAAG,CAAC,SAAS,CAAC,cAAK,GAAG,CAAC,OAAO,IACxC,KAJC,GAAG,GAAG,CAAC,IAAI,IAAI,CAAC,EAAE,CAKtB,CACL,CAAC,GACE,IACH,CACH,CACD,CAAC,CAAC,CAAC,IAAI,IACH,CACN,CAAA;AACF,CAAC"}
1
+ {"version":3,"file":"LiveResultsBlock.js","sourceRoot":"","sources":["../../poi/LiveResultsBlock.tsx"],"names":[],"mappings":";AAYA,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AAY7C,MAAM,UAAU,gBAAgB,CAAC,EAAE,YAAY,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAyB;IAChG,MAAM,SAAS,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CAAA;IAE1C,OAAO,CACN,eAAK,SAAS,EAAC,SAAS,aACvB,eAAK,SAAS,EAAC,kBAAkB,aAChC,wCAAqB,EACrB,iBACC,IAAI,EAAC,QAAQ,EACb,SAAS,EAAC,QAAQ,EAClB,OAAO,EAAE,QAAQ,EACjB,QAAQ,EAAE,CAAC,SAAS,IAAI,KAAK,CAAC,MAAM,KAAK,SAAS,EAClD,KAAK,EAAE,SAAS,CAAC,CAAC,CAAC,mCAAmC,CAAC,CAAC,CAAC,mDAAmD,YAE3G,KAAK,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,aAAa,GAClD,IACJ,EAEL,CAAC,SAAS,CAAC,CAAC,CAAC,CACb,YAAG,SAAS,EAAC,UAAU,kFAAoE,CAC3F,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,CAC9B,YAAG,SAAS,EAAC,UAAU,YAAE,KAAK,CAAC,OAAO,GAAK,CAC3C,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,CAChC,KAAK,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,CACzB,aAAG,SAAS,EAAC,UAAU,oBAClB,YAAY,CAAC,WAAW,EAAE,oBAAgB,KAAK,CAAC,UAAU,SAC3D,CACJ,CAAC,CAAC,CAAC,CACH,8BACC,aAAG,SAAS,EAAC,kBAAkB,sBAAO,KAAK,CAAC,UAAU,6BAA0B,EAChF,aAAI,SAAS,EAAC,kBAAkB,YAC9B,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,CAC3B,yBACC,eAAM,SAAS,EAAC,eAAe,YAAE,GAAG,CAAC,IAAI,GAAQ,EACjD,gBAAM,SAAS,EAAC,eAAe,aAC7B,cAAc,CAAC,GAAG,CAAC,SAAS,CAAC,cAAK,GAAG,CAAC,OAAO,IACxC,KAJC,GAAG,GAAG,CAAC,IAAI,IAAI,CAAC,EAAE,CAKtB,CACL,CAAC,GACE,IACH,CACH,CACD,CAAC,CAAC,CAAC,IAAI,IACH,CACN,CAAA;AACF,CAAC"}
@@ -20,6 +20,12 @@ export interface POIExplorerProps {
20
20
  loadRuntime?: LoadPOIRuntime;
21
21
  /** Live poi.db probe. Absent ⇒ intent-only (no live-results affordance). */
22
22
  runLiveSearch?: POILiveSearch;
23
+ /**
24
+ * Whether {@link runLiveSearch} can serve BRAND subjects (fetch by QID). Default false: a brand subject shows the
25
+ * intent + QID chip but no live block. The docs' httpvfs probe leaves this off (brand-wide byte-range hydration is
26
+ * pathological — measured); a server-side backend can enable it.
27
+ */
28
+ brandLiveSearch?: boolean;
23
29
  }
24
- export declare function POIExplorer({ defaultText, presets, loadRuntime, runLiveSearch, }: POIExplorerProps): ReactNode;
30
+ export declare function POIExplorer({ defaultText, presets, loadRuntime, runLiveSearch, brandLiveSearch, }: POIExplorerProps): ReactNode;
25
31
  //# sourceMappingURL=POIExplorer.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"POIExplorer.d.ts","sourceRoot":"","sources":["../../poi/POIExplorer.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,KAAK,SAAS,EAAY,MAAM,OAAO,CAAA;AAIhD,OAAO,EAAe,KAAK,MAAM,EAAE,MAAM,2BAA2B,CAAA;AAOpE,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAG/D,MAAM,WAAW,gBAAgB;IAChC,sCAAsC;IACtC,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,uDAAuD;IACvD,OAAO,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,CAAA;IAC/B,0EAA0E;IAC1E,WAAW,CAAC,EAAE,cAAc,CAAA;IAC5B,4EAA4E;IAC5E,aAAa,CAAC,EAAE,aAAa,CAAA;CAC7B;AA2CD,wBAAgB,WAAW,CAAC,EAC3B,WAA8B,EAC9B,OAAqB,EACrB,WAAW,EACX,aAAa,GACb,EAAE,gBAAgB,GAAG,SAAS,CAmB9B"}
1
+ {"version":3,"file":"POIExplorer.d.ts","sourceRoot":"","sources":["../../poi/POIExplorer.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,KAAK,SAAS,EAAY,MAAM,OAAO,CAAA;AAIhD,OAAO,EAAe,KAAK,MAAM,EAAE,MAAM,2BAA2B,CAAA;AAOpE,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAG/D,MAAM,WAAW,gBAAgB;IAChC,sCAAsC;IACtC,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,uDAAuD;IACvD,OAAO,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,CAAA;IAC/B,0EAA0E;IAC1E,WAAW,CAAC,EAAE,cAAc,CAAA;IAC5B,4EAA4E;IAC5E,aAAa,CAAC,EAAE,aAAa,CAAA;IAC7B;;;;OAIG;IACH,eAAe,CAAC,EAAE,OAAO,CAAA;CACzB;AAkED,wBAAgB,WAAW,CAAC,EAC3B,WAA8B,EAC9B,OAAqB,EACrB,WAAW,EACX,aAAa,EACb,eAAe,GACf,EAAE,gBAAgB,GAAG,SAAS,CAoB9B"}
@@ -20,12 +20,24 @@ import { QueryInput } from "./QueryInput.js";
20
20
  import { POI_DEFAULT_TEXT, POI_PRESETS } from "./runtime.js";
21
21
  import { SubjectPanel } from "./SubjectPanel.js";
22
22
  import { usePOISearch } from "./usePOISearch.js";
23
- function POIExplorerInner({ defaultText, presets, loadRuntime, runLiveSearch }) {
23
+ function POIExplorerInner({ defaultText, presets, loadRuntime, runLiveSearch, brandLiveSearch, }) {
24
24
  const [text, setText] = useState(defaultText);
25
- const { result, liveSearch, searchLive } = usePOISearch({ text, loadRuntime, runLiveSearch });
26
- return (_jsxs("div", { className: "mw-poi-explorer", children: [_jsx(QueryInput, { id: "mw-poi-input", label: "Query", value: text, onChange: setText, placeholder: POI_DEFAULT_TEXT }), _jsx(PresetChips, { presets: presets, onPick: setText }), result ? (_jsxs("div", { className: "mw-result", children: [_jsx(KindBadge, { kindResult: result.kindResult }), result.subject ? (_jsxs(_Fragment, { children: [_jsx(SubjectPanel, { subject: result.subject }), _jsx(OverpassBlock, { overpassQL: result.overpassQL, overpassError: result.overpassError }), runLiveSearch && !result.subject.buildLocal ? (_jsx(LiveResultsBlock, { categoryLabel: result.subject.category.label, anchor: result.subject.remainder, state: liveSearch, onSearch: searchLive })) : null] })) : (_jsx(AbstainPanel, { kind: result.kindResult.kind }))] })) : null] }));
25
+ const { result, liveSearch, searchLive } = usePOISearch({
26
+ text,
27
+ loadRuntime,
28
+ runLiveSearch,
29
+ brandLiveSearch,
30
+ });
31
+ const subject = result?.subject;
32
+ // The live block appears whenever the subject COULD be live-searched with an anchor — i.e. capable minus the
33
+ // anchor-present requirement (`canSearchLive` also requires an anchor; the block itself renders the "add an anchor"
34
+ // hint, so it must show one step earlier). Category: not build-local. Brand: brand-capable probe + a QID.
35
+ const showLiveBlock = Boolean(runLiveSearch &&
36
+ subject &&
37
+ (subject.kind === "brand" ? brandLiveSearch && subject.wikidata !== undefined : !subject.buildLocal));
38
+ return (_jsxs("div", { className: "mw-poi-explorer", children: [_jsx(QueryInput, { id: "mw-poi-input", label: "Query", value: text, onChange: setText, placeholder: POI_DEFAULT_TEXT }), _jsx(PresetChips, { presets: presets, onPick: setText }), result ? (_jsxs("div", { className: "mw-result", children: [_jsx(KindBadge, { kindResult: result.kindResult }), subject ? (_jsxs(_Fragment, { children: [_jsx(SubjectPanel, { subject: subject }), subject.kind === "category" ? (_jsx(OverpassBlock, { overpassQL: result.overpassQL, overpassError: result.overpassError })) : null, showLiveBlock ? (_jsx(LiveResultsBlock, { subjectLabel: subject.kind === "brand" ? subject.name : subject.category.label, anchor: subject.remainder, state: liveSearch, onSearch: searchLive })) : null] })) : (_jsx(AbstainPanel, { kind: result.kindResult.kind }))] })) : null] }));
27
39
  }
28
- export function POIExplorer({ defaultText = POI_DEFAULT_TEXT, presets = POI_PRESETS, loadRuntime, runLiveSearch, }) {
29
- return (_jsx(ClientOnly, { fallback: _jsx("div", { className: "mw-poi-explorer", children: _jsx("p", { children: "Loading POI tester\u2026" }) }), children: () => (_jsx(POIExplorerInner, { defaultText: defaultText, presets: presets, loadRuntime: loadRuntime, runLiveSearch: runLiveSearch })) }));
40
+ export function POIExplorer({ defaultText = POI_DEFAULT_TEXT, presets = POI_PRESETS, loadRuntime, runLiveSearch, brandLiveSearch, }) {
41
+ return (_jsx(ClientOnly, { fallback: _jsx("div", { className: "mw-poi-explorer", children: _jsx("p", { children: "Loading POI tester\u2026" }) }), children: () => (_jsx(POIExplorerInner, { defaultText: defaultText, presets: presets, loadRuntime: loadRuntime, runLiveSearch: runLiveSearch, brandLiveSearch: brandLiveSearch })) }));
30
42
  }
31
43
  //# sourceMappingURL=POIExplorer.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"POIExplorer.js","sourceRoot":"","sources":["../../poi/POIExplorer.tsx"],"names":[],"mappings":";AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAkB,QAAQ,EAAE,MAAM,OAAO,CAAA;AAEhD,OAAO,EAAE,UAAU,EAAE,MAAM,yBAA0B,CAAA;AACrD,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAyB,CAAA;AACnD,OAAO,EAAE,WAAW,EAAe,MAAM,0BAA2B,CAAA;AACpE,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAoB,CAAA;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAwB,CAAA;AACzD,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAqB,CAAA;AACnD,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAkB,CAAA;AAC7C,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AAC5D,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAoB,CAAA;AAEjD,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAkBhD,SAAS,gBAAgB,CAAC,EAAE,WAAW,EAAE,OAAO,EAAE,WAAW,EAAE,aAAa,EAAyB;IACpG,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,QAAQ,CAAC,WAAW,CAAC,CAAA;IAC7C,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,UAAU,EAAE,GAAG,YAAY,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,aAAa,EAAE,CAAC,CAAA;IAE7F,OAAO,CACN,eAAK,SAAS,EAAC,iBAAiB,aAC/B,KAAC,UAAU,IAAC,EAAE,EAAC,cAAc,EAAC,KAAK,EAAC,OAAO,EAAC,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,WAAW,EAAE,gBAAgB,GAAI,EAC7G,KAAC,WAAW,IAAC,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,GAAI,EAEjD,MAAM,CAAC,CAAC,CAAC,CACT,eAAK,SAAS,EAAC,WAAW,aACzB,KAAC,SAAS,IAAC,UAAU,EAAE,MAAM,CAAC,UAAU,GAAI,EAE3C,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CACjB,8BACC,KAAC,YAAY,IAAC,OAAO,EAAE,MAAM,CAAC,OAAO,GAAI,EACzC,KAAC,aAAa,IAAC,UAAU,EAAE,MAAM,CAAC,UAAU,EAAE,aAAa,EAAE,MAAM,CAAC,aAAa,GAAI,EAEpF,aAAa,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,CAC9C,KAAC,gBAAgB,IAChB,aAAa,EAAE,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,EAC5C,MAAM,EAAE,MAAM,CAAC,OAAO,CAAC,SAAS,EAChC,KAAK,EAAE,UAAU,EACjB,QAAQ,EAAE,UAAU,GACnB,CACF,CAAC,CAAC,CAAC,IAAI,IACN,CACH,CAAC,CAAC,CAAC,CACH,KAAC,YAAY,IAAC,IAAI,EAAE,MAAM,CAAC,UAAU,CAAC,IAAI,GAAI,CAC9C,IACI,CACN,CAAC,CAAC,CAAC,IAAI,IACH,CACN,CAAA;AACF,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,EAC3B,WAAW,GAAG,gBAAgB,EAC9B,OAAO,GAAG,WAAW,EACrB,WAAW,EACX,aAAa,GACK;IAClB,OAAO,CACN,KAAC,UAAU,IACV,QAAQ,EACP,cAAK,SAAS,EAAC,iBAAiB,YAC/B,mDAA0B,GACrB,YAGN,GAAG,EAAE,CAAC,CACN,KAAC,gBAAgB,IAChB,WAAW,EAAE,WAAW,EACxB,OAAO,EAAE,OAAO,EAChB,WAAW,EAAE,WAAW,EACxB,aAAa,EAAE,aAAa,GAC3B,CACF,GACW,CACb,CAAA;AACF,CAAC"}
1
+ {"version":3,"file":"POIExplorer.js","sourceRoot":"","sources":["../../poi/POIExplorer.tsx"],"names":[],"mappings":"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"}
@@ -3,8 +3,9 @@
3
3
  * @license AGPL-3.0
4
4
  * @author Teffen Ellis, et al.
5
5
  *
6
- * `SubjectPanel` — renders the detected POI subject: the category chip, the optional build-local
7
- * badge + note, and the match-detail list (matched phrase, confidence, anchor). Presentational.
6
+ * `SubjectPanel` — renders the detected POI subject. For a CATEGORY: the category chip, the optional
7
+ * build-local badge + note. For a BRAND: the brand-name chip + a Wikidata QID chip (linked). Both
8
+ * share the match-detail list (matched phrase, confidence, anchor). Presentational.
8
9
  */
9
10
  import type { ReactNode } from "react";
10
11
  import type { POISubject } from "./types.ts";
@@ -1 +1 @@
1
- {"version":3,"file":"SubjectPanel.d.ts","sourceRoot":"","sources":["../../poi/SubjectPanel.tsx"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAEtC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAE5C,MAAM,WAAW,iBAAiB;IACjC,OAAO,EAAE,UAAU,CAAA;CACnB;AAED,wBAAgB,YAAY,CAAC,EAAE,OAAO,EAAE,EAAE,iBAAiB,GAAG,SAAS,CA0BtE"}
1
+ {"version":3,"file":"SubjectPanel.d.ts","sourceRoot":"","sources":["../../poi/SubjectPanel.tsx"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAEtC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAE5C,MAAM,WAAW,iBAAiB;IACjC,OAAO,EAAE,UAAU,CAAA;CACnB;AAkBD,wBAAgB,YAAY,CAAC,EAAE,OAAO,EAAE,EAAE,iBAAiB,GAAG,SAAS,CA4CtE"}
@@ -1,5 +1,12 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ /** The shared match-detail list (matched phrase, confidence, anchor) — identical for category + brand subjects. */
3
+ function MatchDetail({ subject }) {
4
+ return (_jsxs("dl", { className: "mw-subject__detail", children: [_jsx("dt", { children: "matched phrase" }), _jsx("dd", { children: _jsx("code", { children: subject.matchedPhrase }) }), _jsx("dt", { children: "confidence" }), _jsxs("dd", { children: [Math.round(subject.confidence * 100), "%"] }), _jsx("dt", { children: "anchor" }), _jsx("dd", { children: subject.remainder ? subject.remainder : _jsx("em", { children: "none \u2014 global query" }) })] }));
5
+ }
2
6
  export function SubjectPanel({ subject }) {
3
- return (_jsxs(_Fragment, { children: [_jsxs("div", { className: "mw-subject__row", children: [_jsx("span", { className: "mw-subject__chip", children: subject.category.label }), subject.buildLocal ? _jsx("span", { className: "mw-subject__badge", children: "build-local" }) : null] }), _jsxs("dl", { className: "mw-subject__detail", children: [_jsx("dt", { children: "matched phrase" }), _jsx("dd", { children: _jsx("code", { children: subject.matchedPhrase }) }), _jsx("dt", { children: "confidence" }), _jsxs("dd", { children: [Math.round(subject.confidence * 100), "%"] }), _jsx("dt", { children: "anchor" }), _jsx("dd", { children: subject.remainder ? subject.remainder : _jsx("em", { children: "none \u2014 global query" }) })] }), subject.buildLocal ? (_jsx("p", { className: "mw-subject__note", children: "Requires the locally-built OSM layer (ODbL) \u2014 mailwoman ships the builder, not the data." })) : null] }));
7
+ if (subject.kind === "brand") {
8
+ return (_jsxs(_Fragment, { children: [_jsxs("div", { className: "mw-subject__row", children: [_jsx("span", { className: "mw-subject__chip", children: subject.name }), _jsx("span", { className: "mw-subject__badge mw-subject__badge--brand", children: "brand" }), subject.wikidata ? (_jsx("a", { className: "mw-subject__qid", href: `https://www.wikidata.org/wiki/${subject.wikidata}`, target: "_blank", rel: "noreferrer", children: subject.wikidata })) : null] }), _jsx(MatchDetail, { subject: subject }), _jsx("p", { className: "mw-subject__note", children: "Matched as a chain brand \u2014 resolved by Wikidata QID against the layer's brand index." })] }));
9
+ }
10
+ return (_jsxs(_Fragment, { children: [_jsxs("div", { className: "mw-subject__row", children: [_jsx("span", { className: "mw-subject__chip", children: subject.category.label }), subject.buildLocal ? _jsx("span", { className: "mw-subject__badge", children: "build-local" }) : null] }), _jsx(MatchDetail, { subject: subject }), subject.buildLocal ? (_jsx("p", { className: "mw-subject__note", children: "Requires the locally-built OSM layer (ODbL) \u2014 mailwoman ships the builder, not the data." })) : null] }));
4
11
  }
5
12
  //# sourceMappingURL=SubjectPanel.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"SubjectPanel.js","sourceRoot":"","sources":["../../poi/SubjectPanel.tsx"],"names":[],"mappings":";AAiBA,MAAM,UAAU,YAAY,CAAC,EAAE,OAAO,EAAqB;IAC1D,OAAO,CACN,8BACC,eAAK,SAAS,EAAC,iBAAiB,aAC/B,eAAM,SAAS,EAAC,kBAAkB,YAAE,OAAO,CAAC,QAAQ,CAAC,KAAK,GAAQ,EACjE,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,eAAM,SAAS,EAAC,mBAAmB,4BAAmB,CAAC,CAAC,CAAC,IAAI,IAC9E,EAEN,cAAI,SAAS,EAAC,oBAAoB,aACjC,0CAAuB,EACvB,uBACC,yBAAO,OAAO,CAAC,aAAa,GAAQ,GAChC,EACL,sCAAmB,EACnB,yBAAK,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,UAAU,GAAG,GAAG,CAAC,SAAO,EAChD,kCAAe,EACf,uBAAK,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,oDAA4B,GAAM,IAC3E,EAEJ,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,CACrB,YAAG,SAAS,EAAC,kBAAkB,8GAE3B,CACJ,CAAC,CAAC,CAAC,IAAI,IACN,CACH,CAAA;AACF,CAAC"}
1
+ {"version":3,"file":"SubjectPanel.js","sourceRoot":"","sources":["../../poi/SubjectPanel.tsx"],"names":[],"mappings":";AAkBA,mHAAmH;AACnH,SAAS,WAAW,CAAC,EAAE,OAAO,EAAqB;IAClD,OAAO,CACN,cAAI,SAAS,EAAC,oBAAoB,aACjC,0CAAuB,EACvB,uBACC,yBAAO,OAAO,CAAC,aAAa,GAAQ,GAChC,EACL,sCAAmB,EACnB,yBAAK,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,UAAU,GAAG,GAAG,CAAC,SAAO,EAChD,kCAAe,EACf,uBAAK,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,oDAA4B,GAAM,IAC3E,CACL,CAAA;AACF,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,EAAE,OAAO,EAAqB;IAC1D,IAAI,OAAO,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;QAC9B,OAAO,CACN,8BACC,eAAK,SAAS,EAAC,iBAAiB,aAC/B,eAAM,SAAS,EAAC,kBAAkB,YAAE,OAAO,CAAC,IAAI,GAAQ,EACxD,eAAM,SAAS,EAAC,4CAA4C,sBAAa,EACxE,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CACnB,YACC,SAAS,EAAC,iBAAiB,EAC3B,IAAI,EAAE,iCAAiC,OAAO,CAAC,QAAQ,EAAE,EACzD,MAAM,EAAC,QAAQ,EACf,GAAG,EAAC,YAAY,YAEf,OAAO,CAAC,QAAQ,GACd,CACJ,CAAC,CAAC,CAAC,IAAI,IACH,EAEN,KAAC,WAAW,IAAC,OAAO,EAAE,OAAO,GAAI,EAEjC,YAAG,SAAS,EAAC,kBAAkB,0GAE3B,IACF,CACH,CAAA;IACF,CAAC;IAED,OAAO,CACN,8BACC,eAAK,SAAS,EAAC,iBAAiB,aAC/B,eAAM,SAAS,EAAC,kBAAkB,YAAE,OAAO,CAAC,QAAQ,CAAC,KAAK,GAAQ,EACjE,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,eAAM,SAAS,EAAC,mBAAmB,4BAAmB,CAAC,CAAC,CAAC,IAAI,IAC9E,EAEN,KAAC,WAAW,IAAC,OAAO,EAAE,OAAO,GAAI,EAEhC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,CACrB,YAAG,SAAS,EAAC,kBAAkB,8GAE3B,CACJ,CAAC,CAAC,CAAC,IAAI,IACN,CACH,CAAA;AACF,CAAC"}
@@ -10,11 +10,17 @@
10
10
  */
11
11
  import type { POIRuntime } from "./types.ts";
12
12
  /**
13
- * Build the POI runtime, dynamically importing the taxonomy JSON so the ~2k-record table lands in its own chunk. A
13
+ * Build the POI runtime, dynamically importing the taxonomy + brand JSON so the tables land in their own chunk. A
14
14
  * static import would inline the whole snapshot into every consumer's bundle.
15
+ *
16
+ * The lexicon unions categories then brands, mirroring the Node runtime's `poiTaxonomyLookup` precedence: a phrase that
17
+ * matches a taxonomy CATEGORY wins (the curated set); only on a category miss does the chain-brand table fire,
18
+ * returning a `kind: "brand"` match carrying the brand's canonical name + Wikidata QID. (The Node path also chains
19
+ * `@mailwoman/variant-aliases` regional slang; the browser tester leaves that out — one fewer package + data table for
20
+ * a demo, and the QID-keyed brand table already covers the headline brands.)
15
21
  */
16
22
  export declare function loadPOIRuntime(): Promise<POIRuntime>;
17
- /** Default example queries for the POI explorer. */
23
+ /** Default example queries for the POI explorer — a mix of category, build-local, and chain-brand subjects. */
18
24
  export declare const POI_PRESETS: readonly [{
19
25
  readonly label: "Drinking fountain";
20
26
  readonly value: "drinking fountain near Springfield";
@@ -25,8 +31,11 @@ export declare const POI_PRESETS: readonly [{
25
31
  readonly label: "Hospital + address";
26
32
  readonly value: "hospital, 350 5th Ave, New York";
27
33
  }, {
28
- readonly label: "Biking trails";
29
- readonly value: "biking trails near Portland";
34
+ readonly label: "Chevron (brand)";
35
+ readonly value: "chevron near Houston";
36
+ }, {
37
+ readonly label: "Applebee's (brand)";
38
+ readonly value: "applebee's near Chicago";
30
39
  }];
31
40
  export declare const POI_DEFAULT_TEXT: "drinking fountain near Springfield";
32
41
  /** `742 m` under 1 km, `1.9 km` past it — matches the demo's distance captions. */
@@ -1 +1 @@
1
- {"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../../poi/runtime.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAMH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAE5C;;;GAGG;AACH,wBAAsB,cAAc,IAAI,OAAO,CAAC,UAAU,CAAC,CAc1D;AAED,oDAAoD;AACpD,eAAO,MAAM,WAAW;;;;;;;;;;;;EAKd,CAAA;AAEV,eAAO,MAAM,gBAAgB,sCAAuB,CAAA;AAEpD,mFAAmF;AACnF,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAIxD"}
1
+ {"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../../poi/runtime.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAMH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAE5C;;;;;;;;;GASG;AACH,wBAAsB,cAAc,IAAI,OAAO,CAAC,UAAU,CAAC,CAgC1D;AAED,+GAA+G;AAC/G,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;EAMd,CAAA;AAEV,eAAO,MAAM,gBAAgB,sCAAuB,CAAA;AAEpD,mFAAmF;AACnF,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAIxD"}
@@ -9,29 +9,53 @@
9
9
  * network, no DOM — the whole intent path runs offline.
10
10
  */
11
11
  import { createKindClassifier } from "@mailwoman/kind-classifier";
12
- import { createPOITaxonomyLookup } from "@mailwoman/poi-taxonomy/table";
12
+ import { createPOIBrandLookup, createPOITaxonomyLookup } from "@mailwoman/poi-taxonomy/table";
13
13
  /**
14
- * Build the POI runtime, dynamically importing the taxonomy JSON so the ~2k-record table lands in its own chunk. A
14
+ * Build the POI runtime, dynamically importing the taxonomy + brand JSON so the tables land in their own chunk. A
15
15
  * static import would inline the whole snapshot into every consumer's bundle.
16
+ *
17
+ * The lexicon unions categories then brands, mirroring the Node runtime's `poiTaxonomyLookup` precedence: a phrase that
18
+ * matches a taxonomy CATEGORY wins (the curated set); only on a category miss does the chain-brand table fire,
19
+ * returning a `kind: "brand"` match carrying the brand's canonical name + Wikidata QID. (The Node path also chains
20
+ * `@mailwoman/variant-aliases` regional slang; the browser tester leaves that out — one fewer package + data table for
21
+ * a demo, and the QID-keyed brand table already covers the headline brands.)
16
22
  */
17
23
  export async function loadPOIRuntime() {
18
- const table = (await import("@mailwoman/poi-taxonomy/data/taxonomy.json")).default;
24
+ const [table, brandTable] = await Promise.all([
25
+ import("@mailwoman/poi-taxonomy/data/taxonomy.json").then((m) => m.default),
26
+ import("@mailwoman/poi-taxonomy/data/brands.json").then((m) => m.default),
27
+ ]);
19
28
  const lookup = createPOITaxonomyLookup(table);
20
- // Adapt `POITaxonomyLookup.lookupPOICategory` to the `POIPhraseLookup` shape the classifier expects.
21
- const lexicon = (phrase, locale) => lookup.lookupPOICategory(phrase, locale).map((match) => ({
22
- kind: "category",
23
- categoryID: match.category.id,
24
- matchedPhrase: match.matchedPhrase,
25
- confidence: match.confidence,
26
- }));
29
+ const brands = createPOIBrandLookup(brandTable);
30
+ // Adapt the taxonomy + brand lookups to the `POIPhraseLookup` shape the classifier expects: categories first, brands
31
+ // on a category miss.
32
+ const lexicon = (phrase, locale) => {
33
+ const categoryHits = lookup.lookupPOICategory(phrase, locale);
34
+ if (categoryHits.length > 0) {
35
+ return categoryHits.map((match) => ({
36
+ kind: "category",
37
+ categoryID: match.category.id,
38
+ matchedPhrase: match.matchedPhrase,
39
+ confidence: match.confidence,
40
+ }));
41
+ }
42
+ return brands.lookupPOIBrand(phrase).map((match) => ({
43
+ kind: "brand",
44
+ categoryID: match.brand.name,
45
+ wikidata: match.brand.wikidata,
46
+ matchedPhrase: match.matchedPhrase,
47
+ confidence: match.confidence,
48
+ }));
49
+ };
27
50
  return { lookup, lexicon, classify: createKindClassifier({ poiLexicon: lexicon }) };
28
51
  }
29
- /** Default example queries for the POI explorer. */
52
+ /** Default example queries for the POI explorer — a mix of category, build-local, and chain-brand subjects. */
30
53
  export const POI_PRESETS = [
31
54
  { label: "Drinking fountain", value: "drinking fountain near Springfield" },
32
55
  { label: "Fire hydrant", value: "fire hydrant" },
33
56
  { label: "Hospital + address", value: "hospital, 350 5th Ave, New York" },
34
- { label: "Biking trails", value: "biking trails near Portland" },
57
+ { label: "Chevron (brand)", value: "chevron near Houston" },
58
+ { label: "Applebee's (brand)", value: "applebee's near Chicago" },
35
59
  ];
36
60
  export const POI_DEFAULT_TEXT = POI_PRESETS[0].value;
37
61
  /** `742 m` under 1 km, `1.9 km` past it — matches the demo's distance captions. */
@@ -1 +1 @@
1
- {"version":3,"file":"runtime.js","sourceRoot":"","sources":["../../poi/runtime.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAA;AAEjE,OAAO,EAAE,uBAAuB,EAAE,MAAM,+BAA+B,CAAA;AAIvE;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc;IACnC,MAAM,KAAK,GAAG,CAAC,MAAM,MAAM,CAAC,4CAA4C,CAAC,CAAC,CAAC,OAAO,CAAA;IAClF,MAAM,MAAM,GAAG,uBAAuB,CAAC,KAAiE,CAAC,CAAA;IAEzG,qGAAqG;IACrG,MAAM,OAAO,GAAoB,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,CACnD,MAAM,CAAC,iBAAiB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QACxD,IAAI,EAAE,UAAU;QAChB,UAAU,EAAE,KAAK,CAAC,QAAQ,CAAC,EAAE;QAC7B,aAAa,EAAE,KAAK,CAAC,aAAa;QAClC,UAAU,EAAE,KAAK,CAAC,UAAU;KAC5B,CAAC,CAAC,CAAA;IAEJ,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,oBAAoB,CAAC,EAAE,UAAU,EAAE,OAAO,EAAE,CAAC,EAAE,CAAA;AACpF,CAAC;AAED,oDAAoD;AACpD,MAAM,CAAC,MAAM,WAAW,GAAG;IAC1B,EAAE,KAAK,EAAE,mBAAmB,EAAE,KAAK,EAAE,oCAAoC,EAAE;IAC3E,EAAE,KAAK,EAAE,cAAc,EAAE,KAAK,EAAE,cAAc,EAAE;IAChD,EAAE,KAAK,EAAE,oBAAoB,EAAE,KAAK,EAAE,iCAAiC,EAAE;IACzE,EAAE,KAAK,EAAE,eAAe,EAAE,KAAK,EAAE,6BAA6B,EAAE;CACvD,CAAA;AAEV,MAAM,CAAC,MAAM,gBAAgB,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC,KAAK,CAAA;AAEpD,mFAAmF;AACnF,MAAM,UAAU,cAAc,CAAC,SAAiB;IAC/C,IAAI,SAAS,GAAG,IAAI;QAAE,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,IAAI,CAAA;IAEzD,OAAO,GAAG,CAAC,SAAS,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAA;AAC7C,CAAC"}
1
+ {"version":3,"file":"runtime.js","sourceRoot":"","sources":["../../poi/runtime.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAA;AAEjE,OAAO,EAAE,oBAAoB,EAAE,uBAAuB,EAAE,MAAM,+BAA+B,CAAA;AAI7F;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc;IACnC,MAAM,CAAC,KAAK,EAAE,UAAU,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;QAC7C,MAAM,CAAC,4CAA4C,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC;QAC3E,MAAM,CAAC,0CAA0C,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC;KACzE,CAAC,CAAA;IACF,MAAM,MAAM,GAAG,uBAAuB,CAAC,KAAiE,CAAC,CAAA;IACzG,MAAM,MAAM,GAAG,oBAAoB,CAAC,UAAmE,CAAC,CAAA;IAExG,qHAAqH;IACrH,sBAAsB;IACtB,MAAM,OAAO,GAAoB,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE;QACnD,MAAM,YAAY,GAAG,MAAM,CAAC,iBAAiB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;QAE7D,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC7B,OAAO,YAAY,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;gBACnC,IAAI,EAAE,UAAU;gBAChB,UAAU,EAAE,KAAK,CAAC,QAAQ,CAAC,EAAE;gBAC7B,aAAa,EAAE,KAAK,CAAC,aAAa;gBAClC,UAAU,EAAE,KAAK,CAAC,UAAU;aAC5B,CAAC,CAAC,CAAA;QACJ,CAAC;QAED,OAAO,MAAM,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;YACpD,IAAI,EAAE,OAAO;YACb,UAAU,EAAE,KAAK,CAAC,KAAK,CAAC,IAAI;YAC5B,QAAQ,EAAE,KAAK,CAAC,KAAK,CAAC,QAAQ;YAC9B,aAAa,EAAE,KAAK,CAAC,aAAa;YAClC,UAAU,EAAE,KAAK,CAAC,UAAU;SAC5B,CAAC,CAAC,CAAA;IACJ,CAAC,CAAA;IAED,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,oBAAoB,CAAC,EAAE,UAAU,EAAE,OAAO,EAAE,CAAC,EAAE,CAAA;AACpF,CAAC;AAED,+GAA+G;AAC/G,MAAM,CAAC,MAAM,WAAW,GAAG;IAC1B,EAAE,KAAK,EAAE,mBAAmB,EAAE,KAAK,EAAE,oCAAoC,EAAE;IAC3E,EAAE,KAAK,EAAE,cAAc,EAAE,KAAK,EAAE,cAAc,EAAE;IAChD,EAAE,KAAK,EAAE,oBAAoB,EAAE,KAAK,EAAE,iCAAiC,EAAE;IACzE,EAAE,KAAK,EAAE,iBAAiB,EAAE,KAAK,EAAE,sBAAsB,EAAE;IAC3D,EAAE,KAAK,EAAE,oBAAoB,EAAE,KAAK,EAAE,yBAAyB,EAAE;CACxD,CAAA;AAEV,MAAM,CAAC,MAAM,gBAAgB,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC,KAAK,CAAA;AAEpD,mFAAmF;AACnF,MAAM,UAAU,cAAc,CAAC,SAAiB;IAC/C,IAAI,SAAS,GAAG,IAAI;QAAE,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,IAAI,CAAA;IAEzD,OAAO,GAAG,CAAC,SAAS,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAA;AAC7C,CAAC"}
@@ -19,17 +19,35 @@ export interface POIRuntime {
19
19
  lexicon: POIPhraseLookup;
20
20
  classify: ReturnType<typeof createKindClassifier>;
21
21
  }
22
- /** A resolved POI subject — the category the query names plus its match metadata. */
23
- export interface POISubject {
24
- category: CategoryRecord;
22
+ /** Fields shared by every resolved POI subject, category or brand. */
23
+ export interface POISubjectBase {
25
24
  matchedPhrase: string;
26
25
  confidence: number;
27
26
  /** The non-subject remainder of the query (the location anchor, e.g. "near Springfield"). */
28
27
  remainder: string;
28
+ }
29
+ /** A resolved POI subject that names a taxonomy CATEGORY (`cafe`, `hospital`, `drinking fountain`). */
30
+ export interface POICategorySubject extends POISubjectBase {
31
+ kind: "category";
32
+ category: CategoryRecord;
29
33
  /** Whether this category needs the locally-built OSM (ODbL) layer — precomputed off the runtime. */
30
34
  buildLocal: boolean;
31
35
  }
32
- /** The intent-only result: the kind verdict plus (when a subject was detected) its OverpassQL export. */
36
+ /**
37
+ * A resolved POI subject that names a chain BRAND (`chevron`, `applebee's`). Brands carry a Wikidata QID and are
38
+ * searched by that QID, NOT by category k-ring — see `@mailwoman/poi-taxonomy`'s brand table + the layer's
39
+ * `brand_wikidata` index.
40
+ */
41
+ export interface POIBrandSubject extends POISubjectBase {
42
+ kind: "brand";
43
+ /** The brand's canonical display name. */
44
+ name: string;
45
+ /** Wikidata QID, when the lexicon carried one (`Q319642` = Chevron). Absent ⇒ matched by name alone. */
46
+ wikidata?: string;
47
+ }
48
+ /** A resolved POI subject — a taxonomy category or a chain brand — plus its match metadata. */
49
+ export type POISubject = POICategorySubject | POIBrandSubject;
50
+ /** The intent-only result: the kind verdict plus (when a subject was detected) its OverpassQL export (category only). */
33
51
  export interface POIExplorerResult {
34
52
  kindResult: QueryKindResult;
35
53
  subject?: POISubject;
@@ -62,11 +80,20 @@ export type POILiveSearchResult = {
62
80
  /**
63
81
  * The injected live-search function. Given the resolved category (+ its Overture leaf fan-out) and the anchor text, it
64
82
  * probes the published poi.db and returns hits. Absent ⇒ the explorer runs intent-only (no "Search live" button).
83
+ *
84
+ * Brand support is ADDITIVE: when the resolved subject is a chain brand, `brandWikidata` carries its QID and the probe
85
+ * fetches by that QID instead of a category k-ring (`categoryID`/`overtureCategoryIDs` are then the brand name / empty
86
+ * and unused). The category path is byte-identical to before. A probe that can't serve brands simply leaves brand live
87
+ * search unwired at the call site (see `usePOISearch`'s `brandLiveSearch` option) — the docs' httpvfs probe does
88
+ * exactly that, brand-wide row hydration being pathological over byte-range (measured; the brand path is server-side
89
+ * only).
65
90
  */
66
91
  export type POILiveSearch = (params: {
67
92
  categoryID: string;
68
93
  overtureCategoryIDs: string[];
69
94
  anchor: string;
95
+ /** Present when the subject is a chain brand — the probe fetches by this QID, not a category k-ring. */
96
+ brandWikidata?: string;
70
97
  }) => Promise<POILiveSearchResult>;
71
98
  /** "Search live" state machine. */
72
99
  export type LiveSearchState = {
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../poi/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAA;AAClF,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAA;AACtE,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,+BAA+B,CAAA;AAE5E,MAAM,MAAM,cAAc,GAAG,UAAU,CAAC,OAAO,uBAAuB,CAAC,CAAA;AACvE,MAAM,MAAM,cAAc,GAAG,WAAW,CAAC,UAAU,CAAC,cAAc,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAA;AAEtF,gHAAgH;AAChH,MAAM,WAAW,UAAU;IAC1B,MAAM,EAAE,cAAc,CAAA;IACtB,OAAO,EAAE,eAAe,CAAA;IACxB,QAAQ,EAAE,UAAU,CAAC,OAAO,oBAAoB,CAAC,CAAA;CACjD;AAED,qFAAqF;AACrF,MAAM,WAAW,UAAU;IAC1B,QAAQ,EAAE,cAAc,CAAA;IACxB,aAAa,EAAE,MAAM,CAAA;IACrB,UAAU,EAAE,MAAM,CAAA;IAClB,6FAA6F;IAC7F,SAAS,EAAE,MAAM,CAAA;IACjB,oGAAoG;IACpG,UAAU,EAAE,OAAO,CAAA;CACnB;AAED,yGAAyG;AACzG,MAAM,WAAW,iBAAiB;IACjC,UAAU,EAAE,eAAe,CAAA;IAC3B,OAAO,CAAC,EAAE,UAAU,CAAA;IACpB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,aAAa,CAAC,EAAE,MAAM,CAAA;CACtB;AAED,2DAA2D;AAC3D,MAAM,WAAW,YAAY;IAC5B,IAAI,EAAE,MAAM,CAAA;IACZ,GAAG,EAAE,MAAM,CAAA;IACX,GAAG,EAAE,MAAM,CAAA;IACX,SAAS,EAAE,MAAM,CAAA;IACjB,OAAO,EAAE,MAAM,CAAA;IACf,UAAU,EAAE,MAAM,CAAA;CAClB;AAED;;;GAGG;AACH,MAAM,MAAM,mBAAmB,GAC5B;IAAE,MAAM,EAAE,SAAS,CAAC;IAAC,IAAI,EAAE,YAAY,EAAE,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,GAC/D;IAAE,MAAM,EAAE,UAAU,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GACtC;IAAE,MAAM,EAAE,aAAa,CAAA;CAAE,CAAA;AAE5B;;;GAGG;AACH,MAAM,MAAM,aAAa,GAAG,CAAC,MAAM,EAAE;IACpC,UAAU,EAAE,MAAM,CAAA;IAClB,mBAAmB,EAAE,MAAM,EAAE,CAAA;IAC7B,MAAM,EAAE,MAAM,CAAA;CACd,KAAK,OAAO,CAAC,mBAAmB,CAAC,CAAA;AAElC,mCAAmC;AACnC,MAAM,MAAM,eAAe,GACxB;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,GAClB;IAAE,MAAM,EAAE,SAAS,CAAA;CAAE,GACrB;IAAE,MAAM,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GACpC;IAAE,MAAM,EAAE,SAAS,CAAC;IAAC,IAAI,EAAE,YAAY,EAAE,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAAA;AAElE,qGAAqG;AACrG,MAAM,MAAM,cAAc,GAAG,MAAM,OAAO,CAAC,UAAU,CAAC,CAAA"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../poi/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAA;AAClF,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAA;AACtE,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,+BAA+B,CAAA;AAE5E,MAAM,MAAM,cAAc,GAAG,UAAU,CAAC,OAAO,uBAAuB,CAAC,CAAA;AACvE,MAAM,MAAM,cAAc,GAAG,WAAW,CAAC,UAAU,CAAC,cAAc,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAA;AAEtF,gHAAgH;AAChH,MAAM,WAAW,UAAU;IAC1B,MAAM,EAAE,cAAc,CAAA;IACtB,OAAO,EAAE,eAAe,CAAA;IACxB,QAAQ,EAAE,UAAU,CAAC,OAAO,oBAAoB,CAAC,CAAA;CACjD;AAED,sEAAsE;AACtE,MAAM,WAAW,cAAc;IAC9B,aAAa,EAAE,MAAM,CAAA;IACrB,UAAU,EAAE,MAAM,CAAA;IAClB,6FAA6F;IAC7F,SAAS,EAAE,MAAM,CAAA;CACjB;AAED,uGAAuG;AACvG,MAAM,WAAW,kBAAmB,SAAQ,cAAc;IACzD,IAAI,EAAE,UAAU,CAAA;IAChB,QAAQ,EAAE,cAAc,CAAA;IACxB,oGAAoG;IACpG,UAAU,EAAE,OAAO,CAAA;CACnB;AAED;;;;GAIG;AACH,MAAM,WAAW,eAAgB,SAAQ,cAAc;IACtD,IAAI,EAAE,OAAO,CAAA;IACb,0CAA0C;IAC1C,IAAI,EAAE,MAAM,CAAA;IACZ,wGAAwG;IACxG,QAAQ,CAAC,EAAE,MAAM,CAAA;CACjB;AAED,+FAA+F;AAC/F,MAAM,MAAM,UAAU,GAAG,kBAAkB,GAAG,eAAe,CAAA;AAE7D,yHAAyH;AACzH,MAAM,WAAW,iBAAiB;IACjC,UAAU,EAAE,eAAe,CAAA;IAC3B,OAAO,CAAC,EAAE,UAAU,CAAA;IACpB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,aAAa,CAAC,EAAE,MAAM,CAAA;CACtB;AAED,2DAA2D;AAC3D,MAAM,WAAW,YAAY;IAC5B,IAAI,EAAE,MAAM,CAAA;IACZ,GAAG,EAAE,MAAM,CAAA;IACX,GAAG,EAAE,MAAM,CAAA;IACX,SAAS,EAAE,MAAM,CAAA;IACjB,OAAO,EAAE,MAAM,CAAA;IACf,UAAU,EAAE,MAAM,CAAA;CAClB;AAED;;;GAGG;AACH,MAAM,MAAM,mBAAmB,GAC5B;IAAE,MAAM,EAAE,SAAS,CAAC;IAAC,IAAI,EAAE,YAAY,EAAE,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,GAC/D;IAAE,MAAM,EAAE,UAAU,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GACtC;IAAE,MAAM,EAAE,aAAa,CAAA;CAAE,CAAA;AAE5B;;;;;;;;;;GAUG;AACH,MAAM,MAAM,aAAa,GAAG,CAAC,MAAM,EAAE;IACpC,UAAU,EAAE,MAAM,CAAA;IAClB,mBAAmB,EAAE,MAAM,EAAE,CAAA;IAC7B,MAAM,EAAE,MAAM,CAAA;IACd,wGAAwG;IACxG,aAAa,CAAC,EAAE,MAAM,CAAA;CACtB,KAAK,OAAO,CAAC,mBAAmB,CAAC,CAAA;AAElC,mCAAmC;AACnC,MAAM,MAAM,eAAe,GACxB;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,GAClB;IAAE,MAAM,EAAE,SAAS,CAAA;CAAE,GACrB;IAAE,MAAM,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GACpC;IAAE,MAAM,EAAE,SAAS,CAAC;IAAC,IAAI,EAAE,YAAY,EAAE,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAAA;AAElE,qGAAqG;AACrG,MAAM,MAAM,cAAc,GAAG,MAAM,OAAO,CAAC,UAAU,CAAC,CAAA"}
@@ -16,6 +16,13 @@ export interface UsePOISearchOptions {
16
16
  loadRuntime?: LoadPOIRuntime;
17
17
  /** Injected live-search probe. Absent ⇒ the live-results affordance is disabled. */
18
18
  runLiveSearch?: POILiveSearch;
19
+ /**
20
+ * Whether the injected probe can serve BRAND subjects (fetch by Wikidata QID). Default false: brand subjects show the
21
+ * intent + QID chip but no live-search affordance. The docs' httpvfs probe leaves this off — brand-wide row hydration
22
+ * is pathological over byte-range (measured) — so brand live search is a server-side-backend capability. Category
23
+ * live search is unaffected either way.
24
+ */
25
+ brandLiveSearch?: boolean;
19
26
  /** Debounce before (re)classifying. @default 250 */
20
27
  debounceMs?: number;
21
28
  }
@@ -31,5 +38,5 @@ export interface UsePOISearch {
31
38
  /** Kick off a live search for the current subject. No-op when {@link canSearchLive} is false. */
32
39
  searchLive: () => Promise<void>;
33
40
  }
34
- export declare function usePOISearch({ text, loadRuntime, runLiveSearch, debounceMs, }: UsePOISearchOptions): UsePOISearch;
41
+ export declare function usePOISearch({ text, loadRuntime, runLiveSearch, brandLiveSearch, debounceMs, }: UsePOISearchOptions): UsePOISearch;
35
42
  //# sourceMappingURL=usePOISearch.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"usePOISearch.d.ts","sourceRoot":"","sources":["../../poi/usePOISearch.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAUH,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,iBAAiB,EAAE,aAAa,EAAc,MAAM,YAAY,CAAA;AAE/G,MAAM,WAAW,mBAAmB;IACnC,yDAAyD;IACzD,IAAI,EAAE,MAAM,CAAA;IACZ,8CAA8C;IAC9C,WAAW,CAAC,EAAE,cAAc,CAAA;IAC5B,oFAAoF;IACpF,aAAa,CAAC,EAAE,aAAa,CAAA;IAC7B,oDAAoD;IACpD,UAAU,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,MAAM,WAAW,YAAY;IAC5B,iDAAiD;IACjD,YAAY,EAAE,OAAO,CAAA;IACrB,oFAAoF;IACpF,MAAM,EAAE,iBAAiB,GAAG,IAAI,CAAA;IAChC,iDAAiD;IACjD,UAAU,EAAE,eAAe,CAAA;IAC3B,8GAA8G;IAC9G,aAAa,EAAE,OAAO,CAAA;IACtB,iGAAiG;IACjG,UAAU,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;CAC/B;AA2BD,wBAAgB,YAAY,CAAC,EAC5B,IAAI,EACJ,WAA4B,EAC5B,aAAa,EACb,UAAgB,GAChB,EAAE,mBAAmB,GAAG,YAAY,CA2GpC"}
1
+ {"version":3,"file":"usePOISearch.d.ts","sourceRoot":"","sources":["../../poi/usePOISearch.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAUH,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,iBAAiB,EAAE,aAAa,EAAc,MAAM,YAAY,CAAA;AAE/G,MAAM,WAAW,mBAAmB;IACnC,yDAAyD;IACzD,IAAI,EAAE,MAAM,CAAA;IACZ,8CAA8C;IAC9C,WAAW,CAAC,EAAE,cAAc,CAAA;IAC5B,oFAAoF;IACpF,aAAa,CAAC,EAAE,aAAa,CAAA;IAC7B;;;;;OAKG;IACH,eAAe,CAAC,EAAE,OAAO,CAAA;IACzB,oDAAoD;IACpD,UAAU,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,MAAM,WAAW,YAAY;IAC5B,iDAAiD;IACjD,YAAY,EAAE,OAAO,CAAA;IACrB,oFAAoF;IACpF,MAAM,EAAE,iBAAiB,GAAG,IAAI,CAAA;IAChC,iDAAiD;IACjD,UAAU,EAAE,eAAe,CAAA;IAC3B,8GAA8G;IAC9G,aAAa,EAAE,OAAO,CAAA;IACtB,iGAAiG;IACjG,UAAU,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;CAC/B;AA2BD,wBAAgB,YAAY,CAAC,EAC5B,IAAI,EACJ,WAA4B,EAC5B,aAAa,EACb,eAAuB,EACvB,UAAgB,GAChB,EAAE,mBAAmB,GAAG,YAAY,CAsJpC"}
@@ -31,7 +31,7 @@ function buildOverpass(runtime, categoryID, matchedPhrase, remainder) {
31
31
  return { overpassError: err instanceof Error ? err.message : String(err) };
32
32
  }
33
33
  }
34
- export function usePOISearch({ text, loadRuntime = loadPOIRuntime, runLiveSearch, debounceMs = 250, }) {
34
+ export function usePOISearch({ text, loadRuntime = loadPOIRuntime, runLiveSearch, brandLiveSearch = false, debounceMs = 250, }) {
35
35
  const [runtime, setRuntime] = useState(null);
36
36
  const [result, setResult] = useState(null);
37
37
  const [liveSearch, setLiveSearch] = useState({ status: "idle" });
@@ -70,14 +70,35 @@ export function usePOISearch({ text, loadRuntime = loadPOIRuntime, runLiveSearch
70
70
  if (cancelled)
71
71
  return;
72
72
  const matched = kindResult.kind === "poi_query" ? matchPOISubject(trimmed, undefined, runtime.lexicon) : null;
73
- const category = matched ? runtime.lookup.getPOICategory(matched.match.categoryID) : undefined;
74
- if (!matched || !category) {
73
+ if (!matched) {
74
+ setResult({ kindResult });
75
+ return;
76
+ }
77
+ // Brand subject: the lexicon carries the brand's canonical name as `categoryID` + its Wikidata QID. No category
78
+ // record, no OverpassQL (brands are searched by QID against the layer's `brand_wikidata` index, not OSM tags).
79
+ if ((matched.match.kind ?? "category") === "brand") {
80
+ setResult({
81
+ kindResult,
82
+ subject: {
83
+ kind: "brand",
84
+ name: matched.match.categoryID,
85
+ ...(matched.match.wikidata ? { wikidata: matched.match.wikidata } : {}),
86
+ matchedPhrase: matched.match.matchedPhrase,
87
+ confidence: matched.match.confidence,
88
+ remainder: matched.remainder,
89
+ },
90
+ });
91
+ return;
92
+ }
93
+ const category = runtime.lookup.getPOICategory(matched.match.categoryID);
94
+ if (!category) {
75
95
  setResult({ kindResult });
76
96
  return;
77
97
  }
78
98
  setResult({
79
99
  kindResult,
80
100
  subject: {
101
+ kind: "category",
81
102
  category,
82
103
  matchedPhrase: matched.match.matchedPhrase,
83
104
  confidence: matched.match.confidence,
@@ -92,18 +113,32 @@ export function usePOISearch({ text, loadRuntime = loadPOIRuntime, runLiveSearch
92
113
  };
93
114
  }, [debouncedText, runtime]);
94
115
  const subject = result?.subject;
95
- const canSearchLive = Boolean(runLiveSearch && runtime && subject && !subject.buildLocal && subject.remainder.trim().length > 0);
116
+ // A subject is live-searchable when a probe is wired, it has an anchor, and: a CATEGORY that isn't build-local, or a
117
+ // BRAND with a QID AND a brand-capable probe (`brandLiveSearch`). Brands without a QID / without a brand probe show
118
+ // the intent + QID chip but no live affordance.
119
+ const subjectLiveCapable = subject !== undefined &&
120
+ (subject.kind === "brand" ? brandLiveSearch && subject.wikidata !== undefined : !subject.buildLocal);
121
+ const canSearchLive = Boolean(runLiveSearch && runtime && subject && subjectLiveCapable && subject.remainder.trim().length > 0);
96
122
  const searchLive = useCallback(async () => {
97
- if (!runLiveSearch || !runtime || !subject || subject.buildLocal || !subject.remainder.trim())
123
+ if (!runLiveSearch || !runtime || !subject || !subject.remainder.trim())
124
+ return;
125
+ if (subject.kind === "category" ? subject.buildLocal : !(brandLiveSearch && subject.wikidata))
98
126
  return;
99
127
  setLiveSearch({ status: "loading" });
100
128
  try {
101
- const outcome = await runLiveSearch({
102
- categoryID: subject.category.id,
103
- // Fan the canonical seed id out over its Overture leaves — the same translation the Node reader uses.
104
- overtureCategoryIDs: runtime.lookup.resolveOvertureCategories(subject.category.id),
105
- anchor: subject.remainder,
106
- });
129
+ const outcome = await runLiveSearch(subject.kind === "brand"
130
+ ? {
131
+ categoryID: subject.name,
132
+ overtureCategoryIDs: [],
133
+ anchor: subject.remainder,
134
+ brandWikidata: subject.wikidata,
135
+ }
136
+ : {
137
+ categoryID: subject.category.id,
138
+ // Fan the canonical seed id out over its Overture leaves — the same translation the Node reader uses.
139
+ overtureCategoryIDs: runtime.lookup.resolveOvertureCategories(subject.category.id),
140
+ anchor: subject.remainder,
141
+ });
107
142
  if (outcome.status === "success") {
108
143
  setLiveSearch({ status: "success", hits: outcome.hits, centerName: outcome.centerName });
109
144
  }
@@ -117,7 +152,7 @@ export function usePOISearch({ text, loadRuntime = loadPOIRuntime, runLiveSearch
117
152
  catch {
118
153
  setLiveSearch({ status: "error", message: "the published POI layer isn't reachable" });
119
154
  }
120
- }, [runLiveSearch, runtime, subject]);
155
+ }, [runLiveSearch, runtime, subject, brandLiveSearch]);
121
156
  return { runtimeReady: runtime !== null, result, liveSearch, canSearchLive, searchLive };
122
157
  }
123
158
  //# sourceMappingURL=usePOISearch.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"usePOISearch.js","sourceRoot":"","sources":["../../poi/usePOISearch.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"usePOISearch.js","sourceRoot":"","sources":["../../poi/usePOISearch.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mailwoman/react",
3
- "version": "7.4.0",
3
+ "version": "7.5.0",
4
4
  "description": "React components + headless hooks for mailwoman — parse/geocode/POI explorers, Storybook-tested, Docusaurus-independent.",
5
5
  "license": "AGPL-3.0-only OR LicenseRef-Commercial",
6
6
  "repository": {
@@ -58,13 +58,13 @@
58
58
  "test:browser": "vitest run --config vitest.config.ts"
59
59
  },
60
60
  "dependencies": {
61
- "@mailwoman/kind-classifier": "7.4.0",
62
- "@mailwoman/poi-taxonomy": "7.4.0",
63
- "@mailwoman/query-shape": "7.4.0"
61
+ "@mailwoman/kind-classifier": "7.5.0",
62
+ "@mailwoman/poi-taxonomy": "7.5.0",
63
+ "@mailwoman/query-shape": "7.5.0"
64
64
  },
65
65
  "devDependencies": {
66
- "@storybook/addon-docs": "^10.5.0",
67
- "@storybook/react-vite": "^10.5.0",
66
+ "@storybook/addon-docs": "^10.5.2",
67
+ "@storybook/react-vite": "^10.5.2",
68
68
  "@types/react": "^19.2.17",
69
69
  "@types/react-dom": "^19.2.3",
70
70
  "@vitejs/plugin-react": "^6.0.3",
@@ -73,8 +73,8 @@
73
73
  "playwright": "^1.61.1",
74
74
  "react": "^19.2.7",
75
75
  "react-dom": "^19.2.7",
76
- "storybook": "^10.5.0",
77
- "vite": "^8.0.16",
76
+ "storybook": "^10.5.2",
77
+ "vite": "^8.1.5",
78
78
  "vitest": "4.1.10"
79
79
  },
80
80
  "peerDependencies": {
@@ -14,15 +14,15 @@ import { formatDistance } from "./runtime.ts"
14
14
  import type { LiveSearchState } from "./types.ts"
15
15
 
16
16
  export interface LiveResultsBlockProps {
17
- /** Category label for empty-state copy ("No hospital results near …"). */
18
- categoryLabel: string
17
+ /** Subject label for empty-state copy — a category ("No hospital results near …") or a brand ("No chevron results …"). */
18
+ subjectLabel: string
19
19
  /** The location anchor the search runs against (empty ⇒ the button is disabled with a hint). */
20
20
  anchor: string
21
21
  state: LiveSearchState
22
22
  onSearch: () => void
23
23
  }
24
24
 
25
- export function LiveResultsBlock({ categoryLabel, anchor, state, onSearch }: LiveResultsBlockProps): ReactNode {
25
+ export function LiveResultsBlock({ subjectLabel, anchor, state, onSearch }: LiveResultsBlockProps): ReactNode {
26
26
  const hasAnchor = anchor.trim().length > 0
27
27
 
28
28
  return (
@@ -47,7 +47,7 @@ export function LiveResultsBlock({ categoryLabel, anchor, state, onSearch }: Liv
47
47
  ) : state.status === "success" ? (
48
48
  state.hits.length === 0 ? (
49
49
  <p className="mw-muted">
50
- No {categoryLabel.toLowerCase()} results near {state.centerName}.
50
+ No {subjectLabel.toLowerCase()} results near {state.centerName}.
51
51
  </p>
52
52
  ) : (
53
53
  <>
@@ -32,6 +32,12 @@ export interface POIExplorerProps {
32
32
  loadRuntime?: LoadPOIRuntime
33
33
  /** Live poi.db probe. Absent ⇒ intent-only (no live-results affordance). */
34
34
  runLiveSearch?: POILiveSearch
35
+ /**
36
+ * Whether {@link runLiveSearch} can serve BRAND subjects (fetch by QID). Default false: a brand subject shows the
37
+ * intent + QID chip but no live block. The docs' httpvfs probe leaves this off (brand-wide byte-range hydration is
38
+ * pathological — measured); a server-side backend can enable it.
39
+ */
40
+ brandLiveSearch?: boolean
35
41
  }
36
42
 
37
43
  interface POIExplorerInnerProps extends POIExplorerProps {
@@ -39,9 +45,30 @@ interface POIExplorerInnerProps extends POIExplorerProps {
39
45
  presets: ReadonlyArray<Preset>
40
46
  }
41
47
 
42
- function POIExplorerInner({ defaultText, presets, loadRuntime, runLiveSearch }: POIExplorerInnerProps): ReactNode {
48
+ function POIExplorerInner({
49
+ defaultText,
50
+ presets,
51
+ loadRuntime,
52
+ runLiveSearch,
53
+ brandLiveSearch,
54
+ }: POIExplorerInnerProps): ReactNode {
43
55
  const [text, setText] = useState(defaultText)
44
- const { result, liveSearch, searchLive } = usePOISearch({ text, loadRuntime, runLiveSearch })
56
+ const { result, liveSearch, searchLive } = usePOISearch({
57
+ text,
58
+ loadRuntime,
59
+ runLiveSearch,
60
+ brandLiveSearch,
61
+ })
62
+
63
+ const subject = result?.subject
64
+ // The live block appears whenever the subject COULD be live-searched with an anchor — i.e. capable minus the
65
+ // anchor-present requirement (`canSearchLive` also requires an anchor; the block itself renders the "add an anchor"
66
+ // hint, so it must show one step earlier). Category: not build-local. Brand: brand-capable probe + a QID.
67
+ const showLiveBlock = Boolean(
68
+ runLiveSearch &&
69
+ subject &&
70
+ (subject.kind === "brand" ? brandLiveSearch && subject.wikidata !== undefined : !subject.buildLocal)
71
+ )
45
72
 
46
73
  return (
47
74
  <div className="mw-poi-explorer">
@@ -52,15 +79,17 @@ function POIExplorerInner({ defaultText, presets, loadRuntime, runLiveSearch }:
52
79
  <div className="mw-result">
53
80
  <KindBadge kindResult={result.kindResult} />
54
81
 
55
- {result.subject ? (
82
+ {subject ? (
56
83
  <>
57
- <SubjectPanel subject={result.subject} />
58
- <OverpassBlock overpassQL={result.overpassQL} overpassError={result.overpassError} />
84
+ <SubjectPanel subject={subject} />
85
+ {subject.kind === "category" ? (
86
+ <OverpassBlock overpassQL={result.overpassQL} overpassError={result.overpassError} />
87
+ ) : null}
59
88
 
60
- {runLiveSearch && !result.subject.buildLocal ? (
89
+ {showLiveBlock ? (
61
90
  <LiveResultsBlock
62
- categoryLabel={result.subject.category.label}
63
- anchor={result.subject.remainder}
91
+ subjectLabel={subject.kind === "brand" ? subject.name : subject.category.label}
92
+ anchor={subject.remainder}
64
93
  state={liveSearch}
65
94
  onSearch={searchLive}
66
95
  />
@@ -80,6 +109,7 @@ export function POIExplorer({
80
109
  presets = POI_PRESETS,
81
110
  loadRuntime,
82
111
  runLiveSearch,
112
+ brandLiveSearch,
83
113
  }: POIExplorerProps): ReactNode {
84
114
  return (
85
115
  <ClientOnly
@@ -95,6 +125,7 @@ export function POIExplorer({
95
125
  presets={presets}
96
126
  loadRuntime={loadRuntime}
97
127
  runLiveSearch={runLiveSearch}
128
+ brandLiveSearch={brandLiveSearch}
98
129
  />
99
130
  )}
100
131
  </ClientOnly>
@@ -3,8 +3,9 @@
3
3
  * @license AGPL-3.0
4
4
  * @author Teffen Ellis, et al.
5
5
  *
6
- * `SubjectPanel` — renders the detected POI subject: the category chip, the optional build-local
7
- * badge + note, and the match-detail list (matched phrase, confidence, anchor). Presentational.
6
+ * `SubjectPanel` — renders the detected POI subject. For a CATEGORY: the category chip, the optional
7
+ * build-local badge + note. For a BRAND: the brand-name chip + a Wikidata QID chip (linked). Both
8
+ * share the match-detail list (matched phrase, confidence, anchor). Presentational.
8
9
  */
9
10
 
10
11
  import type { ReactNode } from "react"
@@ -15,7 +16,50 @@ export interface SubjectPanelProps {
15
16
  subject: POISubject
16
17
  }
17
18
 
19
+ /** The shared match-detail list (matched phrase, confidence, anchor) — identical for category + brand subjects. */
20
+ function MatchDetail({ subject }: SubjectPanelProps): ReactNode {
21
+ return (
22
+ <dl className="mw-subject__detail">
23
+ <dt>matched phrase</dt>
24
+ <dd>
25
+ <code>{subject.matchedPhrase}</code>
26
+ </dd>
27
+ <dt>confidence</dt>
28
+ <dd>{Math.round(subject.confidence * 100)}%</dd>
29
+ <dt>anchor</dt>
30
+ <dd>{subject.remainder ? subject.remainder : <em>none — global query</em>}</dd>
31
+ </dl>
32
+ )
33
+ }
34
+
18
35
  export function SubjectPanel({ subject }: SubjectPanelProps): ReactNode {
36
+ if (subject.kind === "brand") {
37
+ return (
38
+ <>
39
+ <div className="mw-subject__row">
40
+ <span className="mw-subject__chip">{subject.name}</span>
41
+ <span className="mw-subject__badge mw-subject__badge--brand">brand</span>
42
+ {subject.wikidata ? (
43
+ <a
44
+ className="mw-subject__qid"
45
+ href={`https://www.wikidata.org/wiki/${subject.wikidata}`}
46
+ target="_blank"
47
+ rel="noreferrer"
48
+ >
49
+ {subject.wikidata}
50
+ </a>
51
+ ) : null}
52
+ </div>
53
+
54
+ <MatchDetail subject={subject} />
55
+
56
+ <p className="mw-subject__note">
57
+ Matched as a chain brand — resolved by Wikidata QID against the layer's brand index.
58
+ </p>
59
+ </>
60
+ )
61
+ }
62
+
19
63
  return (
20
64
  <>
21
65
  <div className="mw-subject__row">
@@ -23,16 +67,7 @@ export function SubjectPanel({ subject }: SubjectPanelProps): ReactNode {
23
67
  {subject.buildLocal ? <span className="mw-subject__badge">build-local</span> : null}
24
68
  </div>
25
69
 
26
- <dl className="mw-subject__detail">
27
- <dt>matched phrase</dt>
28
- <dd>
29
- <code>{subject.matchedPhrase}</code>
30
- </dd>
31
- <dt>confidence</dt>
32
- <dd>{Math.round(subject.confidence * 100)}%</dd>
33
- <dt>anchor</dt>
34
- <dd>{subject.remainder ? subject.remainder : <em>none — global query</em>}</dd>
35
- </dl>
70
+ <MatchDetail subject={subject} />
36
71
 
37
72
  {subject.buildLocal ? (
38
73
  <p className="mw-subject__note">
package/poi/runtime.ts CHANGED
@@ -11,36 +11,61 @@
11
11
 
12
12
  import { createKindClassifier } from "@mailwoman/kind-classifier"
13
13
  import type { POIPhraseLookup } from "@mailwoman/kind-classifier"
14
- import { createPOITaxonomyLookup } from "@mailwoman/poi-taxonomy/table"
14
+ import { createPOIBrandLookup, createPOITaxonomyLookup } from "@mailwoman/poi-taxonomy/table"
15
15
 
16
16
  import type { POIRuntime } from "./types.ts"
17
17
 
18
18
  /**
19
- * Build the POI runtime, dynamically importing the taxonomy JSON so the ~2k-record table lands in its own chunk. A
19
+ * Build the POI runtime, dynamically importing the taxonomy + brand JSON so the tables land in their own chunk. A
20
20
  * static import would inline the whole snapshot into every consumer's bundle.
21
+ *
22
+ * The lexicon unions categories then brands, mirroring the Node runtime's `poiTaxonomyLookup` precedence: a phrase that
23
+ * matches a taxonomy CATEGORY wins (the curated set); only on a category miss does the chain-brand table fire,
24
+ * returning a `kind: "brand"` match carrying the brand's canonical name + Wikidata QID. (The Node path also chains
25
+ * `@mailwoman/variant-aliases` regional slang; the browser tester leaves that out — one fewer package + data table for
26
+ * a demo, and the QID-keyed brand table already covers the headline brands.)
21
27
  */
22
28
  export async function loadPOIRuntime(): Promise<POIRuntime> {
23
- const table = (await import("@mailwoman/poi-taxonomy/data/taxonomy.json")).default
29
+ const [table, brandTable] = await Promise.all([
30
+ import("@mailwoman/poi-taxonomy/data/taxonomy.json").then((m) => m.default),
31
+ import("@mailwoman/poi-taxonomy/data/brands.json").then((m) => m.default),
32
+ ])
24
33
  const lookup = createPOITaxonomyLookup(table as unknown as Parameters<typeof createPOITaxonomyLookup>[0])
34
+ const brands = createPOIBrandLookup(brandTable as unknown as Parameters<typeof createPOIBrandLookup>[0])
35
+
36
+ // Adapt the taxonomy + brand lookups to the `POIPhraseLookup` shape the classifier expects: categories first, brands
37
+ // on a category miss.
38
+ const lexicon: POIPhraseLookup = (phrase, locale) => {
39
+ const categoryHits = lookup.lookupPOICategory(phrase, locale)
40
+
41
+ if (categoryHits.length > 0) {
42
+ return categoryHits.map((match) => ({
43
+ kind: "category",
44
+ categoryID: match.category.id,
45
+ matchedPhrase: match.matchedPhrase,
46
+ confidence: match.confidence,
47
+ }))
48
+ }
25
49
 
26
- // Adapt `POITaxonomyLookup.lookupPOICategory` to the `POIPhraseLookup` shape the classifier expects.
27
- const lexicon: POIPhraseLookup = (phrase, locale) =>
28
- lookup.lookupPOICategory(phrase, locale).map((match) => ({
29
- kind: "category",
30
- categoryID: match.category.id,
50
+ return brands.lookupPOIBrand(phrase).map((match) => ({
51
+ kind: "brand",
52
+ categoryID: match.brand.name,
53
+ wikidata: match.brand.wikidata,
31
54
  matchedPhrase: match.matchedPhrase,
32
55
  confidence: match.confidence,
33
56
  }))
57
+ }
34
58
 
35
59
  return { lookup, lexicon, classify: createKindClassifier({ poiLexicon: lexicon }) }
36
60
  }
37
61
 
38
- /** Default example queries for the POI explorer. */
62
+ /** Default example queries for the POI explorer — a mix of category, build-local, and chain-brand subjects. */
39
63
  export const POI_PRESETS = [
40
64
  { label: "Drinking fountain", value: "drinking fountain near Springfield" },
41
65
  { label: "Fire hydrant", value: "fire hydrant" },
42
66
  { label: "Hospital + address", value: "hospital, 350 5th Ave, New York" },
43
- { label: "Biking trails", value: "biking trails near Portland" },
67
+ { label: "Chevron (brand)", value: "chevron near Houston" },
68
+ { label: "Applebee's (brand)", value: "applebee's near Chicago" },
44
69
  ] as const
45
70
 
46
71
  export const POI_DEFAULT_TEXT = POI_PRESETS[0].value
package/poi/types.ts CHANGED
@@ -23,18 +23,39 @@ export interface POIRuntime {
23
23
  classify: ReturnType<typeof createKindClassifier>
24
24
  }
25
25
 
26
- /** A resolved POI subject — the category the query names plus its match metadata. */
27
- export interface POISubject {
28
- category: CategoryRecord
26
+ /** Fields shared by every resolved POI subject, category or brand. */
27
+ export interface POISubjectBase {
29
28
  matchedPhrase: string
30
29
  confidence: number
31
30
  /** The non-subject remainder of the query (the location anchor, e.g. "near Springfield"). */
32
31
  remainder: string
32
+ }
33
+
34
+ /** A resolved POI subject that names a taxonomy CATEGORY (`cafe`, `hospital`, `drinking fountain`). */
35
+ export interface POICategorySubject extends POISubjectBase {
36
+ kind: "category"
37
+ category: CategoryRecord
33
38
  /** Whether this category needs the locally-built OSM (ODbL) layer — precomputed off the runtime. */
34
39
  buildLocal: boolean
35
40
  }
36
41
 
37
- /** The intent-only result: the kind verdict plus (when a subject was detected) its OverpassQL export. */
42
+ /**
43
+ * A resolved POI subject that names a chain BRAND (`chevron`, `applebee's`). Brands carry a Wikidata QID and are
44
+ * searched by that QID, NOT by category k-ring — see `@mailwoman/poi-taxonomy`'s brand table + the layer's
45
+ * `brand_wikidata` index.
46
+ */
47
+ export interface POIBrandSubject extends POISubjectBase {
48
+ kind: "brand"
49
+ /** The brand's canonical display name. */
50
+ name: string
51
+ /** Wikidata QID, when the lexicon carried one (`Q319642` = Chevron). Absent ⇒ matched by name alone. */
52
+ wikidata?: string
53
+ }
54
+
55
+ /** A resolved POI subject — a taxonomy category or a chain brand — plus its match metadata. */
56
+ export type POISubject = POICategorySubject | POIBrandSubject
57
+
58
+ /** The intent-only result: the kind verdict plus (when a subject was detected) its OverpassQL export (category only). */
38
59
  export interface POIExplorerResult {
39
60
  kindResult: QueryKindResult
40
61
  subject?: POISubject
@@ -64,11 +85,20 @@ export type POILiveSearchResult =
64
85
  /**
65
86
  * The injected live-search function. Given the resolved category (+ its Overture leaf fan-out) and the anchor text, it
66
87
  * probes the published poi.db and returns hits. Absent ⇒ the explorer runs intent-only (no "Search live" button).
88
+ *
89
+ * Brand support is ADDITIVE: when the resolved subject is a chain brand, `brandWikidata` carries its QID and the probe
90
+ * fetches by that QID instead of a category k-ring (`categoryID`/`overtureCategoryIDs` are then the brand name / empty
91
+ * and unused). The category path is byte-identical to before. A probe that can't serve brands simply leaves brand live
92
+ * search unwired at the call site (see `usePOISearch`'s `brandLiveSearch` option) — the docs' httpvfs probe does
93
+ * exactly that, brand-wide row hydration being pathological over byte-range (measured; the brand path is server-side
94
+ * only).
67
95
  */
68
96
  export type POILiveSearch = (params: {
69
97
  categoryID: string
70
98
  overtureCategoryIDs: string[]
71
99
  anchor: string
100
+ /** Present when the subject is a chain brand — the probe fetches by this QID, not a category k-ring. */
101
+ brandWikidata?: string
72
102
  }) => Promise<POILiveSearchResult>
73
103
 
74
104
  /** "Search live" state machine. */
@@ -26,6 +26,13 @@ export interface UsePOISearchOptions {
26
26
  loadRuntime?: LoadPOIRuntime
27
27
  /** Injected live-search probe. Absent ⇒ the live-results affordance is disabled. */
28
28
  runLiveSearch?: POILiveSearch
29
+ /**
30
+ * Whether the injected probe can serve BRAND subjects (fetch by Wikidata QID). Default false: brand subjects show the
31
+ * intent + QID chip but no live-search affordance. The docs' httpvfs probe leaves this off — brand-wide row hydration
32
+ * is pathological over byte-range (measured) — so brand live search is a server-side-backend capability. Category
33
+ * live search is unaffected either way.
34
+ */
35
+ brandLiveSearch?: boolean
29
36
  /** Debounce before (re)classifying. @default 250 */
30
37
  debounceMs?: number
31
38
  }
@@ -72,6 +79,7 @@ export function usePOISearch({
72
79
  text,
73
80
  loadRuntime = loadPOIRuntime,
74
81
  runLiveSearch,
82
+ brandLiveSearch = false,
75
83
  debounceMs = 250,
76
84
  }: UsePOISearchOptions): UsePOISearch {
77
85
  const [runtime, setRuntime] = useState<POIRuntime | null>(null)
@@ -123,9 +131,34 @@ export function usePOISearch({
123
131
  if (cancelled) return
124
132
 
125
133
  const matched = kindResult.kind === "poi_query" ? matchPOISubject(trimmed, undefined, runtime.lexicon) : null
126
- const category = matched ? runtime.lookup.getPOICategory(matched.match.categoryID) : undefined
127
134
 
128
- if (!matched || !category) {
135
+ if (!matched) {
136
+ setResult({ kindResult })
137
+
138
+ return
139
+ }
140
+
141
+ // Brand subject: the lexicon carries the brand's canonical name as `categoryID` + its Wikidata QID. No category
142
+ // record, no OverpassQL (brands are searched by QID against the layer's `brand_wikidata` index, not OSM tags).
143
+ if ((matched.match.kind ?? "category") === "brand") {
144
+ setResult({
145
+ kindResult,
146
+ subject: {
147
+ kind: "brand",
148
+ name: matched.match.categoryID,
149
+ ...(matched.match.wikidata ? { wikidata: matched.match.wikidata } : {}),
150
+ matchedPhrase: matched.match.matchedPhrase,
151
+ confidence: matched.match.confidence,
152
+ remainder: matched.remainder,
153
+ },
154
+ })
155
+
156
+ return
157
+ }
158
+
159
+ const category = runtime.lookup.getPOICategory(matched.match.categoryID)
160
+
161
+ if (!category) {
129
162
  setResult({ kindResult })
130
163
 
131
164
  return
@@ -134,6 +167,7 @@ export function usePOISearch({
134
167
  setResult({
135
168
  kindResult,
136
169
  subject: {
170
+ kind: "category",
137
171
  category,
138
172
  matchedPhrase: matched.match.matchedPhrase,
139
173
  confidence: matched.match.confidence,
@@ -150,22 +184,39 @@ export function usePOISearch({
150
184
  }, [debouncedText, runtime])
151
185
 
152
186
  const subject = result?.subject
187
+ // A subject is live-searchable when a probe is wired, it has an anchor, and: a CATEGORY that isn't build-local, or a
188
+ // BRAND with a QID AND a brand-capable probe (`brandLiveSearch`). Brands without a QID / without a brand probe show
189
+ // the intent + QID chip but no live affordance.
190
+ const subjectLiveCapable =
191
+ subject !== undefined &&
192
+ (subject.kind === "brand" ? brandLiveSearch && subject.wikidata !== undefined : !subject.buildLocal)
153
193
  const canSearchLive = Boolean(
154
- runLiveSearch && runtime && subject && !subject.buildLocal && subject.remainder.trim().length > 0
194
+ runLiveSearch && runtime && subject && subjectLiveCapable && subject.remainder.trim().length > 0
155
195
  )
156
196
 
157
197
  const searchLive = useCallback(async () => {
158
- if (!runLiveSearch || !runtime || !subject || subject.buildLocal || !subject.remainder.trim()) return
198
+ if (!runLiveSearch || !runtime || !subject || !subject.remainder.trim()) return
199
+
200
+ if (subject.kind === "category" ? subject.buildLocal : !(brandLiveSearch && subject.wikidata)) return
159
201
 
160
202
  setLiveSearch({ status: "loading" })
161
203
 
162
204
  try {
163
- const outcome = await runLiveSearch({
164
- categoryID: subject.category.id,
165
- // Fan the canonical seed id out over its Overture leaves — the same translation the Node reader uses.
166
- overtureCategoryIDs: runtime.lookup.resolveOvertureCategories(subject.category.id),
167
- anchor: subject.remainder,
168
- })
205
+ const outcome = await runLiveSearch(
206
+ subject.kind === "brand"
207
+ ? {
208
+ categoryID: subject.name,
209
+ overtureCategoryIDs: [],
210
+ anchor: subject.remainder,
211
+ brandWikidata: subject.wikidata,
212
+ }
213
+ : {
214
+ categoryID: subject.category.id,
215
+ // Fan the canonical seed id out over its Overture leaves — the same translation the Node reader uses.
216
+ overtureCategoryIDs: runtime.lookup.resolveOvertureCategories(subject.category.id),
217
+ anchor: subject.remainder,
218
+ }
219
+ )
169
220
 
170
221
  if (outcome.status === "success") {
171
222
  setLiveSearch({ status: "success", hits: outcome.hits, centerName: outcome.centerName })
@@ -177,7 +228,7 @@ export function usePOISearch({
177
228
  } catch {
178
229
  setLiveSearch({ status: "error", message: "the published POI layer isn't reachable" })
179
230
  }
180
- }, [runLiveSearch, runtime, subject])
231
+ }, [runLiveSearch, runtime, subject, brandLiveSearch])
181
232
 
182
233
  return { runtimeReady: runtime !== null, result, liveSearch, canSearchLive, searchLive }
183
234
  }
package/styles.css CHANGED
@@ -214,6 +214,27 @@
214
214
  letter-spacing: 0.02em;
215
215
  }
216
216
 
217
+ .mw-subject__badge--brand {
218
+ background: var(--ifm-color-info-contrast-background, rgba(84, 199, 236, 0.15));
219
+ color: var(--ifm-color-info-darkest, #14657d);
220
+ }
221
+
222
+ .mw-subject__qid {
223
+ display: inline-block;
224
+ padding: 0.2rem 0.5rem;
225
+ border-radius: 999px;
226
+ background: var(--ifm-color-emphasis-200, #ebedf0);
227
+ color: var(--ifm-color-emphasis-800, #303846);
228
+ font-family: var(--ifm-font-family-monospace, monospace);
229
+ font-size: 0.75rem;
230
+ font-weight: 600;
231
+ text-decoration: none;
232
+ }
233
+
234
+ .mw-subject__qid:hover {
235
+ text-decoration: underline;
236
+ }
237
+
217
238
  .mw-subject__note {
218
239
  margin: 0 0 0.75rem;
219
240
  font-size: 0.85rem;