@honua/react 0.0.20-alpha.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 (597) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +9 -0
  3. package/contract/analytics-sources.d.ts +149 -0
  4. package/contract/analytics-sources.d.ts.map +1 -0
  5. package/contract/analytics-sources.js +235 -0
  6. package/contract/edit-session.d.ts +203 -0
  7. package/contract/edit-session.d.ts.map +1 -0
  8. package/contract/edit-session.js +760 -0
  9. package/contract/edit-sketch.d.ts +91 -0
  10. package/contract/edit-sketch.d.ts.map +1 -0
  11. package/contract/edit-sketch.js +281 -0
  12. package/contract/index.d.ts +61 -0
  13. package/contract/index.d.ts.map +1 -0
  14. package/contract/index.js +51 -0
  15. package/contract/jobs.d.ts +149 -0
  16. package/contract/jobs.d.ts.map +1 -0
  17. package/contract/jobs.js +40 -0
  18. package/contract/source.d.ts +423 -0
  19. package/contract/source.d.ts.map +1 -0
  20. package/contract/source.js +3802 -0
  21. package/contract/spatial-aggregation.d.ts +336 -0
  22. package/contract/spatial-aggregation.d.ts.map +1 -0
  23. package/contract/spatial-aggregation.js +298 -0
  24. package/contract/temporal.d.ts +455 -0
  25. package/contract/temporal.d.ts.map +1 -0
  26. package/contract/temporal.js +146 -0
  27. package/contract/tiles.d.ts +370 -0
  28. package/contract/tiles.d.ts.map +1 -0
  29. package/contract/tiles.js +519 -0
  30. package/contract/types.d.ts +665 -0
  31. package/contract/types.d.ts.map +1 -0
  32. package/contract/types.js +175 -0
  33. package/contract/widget-source.d.ts +205 -0
  34. package/contract/widget-source.d.ts.map +1 -0
  35. package/contract/widget-source.js +1473 -0
  36. package/control-plane/client.d.ts +95 -0
  37. package/control-plane/client.d.ts.map +1 -0
  38. package/control-plane/client.js +374 -0
  39. package/control-plane/index.d.ts +18 -0
  40. package/control-plane/index.d.ts.map +1 -0
  41. package/control-plane/index.js +14 -0
  42. package/control-plane/types.d.ts +233 -0
  43. package/control-plane/types.d.ts.map +1 -0
  44. package/control-plane/types.js +7 -0
  45. package/core/batch.d.ts +37 -0
  46. package/core/batch.d.ts.map +1 -0
  47. package/core/batch.js +79 -0
  48. package/core/cache-state.d.ts +79 -0
  49. package/core/cache-state.d.ts.map +1 -0
  50. package/core/cache-state.js +87 -0
  51. package/core/client.d.ts +577 -0
  52. package/core/client.d.ts.map +1 -0
  53. package/core/client.js +1664 -0
  54. package/core/compatibility.d.ts +18 -0
  55. package/core/compatibility.d.ts.map +1 -0
  56. package/core/compatibility.js +245 -0
  57. package/core/errors.d.ts +107 -0
  58. package/core/errors.d.ts.map +1 -0
  59. package/core/errors.js +156 -0
  60. package/core/esri-geojson.d.ts +66 -0
  61. package/core/esri-geojson.d.ts.map +1 -0
  62. package/core/esri-geojson.js +363 -0
  63. package/core/geoservices.d.ts +34 -0
  64. package/core/geoservices.d.ts.map +1 -0
  65. package/core/geoservices.js +434 -0
  66. package/core/grpc-adapter.d.ts +23 -0
  67. package/core/grpc-adapter.d.ts.map +1 -0
  68. package/core/grpc-adapter.js +688 -0
  69. package/core/odata.d.ts +347 -0
  70. package/core/odata.d.ts.map +1 -0
  71. package/core/odata.js +913 -0
  72. package/core/ogc-conformance.d.ts +35 -0
  73. package/core/ogc-conformance.d.ts.map +1 -0
  74. package/core/ogc-conformance.js +134 -0
  75. package/core/ogc-features.d.ts +23 -0
  76. package/core/ogc-features.d.ts.map +1 -0
  77. package/core/ogc-features.js +114 -0
  78. package/core/ogc-maps.d.ts +49 -0
  79. package/core/ogc-maps.d.ts.map +1 -0
  80. package/core/ogc-maps.js +126 -0
  81. package/core/ogc-processes.d.ts +118 -0
  82. package/core/ogc-processes.d.ts.map +1 -0
  83. package/core/ogc-processes.js +423 -0
  84. package/core/ogc-records.d.ts +75 -0
  85. package/core/ogc-records.d.ts.map +1 -0
  86. package/core/ogc-records.js +251 -0
  87. package/core/ogc-tiles.d.ts +125 -0
  88. package/core/ogc-tiles.d.ts.map +1 -0
  89. package/core/ogc-tiles.js +183 -0
  90. package/core/path-utils.d.ts +69 -0
  91. package/core/path-utils.d.ts.map +1 -0
  92. package/core/path-utils.js +123 -0
  93. package/core/pbf-decoder.d.ts +39 -0
  94. package/core/pbf-decoder.d.ts.map +1 -0
  95. package/core/pbf-decoder.js +702 -0
  96. package/core/process-runner.d.ts +104 -0
  97. package/core/process-runner.d.ts.map +1 -0
  98. package/core/process-runner.js +315 -0
  99. package/core/protocol-transport.d.ts +76 -0
  100. package/core/protocol-transport.d.ts.map +1 -0
  101. package/core/protocol-transport.js +15 -0
  102. package/core/query-builder.d.ts +261 -0
  103. package/core/query-builder.d.ts.map +1 -0
  104. package/core/query-builder.js +538 -0
  105. package/core/request-pipeline.d.ts +88 -0
  106. package/core/request-pipeline.d.ts.map +1 -0
  107. package/core/request-pipeline.js +273 -0
  108. package/core/spatial-filter.d.ts +93 -0
  109. package/core/spatial-filter.d.ts.map +1 -0
  110. package/core/spatial-filter.js +153 -0
  111. package/core/stac.d.ts +55 -0
  112. package/core/stac.d.ts.map +1 -0
  113. package/core/stac.js +229 -0
  114. package/core/surfaces.d.ts +527 -0
  115. package/core/surfaces.d.ts.map +1 -0
  116. package/core/surfaces.js +1917 -0
  117. package/core/terrain-elevation.d.ts +114 -0
  118. package/core/terrain-elevation.d.ts.map +1 -0
  119. package/core/terrain-elevation.js +150 -0
  120. package/core/types.d.ts +1355 -0
  121. package/core/types.d.ts.map +1 -0
  122. package/core/types.js +13 -0
  123. package/core/wfs-capabilities.d.ts +143 -0
  124. package/core/wfs-capabilities.d.ts.map +1 -0
  125. package/core/wfs-capabilities.js +478 -0
  126. package/core/wfs-filter.d.ts +118 -0
  127. package/core/wfs-filter.d.ts.map +1 -0
  128. package/core/wfs-filter.js +634 -0
  129. package/core/wfs.d.ts +219 -0
  130. package/core/wfs.d.ts.map +1 -0
  131. package/core/wfs.js +406 -0
  132. package/core/wire-shared.d.ts +32 -0
  133. package/core/wire-shared.d.ts.map +1 -0
  134. package/core/wire-shared.js +76 -0
  135. package/core/wms-axis.d.ts +36 -0
  136. package/core/wms-axis.d.ts.map +1 -0
  137. package/core/wms-axis.js +73 -0
  138. package/core/wms-capabilities.d.ts +110 -0
  139. package/core/wms-capabilities.d.ts.map +1 -0
  140. package/core/wms-capabilities.js +559 -0
  141. package/core/wms-types.d.ts +128 -0
  142. package/core/wms-types.d.ts.map +1 -0
  143. package/core/wms-types.js +32 -0
  144. package/core/wms.d.ts +144 -0
  145. package/core/wms.d.ts.map +1 -0
  146. package/core/wms.js +338 -0
  147. package/core/wmts-capabilities.d.ts +82 -0
  148. package/core/wmts-capabilities.d.ts.map +1 -0
  149. package/core/wmts-capabilities.js +402 -0
  150. package/core/wmts.d.ts +103 -0
  151. package/core/wmts.d.ts.map +1 -0
  152. package/core/wmts.js +332 -0
  153. package/core/xml-text.d.ts +20 -0
  154. package/core/xml-text.d.ts.map +1 -0
  155. package/core/xml-text.js +85 -0
  156. package/esri-compat/basemap-gallery.d.ts +38 -0
  157. package/esri-compat/basemap-gallery.d.ts.map +1 -0
  158. package/esri-compat/basemap-gallery.js +159 -0
  159. package/esri-compat/basemap-layer-list.d.ts +35 -0
  160. package/esri-compat/basemap-layer-list.d.ts.map +1 -0
  161. package/esri-compat/basemap-layer-list.js +139 -0
  162. package/esri-compat/basemap.d.ts +32 -0
  163. package/esri-compat/basemap.d.ts.map +1 -0
  164. package/esri-compat/basemap.js +84 -0
  165. package/esri-compat/bookmarks.d.ts +36 -0
  166. package/esri-compat/bookmarks.d.ts.map +1 -0
  167. package/esri-compat/bookmarks.js +108 -0
  168. package/esri-compat/class-breaks-renderer.d.ts +50 -0
  169. package/esri-compat/class-breaks-renderer.d.ts.map +1 -0
  170. package/esri-compat/class-breaks-renderer.js +164 -0
  171. package/esri-compat/color.d.ts +22 -0
  172. package/esri-compat/color.d.ts.map +1 -0
  173. package/esri-compat/color.js +106 -0
  174. package/esri-compat/controls.d.ts +174 -0
  175. package/esri-compat/controls.d.ts.map +1 -0
  176. package/esri-compat/controls.js +479 -0
  177. package/esri-compat/coordinate-conversion.d.ts +41 -0
  178. package/esri-compat/coordinate-conversion.d.ts.map +1 -0
  179. package/esri-compat/coordinate-conversion.js +125 -0
  180. package/esri-compat/directions.d.ts +45 -0
  181. package/esri-compat/directions.d.ts.map +1 -0
  182. package/esri-compat/directions.js +123 -0
  183. package/esri-compat/editor.d.ts +47 -0
  184. package/esri-compat/editor.d.ts.map +1 -0
  185. package/esri-compat/editor.js +170 -0
  186. package/esri-compat/esri-config.d.ts +16 -0
  187. package/esri-compat/esri-config.d.ts.map +1 -0
  188. package/esri-compat/esri-config.js +23 -0
  189. package/esri-compat/esri-request.d.ts +17 -0
  190. package/esri-compat/esri-request.d.ts.map +1 -0
  191. package/esri-compat/esri-request.js +127 -0
  192. package/esri-compat/event-bus.d.ts +106 -0
  193. package/esri-compat/event-bus.d.ts.map +1 -0
  194. package/esri-compat/event-bus.js +90 -0
  195. package/esri-compat/expand.d.ts +36 -0
  196. package/esri-compat/expand.d.ts.map +1 -0
  197. package/esri-compat/expand.js +97 -0
  198. package/esri-compat/extent.d.ts +43 -0
  199. package/esri-compat/extent.d.ts.map +1 -0
  200. package/esri-compat/extent.js +140 -0
  201. package/esri-compat/feature-filter.d.ts +55 -0
  202. package/esri-compat/feature-filter.d.ts.map +1 -0
  203. package/esri-compat/feature-filter.js +109 -0
  204. package/esri-compat/feature-form.d.ts +64 -0
  205. package/esri-compat/feature-form.d.ts.map +1 -0
  206. package/esri-compat/feature-form.js +137 -0
  207. package/esri-compat/feature-layer.d.ts +173 -0
  208. package/esri-compat/feature-layer.d.ts.map +1 -0
  209. package/esri-compat/feature-layer.js +661 -0
  210. package/esri-compat/feature-set.d.ts +32 -0
  211. package/esri-compat/feature-set.d.ts.map +1 -0
  212. package/esri-compat/feature-set.js +80 -0
  213. package/esri-compat/feature-table.d.ts +141 -0
  214. package/esri-compat/feature-table.d.ts.map +1 -0
  215. package/esri-compat/feature-table.js +500 -0
  216. package/esri-compat/feature-templates.d.ts +41 -0
  217. package/esri-compat/feature-templates.d.ts.map +1 -0
  218. package/esri-compat/feature-templates.js +97 -0
  219. package/esri-compat/feature.d.ts +33 -0
  220. package/esri-compat/feature.d.ts.map +1 -0
  221. package/esri-compat/feature.js +83 -0
  222. package/esri-compat/geojson-layer.d.ts +86 -0
  223. package/esri-compat/geojson-layer.d.ts.map +1 -0
  224. package/esri-compat/geojson-layer.js +191 -0
  225. package/esri-compat/geometry-engine.d.ts +107 -0
  226. package/esri-compat/geometry-engine.d.ts.map +1 -0
  227. package/esri-compat/geometry-engine.js +266 -0
  228. package/esri-compat/graphic.d.ts +46 -0
  229. package/esri-compat/graphic.d.ts.map +1 -0
  230. package/esri-compat/graphic.js +103 -0
  231. package/esri-compat/graphics-layer.d.ts +49 -0
  232. package/esri-compat/graphics-layer.d.ts.map +1 -0
  233. package/esri-compat/graphics-layer.js +185 -0
  234. package/esri-compat/group-layer.d.ts +48 -0
  235. package/esri-compat/group-layer.d.ts.map +1 -0
  236. package/esri-compat/group-layer.js +212 -0
  237. package/esri-compat/identify.d.ts +71 -0
  238. package/esri-compat/identify.d.ts.map +1 -0
  239. package/esri-compat/identify.js +299 -0
  240. package/esri-compat/identity-manager.d.ts +31 -0
  241. package/esri-compat/identity-manager.d.ts.map +1 -0
  242. package/esri-compat/identity-manager.js +115 -0
  243. package/esri-compat/imagery-layer.d.ts +78 -0
  244. package/esri-compat/imagery-layer.d.ts.map +1 -0
  245. package/esri-compat/imagery-layer.js +167 -0
  246. package/esri-compat/label-class.d.ts +31 -0
  247. package/esri-compat/label-class.d.ts.map +1 -0
  248. package/esri-compat/label-class.js +102 -0
  249. package/esri-compat/layer-list.d.ts +77 -0
  250. package/esri-compat/layer-list.d.ts.map +1 -0
  251. package/esri-compat/layer-list.js +342 -0
  252. package/esri-compat/legend.d.ts +53 -0
  253. package/esri-compat/legend.d.ts.map +1 -0
  254. package/esri-compat/legend.js +254 -0
  255. package/esri-compat/map-image-layer.d.ts +162 -0
  256. package/esri-compat/map-image-layer.d.ts.map +1 -0
  257. package/esri-compat/map-image-layer.js +709 -0
  258. package/esri-compat/map-view.d.ts +323 -0
  259. package/esri-compat/map-view.d.ts.map +1 -0
  260. package/esri-compat/map-view.js +1175 -0
  261. package/esri-compat/map.d.ts +47 -0
  262. package/esri-compat/map.d.ts.map +1 -0
  263. package/esri-compat/map.js +209 -0
  264. package/esri-compat/measurement-2d.d.ts +61 -0
  265. package/esri-compat/measurement-2d.d.ts.map +1 -0
  266. package/esri-compat/measurement-2d.js +184 -0
  267. package/esri-compat/measurement.d.ts +45 -0
  268. package/esri-compat/measurement.d.ts.map +1 -0
  269. package/esri-compat/measurement.js +193 -0
  270. package/esri-compat/oauth-info.d.ts +35 -0
  271. package/esri-compat/oauth-info.d.ts.map +1 -0
  272. package/esri-compat/oauth-info.js +115 -0
  273. package/esri-compat/picture-marker-symbol.d.ts +35 -0
  274. package/esri-compat/picture-marker-symbol.d.ts.map +1 -0
  275. package/esri-compat/picture-marker-symbol.js +126 -0
  276. package/esri-compat/point.d.ts +31 -0
  277. package/esri-compat/point.d.ts.map +1 -0
  278. package/esri-compat/point.js +102 -0
  279. package/esri-compat/polygon.d.ts +31 -0
  280. package/esri-compat/polygon.d.ts.map +1 -0
  281. package/esri-compat/polygon.js +107 -0
  282. package/esri-compat/polyline.d.ts +31 -0
  283. package/esri-compat/polyline.d.ts.map +1 -0
  284. package/esri-compat/polyline.js +107 -0
  285. package/esri-compat/popup-template.d.ts +55 -0
  286. package/esri-compat/popup-template.d.ts.map +1 -0
  287. package/esri-compat/popup-template.js +128 -0
  288. package/esri-compat/popup.d.ts +54 -0
  289. package/esri-compat/popup.d.ts.map +1 -0
  290. package/esri-compat/popup.js +312 -0
  291. package/esri-compat/print.d.ts +47 -0
  292. package/esri-compat/print.d.ts.map +1 -0
  293. package/esri-compat/print.js +105 -0
  294. package/esri-compat/query.d.ts +58 -0
  295. package/esri-compat/query.d.ts.map +1 -0
  296. package/esri-compat/query.js +128 -0
  297. package/esri-compat/reactive-utils.d.ts +24 -0
  298. package/esri-compat/reactive-utils.d.ts.map +1 -0
  299. package/esri-compat/reactive-utils.js +193 -0
  300. package/esri-compat/request.d.ts +41 -0
  301. package/esri-compat/request.d.ts.map +1 -0
  302. package/esri-compat/request.js +253 -0
  303. package/esri-compat/route-layer.d.ts +59 -0
  304. package/esri-compat/route-layer.d.ts.map +1 -0
  305. package/esri-compat/route-layer.js +223 -0
  306. package/esri-compat/route-task.d.ts +88 -0
  307. package/esri-compat/route-task.d.ts.map +1 -0
  308. package/esri-compat/route-task.js +225 -0
  309. package/esri-compat/scene-view.d.ts +41 -0
  310. package/esri-compat/scene-view.d.ts.map +1 -0
  311. package/esri-compat/scene-view.js +68 -0
  312. package/esri-compat/search.d.ts +112 -0
  313. package/esri-compat/search.d.ts.map +1 -0
  314. package/esri-compat/search.js +820 -0
  315. package/esri-compat/simple-fill-symbol.d.ts +27 -0
  316. package/esri-compat/simple-fill-symbol.d.ts.map +1 -0
  317. package/esri-compat/simple-fill-symbol.js +85 -0
  318. package/esri-compat/simple-line-symbol.d.ts +27 -0
  319. package/esri-compat/simple-line-symbol.d.ts.map +1 -0
  320. package/esri-compat/simple-line-symbol.js +85 -0
  321. package/esri-compat/simple-marker-symbol.d.ts +29 -0
  322. package/esri-compat/simple-marker-symbol.d.ts.map +1 -0
  323. package/esri-compat/simple-marker-symbol.js +92 -0
  324. package/esri-compat/simple-renderer.d.ts +29 -0
  325. package/esri-compat/simple-renderer.d.ts.map +1 -0
  326. package/esri-compat/simple-renderer.js +92 -0
  327. package/esri-compat/sketch.d.ts +64 -0
  328. package/esri-compat/sketch.d.ts.map +1 -0
  329. package/esri-compat/sketch.js +227 -0
  330. package/esri-compat/spatial-reference.d.ts +31 -0
  331. package/esri-compat/spatial-reference.d.ts.map +1 -0
  332. package/esri-compat/spatial-reference.js +102 -0
  333. package/esri-compat/swipe.d.ts +34 -0
  334. package/esri-compat/swipe.d.ts.map +1 -0
  335. package/esri-compat/swipe.js +93 -0
  336. package/esri-compat/table-list.d.ts +36 -0
  337. package/esri-compat/table-list.d.ts.map +1 -0
  338. package/esri-compat/table-list.js +126 -0
  339. package/esri-compat/text-symbol.d.ts +37 -0
  340. package/esri-compat/text-symbol.d.ts.map +1 -0
  341. package/esri-compat/text-symbol.js +123 -0
  342. package/esri-compat/tile-layer.d.ts +52 -0
  343. package/esri-compat/tile-layer.d.ts.map +1 -0
  344. package/esri-compat/tile-layer.js +168 -0
  345. package/esri-compat/time-slider.d.ts +70 -0
  346. package/esri-compat/time-slider.d.ts.map +1 -0
  347. package/esri-compat/time-slider.js +208 -0
  348. package/esri-compat/track.d.ts +51 -0
  349. package/esri-compat/track.d.ts.map +1 -0
  350. package/esri-compat/track.js +174 -0
  351. package/esri-compat/unique-value-renderer.d.ts +41 -0
  352. package/esri-compat/unique-value-renderer.d.ts.map +1 -0
  353. package/esri-compat/unique-value-renderer.js +127 -0
  354. package/esri-compat/url.d.ts +13 -0
  355. package/esri-compat/url.d.ts.map +1 -0
  356. package/esri-compat/url.js +68 -0
  357. package/esri-compat/vector-tile-layer.d.ts +47 -0
  358. package/esri-compat/vector-tile-layer.d.ts.map +1 -0
  359. package/esri-compat/vector-tile-layer.js +130 -0
  360. package/esri-compat/web-map.d.ts +14 -0
  361. package/esri-compat/web-map.d.ts.map +1 -0
  362. package/esri-compat/web-map.js +24 -0
  363. package/esri-compat/wfs-layer.d.ts +64 -0
  364. package/esri-compat/wfs-layer.d.ts.map +1 -0
  365. package/esri-compat/wfs-layer.js +145 -0
  366. package/esri-compat/wms-layer.d.ts +76 -0
  367. package/esri-compat/wms-layer.d.ts.map +1 -0
  368. package/esri-compat/wms-layer.js +157 -0
  369. package/exploration/context.d.ts +25 -0
  370. package/exploration/context.d.ts.map +1 -0
  371. package/exploration/context.js +396 -0
  372. package/exploration/index.d.ts +27 -0
  373. package/exploration/index.d.ts.map +1 -0
  374. package/exploration/index.js +24 -0
  375. package/exploration/presets.d.ts +27 -0
  376. package/exploration/presets.d.ts.map +1 -0
  377. package/exploration/presets.js +114 -0
  378. package/exploration/reducer.d.ts +23 -0
  379. package/exploration/reducer.d.ts.map +1 -0
  380. package/exploration/reducer.js +332 -0
  381. package/exploration/selection.d.ts +25 -0
  382. package/exploration/selection.d.ts.map +1 -0
  383. package/exploration/selection.js +34 -0
  384. package/exploration/selectors.d.ts +56 -0
  385. package/exploration/selectors.d.ts.map +1 -0
  386. package/exploration/selectors.js +110 -0
  387. package/exploration/types.d.ts +294 -0
  388. package/exploration/types.d.ts.map +1 -0
  389. package/exploration/types.js +33 -0
  390. package/expr/expression.d.ts +457 -0
  391. package/expr/expression.d.ts.map +1 -0
  392. package/expr/expression.js +663 -0
  393. package/expr/index.d.ts +32 -0
  394. package/expr/index.d.ts.map +1 -0
  395. package/expr/index.js +30 -0
  396. package/gen/honua/v1/feature_service_pb.d.ts +918 -0
  397. package/gen/honua/v1/feature_service_pb.d.ts.map +1 -0
  398. package/gen/honua/v1/feature_service_pb.js +375 -0
  399. package/generated-app/errors.d.ts +41 -0
  400. package/generated-app/errors.d.ts.map +1 -0
  401. package/generated-app/errors.js +41 -0
  402. package/generated-app/index.d.ts +17 -0
  403. package/generated-app/index.d.ts.map +1 -0
  404. package/generated-app/index.js +12 -0
  405. package/generated-app/manifest.d.ts +183 -0
  406. package/generated-app/manifest.d.ts.map +1 -0
  407. package/generated-app/manifest.js +14 -0
  408. package/generated-app/projection.d.ts +44 -0
  409. package/generated-app/projection.d.ts.map +1 -0
  410. package/generated-app/projection.js +234 -0
  411. package/generated-app/runtime.d.ts +215 -0
  412. package/generated-app/runtime.d.ts.map +1 -0
  413. package/generated-app/runtime.js +1196 -0
  414. package/interactions/detail-model.d.ts +54 -0
  415. package/interactions/detail-model.d.ts.map +1 -0
  416. package/interactions/detail-model.js +105 -0
  417. package/interactions/exploration-bindings.d.ts +120 -0
  418. package/interactions/exploration-bindings.d.ts.map +1 -0
  419. package/interactions/exploration-bindings.js +218 -0
  420. package/interactions/feature-state.d.ts +144 -0
  421. package/interactions/feature-state.d.ts.map +1 -0
  422. package/interactions/feature-state.js +169 -0
  423. package/interactions/hit-test.d.ts +112 -0
  424. package/interactions/hit-test.d.ts.map +1 -0
  425. package/interactions/hit-test.js +291 -0
  426. package/interactions/index.d.ts +31 -0
  427. package/interactions/index.d.ts.map +1 -0
  428. package/interactions/index.js +24 -0
  429. package/interactions/share-state.d.ts +36 -0
  430. package/interactions/share-state.d.ts.map +1 -0
  431. package/interactions/share-state.js +123 -0
  432. package/map/feature-service-adapter.d.ts +138 -0
  433. package/map/feature-service-adapter.d.ts.map +1 -0
  434. package/map/feature-service-adapter.js +279 -0
  435. package/map/honua-map.d.ts +203 -0
  436. package/map/honua-map.d.ts.map +1 -0
  437. package/map/honua-map.js +347 -0
  438. package/map/index.d.ts +27 -0
  439. package/map/index.d.ts.map +1 -0
  440. package/map/index.js +22 -0
  441. package/map/maplibre-target.d.ts +103 -0
  442. package/map/maplibre-target.d.ts.map +1 -0
  443. package/map/maplibre-target.js +164 -0
  444. package/map/webmap-maplibre.d.ts +60 -0
  445. package/map/webmap-maplibre.d.ts.map +1 -0
  446. package/map/webmap-maplibre.js +212 -0
  447. package/package.json +37 -0
  448. package/react/context.d.ts +32 -0
  449. package/react/context.d.ts.map +1 -0
  450. package/react/context.js +19 -0
  451. package/react/honua-layer.d.ts +35 -0
  452. package/react/honua-layer.d.ts.map +1 -0
  453. package/react/honua-layer.js +47 -0
  454. package/react/honua-map.d.ts +83 -0
  455. package/react/honua-map.d.ts.map +1 -0
  456. package/react/honua-map.js +109 -0
  457. package/react/honua-popup.d.ts +26 -0
  458. package/react/honua-popup.d.ts.map +1 -0
  459. package/react/honua-popup.js +34 -0
  460. package/react/hooks.d.ts +127 -0
  461. package/react/hooks.d.ts.map +1 -0
  462. package/react/hooks.js +206 -0
  463. package/react/index.d.ts +42 -0
  464. package/react/index.d.ts.map +1 -0
  465. package/react/index.js +34 -0
  466. package/react/provider.d.ts +36 -0
  467. package/react/provider.d.ts.map +1 -0
  468. package/react/provider.js +35 -0
  469. package/react/query-cache.d.ts +76 -0
  470. package/react/query-cache.d.ts.map +1 -0
  471. package/react/query-cache.js +188 -0
  472. package/runtime/diff.d.ts +31 -0
  473. package/runtime/diff.d.ts.map +1 -0
  474. package/runtime/diff.js +143 -0
  475. package/runtime/errors.d.ts +40 -0
  476. package/runtime/errors.d.ts.map +1 -0
  477. package/runtime/errors.js +35 -0
  478. package/runtime/index.d.ts +59 -0
  479. package/runtime/index.d.ts.map +1 -0
  480. package/runtime/index.js +43 -0
  481. package/runtime/legend.d.ts +23 -0
  482. package/runtime/legend.d.ts.map +1 -0
  483. package/runtime/legend.js +38 -0
  484. package/runtime/load-package.d.ts +125 -0
  485. package/runtime/load-package.d.ts.map +1 -0
  486. package/runtime/load-package.js +264 -0
  487. package/runtime/map-package-fetch.d.ts +107 -0
  488. package/runtime/map-package-fetch.d.ts.map +1 -0
  489. package/runtime/map-package-fetch.js +336 -0
  490. package/runtime/map-package-realtime.d.ts +169 -0
  491. package/runtime/map-package-realtime.d.ts.map +1 -0
  492. package/runtime/map-package-realtime.js +350 -0
  493. package/runtime/map-package-validation.d.ts +43 -0
  494. package/runtime/map-package-validation.d.ts.map +1 -0
  495. package/runtime/map-package-validation.js +269 -0
  496. package/runtime/map-package-watch.d.ts +78 -0
  497. package/runtime/map-package-watch.d.ts.map +1 -0
  498. package/runtime/map-package-watch.js +695 -0
  499. package/runtime/map-package.d.ts +167 -0
  500. package/runtime/map-package.d.ts.map +1 -0
  501. package/runtime/map-package.js +15 -0
  502. package/runtime/ogc-styles.d.ts +110 -0
  503. package/runtime/ogc-styles.d.ts.map +1 -0
  504. package/runtime/ogc-styles.js +195 -0
  505. package/runtime/popups.d.ts +62 -0
  506. package/runtime/popups.d.ts.map +1 -0
  507. package/runtime/popups.js +95 -0
  508. package/runtime/query-tiles.d.ts +217 -0
  509. package/runtime/query-tiles.d.ts.map +1 -0
  510. package/runtime/query-tiles.js +801 -0
  511. package/runtime/runtime.d.ts +243 -0
  512. package/runtime/runtime.d.ts.map +1 -0
  513. package/runtime/runtime.js +1147 -0
  514. package/runtime/source-bridge.d.ts +99 -0
  515. package/runtime/source-bridge.d.ts.map +1 -0
  516. package/runtime/source-bridge.js +401 -0
  517. package/runtime/style-compose.d.ts +46 -0
  518. package/runtime/style-compose.d.ts.map +1 -0
  519. package/runtime/style-compose.js +144 -0
  520. package/runtime/style-interactions.d.ts +141 -0
  521. package/runtime/style-interactions.d.ts.map +1 -0
  522. package/runtime/style-interactions.js +574 -0
  523. package/runtime/style-spec-validation.d.ts +23 -0
  524. package/runtime/style-spec-validation.d.ts.map +1 -0
  525. package/runtime/style-spec-validation.js +357 -0
  526. package/studio/capability-manifest.d.ts +285 -0
  527. package/studio/capability-manifest.d.ts.map +1 -0
  528. package/studio/capability-manifest.js +59 -0
  529. package/studio/chart-spec.d.ts +85 -0
  530. package/studio/chart-spec.d.ts.map +1 -0
  531. package/studio/chart-spec.js +106 -0
  532. package/studio/index.d.ts +34 -0
  533. package/studio/index.d.ts.map +1 -0
  534. package/studio/index.js +27 -0
  535. package/studio/provenance.d.ts +131 -0
  536. package/studio/provenance.d.ts.map +1 -0
  537. package/studio/provenance.js +39 -0
  538. package/studio/publish.d.ts +64 -0
  539. package/studio/publish.d.ts.map +1 -0
  540. package/studio/publish.js +13 -0
  541. package/studio/types.d.ts +278 -0
  542. package/studio/types.d.ts.map +1 -0
  543. package/studio/types.js +71 -0
  544. package/studio/validate.d.ts +45 -0
  545. package/studio/validate.d.ts.map +1 -0
  546. package/studio/validate.js +255 -0
  547. package/studio/validation.d.ts +112 -0
  548. package/studio/validation.d.ts.map +1 -0
  549. package/studio/validation.js +42 -0
  550. package/style/factory.d.ts +30 -0
  551. package/style/factory.d.ts.map +1 -0
  552. package/style/factory.js +61 -0
  553. package/style/index.d.ts +25 -0
  554. package/style/index.d.ts.map +1 -0
  555. package/style/index.js +24 -0
  556. package/style/specification.d.ts +203 -0
  557. package/style/specification.d.ts.map +1 -0
  558. package/style/specification.js +178 -0
  559. package/style/wms-wmts-resolvers.d.ts +38 -0
  560. package/style/wms-wmts-resolvers.d.ts.map +1 -0
  561. package/style/wms-wmts-resolvers.js +92 -0
  562. package/webmap/contract.d.ts +28 -0
  563. package/webmap/contract.d.ts.map +1 -0
  564. package/webmap/contract.js +130 -0
  565. package/webmap/convert-basemap.d.ts +17 -0
  566. package/webmap/convert-basemap.d.ts.map +1 -0
  567. package/webmap/convert-basemap.js +78 -0
  568. package/webmap/convert-extent.d.ts +17 -0
  569. package/webmap/convert-extent.d.ts.map +1 -0
  570. package/webmap/convert-extent.js +114 -0
  571. package/webmap/convert-label.d.ts +13 -0
  572. package/webmap/convert-label.d.ts.map +1 -0
  573. package/webmap/convert-label.js +125 -0
  574. package/webmap/convert-layer.d.ts +22 -0
  575. package/webmap/convert-layer.d.ts.map +1 -0
  576. package/webmap/convert-layer.js +181 -0
  577. package/webmap/convert-popup.d.ts +34 -0
  578. package/webmap/convert-popup.d.ts.map +1 -0
  579. package/webmap/convert-popup.js +68 -0
  580. package/webmap/convert-renderer.d.ts +17 -0
  581. package/webmap/convert-renderer.d.ts.map +1 -0
  582. package/webmap/convert-renderer.js +161 -0
  583. package/webmap/convert-symbol.d.ts +17 -0
  584. package/webmap/convert-symbol.d.ts.map +1 -0
  585. package/webmap/convert-symbol.js +122 -0
  586. package/webmap/index.d.ts +44 -0
  587. package/webmap/index.d.ts.map +1 -0
  588. package/webmap/index.js +33 -0
  589. package/webmap/parse.d.ts +25 -0
  590. package/webmap/parse.d.ts.map +1 -0
  591. package/webmap/parse.js +83 -0
  592. package/webmap/types.d.ts +264 -0
  593. package/webmap/types.d.ts.map +1 -0
  594. package/webmap/types.js +13 -0
  595. package/webmap/warnings.d.ts +30 -0
  596. package/webmap/warnings.d.ts.map +1 -0
  597. package/webmap/warnings.js +37 -0
@@ -0,0 +1,1147 @@
1
+ /**
2
+ * `HonuaMapRuntime` — the operational API surface `#22` mixed-protocol
3
+ * composition and `#29` operator components compose on top of. The
4
+ * runtime never instantiates a MapLibre `Map`; the host passes one in.
5
+ *
6
+ * Types use a duck-typed `MaplibreMap` so the SDK stays bundle-neutral
7
+ * and does not hard-couple to a specific maplibre-gl version.
8
+ *
9
+ * @module
10
+ */
11
+ import { loadQueryTileFeatureDetail } from "../contract/index.js";
12
+ import { bindMapSelectionToExploration, syncFeatureStateSelection } from "../interactions/exploration-bindings.js";
13
+ import { createHoverHandler, createSelectionHandler } from "../interactions/feature-state.js";
14
+ import { hitTestMap } from "../interactions/hit-test.js";
15
+ import { diffPackages } from "./diff.js";
16
+ import { HonuaMapPackageError } from "./errors.js";
17
+ import { buildLegend } from "./legend.js";
18
+ import { bindPopup } from "./popups.js";
19
+ import { featureStateTargetFromSelection, materializeRuntimeLayer, materializeRuntimeSource, materializeStyleValue, protocolForSource, rendererRuntimeDiagnosticError, resolveFeatureIdFromEventFeature, resolveRuntimeBeforeId, selectionTargetForLayer, sourceContextForLayer, throwRuntimeDiagnostics, validateRuntimeFilterExpression, validateRuntimeLayer, validateRuntimeSource, validateRuntimeStyleExpression, } from "./style-interactions.js";
20
+ // ── Runtime ──────────────────────────────────────────────────
21
+ export class HonuaMapRuntime {
22
+ map;
23
+ #packageRef;
24
+ #listeners = new Set();
25
+ #telemetry;
26
+ #popupFactory;
27
+ #popupRenderer;
28
+ #styleSpecValidationMode;
29
+ #popupBindings = new Map();
30
+ #reload;
31
+ #honuaMap;
32
+ #dataset;
33
+ #composedStyle;
34
+ #disposed = false;
35
+ /** @internal — constructed by {@link loadMapPackage}. */
36
+ constructor(internals) {
37
+ this.map = internals.map;
38
+ this.#honuaMap = internals.honuaMap;
39
+ this.#dataset = internals.dataset;
40
+ this.#composedStyle = internals.composedStyle;
41
+ this.#packageRef = internals.packageRef;
42
+ this.#telemetry = internals.telemetry;
43
+ this.#popupFactory = internals.popupFactory;
44
+ this.#popupRenderer = internals.popupRenderer;
45
+ this.#styleSpecValidationMode = internals.styleSpecValidationMode;
46
+ this.#reload = internals.reload;
47
+ }
48
+ /**
49
+ * The `HonuaMap` owning the current package's sources and layers. The
50
+ * reference is replaced after every successful `updatePackage` call so
51
+ * consumers always observe the live source and layer specs rather than
52
+ * the ones captured at first load.
53
+ */
54
+ get honuaMap() {
55
+ return this.#honuaMap;
56
+ }
57
+ /**
58
+ * The `Dataset` bound to the current package's source bindings. The
59
+ * reference is replaced after every successful `updatePackage` call so
60
+ * a source-binding locator or filter change is visible through
61
+ * `runtime.dataset.source(id)`.
62
+ */
63
+ get dataset() {
64
+ return this.#dataset;
65
+ }
66
+ /** The currently applied package. */
67
+ get mapPackage() {
68
+ return this.#packageRef.current;
69
+ }
70
+ /** The composed MapLibre style last handed to the underlying map. */
71
+ get composedStyle() {
72
+ return this.#composedStyle;
73
+ }
74
+ // ── Operational API ─────────────────────────────────────────
75
+ getLegend() {
76
+ return buildLegend(this.#packageRef.current.legend, this.#composedStyle);
77
+ }
78
+ setLayerVisibility(layerId, visible) {
79
+ this.#assertLive();
80
+ this.map.setLayoutProperty?.(layerId, "visibility", visible ? "visible" : "none");
81
+ }
82
+ validateStyleExpression(value) {
83
+ return validateRuntimeStyleExpression(value, {
84
+ styleSpecValidationMode: this.#styleSpecValidationMode,
85
+ });
86
+ }
87
+ validateFilterExpression(filter, layerId) {
88
+ const layerContext = layerId
89
+ ? sourceContextForLayer(this.#composedStyle, this.#packageRef.current, layerId)
90
+ : undefined;
91
+ return validateRuntimeFilterExpression(filter, {
92
+ ...(layerId ? { layerId, path: `layers.${layerId}.filter` } : {}),
93
+ ...(layerContext
94
+ ? {
95
+ sourceId: layerContext.sourceId,
96
+ protocol: layerContext.protocol,
97
+ }
98
+ : {}),
99
+ styleSpecValidationMode: this.#styleSpecValidationMode,
100
+ });
101
+ }
102
+ addSource(sourceId, source) {
103
+ this.#assertLive();
104
+ const spec = materializeRuntimeSource(source);
105
+ const diagnostics = [
106
+ ...(Object.hasOwn(this.#composedStyle.sources, sourceId)
107
+ ? [
108
+ {
109
+ code: "source-duplicate",
110
+ severity: "error",
111
+ message: `Source "${sourceId}" already exists.`,
112
+ path: `sources.${sourceId}`,
113
+ sourceId,
114
+ protocol: spec.type,
115
+ },
116
+ ]
117
+ : []),
118
+ ...validateRuntimeSource(sourceId, spec, {
119
+ style: this.#composedStyle,
120
+ mapPackage: this.#packageRef.current,
121
+ operation: "addSource",
122
+ styleSpecValidationMode: this.#styleSpecValidationMode,
123
+ }),
124
+ ];
125
+ throwRuntimeDiagnostics(diagnostics, `Cannot add source "${sourceId}".`);
126
+ const nextStyle = {
127
+ ...this.#composedStyle,
128
+ sources: { ...this.#composedStyle.sources, [sourceId]: spec },
129
+ };
130
+ try {
131
+ this.#honuaMap.addSource(sourceId, spec);
132
+ try {
133
+ this.#applyRendererSourceAdd(sourceId, spec, nextStyle);
134
+ }
135
+ catch (error) {
136
+ this.#honuaMap.removeSource(sourceId);
137
+ throw error;
138
+ }
139
+ this.#composedStyle = nextStyle;
140
+ }
141
+ catch (error) {
142
+ if (error instanceof Error && error.name === "HonuaRuntimeDiagnosticError")
143
+ throw error;
144
+ throw rendererRuntimeDiagnosticError(`addSource("${sourceId}") failed`, {
145
+ code: "source-add-failed",
146
+ message: errorMessage(error),
147
+ path: `sources.${sourceId}`,
148
+ sourceId,
149
+ protocol: spec.type,
150
+ }, error);
151
+ }
152
+ }
153
+ updateSource(sourceId, source) {
154
+ this.#assertLive();
155
+ const previous = this.#composedStyle.sources[sourceId];
156
+ const spec = materializeRuntimeSource(source);
157
+ const diagnostics = [
158
+ ...(!previous
159
+ ? [
160
+ {
161
+ code: "source-not-found",
162
+ severity: "error",
163
+ message: `Source "${sourceId}" does not exist.`,
164
+ path: `sources.${sourceId}`,
165
+ sourceId,
166
+ protocol: spec.type,
167
+ },
168
+ ]
169
+ : []),
170
+ ...validateRuntimeSource(sourceId, spec, {
171
+ style: this.#composedStyle,
172
+ mapPackage: this.#packageRef.current,
173
+ operation: "updateSource",
174
+ styleSpecValidationMode: this.#styleSpecValidationMode,
175
+ }),
176
+ ];
177
+ throwRuntimeDiagnostics(diagnostics, `Cannot update source "${sourceId}".`);
178
+ const nextStyle = {
179
+ ...this.#composedStyle,
180
+ sources: { ...this.#composedStyle.sources, [sourceId]: spec },
181
+ };
182
+ try {
183
+ this.#honuaMap.updateSource(sourceId, spec);
184
+ try {
185
+ this.map.setStyle(nextStyle, { diff: true });
186
+ }
187
+ catch (error) {
188
+ if (previous)
189
+ this.#honuaMap.updateSource(sourceId, previous);
190
+ throw error;
191
+ }
192
+ this.#composedStyle = nextStyle;
193
+ }
194
+ catch (error) {
195
+ throw rendererRuntimeDiagnosticError(`updateSource("${sourceId}") failed`, {
196
+ code: "source-update-failed",
197
+ message: errorMessage(error),
198
+ path: `sources.${sourceId}`,
199
+ sourceId,
200
+ protocol: spec.type,
201
+ }, error);
202
+ }
203
+ }
204
+ removeSource(sourceId) {
205
+ this.#assertLive();
206
+ if (!Object.hasOwn(this.#composedStyle.sources, sourceId)) {
207
+ return [];
208
+ }
209
+ const removedLayerIds = this.#composedStyle.layers
210
+ .filter((layer) => layer.source === sourceId)
211
+ .map((layer) => layer.id);
212
+ const nextSources = { ...this.#composedStyle.sources };
213
+ delete nextSources[sourceId];
214
+ const nextStyle = {
215
+ ...this.#composedStyle,
216
+ sources: nextSources,
217
+ layers: this.#composedStyle.layers.filter((layer) => layer.source !== sourceId),
218
+ };
219
+ try {
220
+ this.#applyRendererSourceRemove(sourceId, removedLayerIds, nextStyle);
221
+ this.#honuaMap.removeSource(sourceId);
222
+ this.#composedStyle = nextStyle;
223
+ return removedLayerIds;
224
+ }
225
+ catch (error) {
226
+ throw rendererRuntimeDiagnosticError(`removeSource("${sourceId}") failed`, {
227
+ code: "source-remove-failed",
228
+ message: errorMessage(error),
229
+ path: `sources.${sourceId}`,
230
+ sourceId,
231
+ }, error);
232
+ }
233
+ }
234
+ addLayer(layer, order) {
235
+ this.#assertLive();
236
+ const spec = materializeRuntimeLayer(layer);
237
+ const orderResult = resolveRuntimeBeforeId(this.#composedStyle, order);
238
+ const diagnostics = [
239
+ ...(this.#composedStyle.layers.some((entry) => entry.id === spec.id)
240
+ ? [
241
+ {
242
+ code: "layer-duplicate",
243
+ severity: "error",
244
+ message: `Layer "${spec.id}" already exists.`,
245
+ path: `layers.${spec.id}`,
246
+ layerId: spec.id,
247
+ sourceId: spec.source,
248
+ },
249
+ ]
250
+ : []),
251
+ ...orderResult.diagnostics,
252
+ ...validateRuntimeLayer(spec, {
253
+ style: this.#composedStyle,
254
+ mapPackage: this.#packageRef.current,
255
+ operation: "addLayer",
256
+ styleSpecValidationMode: this.#styleSpecValidationMode,
257
+ }),
258
+ ];
259
+ throwRuntimeDiagnostics(diagnostics, `Cannot add layer "${spec.id}".`);
260
+ const nextStyle = insertLayer(this.#composedStyle, spec, orderResult.beforeId);
261
+ try {
262
+ this.#honuaMap.addLayer(spec, orderResult.beforeId);
263
+ try {
264
+ this.#applyRendererLayerAdd(spec, orderResult.beforeId, nextStyle);
265
+ }
266
+ catch (error) {
267
+ this.#honuaMap.removeLayer(spec.id);
268
+ throw error;
269
+ }
270
+ this.#composedStyle = nextStyle;
271
+ }
272
+ catch (error) {
273
+ throw rendererRuntimeDiagnosticError(`addLayer("${spec.id}") failed`, {
274
+ code: "layer-add-failed",
275
+ message: errorMessage(error),
276
+ path: `layers.${spec.id}`,
277
+ sourceId: spec.source,
278
+ layerId: spec.id,
279
+ protocol: sourceContextForLayer(nextStyle, this.#packageRef.current, spec.id)?.protocol,
280
+ }, error);
281
+ }
282
+ }
283
+ updateLayer(layerId, update) {
284
+ this.#assertLive();
285
+ const previous = this.#composedStyle.layers.find((layer) => layer.id === layerId);
286
+ if (!previous) {
287
+ throwRuntimeDiagnostics([
288
+ {
289
+ code: "layer-not-found",
290
+ severity: "error",
291
+ message: `Layer "${layerId}" does not exist.`,
292
+ path: `layers.${layerId}`,
293
+ layerId,
294
+ },
295
+ ], `Cannot update layer "${layerId}".`);
296
+ return;
297
+ }
298
+ const { order, ...rawPatch } = update;
299
+ const patch = materializeStyleValue(rawPatch);
300
+ const nextLayer = { ...previous, ...patch, id: layerId };
301
+ const orderResult = resolveRuntimeBeforeId(this.#composedStyle, order, layerId);
302
+ const diagnostics = [
303
+ ...orderResult.diagnostics,
304
+ ...validateRuntimeLayer(nextLayer, {
305
+ style: this.#composedStyle,
306
+ mapPackage: this.#packageRef.current,
307
+ operation: "updateLayer",
308
+ styleSpecValidationMode: this.#styleSpecValidationMode,
309
+ }),
310
+ ];
311
+ throwRuntimeDiagnostics(diagnostics, `Cannot update layer "${layerId}".`);
312
+ const nextStyle = replaceLayer(this.#composedStyle, nextLayer, order === undefined ? undefined : orderResult.beforeId, order === undefined);
313
+ const incremental = order === undefined && canPatchLayerWithMap(this.map, previous, nextLayer);
314
+ try {
315
+ if (incremental) {
316
+ this.#patchLayer(layerId, previous, nextLayer);
317
+ }
318
+ else {
319
+ this.map.setStyle(nextStyle, { diff: true });
320
+ }
321
+ this.#honuaMap.updateLayer(layerId, patch);
322
+ if (order !== undefined) {
323
+ this.#honuaMap.moveLayer(layerId, orderResult.beforeId);
324
+ }
325
+ this.#composedStyle = nextStyle;
326
+ }
327
+ catch (error) {
328
+ throw rendererRuntimeDiagnosticError(`updateLayer("${layerId}") failed`, {
329
+ code: "layer-update-failed",
330
+ message: errorMessage(error),
331
+ path: `layers.${layerId}`,
332
+ sourceId: nextLayer.source,
333
+ layerId,
334
+ protocol: sourceContextForLayer(nextStyle, this.#packageRef.current, layerId)?.protocol,
335
+ }, error);
336
+ }
337
+ }
338
+ removeLayer(layerId) {
339
+ this.#assertLive();
340
+ const existing = this.#composedStyle.layers.find((layer) => layer.id === layerId);
341
+ if (!existing)
342
+ return false;
343
+ const nextStyle = {
344
+ ...this.#composedStyle,
345
+ layers: this.#composedStyle.layers.filter((layer) => layer.id !== layerId),
346
+ };
347
+ try {
348
+ if (this.map.removeLayer) {
349
+ this.map.removeLayer(layerId);
350
+ }
351
+ else {
352
+ this.map.setStyle(nextStyle, { diff: true });
353
+ }
354
+ this.#honuaMap.removeLayer(layerId);
355
+ this.#composedStyle = nextStyle;
356
+ return true;
357
+ }
358
+ catch (error) {
359
+ throw rendererRuntimeDiagnosticError(`removeLayer("${layerId}") failed`, {
360
+ code: "layer-remove-failed",
361
+ message: errorMessage(error),
362
+ path: `layers.${layerId}`,
363
+ sourceId: existing.source,
364
+ layerId,
365
+ protocol: sourceContextForLayer(this.#composedStyle, this.#packageRef.current, layerId)?.protocol,
366
+ }, error);
367
+ }
368
+ }
369
+ moveLayer(layerId, order) {
370
+ this.#assertLive();
371
+ const existing = this.#composedStyle.layers.find((layer) => layer.id === layerId);
372
+ if (!existing) {
373
+ throwRuntimeDiagnostics([
374
+ {
375
+ code: "layer-not-found",
376
+ severity: "error",
377
+ message: `Layer "${layerId}" does not exist.`,
378
+ path: `layers.${layerId}`,
379
+ layerId,
380
+ },
381
+ ], `Cannot move layer "${layerId}".`);
382
+ return;
383
+ }
384
+ const orderResult = resolveRuntimeBeforeId(this.#composedStyle, order, layerId);
385
+ throwRuntimeDiagnostics(orderResult.diagnostics, `Cannot move layer "${layerId}".`);
386
+ const nextStyle = replaceLayer(this.#composedStyle, existing, orderResult.beforeId, false);
387
+ try {
388
+ if (this.map.moveLayer) {
389
+ this.map.moveLayer(layerId, orderResult.beforeId);
390
+ }
391
+ else {
392
+ this.map.setStyle(nextStyle, { diff: true });
393
+ }
394
+ this.#honuaMap.moveLayer(layerId, orderResult.beforeId);
395
+ this.#composedStyle = nextStyle;
396
+ }
397
+ catch (error) {
398
+ throw rendererRuntimeDiagnosticError(`moveLayer("${layerId}") failed`, {
399
+ code: "layer-move-failed",
400
+ message: errorMessage(error),
401
+ path: `layers.${layerId}`,
402
+ sourceId: existing.source,
403
+ layerId,
404
+ protocol: sourceContextForLayer(this.#composedStyle, this.#packageRef.current, layerId)?.protocol,
405
+ }, error);
406
+ }
407
+ }
408
+ setLayerPaint(layerId, paint) {
409
+ this.updateLayer(layerId, { paint });
410
+ }
411
+ setLayerLayout(layerId, layout) {
412
+ this.updateLayer(layerId, { layout });
413
+ }
414
+ setLayerFilter(layerId, filter) {
415
+ this.updateLayer(layerId, { filter });
416
+ }
417
+ refreshSource(sourceId) {
418
+ this.#assertLive();
419
+ if (!Object.hasOwn(this.#composedStyle.sources, sourceId)) {
420
+ throwRuntimeDiagnostics([
421
+ {
422
+ code: "source-not-found",
423
+ severity: "error",
424
+ message: `Source "${sourceId}" does not exist.`,
425
+ path: `sources.${sourceId}`,
426
+ sourceId,
427
+ },
428
+ ], `Cannot refresh source "${sourceId}".`);
429
+ return false;
430
+ }
431
+ const source = this.map.getSource?.(sourceId);
432
+ if (typeof source?.reload !== "function")
433
+ return false;
434
+ try {
435
+ source.reload();
436
+ this.#emit({ type: "source-ready", sourceId });
437
+ return true;
438
+ }
439
+ catch (error) {
440
+ throw rendererRuntimeDiagnosticError(`refreshSource("${sourceId}") failed`, {
441
+ code: "source-refresh-failed",
442
+ message: errorMessage(error),
443
+ path: `sources.${sourceId}`,
444
+ sourceId,
445
+ protocol: protocolForSource(this.#composedStyle, this.#packageRef.current, sourceId),
446
+ }, error);
447
+ }
448
+ }
449
+ layerSelectionTarget(layerId, id) {
450
+ const target = selectionTargetForLayer(this.#composedStyle, layerId, id);
451
+ if (!target) {
452
+ throwRuntimeDiagnostics([
453
+ {
454
+ code: "layer-source-missing",
455
+ severity: "error",
456
+ message: `Layer "${layerId}" does not have a source for feature selection.`,
457
+ path: `layers.${layerId}.source`,
458
+ layerId,
459
+ },
460
+ ], `Cannot build a source-qualified selection target for layer "${layerId}".`);
461
+ throw new Error("unreachable");
462
+ }
463
+ return target;
464
+ }
465
+ setFeatureStateForTarget(target, state) {
466
+ this.#assertLive();
467
+ this.map.setFeatureState(normalizeFeatureStateTarget(target), state);
468
+ }
469
+ getFeatureStateForTarget(target) {
470
+ this.#assertLive();
471
+ return this.map.getFeatureState(normalizeFeatureStateTarget(target));
472
+ }
473
+ removeFeatureStateForTarget(target, key) {
474
+ this.#assertLive();
475
+ this.map.removeFeatureState(normalizeFeatureStateTarget(target), key);
476
+ }
477
+ bindHover(layerId, options = {}) {
478
+ this.#assertLive();
479
+ const context = this.#interactionContext(layerId, options.sourceId, options.sourceLayer);
480
+ return createHoverHandler(this.map, {
481
+ source: context.sourceId,
482
+ sourceLayer: context.sourceLayer,
483
+ layer: layerId,
484
+ stateKey: options.stateKey,
485
+ });
486
+ }
487
+ bindClick(layerId, handler, options = {}) {
488
+ this.#assertLive();
489
+ const context = this.#interactionContext(layerId, options.sourceId, options.sourceLayer);
490
+ const onClick = (event) => {
491
+ const feature = firstEventFeature(event);
492
+ const featureId = feature ? resolveFeatureIdFromEventFeature(feature, event, options) : undefined;
493
+ handler({
494
+ type: "click",
495
+ layerId,
496
+ sourceId: context.sourceId,
497
+ sourceLayer: context.sourceLayer,
498
+ feature,
499
+ featureId,
500
+ ...(featureId !== undefined
501
+ ? {
502
+ selectionTarget: {
503
+ sourceId: context.sourceId,
504
+ id: featureId,
505
+ ...(context.sourceLayer !== undefined ? { sourceLayer: context.sourceLayer } : {}),
506
+ },
507
+ }
508
+ : {}),
509
+ originalEvent: event,
510
+ });
511
+ };
512
+ this.map.on("click", layerId, onClick);
513
+ return {
514
+ remove: () => this.map.off("click", layerId, onClick),
515
+ };
516
+ }
517
+ async hitTest(input, options = {}) {
518
+ this.#assertLive();
519
+ return hitTestMap(this.map, input, {
520
+ ...options,
521
+ featureContexts: this.#hitFeatureContexts(options.layers),
522
+ detailLoader: options.loadDetails
523
+ ? (context, detailOptions) => this.#loadHitDetail(context, detailOptions, options)
524
+ : undefined,
525
+ });
526
+ }
527
+ onPointer(handler, options = {}) {
528
+ this.#assertLive();
529
+ const eventName = options.event ?? "click";
530
+ const onPointer = (event) => {
531
+ void this.hitTest(event, options).then((hit) => {
532
+ const pointer = {
533
+ type: eventName,
534
+ point: hit.point,
535
+ ...(hit.lngLat ? { lngLat: hit.lngLat } : {}),
536
+ originalEvent: event,
537
+ };
538
+ return handler(pointer, hit);
539
+ });
540
+ };
541
+ this.map.on(eventName, onPointer);
542
+ return {
543
+ remove: () => this.map.off(eventName, onPointer),
544
+ };
545
+ }
546
+ bindSelect(layerId, options = {}) {
547
+ this.#assertLive();
548
+ const context = this.#interactionContext(layerId, options.sourceId, options.sourceLayer);
549
+ return createSelectionHandler(this.map, {
550
+ source: context.sourceId,
551
+ sourceLayer: context.sourceLayer,
552
+ layer: layerId,
553
+ stateKey: options.stateKey,
554
+ multiSelect: options.multiSelect,
555
+ onChange: options.onChange,
556
+ onSelectionTargetsChange: options.onSelectionTargetsChange,
557
+ });
558
+ }
559
+ bindSelectionToExploration(layerId, view, options = {}) {
560
+ this.#assertLive();
561
+ const context = this.#interactionContext(layerId, options.sourceId, options.sourceLayer);
562
+ return bindMapSelectionToExploration(this.map, view, {
563
+ source: context.sourceId,
564
+ sourceLayer: context.sourceLayer,
565
+ layer: layerId,
566
+ stateKey: options.stateKey,
567
+ multiSelect: options.multiSelect,
568
+ onChange: options.onChange,
569
+ onSelectionTargetsChange: options.onSelectionTargetsChange,
570
+ replaceSelection: options.replaceSelection,
571
+ });
572
+ }
573
+ syncSelectionFromExploration(layerId, view, options = {}) {
574
+ this.#assertLive();
575
+ const context = this.#interactionContext(layerId, options.sourceId, options.sourceLayer);
576
+ return syncFeatureStateSelection(this.map, view, {
577
+ source: context.sourceId,
578
+ sourceLayer: context.sourceLayer,
579
+ stateKey: options.stateKey,
580
+ });
581
+ }
582
+ bindPopup(layerId, binding) {
583
+ this.#assertLive();
584
+ if (!this.#popupFactory) {
585
+ throw new HonuaMapPackageError("bindPopup requires opts.popupFactory to be set on loadMapPackage", {
586
+ packageId: this.#packageRef.current.mapPackageId,
587
+ stage: "popup",
588
+ detail: { layerId },
589
+ });
590
+ }
591
+ const sourceId = layerIdToSource(this.#composedStyle, layerId);
592
+ const resolvedFromPackage = binding === undefined;
593
+ const resolved = binding ?? popupBindingForSource(this.#packageRef.current, sourceId);
594
+ if (!resolved) {
595
+ throw new HonuaMapPackageError(`no popupBinding found for layer "${layerId}"; supply a binding argument or add one to MapPackage.popupBindings`, { packageId: this.#packageRef.current.mapPackageId, stage: "popup", detail: { layerId } });
596
+ }
597
+ this.#popupBindings.get(layerId)?.handle.remove();
598
+ const handle = bindPopup(this.map, {
599
+ binding: resolved,
600
+ layerId,
601
+ popupFactory: this.#popupFactory,
602
+ render: this.#popupRenderer,
603
+ });
604
+ this.#popupBindings.set(layerId, { handle, sourceId, binding: resolved, resolvedFromPackage });
605
+ return {
606
+ remove: () => {
607
+ handle.remove();
608
+ if (this.#popupBindings.get(layerId)?.handle === handle) {
609
+ this.#popupBindings.delete(layerId);
610
+ }
611
+ },
612
+ };
613
+ }
614
+ setViewState(view) {
615
+ this.#assertLive();
616
+ const bbox = view.bbox ?? this.#packageRef.current.initialView?.bbox;
617
+ if (view.bbox && this.map.fitBounds) {
618
+ const [west, south, east, north] = view.bbox;
619
+ this.map.fitBounds([
620
+ [west, south],
621
+ [east, north],
622
+ ], {
623
+ animate: view.animate ?? false,
624
+ ...(view.padding !== undefined ? { padding: view.padding } : {}),
625
+ });
626
+ return;
627
+ }
628
+ if (view.center) {
629
+ this.map.jumpTo?.({
630
+ center: view.center,
631
+ ...(view.zoom !== undefined ? { zoom: view.zoom } : {}),
632
+ ...(view.bearing !== undefined ? { bearing: view.bearing } : {}),
633
+ ...(view.pitch !== undefined ? { pitch: view.pitch } : {}),
634
+ });
635
+ return;
636
+ }
637
+ if (bbox && this.map.fitBounds) {
638
+ const [west, south, east, north] = bbox;
639
+ this.map.fitBounds([
640
+ [west, south],
641
+ [east, north],
642
+ ], { animate: false });
643
+ }
644
+ }
645
+ /**
646
+ * Diff the current package against `next`. Applies the change
647
+ * incrementally when safe; falls back to `map.setStyle` for structural
648
+ * changes. Preserves unknown fields from `next` on round-trip.
649
+ */
650
+ async updatePackage(next) {
651
+ this.#assertLive();
652
+ const span = this.#startSpan("update", next.mapPackageId, { previousId: this.#packageRef.current.mapPackageId });
653
+ try {
654
+ if (next.format !== this.#packageRef.current.format) {
655
+ throw new HonuaMapPackageError(`updatePackage: format "${next.format}" is incompatible with "${this.#packageRef.current.format}"`, {
656
+ packageId: next.mapPackageId,
657
+ stage: "update",
658
+ detail: { expected: this.#packageRef.current.format, received: next.format },
659
+ });
660
+ }
661
+ let diff = diffPackages(this.#packageRef.current, next);
662
+ const reload = await this.#reload(next);
663
+ const composedStructuralReason = diff.incremental
664
+ ? detectUnpatchableLayerChange(this.map, this.#composedStyle, reload.composed)
665
+ : undefined;
666
+ if (composedStructuralReason) {
667
+ diff = {
668
+ ...diff,
669
+ incremental: false,
670
+ structuralReason: composedStructuralReason,
671
+ };
672
+ }
673
+ if (!diff.incremental) {
674
+ // setStyle first so a host-map failure leaves the previous
675
+ // runtime state intact. Only after it succeeds do we clear the
676
+ // old HonuaMap, swap in the new dataset / honuaMap, and tear
677
+ // down popup bindings whose layer, source, or package binding
678
+ // changed.
679
+ const previousHonuaMap = this.#honuaMap;
680
+ this.map.setStyle(reload.composed);
681
+ previousHonuaMap.clear();
682
+ this.#honuaMap = reload.honuaMap;
683
+ this.#dataset = reload.dataset;
684
+ this.#packageRef.current = next;
685
+ this.#composedStyle = reload.composed;
686
+ this.#reapPopupBindings(reload.composed, next);
687
+ this.#emit({ type: "package-updated", packageId: next.mapPackageId, diff });
688
+ this.#emitReloadFailures(reload.failedSources);
689
+ this.#finishSpan(span);
690
+ return;
691
+ }
692
+ this.#applyIncremental(reload.composed, diff);
693
+ this.#honuaMap = reload.honuaMap;
694
+ this.#dataset = reload.dataset;
695
+ this.#packageRef.current = next;
696
+ this.#composedStyle = reload.composed;
697
+ this.#reapPopupBindings(reload.composed, next);
698
+ this.#emit({ type: "package-updated", packageId: next.mapPackageId, diff });
699
+ this.#emitReloadFailures(reload.failedSources);
700
+ this.#finishSpan(span);
701
+ }
702
+ catch (error) {
703
+ this.#finishSpan(span, error);
704
+ if (error instanceof HonuaMapPackageError)
705
+ throw error;
706
+ throw new HonuaMapPackageError("updatePackage failed", {
707
+ packageId: next.mapPackageId,
708
+ stage: "update",
709
+ cause: error,
710
+ });
711
+ }
712
+ }
713
+ on(listener) {
714
+ this.#listeners.add(listener);
715
+ return {
716
+ remove: () => {
717
+ this.#listeners.delete(listener);
718
+ },
719
+ };
720
+ }
721
+ /** @internal used by the loader to emit `package-loaded`. */
722
+ _emit(event) {
723
+ this.#emit(event);
724
+ }
725
+ /**
726
+ * Surface a per-source failure detected outside the loader path —
727
+ * typically a query / stream rejection in a mixed-source fan-out
728
+ * (the canonical consumer is `#29`'s operator components). Emits the
729
+ * existing `source-error` runtime event so listeners do not have to
730
+ * subscribe to a parallel error channel and pipes the failure
731
+ * through {@link HonuaRuntimeTelemetry.error} as a `source-bind`
732
+ * span if the consumer wired one up.
733
+ *
734
+ * Idempotent and side-effect-free outside listener / telemetry
735
+ * fan-out: the runtime does not retry, suppress, or reshape the
736
+ * underlying source. Disposed runtimes silently no-op so a late
737
+ * rejection from a stream never throws inside an event handler.
738
+ */
739
+ reportSourceError(sourceId, error) {
740
+ if (this.#disposed)
741
+ return;
742
+ if (this.#telemetry?.error) {
743
+ const startedAt = Date.now();
744
+ this.#telemetry.error({
745
+ kind: "source-bind",
746
+ packageId: this.#packageRef.current.mapPackageId,
747
+ startedAt,
748
+ finishedAt: startedAt,
749
+ durationMs: 0,
750
+ detail: { sourceId },
751
+ error,
752
+ });
753
+ }
754
+ this.#emit({ type: "source-error", sourceId, error });
755
+ }
756
+ dispose() {
757
+ if (this.#disposed)
758
+ return;
759
+ const span = this.#startSpan("dispose", this.#packageRef.current.mapPackageId);
760
+ try {
761
+ for (const binding of this.#popupBindings.values())
762
+ binding.handle.remove();
763
+ this.#popupBindings.clear();
764
+ for (const layer of this.#composedStyle.layers) {
765
+ this.map.removeLayer?.(layer.id);
766
+ }
767
+ for (const sourceId of Object.keys(this.#composedStyle.sources)) {
768
+ this.map.removeSource?.(sourceId);
769
+ }
770
+ this.#honuaMap.clear();
771
+ this.#emit({ type: "disposed", packageId: this.#packageRef.current.mapPackageId });
772
+ this.#listeners.clear();
773
+ this.#disposed = true;
774
+ this.#finishSpan(span);
775
+ }
776
+ catch (error) {
777
+ this.#finishSpan(span, error);
778
+ throw error;
779
+ }
780
+ }
781
+ // ── Private helpers ─────────────────────────────────────────
782
+ #applyRendererSourceAdd(sourceId, source, nextStyle) {
783
+ if (this.map.addSource) {
784
+ this.map.addSource(sourceId, source);
785
+ return;
786
+ }
787
+ this.map.setStyle(nextStyle, { diff: true });
788
+ }
789
+ #applyRendererSourceRemove(sourceId, removedLayerIds, nextStyle) {
790
+ if (!this.map.removeLayer || !this.map.removeSource) {
791
+ this.map.setStyle(nextStyle, { diff: true });
792
+ return;
793
+ }
794
+ for (const layerId of [...removedLayerIds].reverse()) {
795
+ this.map.removeLayer(layerId);
796
+ }
797
+ this.map.removeSource(sourceId);
798
+ }
799
+ #applyRendererLayerAdd(layer, beforeId, nextStyle) {
800
+ if (this.map.addLayer) {
801
+ this.map.addLayer(layer, beforeId);
802
+ return;
803
+ }
804
+ this.map.setStyle(nextStyle, { diff: true });
805
+ }
806
+ #interactionContext(layerId, sourceIdOverride, sourceLayerOverride) {
807
+ const context = sourceContextForLayer(this.#composedStyle, this.#packageRef.current, layerId);
808
+ const sourceId = sourceIdOverride ?? context?.sourceId;
809
+ if (!sourceId) {
810
+ throwRuntimeDiagnostics([
811
+ {
812
+ code: "layer-source-missing",
813
+ severity: "error",
814
+ message: `Layer "${layerId}" does not have a source for interactions.`,
815
+ path: `layers.${layerId}.source`,
816
+ layerId,
817
+ },
818
+ ], `Cannot bind interactions for layer "${layerId}".`);
819
+ throw new Error("unreachable");
820
+ }
821
+ return {
822
+ sourceId,
823
+ sourceLayer: sourceLayerOverride ?? context?.sourceLayer,
824
+ protocol: context?.protocol,
825
+ };
826
+ }
827
+ #hitFeatureContexts(layerIds) {
828
+ const contexts = {};
829
+ const layers = layerIds
830
+ ? this.#composedStyle.layers.filter((layer) => layerIds.includes(layer.id))
831
+ : this.#composedStyle.layers;
832
+ for (const layer of layers) {
833
+ const context = sourceContextForLayer(this.#composedStyle, this.#packageRef.current, layer.id);
834
+ contexts[layer.id] = {
835
+ layerId: layer.id,
836
+ layerType: layer.type,
837
+ sourceId: context?.sourceId,
838
+ sourceLayer: context?.sourceLayer,
839
+ protocol: context?.protocol,
840
+ };
841
+ }
842
+ return contexts;
843
+ }
844
+ async #loadHitDetail(context, options, hitTestOptions) {
845
+ const source = this.#dataset.source(context.target.sourceId);
846
+ if (!source)
847
+ return undefined;
848
+ const descriptor = hitTestOptions.queryTileSources?.[context.target.sourceId];
849
+ if (descriptor) {
850
+ return loadQueryTileFeatureDetail({
851
+ source,
852
+ descriptor,
853
+ target: context.target,
854
+ signal: options.signal,
855
+ });
856
+ }
857
+ const idField = firstString(hitTestOptions.featureIdProperty, context.hit.properties.OBJECTID !== undefined
858
+ ? "OBJECTID"
859
+ : context.hit.properties.objectid !== undefined
860
+ ? "objectid"
861
+ : context.hit.properties.ObjectID !== undefined
862
+ ? "ObjectID"
863
+ : context.hit.properties.id !== undefined
864
+ ? "id"
865
+ : undefined);
866
+ if (!idField)
867
+ return undefined;
868
+ const result = await source.query({
869
+ where: `${idField} = ${sqlLiteral(context.target.id)}`,
870
+ returnGeometry: true,
871
+ pagination: { limit: 1 },
872
+ signal: options.signal,
873
+ });
874
+ return result.features[0];
875
+ }
876
+ #applyIncremental(composed, diff) {
877
+ const prevStyle = this.#composedStyle;
878
+ for (const layerId of diff.removedLayerIds) {
879
+ this.#honuaMap.removeLayer(layerId);
880
+ this.map.removeLayer?.(layerId);
881
+ }
882
+ const prevLayers = new Map(prevStyle.layers.map((l) => [l.id, l]));
883
+ const nextLayers = new Map(composed.layers.map((l) => [l.id, l]));
884
+ for (const layerId of diff.changedLayerIds) {
885
+ const nextLayer = nextLayers.get(layerId);
886
+ const prevLayer = prevLayers.get(layerId);
887
+ if (!nextLayer || !prevLayer)
888
+ continue;
889
+ this.#patchLayer(layerId, prevLayer, nextLayer);
890
+ }
891
+ for (const layerId of prevLayers.keys()) {
892
+ if (diff.removedLayerIds.includes(layerId) || diff.changedLayerIds.includes(layerId))
893
+ continue;
894
+ const nextLayer = nextLayers.get(layerId);
895
+ const prevLayer = prevLayers.get(layerId);
896
+ if (!nextLayer || !prevLayer)
897
+ continue;
898
+ if (!shallowPaintLayoutEqual(prevLayer, nextLayer)) {
899
+ this.#patchLayer(layerId, prevLayer, nextLayer);
900
+ }
901
+ }
902
+ }
903
+ #patchLayer(layerId, prev, next) {
904
+ const prevPaint = prev.paint ?? {};
905
+ const nextPaint = next.paint ?? {};
906
+ if (!this.map.setPaintProperty && !sameJson(prevPaint, nextPaint)) {
907
+ throw new Error(`Renderer cannot patch paint properties for layer "${layerId}".`);
908
+ }
909
+ if (this.map.setPaintProperty) {
910
+ const keys = unionKeys(prevPaint, nextPaint);
911
+ for (const key of keys) {
912
+ const prevValue = prevPaint[key];
913
+ const nextValue = Object.hasOwn(nextPaint, key) ? nextPaint[key] : undefined;
914
+ if (prevValue === nextValue)
915
+ continue;
916
+ this.map.setPaintProperty(layerId, key, nextValue);
917
+ }
918
+ }
919
+ const prevLayout = prev.layout ?? {};
920
+ const nextLayout = next.layout ?? {};
921
+ if (!this.map.setLayoutProperty && !sameJson(prevLayout, nextLayout)) {
922
+ throw new Error(`Renderer cannot patch layout properties for layer "${layerId}".`);
923
+ }
924
+ if (this.map.setLayoutProperty) {
925
+ const keys = unionKeys(prevLayout, nextLayout);
926
+ for (const key of keys) {
927
+ const prevValue = prevLayout[key];
928
+ const nextValue = Object.hasOwn(nextLayout, key) ? nextLayout[key] : undefined;
929
+ if (prevValue === nextValue)
930
+ continue;
931
+ this.map.setLayoutProperty(layerId, key, nextValue);
932
+ }
933
+ }
934
+ if (!this.map.setFilter && !sameJson(prev.filter, next.filter)) {
935
+ throw new Error(`Renderer cannot patch filter for layer "${layerId}".`);
936
+ }
937
+ if (this.map.setFilter && !sameJson(prev.filter, next.filter)) {
938
+ this.map.setFilter(layerId, next.filter);
939
+ }
940
+ }
941
+ #reapPopupBindings(composed, pkg) {
942
+ if (this.#popupBindings.size === 0)
943
+ return;
944
+ for (const [layerId, active] of Array.from(this.#popupBindings)) {
945
+ const nextSourceId = layerIdToSource(composed, layerId);
946
+ const packageBindingChanged = active.resolvedFromPackage && !sameJson(active.binding, popupBindingForSource(pkg, nextSourceId));
947
+ if (!nextSourceId || nextSourceId !== active.sourceId || packageBindingChanged) {
948
+ active.handle.remove();
949
+ this.#popupBindings.delete(layerId);
950
+ }
951
+ }
952
+ }
953
+ #emit(event) {
954
+ for (const listener of this.#listeners)
955
+ listener(event);
956
+ }
957
+ #emitReloadFailures(failures) {
958
+ if (!failures || failures.length === 0)
959
+ return;
960
+ for (const failure of failures) {
961
+ this.#emit({ type: "source-error", sourceId: failure.sourceId, error: failure.error });
962
+ }
963
+ }
964
+ #assertLive() {
965
+ if (this.#disposed) {
966
+ throw new HonuaMapPackageError("runtime is disposed", {
967
+ packageId: this.#packageRef.current.mapPackageId,
968
+ stage: "dispose",
969
+ });
970
+ }
971
+ }
972
+ #startSpan(kind, packageId, detail) {
973
+ const span = { kind, packageId, startedAt: Date.now(), detail };
974
+ this.#telemetry?.before?.(span);
975
+ return span;
976
+ }
977
+ #finishSpan(span, error) {
978
+ const finishedAt = Date.now();
979
+ const result = {
980
+ ...span,
981
+ finishedAt,
982
+ durationMs: finishedAt - span.startedAt,
983
+ };
984
+ if (error !== undefined) {
985
+ result.error = error;
986
+ this.#telemetry?.error?.(result);
987
+ }
988
+ else {
989
+ this.#telemetry?.after?.(result);
990
+ }
991
+ }
992
+ }
993
+ // ── Helpers ──────────────────────────────────────────────────
994
+ function insertLayer(style, layer, beforeId) {
995
+ const layers = [...style.layers];
996
+ if (beforeId) {
997
+ const index = layers.findIndex((entry) => entry.id === beforeId);
998
+ if (index >= 0) {
999
+ layers.splice(index, 0, layer);
1000
+ }
1001
+ else {
1002
+ layers.push(layer);
1003
+ }
1004
+ }
1005
+ else {
1006
+ layers.push(layer);
1007
+ }
1008
+ return { ...style, layers };
1009
+ }
1010
+ function replaceLayer(style, layer, beforeId, preserveIndexWhenNoBefore = true) {
1011
+ const layers = style.layers.filter((entry) => entry.id !== layer.id);
1012
+ if (beforeId) {
1013
+ const index = layers.findIndex((entry) => entry.id === beforeId);
1014
+ if (index >= 0) {
1015
+ layers.splice(index, 0, layer);
1016
+ }
1017
+ else {
1018
+ layers.push(layer);
1019
+ }
1020
+ }
1021
+ else {
1022
+ const previousIndex = style.layers.findIndex((entry) => entry.id === layer.id);
1023
+ if (preserveIndexWhenNoBefore && previousIndex >= 0 && previousIndex < layers.length) {
1024
+ layers.splice(previousIndex, 0, layer);
1025
+ }
1026
+ else {
1027
+ layers.push(layer);
1028
+ }
1029
+ }
1030
+ return { ...style, layers };
1031
+ }
1032
+ function normalizeFeatureStateTarget(target) {
1033
+ if ("sourceId" in target) {
1034
+ return featureStateTargetFromSelection(target);
1035
+ }
1036
+ return target;
1037
+ }
1038
+ function firstEventFeature(event) {
1039
+ if (typeof event !== "object" || event === null || !("features" in event)) {
1040
+ return undefined;
1041
+ }
1042
+ const features = event.features;
1043
+ return Array.isArray(features) ? features[0] : undefined;
1044
+ }
1045
+ function errorMessage(error) {
1046
+ return error instanceof Error ? error.message : String(error);
1047
+ }
1048
+ function firstString(...values) {
1049
+ return values.find((value) => typeof value === "string" && value.length > 0);
1050
+ }
1051
+ function sqlLiteral(value) {
1052
+ return typeof value === "number" ? String(value) : `'${value.replaceAll("'", "''")}'`;
1053
+ }
1054
+ function layerIdToSource(style, layerId) {
1055
+ return style.layers.find((l) => l.id === layerId)?.source;
1056
+ }
1057
+ function popupBindingForSource(pkg, sourceId) {
1058
+ if (!sourceId)
1059
+ return undefined;
1060
+ return pkg.popupBindings?.find((binding) => binding.sourceId === sourceId);
1061
+ }
1062
+ function detectUnpatchableLayerChange(map, previous, next) {
1063
+ // Tolerant source failure / recovery on reload can change the composed
1064
+ // layer or source set without showing up in the raw package diff
1065
+ // (which is computed from `mapSpec`, not the post-filter composed
1066
+ // style). Force structural fallback whenever the composed shape
1067
+ // differs so `#applyIncremental` does not leave stale MapLibre layers
1068
+ // or sources behind.
1069
+ const previousLayerIds = previous.layers.map((layer) => layer.id);
1070
+ const nextLayerIds = next.layers.map((layer) => layer.id);
1071
+ if (previousLayerIds.length !== nextLayerIds.length) {
1072
+ return "composed layer set changed (tolerant source failure or recovery)";
1073
+ }
1074
+ for (let i = 0; i < previousLayerIds.length; i++) {
1075
+ if (previousLayerIds[i] !== nextLayerIds[i]) {
1076
+ return "composed layer set or order changed (tolerant source failure or recovery)";
1077
+ }
1078
+ }
1079
+ const previousSourceIds = Object.keys(previous.sources).sort();
1080
+ const nextSourceIds = Object.keys(next.sources).sort();
1081
+ if (previousSourceIds.length !== nextSourceIds.length) {
1082
+ return "composed source set changed (tolerant source failure or recovery)";
1083
+ }
1084
+ for (let i = 0; i < previousSourceIds.length; i++) {
1085
+ if (previousSourceIds[i] !== nextSourceIds[i]) {
1086
+ return "composed source set changed (tolerant source failure or recovery)";
1087
+ }
1088
+ }
1089
+ for (const sourceId of previousSourceIds) {
1090
+ if (!sameJson(previous.sources[sourceId], next.sources[sourceId])) {
1091
+ return `composed source "${sourceId}" changed`;
1092
+ }
1093
+ }
1094
+ const previousLayers = new Map(previous.layers.map((layer) => [layer.id, layer]));
1095
+ for (const nextLayer of next.layers) {
1096
+ const previousLayer = previousLayers.get(nextLayer.id);
1097
+ if (!previousLayer)
1098
+ continue;
1099
+ if (!patchableLayerShapeEqual(previousLayer, nextLayer)) {
1100
+ return `layer "${nextLayer.id}" changed outside paint/layout/filter`;
1101
+ }
1102
+ if (!canPatchLayerWithMap(map, previousLayer, nextLayer)) {
1103
+ return `layer "${nextLayer.id}" requires unsupported incremental patch APIs`;
1104
+ }
1105
+ }
1106
+ return undefined;
1107
+ }
1108
+ function patchableLayerShapeEqual(a, b) {
1109
+ return (a.type === b.type &&
1110
+ (a.source ?? "") === (b.source ?? "") &&
1111
+ a["source-layer"] === b["source-layer"] &&
1112
+ a.minzoom === b.minzoom &&
1113
+ a.maxzoom === b.maxzoom &&
1114
+ sameJson(a.metadata, b.metadata));
1115
+ }
1116
+ function canPatchLayerWithMap(map, previous, next) {
1117
+ if (!patchableLayerShapeEqual(previous, next))
1118
+ return false;
1119
+ if (!sameJson(previous.paint ?? {}, next.paint ?? {}) && !map.setPaintProperty)
1120
+ return false;
1121
+ if (!sameJson(previous.layout ?? {}, next.layout ?? {}) && !map.setLayoutProperty)
1122
+ return false;
1123
+ if (!sameJson(previous.filter, next.filter) && !map.setFilter)
1124
+ return false;
1125
+ return true;
1126
+ }
1127
+ function shallowPaintLayoutEqual(a, b) {
1128
+ return (sameJson(a.paint ?? {}, b.paint ?? {}) && sameJson(a.layout ?? {}, b.layout ?? {}) && sameJson(a.filter, b.filter));
1129
+ }
1130
+ function unionKeys(a, b) {
1131
+ const seen = new Set();
1132
+ for (const key of Object.keys(a))
1133
+ seen.add(key);
1134
+ for (const key of Object.keys(b))
1135
+ seen.add(key);
1136
+ return [...seen];
1137
+ }
1138
+ function sameJson(a, b) {
1139
+ if (a === b)
1140
+ return true;
1141
+ try {
1142
+ return JSON.stringify(a) === JSON.stringify(b);
1143
+ }
1144
+ catch {
1145
+ return false;
1146
+ }
1147
+ }