@mailwoman/react 10.0.0 → 10.2.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 (389) hide show
  1. package/README.md +18 -16
  2. package/fonts.css +97 -22
  3. package/lib/common/About.tsx +10 -10
  4. package/lib/common/ClientOnly.tsx +2 -14
  5. package/lib/common/CopyButton.tsx +9 -3
  6. package/lib/common/LoadingIndicator.tsx +13 -5
  7. package/lib/common/PresetChips.tsx +11 -8
  8. package/lib/common/confidence-tiers.ts +8 -7
  9. package/lib/common/cx.ts +3 -1
  10. package/lib/common/text-tokens.ts +10 -13
  11. package/lib/common/useBuildInfo.ts +54 -0
  12. package/lib/common/useClipboard.ts +2 -11
  13. package/lib/common.ts +22 -0
  14. package/lib/index.ts +27 -18
  15. package/lib/map/AppIdentity.tsx +89 -0
  16. package/lib/map/CompareToggle.tsx +8 -31
  17. package/lib/map/DebugInfo.tsx +75 -0
  18. package/lib/map/Geocoder.tsx +65 -50
  19. package/lib/map/GeocoderControls.tsx +425 -141
  20. package/lib/map/GraticuleLayer.tsx +56 -0
  21. package/lib/map/MapCanvas.tsx +26 -13
  22. package/lib/map/MapChipRow.tsx +4 -8
  23. package/lib/map/MapCompass.tsx +18 -25
  24. package/lib/map/MapControlStack.tsx +11 -10
  25. package/lib/map/MapFooter.tsx +5 -17
  26. package/lib/map/MapProgressBar.tsx +10 -13
  27. package/lib/map/MapSearchBar.tsx +31 -17
  28. package/lib/map/MapSheet.tsx +24 -15
  29. package/lib/map/OverlayLayers.tsx +14 -3
  30. package/lib/map/PlaceAutocomplete.tsx +12 -21
  31. package/lib/map/PlaceMarker.tsx +10 -4
  32. package/lib/map/ResolvedPlaceLayers.tsx +14 -15
  33. package/lib/map/ResultCamera.tsx +10 -31
  34. package/lib/map/ResultOverlay.tsx +14 -16
  35. package/lib/map/ResultPanel.tsx +1 -20
  36. package/lib/map/VersionPicker.tsx +10 -19
  37. package/lib/map/fake-runtime.ts +46 -19
  38. package/lib/map/geometry.ts +14 -47
  39. package/lib/map/graticule.ts +80 -0
  40. package/lib/map/map-debug.ts +4 -2
  41. package/lib/map/place-render.ts +30 -62
  42. package/lib/map/types.ts +57 -116
  43. package/lib/map/useCompareState.ts +5 -4
  44. package/lib/map/useGeocode.ts +7 -5
  45. package/lib/map/useMapBearing.ts +13 -13
  46. package/lib/map/useMapLabelPick.ts +21 -30
  47. package/lib/map/useMapPlaceRender.ts +3 -7
  48. package/lib/map/usePlaceAutocomplete.ts +44 -50
  49. package/lib/map.ts +92 -0
  50. package/lib/pipeline/CandidatePicker.tsx +13 -5
  51. package/lib/pipeline/ConfidenceCell.tsx +2 -2
  52. package/lib/pipeline/FailureDiagnostic.tsx +8 -2
  53. package/lib/pipeline/PipelineExplorer.tsx +6 -3
  54. package/lib/pipeline/QueryForm.tsx +5 -2
  55. package/lib/pipeline/ResolvedPlace.tsx +2 -2
  56. package/lib/pipeline/SpanHighlight.tsx +7 -5
  57. package/lib/pipeline/TimingPanel.tsx +1 -1
  58. package/lib/pipeline/TreeView.tsx +2 -2
  59. package/lib/pipeline/copy.ts +22 -25
  60. package/lib/pipeline/presets.ts +15 -13
  61. package/lib/pipeline/types.ts +20 -17
  62. package/lib/pipeline/useParsePipeline.ts +16 -13
  63. package/lib/pipeline.ts +36 -0
  64. package/lib/poi/AbstainPanel.tsx +1 -1
  65. package/lib/poi/LiveResultsBlock.tsx +2 -1
  66. package/lib/poi/POIExplorer.tsx +29 -17
  67. package/lib/poi/QueryInput.tsx +1 -1
  68. package/lib/poi/SubjectPanel.tsx +4 -3
  69. package/lib/poi/runtime.ts +14 -16
  70. package/lib/poi/types.ts +58 -47
  71. package/lib/poi/usePOISearch.ts +91 -82
  72. package/lib/poi.ts +40 -0
  73. package/lib/runtime/useReleaseRuntime.ts +122 -90
  74. package/lib/search/SearchModal.tsx +478 -0
  75. package/lib/search/search.css +282 -0
  76. package/lib/search/types.ts +68 -0
  77. package/lib/search.ts +11 -0
  78. package/out/common/About.d.ts +6 -6
  79. package/out/common/About.d.ts.map +1 -1
  80. package/out/common/About.js +1 -1
  81. package/out/common/About.js.map +1 -1
  82. package/out/common/ClientOnly.d.ts +2 -11
  83. package/out/common/ClientOnly.d.ts.map +1 -1
  84. package/out/common/ClientOnly.js +1 -13
  85. package/out/common/ClientOnly.js.map +1 -1
  86. package/out/common/CopyButton.d.ts +9 -3
  87. package/out/common/CopyButton.d.ts.map +1 -1
  88. package/out/common/CopyButton.js.map +1 -1
  89. package/out/common/LoadingIndicator.d.ts +13 -5
  90. package/out/common/LoadingIndicator.d.ts.map +1 -1
  91. package/out/common/LoadingIndicator.js.map +1 -1
  92. package/out/common/PresetChips.d.ts +11 -8
  93. package/out/common/PresetChips.d.ts.map +1 -1
  94. package/out/common/PresetChips.js.map +1 -1
  95. package/out/common/confidence-tiers.d.ts +8 -7
  96. package/out/common/confidence-tiers.d.ts.map +1 -1
  97. package/out/common/confidence-tiers.js +7 -6
  98. package/out/common/confidence-tiers.js.map +1 -1
  99. package/out/common/cx.d.ts +3 -1
  100. package/out/common/cx.d.ts.map +1 -1
  101. package/out/common/cx.js +3 -1
  102. package/out/common/cx.js.map +1 -1
  103. package/out/common/text-tokens.d.ts +6 -11
  104. package/out/common/text-tokens.d.ts.map +1 -1
  105. package/out/common/text-tokens.js +6 -3
  106. package/out/common/text-tokens.js.map +1 -1
  107. package/out/common/useBuildInfo.d.ts +27 -0
  108. package/out/common/useBuildInfo.d.ts.map +1 -0
  109. package/out/common/useBuildInfo.js +32 -0
  110. package/out/common/useBuildInfo.js.map +1 -0
  111. package/out/common/useClipboard.d.ts +1 -3
  112. package/out/common/useClipboard.d.ts.map +1 -1
  113. package/out/common/useClipboard.js +2 -11
  114. package/out/common/useClipboard.js.map +1 -1
  115. package/out/common.d.ts +22 -0
  116. package/out/common.d.ts.map +1 -0
  117. package/out/common.js +15 -0
  118. package/out/common.js.map +1 -0
  119. package/out/index.d.ts +26 -16
  120. package/out/index.d.ts.map +1 -1
  121. package/out/index.js +21 -15
  122. package/out/index.js.map +1 -1
  123. package/out/map/AppIdentity.d.ts +46 -0
  124. package/out/map/AppIdentity.d.ts.map +1 -0
  125. package/out/map/AppIdentity.js +16 -0
  126. package/out/map/AppIdentity.js.map +1 -0
  127. package/out/map/CompareToggle.d.ts +8 -31
  128. package/out/map/CompareToggle.d.ts.map +1 -1
  129. package/out/map/CompareToggle.js +4 -1
  130. package/out/map/CompareToggle.js.map +1 -1
  131. package/out/map/DebugInfo.d.ts +27 -0
  132. package/out/map/DebugInfo.d.ts.map +1 -0
  133. package/out/map/DebugInfo.js +36 -0
  134. package/out/map/DebugInfo.js.map +1 -0
  135. package/out/map/Geocoder.d.ts +41 -30
  136. package/out/map/Geocoder.d.ts.map +1 -1
  137. package/out/map/Geocoder.js +23 -37
  138. package/out/map/Geocoder.js.map +1 -1
  139. package/out/map/GeocoderControls.d.ts +15 -44
  140. package/out/map/GeocoderControls.d.ts.map +1 -1
  141. package/out/map/GeocoderControls.js +250 -39
  142. package/out/map/GeocoderControls.js.map +1 -1
  143. package/out/map/GraticuleLayer.d.ts +30 -0
  144. package/out/map/GraticuleLayer.d.ts.map +1 -0
  145. package/out/map/GraticuleLayer.js +25 -0
  146. package/out/map/GraticuleLayer.js.map +1 -0
  147. package/out/map/MapCanvas.d.ts +26 -13
  148. package/out/map/MapCanvas.d.ts.map +1 -1
  149. package/out/map/MapCanvas.js +5 -2
  150. package/out/map/MapCanvas.js.map +1 -1
  151. package/out/map/MapChipRow.d.ts +4 -8
  152. package/out/map/MapChipRow.d.ts.map +1 -1
  153. package/out/map/MapChipRow.js.map +1 -1
  154. package/out/map/MapCompass.d.ts +14 -21
  155. package/out/map/MapCompass.d.ts.map +1 -1
  156. package/out/map/MapCompass.js +5 -1
  157. package/out/map/MapCompass.js.map +1 -1
  158. package/out/map/MapControlStack.d.ts +11 -10
  159. package/out/map/MapControlStack.d.ts.map +1 -1
  160. package/out/map/MapControlStack.js +4 -1
  161. package/out/map/MapControlStack.js.map +1 -1
  162. package/out/map/MapFooter.d.ts +5 -16
  163. package/out/map/MapFooter.d.ts.map +1 -1
  164. package/out/map/MapFooter.js +0 -14
  165. package/out/map/MapFooter.js.map +1 -1
  166. package/out/map/MapProgressBar.d.ts +10 -13
  167. package/out/map/MapProgressBar.d.ts.map +1 -1
  168. package/out/map/MapProgressBar.js.map +1 -1
  169. package/out/map/MapSearchBar.d.ts +16 -17
  170. package/out/map/MapSearchBar.d.ts.map +1 -1
  171. package/out/map/MapSearchBar.js +6 -0
  172. package/out/map/MapSearchBar.js.map +1 -1
  173. package/out/map/MapSheet.d.ts +15 -12
  174. package/out/map/MapSheet.d.ts.map +1 -1
  175. package/out/map/MapSheet.js +8 -12
  176. package/out/map/MapSheet.js.map +1 -1
  177. package/out/map/OverlayLayers.d.ts +8 -2
  178. package/out/map/OverlayLayers.d.ts.map +1 -1
  179. package/out/map/OverlayLayers.js +3 -3
  180. package/out/map/OverlayLayers.js.map +1 -1
  181. package/out/map/PlaceAutocomplete.d.ts +12 -21
  182. package/out/map/PlaceAutocomplete.d.ts.map +1 -1
  183. package/out/map/PlaceAutocomplete.js +2 -1
  184. package/out/map/PlaceAutocomplete.js.map +1 -1
  185. package/out/map/PlaceMarker.d.ts +10 -4
  186. package/out/map/PlaceMarker.d.ts.map +1 -1
  187. package/out/map/PlaceMarker.js +3 -1
  188. package/out/map/PlaceMarker.js.map +1 -1
  189. package/out/map/ResolvedPlaceLayers.d.ts +14 -15
  190. package/out/map/ResolvedPlaceLayers.d.ts.map +1 -1
  191. package/out/map/ResolvedPlaceLayers.js +1 -1
  192. package/out/map/ResolvedPlaceLayers.js.map +1 -1
  193. package/out/map/ResultCamera.d.ts +10 -31
  194. package/out/map/ResultCamera.d.ts.map +1 -1
  195. package/out/map/ResultCamera.js +3 -28
  196. package/out/map/ResultCamera.js.map +1 -1
  197. package/out/map/ResultOverlay.d.ts +14 -16
  198. package/out/map/ResultOverlay.d.ts.map +1 -1
  199. package/out/map/ResultOverlay.js +1 -2
  200. package/out/map/ResultOverlay.js.map +1 -1
  201. package/out/map/ResultPanel.d.ts +1 -20
  202. package/out/map/ResultPanel.d.ts.map +1 -1
  203. package/out/map/ResultPanel.js.map +1 -1
  204. package/out/map/VersionPicker.d.ts +7 -19
  205. package/out/map/VersionPicker.d.ts.map +1 -1
  206. package/out/map/VersionPicker.js +5 -2
  207. package/out/map/VersionPicker.js.map +1 -1
  208. package/out/map/fake-runtime.d.ts +9 -11
  209. package/out/map/fake-runtime.d.ts.map +1 -1
  210. package/out/map/fake-runtime.js +45 -19
  211. package/out/map/fake-runtime.js.map +1 -1
  212. package/out/map/geometry.d.ts +13 -34
  213. package/out/map/geometry.d.ts.map +1 -1
  214. package/out/map/geometry.js +9 -34
  215. package/out/map/geometry.js.map +1 -1
  216. package/out/map/graticule.d.ts +17 -0
  217. package/out/map/graticule.d.ts.map +1 -0
  218. package/out/map/graticule.js +67 -0
  219. package/out/map/graticule.js.map +1 -0
  220. package/out/map/map-debug.d.ts +4 -2
  221. package/out/map/map-debug.d.ts.map +1 -1
  222. package/out/map/map-debug.js +1 -1
  223. package/out/map/map-debug.js.map +1 -1
  224. package/out/map/place-render.d.ts +25 -45
  225. package/out/map/place-render.d.ts.map +1 -1
  226. package/out/map/place-render.js +4 -39
  227. package/out/map/place-render.js.map +1 -1
  228. package/out/map/types.d.ts +57 -113
  229. package/out/map/types.d.ts.map +1 -1
  230. package/out/map/types.js +1 -10
  231. package/out/map/types.js.map +1 -1
  232. package/out/map/useCompareState.d.ts +5 -4
  233. package/out/map/useCompareState.d.ts.map +1 -1
  234. package/out/map/useCompareState.js +3 -3
  235. package/out/map/useCompareState.js.map +1 -1
  236. package/out/map/useGeocode.d.ts +5 -3
  237. package/out/map/useGeocode.d.ts.map +1 -1
  238. package/out/map/useGeocode.js +4 -4
  239. package/out/map/useGeocode.js.map +1 -1
  240. package/out/map/useMapBearing.d.ts +11 -11
  241. package/out/map/useMapBearing.d.ts.map +1 -1
  242. package/out/map/useMapBearing.js +6 -11
  243. package/out/map/useMapBearing.js.map +1 -1
  244. package/out/map/useMapLabelPick.d.ts +4 -14
  245. package/out/map/useMapLabelPick.d.ts.map +1 -1
  246. package/out/map/useMapLabelPick.js +21 -30
  247. package/out/map/useMapLabelPick.js.map +1 -1
  248. package/out/map/useMapPlaceRender.d.ts +3 -7
  249. package/out/map/useMapPlaceRender.d.ts.map +1 -1
  250. package/out/map/useMapPlaceRender.js +2 -6
  251. package/out/map/useMapPlaceRender.js.map +1 -1
  252. package/out/map/usePlaceAutocomplete.d.ts +30 -28
  253. package/out/map/usePlaceAutocomplete.d.ts.map +1 -1
  254. package/out/map/usePlaceAutocomplete.js +6 -33
  255. package/out/map/usePlaceAutocomplete.js.map +1 -1
  256. package/out/map.d.ts +67 -0
  257. package/out/map.d.ts.map +1 -0
  258. package/out/map.js +45 -0
  259. package/out/map.js.map +1 -0
  260. package/out/pipeline/CandidatePicker.d.ts +12 -2
  261. package/out/pipeline/CandidatePicker.d.ts.map +1 -1
  262. package/out/pipeline/CandidatePicker.js +1 -1
  263. package/out/pipeline/CandidatePicker.js.map +1 -1
  264. package/out/pipeline/ConfidenceCell.d.ts +2 -2
  265. package/out/pipeline/ConfidenceCell.d.ts.map +1 -1
  266. package/out/pipeline/ConfidenceCell.js +1 -1
  267. package/out/pipeline/FailureDiagnostic.d.ts +8 -2
  268. package/out/pipeline/FailureDiagnostic.d.ts.map +1 -1
  269. package/out/pipeline/FailureDiagnostic.js +3 -0
  270. package/out/pipeline/FailureDiagnostic.js.map +1 -1
  271. package/out/pipeline/PipelineExplorer.d.ts +6 -2
  272. package/out/pipeline/PipelineExplorer.d.ts.map +1 -1
  273. package/out/pipeline/PipelineExplorer.js +1 -1
  274. package/out/pipeline/PipelineExplorer.js.map +1 -1
  275. package/out/pipeline/QueryForm.d.ts +5 -2
  276. package/out/pipeline/QueryForm.d.ts.map +1 -1
  277. package/out/pipeline/QueryForm.js.map +1 -1
  278. package/out/pipeline/ResolvedPlace.d.ts +1 -1
  279. package/out/pipeline/ResolvedPlace.d.ts.map +1 -1
  280. package/out/pipeline/SpanHighlight.d.ts +4 -3
  281. package/out/pipeline/SpanHighlight.d.ts.map +1 -1
  282. package/out/pipeline/SpanHighlight.js +3 -2
  283. package/out/pipeline/SpanHighlight.js.map +1 -1
  284. package/out/pipeline/TimingPanel.d.ts +1 -1
  285. package/out/pipeline/TreeView.d.ts +1 -1
  286. package/out/pipeline/TreeView.js.map +1 -1
  287. package/out/pipeline/copy.d.ts +1 -1
  288. package/out/pipeline/copy.d.ts.map +1 -1
  289. package/out/pipeline/copy.js +4 -3
  290. package/out/pipeline/copy.js.map +1 -1
  291. package/out/pipeline/presets.d.ts +5 -4
  292. package/out/pipeline/presets.d.ts.map +1 -1
  293. package/out/pipeline/presets.js +15 -13
  294. package/out/pipeline/presets.js.map +1 -1
  295. package/out/pipeline/types.d.ts +20 -17
  296. package/out/pipeline/types.d.ts.map +1 -1
  297. package/out/pipeline/types.js +2 -4
  298. package/out/pipeline/types.js.map +1 -1
  299. package/out/pipeline/useParsePipeline.d.ts +14 -9
  300. package/out/pipeline/useParsePipeline.d.ts.map +1 -1
  301. package/out/pipeline/useParsePipeline.js +7 -8
  302. package/out/pipeline/useParsePipeline.js.map +1 -1
  303. package/out/pipeline.d.ts +33 -0
  304. package/out/pipeline.d.ts.map +1 -0
  305. package/out/pipeline.js +21 -0
  306. package/out/pipeline.js.map +1 -0
  307. package/out/poi/AbstainPanel.d.ts +1 -1
  308. package/out/poi/LiveResultsBlock.d.ts +2 -1
  309. package/out/poi/LiveResultsBlock.d.ts.map +1 -1
  310. package/out/poi/LiveResultsBlock.js.map +1 -1
  311. package/out/poi/POIExplorer.d.ts +22 -12
  312. package/out/poi/POIExplorer.d.ts.map +1 -1
  313. package/out/poi/POIExplorer.js +11 -10
  314. package/out/poi/POIExplorer.js.map +1 -1
  315. package/out/poi/QueryInput.d.ts +1 -1
  316. package/out/poi/SubjectPanel.d.ts +2 -2
  317. package/out/poi/SubjectPanel.d.ts.map +1 -1
  318. package/out/poi/SubjectPanel.js +2 -1
  319. package/out/poi/SubjectPanel.js.map +1 -1
  320. package/out/poi/runtime.d.ts +5 -14
  321. package/out/poi/runtime.d.ts.map +1 -1
  322. package/out/poi/runtime.js +14 -16
  323. package/out/poi/runtime.js.map +1 -1
  324. package/out/poi/types.d.ts +53 -45
  325. package/out/poi/types.d.ts.map +1 -1
  326. package/out/poi/types.js +2 -4
  327. package/out/poi/types.js.map +1 -1
  328. package/out/poi/usePOISearch.d.ts +30 -17
  329. package/out/poi/usePOISearch.d.ts.map +1 -1
  330. package/out/poi/usePOISearch.js +48 -64
  331. package/out/poi/usePOISearch.js.map +1 -1
  332. package/out/poi.d.ts +23 -0
  333. package/out/poi.d.ts.map +1 -0
  334. package/out/poi.js +15 -0
  335. package/out/poi.js.map +1 -0
  336. package/out/runtime/useReleaseRuntime.d.ts +63 -74
  337. package/out/runtime/useReleaseRuntime.d.ts.map +1 -1
  338. package/out/runtime/useReleaseRuntime.js +31 -32
  339. package/out/runtime/useReleaseRuntime.js.map +1 -1
  340. package/out/{runtime/index.d.ts → runtime.d.ts} +1 -1
  341. package/out/runtime.d.ts.map +1 -0
  342. package/out/{runtime/index.js → runtime.js} +1 -1
  343. package/out/runtime.js.map +1 -0
  344. package/out/search/SearchModal.d.ts +40 -0
  345. package/out/search/SearchModal.d.ts.map +1 -0
  346. package/out/search/SearchModal.js +255 -0
  347. package/out/search/SearchModal.js.map +1 -0
  348. package/out/search/types.d.ts +65 -0
  349. package/out/search/types.d.ts.map +1 -0
  350. package/out/search/types.js +13 -0
  351. package/out/search/types.js.map +1 -0
  352. package/out/search.d.ts +11 -0
  353. package/out/search.d.ts.map +1 -0
  354. package/out/search.js +9 -0
  355. package/out/search.js.map +1 -0
  356. package/package.json +73 -165
  357. package/styles.css +482 -266
  358. package/tokens/index.css +24 -6
  359. package/tokens/tokens.json +114 -6
  360. package/lib/common/index.ts +0 -22
  361. package/lib/map/BackendControl.tsx +0 -51
  362. package/lib/map/index.ts +0 -95
  363. package/lib/pipeline/index.ts +0 -36
  364. package/lib/poi/index.ts +0 -39
  365. package/out/common/index.d.ts +0 -22
  366. package/out/common/index.d.ts.map +0 -1
  367. package/out/common/index.js +0 -15
  368. package/out/common/index.js.map +0 -1
  369. package/out/map/BackendControl.d.ts +0 -32
  370. package/out/map/BackendControl.d.ts.map +0 -1
  371. package/out/map/BackendControl.js +0 -8
  372. package/out/map/BackendControl.js.map +0 -1
  373. package/out/map/index.d.ts +0 -69
  374. package/out/map/index.d.ts.map +0 -1
  375. package/out/map/index.js +0 -46
  376. package/out/map/index.js.map +0 -1
  377. package/out/pipeline/index.d.ts +0 -33
  378. package/out/pipeline/index.d.ts.map +0 -1
  379. package/out/pipeline/index.js +0 -21
  380. package/out/pipeline/index.js.map +0 -1
  381. package/out/poi/index.d.ts +0 -23
  382. package/out/poi/index.d.ts.map +0 -1
  383. package/out/poi/index.js +0 -15
  384. package/out/poi/index.js.map +0 -1
  385. package/out/runtime/index.d.ts.map +0 -1
  386. package/out/runtime/index.js.map +0 -1
  387. package/styleframe.config.ts +0 -329
  388. package/vitest.node.config.ts +0 -20
  389. /package/lib/{runtime/index.ts → runtime.ts} +0 -0
@@ -2,172 +2,182 @@
2
2
  * @copyright Sister Software
3
3
  * @license AGPL-3.0
4
4
  * @author Teffen Ellis, et al.
5
- *
6
- * `useReleaseRuntime` — the headless load-orchestration hook shared by every mailwoman browser surface (the
7
- * inline doc-embeds via `RuntimeEmbed`, and the geocoder). It owns the version-selection state
8
- * machine, the per-version load SEQUENCING, cancellation, and the ready / loading / error state — but
9
- * NOTHING model- or map-specific. The actual asset fetchers (the ONNX classifier factory, the httpvfs
10
- * WOF opener, the FST fetch, the releases.json fetch) are INJECTED by the host as async functions, so
11
- * this module imports only React: no `onnxruntime-web`, no `sql.js-httpvfs`, no `maplibre-gl`, no
12
- * `fetch`-specific plumbing. That keeps it node-import-safe and root-exportable from
13
- * `@mailwoman/react` — the exact interface `PipelineRuntime` established, generalized to the loader itself.
14
- *
15
- * The hook is generic over `TAssets` (the opaque bundle the host's `loadAssets` returns — classifier,
16
- * FST, WOF lookup, calibrator, …) and `TRelease` (the host's release-manifest entry). The package
17
- * never inspects either; it just holds, reveals, and re-loads them across version/backend switches.
18
5
  */
19
6
 
20
7
  import { useCallback, useEffect, useMemo, useRef, useState } from "react"
21
8
 
22
9
  /**
23
- * The minimal contract a release-manifest entry must satisfy. Hosts extend this with their own fields.
10
+ * The minimal fields of a release-manifest entry.
11
+ * Hosts can add their own fields.
24
12
  */
25
13
  export interface ReleaseBase {
26
- /**
27
- * The version tag this entry describes (matched against `selectedVersion`).
28
- */
29
14
  version: string
15
+
30
16
  /**
31
- * Optional display label a version picker shows; falls back to `version`.
17
+ * The version picker's display label, falling back to `version`.
32
18
  */
33
19
  label?: string
34
20
  }
35
21
 
36
22
  /**
37
- * The releases manifest the host fetches — the default version plus the selectable release entries.
23
+ * The releases manifest that the host fetches.
38
24
  */
39
25
  export interface ReleaseManifest<TRelease extends ReleaseBase = ReleaseBase> {
40
26
  /**
41
- * The version selected on first load (before the user picks another).
27
+ * The version that the hook selects when the manifest first loads.
42
28
  */
43
29
  defaultVersion: string
44
- /**
45
- * Every selectable release.
46
- */
30
+
47
31
  releases: TRelease[]
48
32
  }
49
33
 
50
34
  /**
51
- * The progress channel handed to the host's `loadAssets`. The host reports load progress + the resolved backend + the
52
- * staged step labels/index THROUGH these setters (all no-op once the load is superseded/aborted), while the hook owns
53
- * the terminal state (revealing the assets + clearing progress on success, surfacing the error on failure).
35
+ * The abort signal and progress setters that the hook passes to a host's `loadAssets`.
36
+ *
37
+ * The setters stop affecting state after abort or supersession.
38
+ * The hook sets the final ready or error state.
54
39
  */
55
40
  export interface AssetsLoadContext {
56
41
  /**
57
- * Aborts when this load is superseded (version/backend switch) or the provider unmounts.
42
+ * The signal aborts when a version switch supersedes this load or when the component unmounts.
58
43
  */
59
44
  signal: AbortSignal
45
+
60
46
  /**
61
- * Whether the host should force the CPU/WASM backend (opt out of WebGPU) for this load.
62
- */
63
- forceWASM: boolean
64
- /**
65
- * Set the human-readable progress line (e.g. `Loading v7 model (~28 MB)…`).
47
+ * Sets the progress line, such as `Loading v7 model (~28 MB)…`.
66
48
  */
67
49
  setProgress: (progress: string) => void
68
- /**
69
- * Set the staged-loader step labels (e.g. `["Loading classifier", "Loading FST gazetteer"]`).
70
- */
50
+
71
51
  setStepLabels: (labels: string[]) => void
52
+
72
53
  /**
73
- * Advance the staged-loader step index (0-based).
54
+ * Sets the zero-based index of the current loader step.
74
55
  */
75
56
  setStepIndex: (index: number) => void
57
+
76
58
  /**
77
- * Report the backend the neural runtime resolved to (e.g. `webgpu (27 MB int8)`).
59
+ * Reports the neural runtime's backend and model size, such as `wasm (27 MB int8)`.
78
60
  */
79
61
  setBackend: (backend: string) => void
62
+
63
+ /**
64
+ * Reports the fraction of the current download received so far, in [0, 1], or `null`
65
+ * when no download is in progress or the response declares no length.
66
+ *
67
+ * The step index cannot show it because the model is fetched before the first step begins.
68
+ */
69
+ setByteFraction: (fraction: number | null) => void
80
70
  }
81
71
 
82
72
  /**
83
- * The injected loaders the hook orchestrates. Nothing here is model- or map-aware — the host owns all that.
73
+ * The host's manifest loader, asset loader and optional asset disposer for {@link useReleaseRuntime}.
84
74
  */
85
75
  export interface ReleaseRuntimeConfig<TAssets, TRelease extends ReleaseBase = ReleaseBase> {
86
76
  /**
87
- * Fetch + normalize the releases manifest. Returns `null` when no manifest is available (the surface then shows
88
- * nothing selectable). Rejecting surfaces `errorMessage`. Runs once on mount.
77
+ * Fetches the releases manifest once on mount.
78
+ *
79
+ * It returns `null` when the manifest is unavailable.
80
+ * The hook reports a rejection through `errorMessage`.
89
81
  */
90
82
  loadManifest: (signal: AbortSignal) => Promise<ReleaseManifest<TRelease> | null>
83
+
91
84
  /**
92
- * Load the full asset bundle for one release — the classifier, FST, WOF lookup, calibrator, whatever the host needs.
93
- * Runs on every version or `forceWASM` change. Report progress via `ctx`; return the bundle. Rejecting surfaces
94
- * `errorMessage`. Bail early when `ctx.signal.aborted` — the hook discards a superseded result regardless.
85
+ * Loads the asset bundle for one release and reports progress through `ctx`.
86
+ *
87
+ * The hook calls it on every version change.
88
+ * It reports a rejection through `errorMessage`.
89
+ *
90
+ * It disposes a result that resolves after `ctx.signal` aborts.
95
91
  */
96
92
  loadAssets: (release: TRelease, ctx: AssetsLoadContext) => Promise<TAssets>
93
+
97
94
  /**
98
- * The progress line shown before the manifest arrives. @default "Loading releases…"
95
+ * Releases resources the garbage collector does not own, such as an ONNX
96
+ * session's WASM heap or a GPU buffer.
97
+ *
98
+ * The hook calls it when replacing a bundle.
99
+ * It also calls it if a bundle resolves after abort or when unmounting.
100
+ *
101
+ * Without this function, each reload leaves the model resident.
102
+ */
103
+ disposeAssets?: (assets: TAssets) => void | Promise<void>
104
+
105
+ /**
106
+ * The progress line shown before the manifest arrives.
107
+ *
108
+ * @defaultValue `"Loading releases…"`
99
109
  */
100
110
  initialProgress?: string
101
111
  }
102
112
 
103
113
  /**
104
- * The state `useReleaseRuntime` produces — the load-orchestration state a surface renders + re-projects.
114
+ * The release-loading state that {@link useReleaseRuntime} returns.
105
115
  *
106
- * This is the LOADER STATE, deliberately distinct from {@link GeocoderRuntime} (the injected runtime contract
107
- * `<Geocoder>` consumes). A host builds a {@link GeocoderRuntime} by pairing this loader state (assets + backend +
108
- * version) with the map surface (style, overlays, bias, parse) — see the map subpath's `GeocoderRuntime`.
116
+ * A host pairs it with its map surface to build a `GeocoderRuntime`.
109
117
  */
110
118
  export interface ReleaseLoaderState<TAssets, TRelease extends ReleaseBase = ReleaseBase> {
111
119
  /**
112
- * The releases manifest, once fetched.
120
+ * The releases manifest, `null` until it loads or when none is available.
113
121
  */
114
122
  manifest: ReleaseManifest<TRelease> | null
123
+
115
124
  /**
116
- * The currently-selected version, or `null` before the manifest resolves.
125
+ * The selected version, `null` before the manifest loads.
117
126
  */
118
127
  selectedVersion: string | null
128
+
119
129
  /**
120
- * The release entry matching `selectedVersion` (convenience over `manifest.releases.find`).
130
+ * The manifest entry that matches `selectedVersion`, or `null` when none matches.
121
131
  */
122
132
  selectedRelease: TRelease | null
133
+
123
134
  /**
124
- * The loaded asset bundle for the selected version, or `null` while (re)loading.
135
+ * The asset bundle for the selected version, `null` while it loads.
125
136
  */
126
137
  assets: TAssets | null
127
- /**
128
- * Whether the asset bundle is loaded and ready to use.
129
- */
138
+
130
139
  ready: boolean
140
+
131
141
  /**
132
- * Human-readable load progress (`""` when idle/ready).
142
+ * The load progress line, empty once loading finishes or fails.
133
143
  */
134
144
  loadingProgress: string
145
+
135
146
  /**
136
- * Staged-loader step index (0-based; `-1` before the first step).
147
+ * The zero-based loader step index, `-1` before the first step.
137
148
  */
138
149
  loadingStepIndex: number
150
+
151
+ loadingStepLabels: string[]
152
+
139
153
  /**
140
- * Staged-loader step labels.
154
+ * The fraction of the current download received so far, in [0, 1], or `null`
155
+ * when no download is in progress or the length is unknown.
141
156
  */
142
- loadingStepLabels: string[]
157
+ loadingByteFraction: number | null
158
+
143
159
  /**
144
- * A load error (manifest or asset), distinct from any per-parse error a consumer tracks separately.
160
+ * A manifest or asset load error, separate from any parse error a consumer tracks.
145
161
  */
146
162
  errorMessage: string | null
163
+
147
164
  /**
148
- * The backend the neural runtime resolved to (e.g. `webgpu (27 MB int8)`), or `""` before it's known.
165
+ * The neural runtime's backend and model size, such as `wasm (27 MB int8)`;
166
+ * it is `""` before the model loads.
149
167
  */
150
168
  activeBackend: string
169
+
151
170
  /**
152
- * Whether the CPU/WASM backend is currently forced.
153
- */
154
- forceWASM: boolean
155
- /**
156
- * Switch to a different version (clears any error, then reloads the asset bundle).
171
+ * Switches to another version, clearing any error and reloading the asset bundle.
157
172
  */
158
173
  selectVersion: (version: string) => void
159
- /**
160
- * Force (or unforce) the CPU/WASM backend — reloads the asset bundle.
161
- */
162
- setForceWASM: (forceWASM: boolean) => void
163
174
  }
164
175
 
165
176
  /**
166
- * Drive the shared version → asset-bundle load state machine over a host-injected loader.
177
+ * Loads the release manifest on mount and the selected release's assets whenever the version changes.
167
178
  *
168
- * Sequence: on mount `loadManifest` runs and its `defaultVersion` becomes the selection; each version (or `forceWASM`)
169
- * change reloads the bundle via `loadAssets`, the previous load aborted first. The assets are revealed ATOMICALLY when
170
- * `loadAssets` resolves (so `ready` flips exactly once per load), and consumers wait on `ready`.
179
+ * Each reload aborts the previous load and disposes the old assets.
180
+ * `ready` becomes true after the new assets load.
171
181
  */
172
182
  export function useReleaseRuntime<TAssets, TRelease extends ReleaseBase = ReleaseBase>(
173
183
  config: ReleaseRuntimeConfig<TAssets, TRelease>
@@ -182,25 +192,23 @@ export function useReleaseRuntime<TAssets, TRelease extends ReleaseBase = Releas
182
192
  const [loadingStepLabels, setLoadingStepLabels] = useState<string[]>([])
183
193
  const [errorMessage, setErrorMessage] = useState<string | null>(null)
184
194
  const [activeBackend, setActiveBackend] = useState<string>("")
185
- const [forceWASM, setForceWASMState] = useState(false)
195
+ const [loadingByteFraction, setLoadingByteFraction] = useState<number | null>(null)
186
196
 
187
- // Latest-ref the injected loaders: a host that re-creates them each render (an inline arrow) must NOT retrigger the
188
- // load effects, which key ONLY on version/backend. The effects read `.current` at run time.
189
197
  const loadManifestRef = useRef(config.loadManifest)
190
198
  const loadAssetsRef = useRef(config.loadAssets)
199
+ const disposeAssetsRef = useRef(config.disposeAssets)
200
+
201
+ const liveAssetsRef = useRef<TAssets | null>(null)
191
202
 
192
- // Latest manifest for the version-load effect, so it can resolve the release WITHOUT depending on `manifest`
193
- // identity — which would double-fire the load the instant the manifest first arrives (the selection transition
194
- // null → defaultVersion already fires it once).
195
203
  const manifestRef = useRef<ReleaseManifest<TRelease> | null>(null)
196
204
 
197
205
  useEffect(() => {
198
206
  loadManifestRef.current = config.loadManifest
199
207
  loadAssetsRef.current = config.loadAssets
208
+ disposeAssetsRef.current = config.disposeAssets
200
209
  manifestRef.current = manifest
201
- }, [config.loadAssets, config.loadManifest, manifest])
210
+ }, [config.disposeAssets, config.loadAssets, config.loadManifest, manifest])
202
211
 
203
- // Mount: fetch the manifest, then select the default version.
204
212
  useEffect(() => {
205
213
  const controller = new AbortController()
206
214
 
@@ -223,7 +231,6 @@ export function useReleaseRuntime<TAssets, TRelease extends ReleaseBase = Releas
223
231
  return () => controller.abort()
224
232
  }, [])
225
233
 
226
- // Load the per-version asset bundle when the version (or the backend force) changes.
227
234
  useEffect(() => {
228
235
  if (!selectedVersion) return
229
236
 
@@ -242,25 +249,41 @@ export function useReleaseRuntime<TAssets, TRelease extends ReleaseBase = Releas
242
249
 
243
250
  void (async () => {
244
251
  try {
252
+ const outgoing = liveAssetsRef.current
253
+
254
+ liveAssetsRef.current = null
255
+
256
+ if (outgoing) {
257
+ await disposeAssetsRef.current?.(outgoing)
258
+ }
259
+
245
260
  setAssets(null)
246
261
  setLoadingStepIndex(-1)
247
262
  setLoadingStepLabels([])
248
263
  setActiveBackend("")
264
+ setLoadingByteFraction(null)
249
265
 
250
266
  const ctx: AssetsLoadContext = {
251
267
  signal,
252
- forceWASM,
253
268
  setProgress: (progress) => guard(() => setLoadingProgress(progress)),
254
269
  setStepLabels: (labels) => guard(() => setLoadingStepLabels(labels)),
255
270
  setStepIndex: (index) => guard(() => setLoadingStepIndex(index)),
256
271
  setBackend: (backend) => guard(() => setActiveBackend(backend)),
272
+ setByteFraction: (fraction) => guard(() => setLoadingByteFraction(fraction)),
257
273
  }
258
274
 
259
275
  const loaded = await loadAssetsRef.current(release, ctx)
260
276
 
261
- if (signal.aborted) return
277
+ if (signal.aborted) {
278
+ await disposeAssetsRef.current?.(loaded)
279
+
280
+ return
281
+ }
282
+
283
+ liveAssetsRef.current = loaded
262
284
  setAssets(loaded)
263
285
  setLoadingProgress("")
286
+ setLoadingByteFraction(null)
264
287
  } catch (error) {
265
288
  if (signal.aborted) return
266
289
  setErrorMessage(error instanceof Error ? error.message : String(error))
@@ -269,15 +292,25 @@ export function useReleaseRuntime<TAssets, TRelease extends ReleaseBase = Releas
269
292
  })()
270
293
 
271
294
  return () => controller.abort()
272
- }, [selectedVersion, forceWASM])
295
+ }, [selectedVersion])
296
+
297
+ useEffect(() => {
298
+ return () => {
299
+ const live = liveAssetsRef.current
300
+
301
+ liveAssetsRef.current = null
302
+
303
+ if (live) {
304
+ void disposeAssetsRef.current?.(live)
305
+ }
306
+ }
307
+ }, [])
273
308
 
274
309
  const selectVersion = useCallback((version: string) => {
275
310
  setSelectedVersion(version)
276
311
  setErrorMessage(null)
277
312
  }, [])
278
313
 
279
- const setForceWASM = useCallback((next: boolean) => setForceWASMState(next), [])
280
-
281
314
  const selectedRelease = useMemo(
282
315
  () => manifest?.releases.find((r) => r.version === selectedVersion) ?? null,
283
316
  [manifest, selectedVersion]
@@ -292,10 +325,9 @@ export function useReleaseRuntime<TAssets, TRelease extends ReleaseBase = Releas
292
325
  loadingProgress,
293
326
  loadingStepIndex,
294
327
  loadingStepLabels,
328
+ loadingByteFraction,
295
329
  errorMessage,
296
330
  activeBackend,
297
- forceWASM,
298
331
  selectVersion,
299
- setForceWASM,
300
332
  }
301
333
  }