@mapvx/web-js 4.0.2 → 4.0.3-dev.2

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 (339) hide show
  1. package/README.md +7 -7
  2. package/dist/cjs/index.js +4 -2
  3. package/dist/es/assets/icons.d.ts +0 -1
  4. package/dist/es/assets/icons.js +0 -50
  5. package/dist/es/config/draco.d.ts +0 -1
  6. package/dist/es/config/draco.js +0 -10
  7. package/dist/es/config/sdkConfig.d.ts +0 -1
  8. package/dist/es/config/sdkConfig.js +0 -1
  9. package/dist/es/controllers/markerLayoutController.d.ts +0 -1
  10. package/dist/es/controllers/markerLayoutController.js +0 -103
  11. package/dist/es/controllers/routeController.d.ts +0 -1
  12. package/dist/es/controllers/routeController.js +1 -473
  13. package/dist/es/domain/models/_internal.d.ts +0 -1
  14. package/dist/es/domain/models/_internal.js +0 -8
  15. package/dist/es/domain/models/animation.d.ts +0 -1
  16. package/dist/es/domain/models/animation.js +0 -6
  17. package/dist/es/domain/models/banner.d.ts +0 -1
  18. package/dist/es/domain/models/banner.js +0 -10
  19. package/dist/es/domain/models/campaign.d.ts +0 -1
  20. package/dist/es/domain/models/campaign.js +0 -29
  21. package/dist/es/domain/models/categories.d.ts +0 -1
  22. package/dist/es/domain/models/categories.js +0 -20
  23. package/dist/es/domain/models/circle.d.ts +0 -1
  24. package/dist/es/domain/models/circle.js +0 -118
  25. package/dist/es/domain/models/cityFilterOption.d.ts +0 -1
  26. package/dist/es/domain/models/cityFilterOption.js +0 -1
  27. package/dist/es/domain/models/configuration.d.ts +0 -1
  28. package/dist/es/domain/models/configuration.js +0 -1
  29. package/dist/es/domain/models/cssCustomization.d.ts +0 -1
  30. package/dist/es/domain/models/cssCustomization.js +0 -1
  31. package/dist/es/domain/models/fitOptions.d.ts +0 -1
  32. package/dist/es/domain/models/fitOptions.js +0 -1
  33. package/dist/es/domain/models/innerFloors.d.ts +0 -1
  34. package/dist/es/domain/models/innerFloors.js +0 -1
  35. package/dist/es/domain/models/institution.d.ts +0 -1
  36. package/dist/es/domain/models/institution.js +0 -26
  37. package/dist/es/domain/models/latLng.d.ts +0 -1
  38. package/dist/es/domain/models/latLng.js +0 -1
  39. package/dist/es/domain/models/location.d.ts +0 -1
  40. package/dist/es/domain/models/location.js +0 -1
  41. package/dist/es/domain/models/loggeable.d.ts +0 -1
  42. package/dist/es/domain/models/loggeable.js +0 -24
  43. package/dist/es/domain/models/mapCamera.d.ts +0 -1
  44. package/dist/es/domain/models/mapCamera.js +0 -1
  45. package/dist/es/domain/models/mapConfig.d.ts +0 -1
  46. package/dist/es/domain/models/mapConfig.js +1 -17
  47. package/dist/es/domain/models/marker.d.ts +0 -1
  48. package/dist/es/domain/models/marker.js +0 -292
  49. package/dist/es/domain/models/multilanguage.d.ts +0 -1
  50. package/dist/es/domain/models/multilanguage.js +0 -10
  51. package/dist/es/domain/models/openingHours.d.ts +0 -1
  52. package/dist/es/domain/models/openingHours.js +0 -1
  53. package/dist/es/domain/models/place.d.ts +0 -1
  54. package/dist/es/domain/models/place.js +0 -68
  55. package/dist/es/domain/models/platform.d.ts +0 -1
  56. package/dist/es/domain/models/platform.js +0 -1
  57. package/dist/es/domain/models/popover.d.ts +0 -1
  58. package/dist/es/domain/models/popover.js +0 -1
  59. package/dist/es/domain/models/product.d.ts +0 -1
  60. package/dist/es/domain/models/product.js +0 -1
  61. package/dist/es/domain/models/property.d.ts +0 -1
  62. package/dist/es/domain/models/property.js +0 -16
  63. package/dist/es/domain/models/route.d.ts +0 -1
  64. package/dist/es/domain/models/route.js +0 -71
  65. package/dist/es/domain/models/routeConfiguration.d.ts +0 -1
  66. package/dist/es/domain/models/routeConfiguration.js +0 -36
  67. package/dist/es/domain/models/routeInstance.d.ts +0 -1
  68. package/dist/es/domain/models/routeInstance.js +0 -8
  69. package/dist/es/domain/models/routeStyle.d.ts +0 -1
  70. package/dist/es/domain/models/routeStyle.js +0 -1
  71. package/dist/es/domain/models/scene3D.d.ts +0 -1
  72. package/dist/es/domain/models/scene3D.js +0 -1
  73. package/dist/es/domain/models/transport.d.ts +0 -1
  74. package/dist/es/domain/models/transport.js +0 -12
  75. package/dist/es/domain/ports/ICache.d.ts +0 -1
  76. package/dist/es/domain/ports/ICache.js +0 -1
  77. package/dist/es/domain/ports/IHttpClient.d.ts +0 -1
  78. package/dist/es/domain/ports/IHttpClient.js +0 -1
  79. package/dist/es/domain/ports/ILogger.d.ts +0 -1
  80. package/dist/es/domain/ports/ILogger.js +0 -9
  81. package/dist/es/domain/ports/index.d.ts +0 -1
  82. package/dist/es/domain/ports/index.js +0 -5
  83. package/dist/es/index.d.ts +0 -1
  84. package/dist/es/index.js +1 -28
  85. package/dist/es/infrastructure/cache/CacheManager.d.ts +0 -1
  86. package/dist/es/infrastructure/cache/CacheManager.js +0 -94
  87. package/dist/es/infrastructure/cache/LRUCache.d.ts +0 -1
  88. package/dist/es/infrastructure/cache/LRUCache.js +0 -57
  89. package/dist/es/infrastructure/cache/PersistentCache.d.ts +0 -1
  90. package/dist/es/infrastructure/cache/PersistentCache.js +0 -51
  91. package/dist/es/infrastructure/cache/cacheConfig.d.ts +0 -1
  92. package/dist/es/infrastructure/cache/cacheConfig.js +8 -27
  93. package/dist/es/infrastructure/http/FetchHttpClient.d.ts +0 -1
  94. package/dist/es/infrastructure/http/FetchHttpClient.js +0 -36
  95. package/dist/es/infrastructure/logging/MVXLogger.d.ts +0 -1
  96. package/dist/es/infrastructure/logging/MVXLogger.js +0 -37
  97. package/dist/es/interfaces/cache.d.ts +0 -1
  98. package/dist/es/interfaces/cache.js +0 -1
  99. package/dist/es/interfaces/healthResponse.d.ts +0 -1
  100. package/dist/es/interfaces/healthResponse.js +0 -1
  101. package/dist/es/interfaces/institutionResponse.d.ts +0 -1
  102. package/dist/es/interfaces/institutionResponse.js +0 -1
  103. package/dist/es/interfaces/metadata.d.ts +0 -1
  104. package/dist/es/interfaces/metadata.js +0 -1
  105. package/dist/es/interfaces/placeResponse.d.ts +0 -1
  106. package/dist/es/interfaces/placeResponse.js +0 -1
  107. package/dist/es/interfaces/routeCacheResponse.d.ts +0 -1
  108. package/dist/es/interfaces/routeCacheResponse.js +0 -1
  109. package/dist/es/interfaces/routeResponse.d.ts +0 -1
  110. package/dist/es/interfaces/routeResponse.js +0 -1
  111. package/dist/es/interfaces/styleResponse.d.ts +0 -1
  112. package/dist/es/interfaces/styleResponse.js +0 -1
  113. package/dist/es/logger/logger.d.ts +0 -1
  114. package/dist/es/logger/logger.js +0 -10
  115. package/dist/es/logger/sentry.d.ts +0 -1
  116. package/dist/es/logger/sentry.js +1 -39
  117. package/dist/es/map/fitCamera.d.ts +0 -1
  118. package/dist/es/map/fitCamera.js +0 -44
  119. package/dist/es/map/generated/maplibreWorkerSource.d.ts +0 -1
  120. package/dist/es/map/generated/maplibreWorkerSource.js +0 -12
  121. package/dist/es/map/installMapLibreWorker.d.ts +0 -1
  122. package/dist/es/map/installMapLibreWorker.js +0 -100
  123. package/dist/es/map/liveMapFitTransform.d.ts +0 -1
  124. package/dist/es/map/liveMapFitTransform.js +0 -82
  125. package/dist/es/map/map.d.ts +0 -1
  126. package/dist/es/map/map.js +4 -681
  127. package/dist/es/map/mapInteractionOptions.d.ts +0 -1
  128. package/dist/es/map/mapInteractionOptions.js +0 -35
  129. package/dist/es/map/scene3DController.d.ts +0 -1
  130. package/dist/es/map/scene3DController.js +0 -221
  131. package/dist/es/repository/repository.d.ts +0 -1
  132. package/dist/es/repository/repository.js +0 -56
  133. package/dist/es/repository/requester.d.ts +0 -1
  134. package/dist/es/repository/requester.js +0 -233
  135. package/dist/es/sdk.d.ts +0 -1
  136. package/dist/es/sdk.js +0 -35
  137. package/dist/es/utils/3d.d.ts +0 -1
  138. package/dist/es/utils/3d.js +0 -79
  139. package/dist/es/utils/deckLayers.d.ts +0 -1
  140. package/dist/es/utils/deckLayers.js +1 -27
  141. package/dist/es/utils/error.d.ts +0 -1
  142. package/dist/es/utils/error.js +0 -7
  143. package/dist/es/utils/images.d.ts +0 -1
  144. package/dist/es/utils/images.js +0 -7
  145. package/dist/es/utils/loadGlb.d.ts +0 -1
  146. package/dist/es/utils/loadGlb.js +2 -96
  147. package/dist/es/utils/mapvxHostname.d.ts +0 -1
  148. package/dist/es/utils/mapvxHostname.js +0 -11
  149. package/dist/es/utils/nav-functions.d.ts +0 -1
  150. package/dist/es/utils/nav-functions.js +0 -82
  151. package/dist/es/utils/opening-hours-helper.d.ts +0 -1
  152. package/dist/es/utils/opening-hours-helper.js +6 -382
  153. package/dist/es/utils/preconnect.d.ts +0 -1
  154. package/dist/es/utils/preconnect.js +0 -61
  155. package/dist/es/utils/route-utils.d.ts +0 -1
  156. package/dist/es/utils/route-utils.js +0 -25
  157. package/dist/es/utils/semaphore.d.ts +0 -1
  158. package/dist/es/utils/semaphore.js +0 -78
  159. package/dist/es/utils/three.d.ts +0 -1
  160. package/dist/es/utils/three.js +0 -43
  161. package/dist/es/utils/threeScene.d.ts +0 -1
  162. package/dist/es/utils/threeScene.js +0 -38
  163. package/dist/es/utils/update-css.d.ts +0 -1
  164. package/dist/es/utils/update-css.js +0 -26
  165. package/dist/es/utils/utils.d.ts +0 -1
  166. package/dist/es/utils/utils.js +0 -53
  167. package/dist/umd/index.js +4 -29240
  168. package/dist/umd/index.js.LICENSE.txt +1 -0
  169. package/dist/umd/styles.css +0 -1
  170. package/dist/umd/styles.js +3 -32
  171. package/package.json +12 -6
  172. package/dist/cjs/index.js.map +0 -1
  173. package/dist/es/assets/icons.d.ts.map +0 -1
  174. package/dist/es/assets/icons.js.map +0 -1
  175. package/dist/es/config/draco.d.ts.map +0 -1
  176. package/dist/es/config/draco.js.map +0 -1
  177. package/dist/es/config/sdkConfig.d.ts.map +0 -1
  178. package/dist/es/config/sdkConfig.js.map +0 -1
  179. package/dist/es/controllers/markerLayoutController.d.ts.map +0 -1
  180. package/dist/es/controllers/markerLayoutController.js.map +0 -1
  181. package/dist/es/controllers/routeController.d.ts.map +0 -1
  182. package/dist/es/controllers/routeController.js.map +0 -1
  183. package/dist/es/domain/models/_internal.d.ts.map +0 -1
  184. package/dist/es/domain/models/_internal.js.map +0 -1
  185. package/dist/es/domain/models/animation.d.ts.map +0 -1
  186. package/dist/es/domain/models/animation.js.map +0 -1
  187. package/dist/es/domain/models/banner.d.ts.map +0 -1
  188. package/dist/es/domain/models/banner.js.map +0 -1
  189. package/dist/es/domain/models/campaign.d.ts.map +0 -1
  190. package/dist/es/domain/models/campaign.js.map +0 -1
  191. package/dist/es/domain/models/categories.d.ts.map +0 -1
  192. package/dist/es/domain/models/categories.js.map +0 -1
  193. package/dist/es/domain/models/circle.d.ts.map +0 -1
  194. package/dist/es/domain/models/circle.js.map +0 -1
  195. package/dist/es/domain/models/cityFilterOption.d.ts.map +0 -1
  196. package/dist/es/domain/models/cityFilterOption.js.map +0 -1
  197. package/dist/es/domain/models/configuration.d.ts.map +0 -1
  198. package/dist/es/domain/models/configuration.js.map +0 -1
  199. package/dist/es/domain/models/cssCustomization.d.ts.map +0 -1
  200. package/dist/es/domain/models/cssCustomization.js.map +0 -1
  201. package/dist/es/domain/models/fitOptions.d.ts.map +0 -1
  202. package/dist/es/domain/models/fitOptions.js.map +0 -1
  203. package/dist/es/domain/models/innerFloors.d.ts.map +0 -1
  204. package/dist/es/domain/models/innerFloors.js.map +0 -1
  205. package/dist/es/domain/models/institution.d.ts.map +0 -1
  206. package/dist/es/domain/models/institution.js.map +0 -1
  207. package/dist/es/domain/models/latLng.d.ts.map +0 -1
  208. package/dist/es/domain/models/latLng.js.map +0 -1
  209. package/dist/es/domain/models/location.d.ts.map +0 -1
  210. package/dist/es/domain/models/location.js.map +0 -1
  211. package/dist/es/domain/models/loggeable.d.ts.map +0 -1
  212. package/dist/es/domain/models/loggeable.js.map +0 -1
  213. package/dist/es/domain/models/mapCamera.d.ts.map +0 -1
  214. package/dist/es/domain/models/mapCamera.js.map +0 -1
  215. package/dist/es/domain/models/mapConfig.d.ts.map +0 -1
  216. package/dist/es/domain/models/mapConfig.js.map +0 -1
  217. package/dist/es/domain/models/marker.d.ts.map +0 -1
  218. package/dist/es/domain/models/marker.js.map +0 -1
  219. package/dist/es/domain/models/multilanguage.d.ts.map +0 -1
  220. package/dist/es/domain/models/multilanguage.js.map +0 -1
  221. package/dist/es/domain/models/openingHours.d.ts.map +0 -1
  222. package/dist/es/domain/models/openingHours.js.map +0 -1
  223. package/dist/es/domain/models/place.d.ts.map +0 -1
  224. package/dist/es/domain/models/place.js.map +0 -1
  225. package/dist/es/domain/models/platform.d.ts.map +0 -1
  226. package/dist/es/domain/models/platform.js.map +0 -1
  227. package/dist/es/domain/models/popover.d.ts.map +0 -1
  228. package/dist/es/domain/models/popover.js.map +0 -1
  229. package/dist/es/domain/models/product.d.ts.map +0 -1
  230. package/dist/es/domain/models/product.js.map +0 -1
  231. package/dist/es/domain/models/property.d.ts.map +0 -1
  232. package/dist/es/domain/models/property.js.map +0 -1
  233. package/dist/es/domain/models/route.d.ts.map +0 -1
  234. package/dist/es/domain/models/route.js.map +0 -1
  235. package/dist/es/domain/models/routeConfiguration.d.ts.map +0 -1
  236. package/dist/es/domain/models/routeConfiguration.js.map +0 -1
  237. package/dist/es/domain/models/routeInstance.d.ts.map +0 -1
  238. package/dist/es/domain/models/routeInstance.js.map +0 -1
  239. package/dist/es/domain/models/routeStyle.d.ts.map +0 -1
  240. package/dist/es/domain/models/routeStyle.js.map +0 -1
  241. package/dist/es/domain/models/scene3D.d.ts.map +0 -1
  242. package/dist/es/domain/models/scene3D.js.map +0 -1
  243. package/dist/es/domain/models/transport.d.ts.map +0 -1
  244. package/dist/es/domain/models/transport.js.map +0 -1
  245. package/dist/es/domain/ports/ICache.d.ts.map +0 -1
  246. package/dist/es/domain/ports/ICache.js.map +0 -1
  247. package/dist/es/domain/ports/IHttpClient.d.ts.map +0 -1
  248. package/dist/es/domain/ports/IHttpClient.js.map +0 -1
  249. package/dist/es/domain/ports/ILogger.d.ts.map +0 -1
  250. package/dist/es/domain/ports/ILogger.js.map +0 -1
  251. package/dist/es/domain/ports/index.d.ts.map +0 -1
  252. package/dist/es/domain/ports/index.js.map +0 -1
  253. package/dist/es/index.d.ts.map +0 -1
  254. package/dist/es/index.js.map +0 -1
  255. package/dist/es/infrastructure/cache/CacheManager.d.ts.map +0 -1
  256. package/dist/es/infrastructure/cache/CacheManager.js.map +0 -1
  257. package/dist/es/infrastructure/cache/LRUCache.d.ts.map +0 -1
  258. package/dist/es/infrastructure/cache/LRUCache.js.map +0 -1
  259. package/dist/es/infrastructure/cache/PersistentCache.d.ts.map +0 -1
  260. package/dist/es/infrastructure/cache/PersistentCache.js.map +0 -1
  261. package/dist/es/infrastructure/cache/cacheConfig.d.ts.map +0 -1
  262. package/dist/es/infrastructure/cache/cacheConfig.js.map +0 -1
  263. package/dist/es/infrastructure/http/FetchHttpClient.d.ts.map +0 -1
  264. package/dist/es/infrastructure/http/FetchHttpClient.js.map +0 -1
  265. package/dist/es/infrastructure/logging/MVXLogger.d.ts.map +0 -1
  266. package/dist/es/infrastructure/logging/MVXLogger.js.map +0 -1
  267. package/dist/es/interfaces/cache.d.ts.map +0 -1
  268. package/dist/es/interfaces/cache.js.map +0 -1
  269. package/dist/es/interfaces/healthResponse.d.ts.map +0 -1
  270. package/dist/es/interfaces/healthResponse.js.map +0 -1
  271. package/dist/es/interfaces/institutionResponse.d.ts.map +0 -1
  272. package/dist/es/interfaces/institutionResponse.js.map +0 -1
  273. package/dist/es/interfaces/metadata.d.ts.map +0 -1
  274. package/dist/es/interfaces/metadata.js.map +0 -1
  275. package/dist/es/interfaces/placeResponse.d.ts.map +0 -1
  276. package/dist/es/interfaces/placeResponse.js.map +0 -1
  277. package/dist/es/interfaces/routeCacheResponse.d.ts.map +0 -1
  278. package/dist/es/interfaces/routeCacheResponse.js.map +0 -1
  279. package/dist/es/interfaces/routeResponse.d.ts.map +0 -1
  280. package/dist/es/interfaces/routeResponse.js.map +0 -1
  281. package/dist/es/interfaces/styleResponse.d.ts.map +0 -1
  282. package/dist/es/interfaces/styleResponse.js.map +0 -1
  283. package/dist/es/logger/logger.d.ts.map +0 -1
  284. package/dist/es/logger/logger.js.map +0 -1
  285. package/dist/es/logger/sentry.d.ts.map +0 -1
  286. package/dist/es/logger/sentry.js.map +0 -1
  287. package/dist/es/map/fitCamera.d.ts.map +0 -1
  288. package/dist/es/map/fitCamera.js.map +0 -1
  289. package/dist/es/map/generated/maplibreWorkerSource.d.ts.map +0 -1
  290. package/dist/es/map/generated/maplibreWorkerSource.js.map +0 -1
  291. package/dist/es/map/installMapLibreWorker.d.ts.map +0 -1
  292. package/dist/es/map/installMapLibreWorker.js.map +0 -1
  293. package/dist/es/map/liveMapFitTransform.d.ts.map +0 -1
  294. package/dist/es/map/liveMapFitTransform.js.map +0 -1
  295. package/dist/es/map/map.d.ts.map +0 -1
  296. package/dist/es/map/map.js.map +0 -1
  297. package/dist/es/map/mapInteractionOptions.d.ts.map +0 -1
  298. package/dist/es/map/mapInteractionOptions.js.map +0 -1
  299. package/dist/es/map/scene3DController.d.ts.map +0 -1
  300. package/dist/es/map/scene3DController.js.map +0 -1
  301. package/dist/es/repository/repository.d.ts.map +0 -1
  302. package/dist/es/repository/repository.js.map +0 -1
  303. package/dist/es/repository/requester.d.ts.map +0 -1
  304. package/dist/es/repository/requester.js.map +0 -1
  305. package/dist/es/sdk.d.ts.map +0 -1
  306. package/dist/es/sdk.js.map +0 -1
  307. package/dist/es/utils/3d.d.ts.map +0 -1
  308. package/dist/es/utils/3d.js.map +0 -1
  309. package/dist/es/utils/deckLayers.d.ts.map +0 -1
  310. package/dist/es/utils/deckLayers.js.map +0 -1
  311. package/dist/es/utils/error.d.ts.map +0 -1
  312. package/dist/es/utils/error.js.map +0 -1
  313. package/dist/es/utils/images.d.ts.map +0 -1
  314. package/dist/es/utils/images.js.map +0 -1
  315. package/dist/es/utils/loadGlb.d.ts.map +0 -1
  316. package/dist/es/utils/loadGlb.js.map +0 -1
  317. package/dist/es/utils/mapvxHostname.d.ts.map +0 -1
  318. package/dist/es/utils/mapvxHostname.js.map +0 -1
  319. package/dist/es/utils/nav-functions.d.ts.map +0 -1
  320. package/dist/es/utils/nav-functions.js.map +0 -1
  321. package/dist/es/utils/opening-hours-helper.d.ts.map +0 -1
  322. package/dist/es/utils/opening-hours-helper.js.map +0 -1
  323. package/dist/es/utils/preconnect.d.ts.map +0 -1
  324. package/dist/es/utils/preconnect.js.map +0 -1
  325. package/dist/es/utils/route-utils.d.ts.map +0 -1
  326. package/dist/es/utils/route-utils.js.map +0 -1
  327. package/dist/es/utils/semaphore.d.ts.map +0 -1
  328. package/dist/es/utils/semaphore.js.map +0 -1
  329. package/dist/es/utils/three.d.ts.map +0 -1
  330. package/dist/es/utils/three.js.map +0 -1
  331. package/dist/es/utils/threeScene.d.ts.map +0 -1
  332. package/dist/es/utils/threeScene.js.map +0 -1
  333. package/dist/es/utils/update-css.d.ts.map +0 -1
  334. package/dist/es/utils/update-css.js.map +0 -1
  335. package/dist/es/utils/utils.d.ts.map +0 -1
  336. package/dist/es/utils/utils.js.map +0 -1
  337. package/dist/umd/index.js.map +0 -1
  338. package/dist/umd/styles.css.map +0 -1
  339. package/dist/umd/styles.js.map +0 -1
@@ -1,73 +1,27 @@
1
1
  import { LngLatBounds, Map, NavigationControl, Popup, addProtocol, } from "maplibre-gl";
2
2
  import { Semaphore } from "../utils/semaphore";
3
3
  import { installMapLibreWorker } from "./installMapLibreWorker";
4
- /** Shared GeoJSON source holding every circle drawn through the circle API. */
5
4
  const CIRCLE_SOURCE_ID = "mapvx-circles";
6
- /** Fill layer rendering the translucent interior of the circles. */
7
5
  const CIRCLE_FILL_LAYER_ID = "mapvx-circles-fill";
8
- /** Line layer rendering the circle outlines. */
9
6
  const CIRCLE_LINE_LAYER_ID = "mapvx-circles-line";
10
- /**
11
- * Layer-id suffix per circle render order. The default placement keeps the
12
- * unsuffixed ids so existing consumers referencing them keep working.
13
- */
14
7
  const CIRCLE_LAYER_SUFFIXES = {
15
8
  aboveBasemap: "",
16
9
  belowLabels: "-below-labels",
17
10
  top: "-top",
18
11
  };
19
- /**
20
- * How many times a failed vector tile is reloaded before it is dropped from the retry
21
- * queue. Bounded so a permanently unavailable tile stops being requested, while a tile
22
- * that failed on a transient network error still gets several chances.
23
- */
24
12
  const MAX_TILE_RETRIES = 5;
25
- /**
26
- * Base delay for the retry backoff. Attempt N waits `BASE * 2^(N-1)` before it is
27
- * eligible again — 1s, 2s, 4s, 8s — so a tile that keeps failing is retried ever less
28
- * often instead of once per timer tick.
29
- */
30
13
  const TILE_RETRY_BASE_DELAY_MS = 1000;
31
- /**
32
- * Safety deadline for {@link InternalMapVXMap.setStyle}'s `onStyleReady` callback. The
33
- * callback normally fires on the map's `idle` event, but `idle` may never arrive (the
34
- * style request failed, the swap never settles). Callers hide the map behind a loading
35
- * overlay until the callback arrives, so it must be released no matter what.
36
- */
37
14
  const STYLE_READY_TIMEOUT_MS = 4000;
38
- /**
39
- * Frames a floor change waits before it will believe the indoor tiles are
40
- * already rebuilt (see `updateMarkersWhenFloorSettles`). Genuinely a frame
41
- * count: the reload is dispatched on the map's next render, so this is how
42
- * many renders it gets to be observed in.
43
- */
44
15
  const FLOOR_SETTLE_MIN_FRAMES = 3;
45
- /**
46
- * Longest a floor change waits for the new floor's tiles before switching the
47
- * HTML markers anyway, so a stalled source never hides markers for good.
48
- *
49
- * A deadline rather than a frame count. The panels this matters on run at
50
- * 20-30 fps, where a 60-frame cap is two to three seconds — and the wait also
51
- * gates `addMarker`, so overshooting it is not merely a late marker switch.
52
- */
53
16
  const FLOOR_SETTLE_MAX_MS = 1000;
54
- /** Fill/line layer ids for one circle render-order bucket. */
55
17
  function circleLayerIdsFor(order) {
56
18
  const suffix = CIRCLE_LAYER_SUFFIXES[order];
57
19
  return { fill: CIRCLE_FILL_LAYER_ID + suffix, line: CIRCLE_LINE_LAYER_ID + suffix };
58
20
  }
59
- /** True for the layer ids owned by the circle API, regardless of bucket. */
60
21
  function isCircleLayerId(id) {
61
22
  return id.startsWith(CIRCLE_FILL_LAYER_ID) || id.startsWith(CIRCLE_LINE_LAYER_ID);
62
23
  }
63
- // Flag to track if cached-tile protocol has been registered
64
24
  let cachedTileProtocolRegistered = false;
65
- /**
66
- * Deep clone helper that works in all environments.
67
- * Uses structuredClone if available, otherwise falls back to JSON serialization.
68
- * @param obj The object to clone
69
- * @returns A deep clone of the object
70
- */
71
25
  function deepClone(obj) {
72
26
  if (obj === undefined || obj === null) {
73
27
  return obj;
@@ -77,28 +31,12 @@ function deepClone(obj) {
77
31
  }
78
32
  return JSON.parse(JSON.stringify(obj));
79
33
  }
80
- /**
81
- * Register a custom protocol for cached tiles that routes requests through the main thread.
82
- * This allows the service worker to intercept and cache tile requests.
83
- *
84
- * Wraps fetches in a {@link Semaphore} so tile CDN / WAFs are not hit with
85
- * unbounded parallel requests (same host as the service worker cache). The
86
- * semaphore is created once with the limit from the first map's config; later
87
- * calls are no-ops because the protocol can only be registered once globally
88
- * on MapLibre.
89
- *
90
- * @param maxConcurrentFetches - Maximum number of in-flight tile fetches.
91
- */
92
34
  function registerCachedTileProtocol(maxConcurrentFetches) {
93
35
  if (cachedTileProtocolRegistered)
94
36
  return;
95
37
  const semaphore = new Semaphore(maxConcurrentFetches);
96
38
  addProtocol("cached-tile", (params, abortController) => {
97
39
  const url = params.url.replace("cached-tile://", "https://");
98
- // Pass the abort signal to acquire() so a request cancelled while still
99
- // queued (e.g. during rapid zoom) drops out of the FIFO queue instead of
100
- // waiting for a slot just to bail. release() runs only inside this chain,
101
- // i.e. only after a slot was actually granted.
102
40
  return semaphore.acquire(abortController.signal).then(() => fetch(url, { signal: abortController.signal })
103
41
  .then((response) => {
104
42
  if (!response.ok) {
@@ -113,12 +51,6 @@ function registerCachedTileProtocol(maxConcurrentFetches) {
113
51
  });
114
52
  cachedTileProtocolRegistered = true;
115
53
  }
116
- /**
117
- * Converts a PaddingValue to pixels based on the container and viewport dimensions.
118
- * @param value The padding value (number or string with unit)
119
- * @param dimension The reference dimension in pixels (container width/height)
120
- * @returns The padding value in pixels
121
- */
122
54
  function parsePaddingValue(value, dimension) {
123
55
  if (value === undefined) {
124
56
  return 0;
@@ -145,13 +77,6 @@ function parsePaddingValue(value, dimension) {
145
77
  return numericValue;
146
78
  }
147
79
  }
148
- /**
149
- * Converts PaddingOptions with mixed units to MapLibre's pixel-based padding format.
150
- * @param padding The padding options with optional fields and mixed units
151
- * @param containerWidth The map container width in pixels
152
- * @param containerHeight The map container height in pixels
153
- * @returns Padding object with all values in pixels
154
- */
155
80
  function convertPaddingToPixels(padding, containerWidth, containerHeight) {
156
81
  if (!padding) {
157
82
  return { top: 0, bottom: 0, left: 0, right: 0 };
@@ -180,129 +105,38 @@ import { Scene3DController } from "./scene3DController";
180
105
  import { computeOrientedCamera, refineCameraForPitch } from "./fitCamera";
181
106
  import { LiveMapFitTransform } from "./liveMapFitTransform";
182
107
  import { buildInteractionOptions, shouldDisableTouchRotation } from "./mapInteractionOptions";
183
- /**
184
- * Class to interact with the map.
185
- * @category Map
186
- * @hidden
187
- */
188
- /**
189
- * Whether a style publishes any `fill-extrusion` layer, i.e. whether it has extruded rooms for the
190
- * 3D scene to stand on.
191
- *
192
- * This is the only reliable signal for "does 3D work here". `mapStyleJson` is served per API key,
193
- * so the same venue comes back with extrusions on a 3D key and flat on a 2D one — the place id
194
- * cannot answer the question.
195
- *
196
- * @param style The style about to be applied, or the one currently applied.
197
- * @returns `true` when at least one layer is `fill-extrusion`.
198
- */
199
108
  function styleHasExtrusions(style) {
200
109
  return style.layers.some((layer) => layer.type === "fill-extrusion");
201
110
  }
202
111
  export class InternalMapVXMap extends Loggeable {
203
- /** Whether a floor change is still rebuilding, so markers wait for it. */
204
112
  get floorSettlePending() {
205
113
  return this.floorSettleDeadline != null && this.now() < this.floorSettleDeadline;
206
114
  }
207
- /** Wall clock for the settle deadline; `Date.now` where `performance` is absent. */
208
115
  now() {
209
116
  return typeof performance !== "undefined" ? performance.now() : Date.now();
210
117
  }
211
- /**
212
- * Creates a new map instance with the parameters specified in mapConfig and assigns it to the provided HTML container.
213
- * @param mapConfig Configuration parameters for the map.
214
- * @param container Container where the assignment of the created map is required.
215
- * @param parentPlace Parent place required for map floor mapping, along with the display of subplaces.
216
- * @param token The token provided for the creation and fetching of map information.
217
- * @returns A new instance of MapVXMap.
218
- */
219
118
  constructor(mapConfig, container, token) {
220
119
  var _a, _b, _c;
221
120
  super();
222
- /**
223
- * Monotonic counter for {@link addLiveRoute} calls. Refreshes overlap (each one
224
- * awaits a fetch), so only the call holding the latest ticket may touch the
225
- * map — an older response resolving last is discarded instead of clobbering
226
- * the newer route.
227
- */
228
121
  this.liveRouteTicket = 0;
229
122
  this.potentialParentPlaces = [];
230
123
  this.innerFloors = [];
231
124
  this.subPlaces = [];
232
125
  this.currentFloor = "";
233
126
  this.baseFilters = {};
234
- /**
235
- * Layer ids whose declared (base) filter has already been resolved — either captured
236
- * into {@link baseFilters} or confirmed absent.
237
- *
238
- * `baseFilters[id] === undefined` cannot carry that information on its own: it means
239
- * both "not looked at yet" and "looked at, the layer declares no filter". Without the
240
- * distinction, a later pass re-reads the layer's LIVE filter — which by then is the
241
- * one this class wrote — and stores our own floor/public-place filter as if it were
242
- * the style's, so the layer keeps filtering by a stale floor forever.
243
- *
244
- * An id lands here the moment its declared filter is read from the style spec, or the
245
- * moment this class writes a filter to that layer, whichever happens first. Layers
246
- * added asynchronously after a `setStyle` swap are in neither situation, so their
247
- * genuinely pristine live filter is still captured on first touch.
248
- */
249
127
  this.capturedBaseFilters = new Set();
250
- /**
251
- * Monotonic id of the most recently STARTED style swap. Every {@link setStyle} call
252
- * captures its own value and checks it again in each async continuation, so a
253
- * superseded swap can neither touch the shared bookkeeping (`styleReadyTimer`,
254
- * `pendingStyleSwapListener`) nor apply its obsolete style to the live map.
255
- *
256
- * A per-call `readied` flag is not enough: the timer and the listener slot are
257
- * single-valued instance state, so two overlapping swaps otherwise clobber each
258
- * other's — one caller's overlay is released by the other's failure, or an
259
- * abandoned listener re-seeds filters from layer ids the current style lacks.
260
- */
261
128
  this.styleSwapGeneration = 0;
262
129
  this.markers = [];
263
130
  this.circles = [];
264
131
  this.enableHover = false;
265
132
  this.hoveredId = "unselected";
266
133
  this.failedTiles = new Set();
267
- /**
268
- * Retry bookkeeping per failed tile. A WeakMap so it can never outlive the tiles
269
- * themselves — entries disappear with the tile objects, which is why none of the
270
- * `failedTiles.clear()` paths have to reset it.
271
- */
272
134
  this.tileRetryState = new WeakMap();
273
135
  this.geoLocation = navigator.geolocation;
274
- /** Floor-change settle bookkeeping (see `updateMarkersWhenFloorSettles`). */
275
136
  this.floorSettleToken = 0;
276
- /**
277
- * When the floor-change settle stops holding markers back, or `null` when no
278
- * change is in flight.
279
- *
280
- * A deadline rather than a flag, because `addMarker` reads it: the poll that
281
- * would clear a flag runs on `requestAnimationFrame`, which does not fire in
282
- * a backgrounded tab and does not run at all for a map torn down through
283
- * MapLibre's own `remove()` rather than `destroyMap`. A flag left set there
284
- * makes every later `addMarker` skip the call that attaches the marker, for
285
- * good; a deadline expires on its own.
286
- */
287
137
  this.floorSettleDeadline = null;
288
- /** Owns the deck.gl overlay + GLB scene; created on style load only when 3D is active. */
289
138
  this.scene3D = undefined;
290
- /**
291
- * Whether the style currently applied publishes `fill-extrusion` layers, i.e. whether there are
292
- * roofs for the 3D scene to sit on. Recomputed on every style the map is given, because the style
293
- * is served per API key, not per venue: the same place can come back 3D on one key and flat on
294
- * another. Assumed true until a style says otherwise, so 2D maps (which never read it) are
295
- * unaffected.
296
- */
297
139
  this.styleSupports3D = true;
298
- // First statement on purpose, and further forward than it looks necessary. MapLibre reads
299
- // WORKER_URL once, when its first Dispatcher is built, and never again while any map is alive
300
- // — so the worker has to be installed before *anything* touches MapLibre, not merely before
301
- // `new Map(...)`. Today the constructor reaches MapLibre only through the map itself, but
302
- // until recently it also called `setRTLTextPlugin()` here, which builds a Dispatcher of its
303
- // own 200 lines ahead of the map; `prewarm()` and `importScriptInWorkers()` do the same.
304
- // Keeping this first means no later edit can slip such a call in front of it.
305
- // See installMapLibreWorker and DEVELOPER_DOCS/MAPLIBRE_V6_MIGRATION.md.
306
140
  installMapLibreWorker();
307
141
  this.repository = new Repository(token, (_a = mapConfig.lang) !== null && _a !== void 0 ? _a : "en", mapConfig.apiUrl, undefined, mapConfig.mapvxRequestContext, {
308
142
  routeApiUrl: mapConfig.routeApiUrl,
@@ -331,9 +165,6 @@ export class InternalMapVXMap extends Loggeable {
331
165
  })();
332
166
  this.markerLayoutConfig = Object.assign(Object.assign({}, DEFAULT_MARKER_LAYOUT_CONFIG), mapConfig.markerLayout);
333
167
  this.markerLayoutController = new MarkerLayoutController(this, this.markerLayoutConfig);
334
- // `container` is the very element handed to MapLibre below, and every
335
- // marker is mounted inside it, so publishing the gap/width variables here
336
- // covers markers added before the map's "load" event fires.
337
168
  this.markerLayoutController.applyLayoutVariables(container);
338
169
  if (mapConfig.parentPlaceId != null) {
339
170
  this.initialPlaceDetailSetUp(mapConfig.parentPlaceId, mapConfig.authToken);
@@ -345,12 +176,6 @@ export class InternalMapVXMap extends Loggeable {
345
176
  this.enableHover = mapConfig.enableHover || false;
346
177
  this.initialMapStyleSetUp(mapConfig, container);
347
178
  }
348
- /**
349
- * Transform style sources to use cached-tile:// protocol for tile URLs.
350
- * This enables the service worker to intercept and cache tile requests.
351
- * @param style The original style specification
352
- * @returns A new style with transformed tile URLs
353
- */
354
179
  transformStyleForCaching(style) {
355
180
  if (!style) {
356
181
  return style;
@@ -359,9 +184,6 @@ export class InternalMapVXMap extends Loggeable {
359
184
  if (transformedStyle === null || transformedStyle === void 0 ? void 0 : transformedStyle.sources) {
360
185
  for (const sourceKey of Object.keys(transformedStyle.sources)) {
361
186
  const source = transformedStyle.sources[sourceKey];
362
- // Transform vector and raster tile sources
363
- // Only transform source.tiles (actual tile URLs), NOT source.url (TileJSON metadata URL)
364
- // source.url points to a TileJSON file that returns JSON, not binary tile data
365
187
  if (source.tiles && Array.isArray(source.tiles)) {
366
188
  source.tiles = source.tiles.map((tileUrl) => {
367
189
  if (tileUrl.startsWith("https://")) {
@@ -418,11 +240,6 @@ export class InternalMapVXMap extends Loggeable {
418
240
  .catch(console.error);
419
241
  return;
420
242
  }
421
- // Through the same helper as `setStyle` and `changeParentPlaceTo`. This PR
422
- // forwards `styleRef`/`styleTheme` to the initial load too, and a ref scoped
423
- // to the user's client rather than to the api key resolves only over bearer
424
- // — fetched over the api-key path it 4xx'd, and since this is the call that
425
- // creates the map, the map was never created at all.
426
243
  this.fetchVenueStyle(mapConfig.parentPlaceId, mapConfig.styleRef, mapConfig.styleTheme)
427
244
  .then((style) => {
428
245
  return this.onMapStyleLoaded(mapConfig, container, style);
@@ -433,15 +250,11 @@ export class InternalMapVXMap extends Loggeable {
433
250
  }
434
251
  onMapStyleLoaded(mapConfig, container, style) {
435
252
  var _a, _b, _c, _d, _e, _f, _g, _h;
436
- // Determine if service worker caching should be enabled
437
253
  const useServiceWorkerCaching = this.tileCacheConfig.enabled && this.tileCacheConfig.persistToServiceWorker;
438
254
  if (useServiceWorkerCaching) {
439
255
  registerCachedTileProtocol(this.tileCacheConfig.maxConcurrentTileFetches);
440
256
  }
441
- // Transform tile URLs only if service worker caching is enabled
442
257
  const finalStyle = useServiceWorkerCaching ? this.transformStyleForCaching(style) : style;
443
- // Read straight off the style object rather than `map.getStyle()`: the map does not exist yet
444
- // here, and the decision has to be made before the 3D controller is constructed below.
445
258
  this.styleSupports3D = styleHasExtrusions(finalStyle);
446
259
  if (this.mode === "3D" && !this.styleSupports3D) {
447
260
  this.logWarning(new Error("3D was requested but this style publishes no `fill-extrusion` layers, so there are no " +
@@ -450,18 +263,13 @@ export class InternalMapVXMap extends Loggeable {
450
263
  "floating above the ground. The style is served per API key, not per venue, so check " +
451
264
  "that this key publishes 3D."), { functionName: "onMapStyleLoaded", parentPlaceId: (_a = this.parentPlaceId) !== null && _a !== void 0 ? _a : "" });
452
265
  }
453
- const mapOptions = Object.assign({ container, style: finalStyle, center: mapConfig.center, zoom: mapConfig.zoom, pitch: (_b = mapConfig.pitch) !== null && _b !== void 0 ? _b : 0, attributionControl: false, maplibreLogo: false, bearingSnap: (_c = mapConfig.bearingSnap) !== null && _c !== void 0 ? _c : 0, cancelPendingTileRequestsWhileZooming: true,
454
- // Use configured maxTiles for MapLibre's memory cache
455
- maxTileCacheSize: this.tileCacheConfig.maxTiles }, buildInteractionOptions(mapConfig));
266
+ const mapOptions = Object.assign({ container, style: finalStyle, center: mapConfig.center, zoom: mapConfig.zoom, pitch: (_b = mapConfig.pitch) !== null && _b !== void 0 ? _b : 0, attributionControl: false, maplibreLogo: false, bearingSnap: (_c = mapConfig.bearingSnap) !== null && _c !== void 0 ? _c : 0, cancelPendingTileRequestsWhileZooming: true, maxTileCacheSize: this.tileCacheConfig.maxTiles }, buildInteractionOptions(mapConfig));
456
267
  if (mapConfig.maxZoom)
457
268
  mapOptions.maxZoom = mapConfig.maxZoom;
458
269
  if (mapConfig.minZoom)
459
270
  mapOptions.minZoom = mapConfig.minZoom;
460
- // Reduced internal resolution on request (fill-rate relief for low-end GPUs);
461
- // MapLibre keeps devicePixelRatio when the option is left out.
462
271
  if (mapConfig.pixelRatio !== undefined)
463
272
  mapOptions.pixelRatio = mapConfig.pixelRatio;
464
- // `0` disables the post-gesture fade tail entirely; keep MapLibre's default otherwise.
465
273
  if (mapConfig.fadeDuration !== undefined)
466
274
  mapOptions.fadeDuration = mapConfig.fadeDuration;
467
275
  if (mapConfig.maxBounds && mapConfig.maxBounds.length > 1) {
@@ -469,13 +277,9 @@ export class InternalMapVXMap extends Loggeable {
469
277
  mapOptions.maxBounds = new LngLatBounds([boundingBox[0].lng, boundingBox[0].lat], [boundingBox[1].lng, boundingBox[1].lat]);
470
278
  }
471
279
  this.map = new Map(mapOptions);
472
- // Create the 3D controller only when the map opts into 3D. All heavy WebGL / deck.gl work is
473
- // owned by it; in 2D mode `this.scene3D` stays undefined and every hook below is a no-op.
474
280
  if (this.is3DSceneActive() && this.scene3DConfig) {
475
281
  this.scene3D = new Scene3DController(this.map, this.scene3DConfig, this.initialCenter, mapConfig.onScene3DModelsProgress);
476
282
  }
477
- // When rotation is disabled we still want pinch-to-zoom to work, so the
478
- // two-finger rotation is turned off here instead of via the constructor.
479
283
  if (shouldDisableTouchRotation(mapConfig)) {
480
284
  (_e = (_d = this.map.touchZoomRotate) === null || _d === void 0 ? void 0 : _d.disableRotation) === null || _e === void 0 ? void 0 : _e.call(_d);
481
285
  }
@@ -485,7 +289,6 @@ export class InternalMapVXMap extends Loggeable {
485
289
  }), (_h = mapConfig.navigationPosition) !== null && _h !== void 0 ? _h : "top-right");
486
290
  this.map.on("load", () => {
487
291
  var _a, _b;
488
- // 3D libraries load asynchronously; the rest of the load flow does not wait on them.
489
292
  void ((_a = this.scene3D) === null || _a === void 0 ? void 0 : _a.onMapLoad());
490
293
  this.whenStyleUpdates(style);
491
294
  if (mapConfig.lang)
@@ -495,8 +298,6 @@ export class InternalMapVXMap extends Loggeable {
495
298
  this.subscribeToFailedTiles();
496
299
  this.markerLayoutController.attach();
497
300
  });
498
- // Self-healing for circles: a full style reload wipes custom sources and
499
- // layers, and not every restyle path goes through whenStyleUpdates.
500
301
  this.map.on("styledata", () => {
501
302
  if (this.circles.length > 0)
502
303
  this.ensureCircleLayers();
@@ -522,15 +323,6 @@ export class InternalMapVXMap extends Loggeable {
522
323
  style.layers
523
324
  .filter((layer) => layer.id.startsWith("indoor-"))
524
325
  .forEach((layer) => {
525
- // Seed from the STYLE SPEC — the only pristine source — and do it BEFORE the
526
- // setFilter below overwrites the live filter. Reading it back afterwards would
527
- // return our own `publicPlaceFilter` and store it as the layer's declared one,
528
- // turning `public_place` from an OR into an AND and hiding every private
529
- // feature on the selected floor. Every indoor layer is covered, not just
530
- // fill/line/symbol: a `circle` layer is discriminated by its filter just the
531
- // same, and dropping it makes the layer repaint every feature.
532
- // `filter` is absent from the union member for `background` layers, hence the
533
- // structural read rather than `layer.filter`.
534
326
  const declared = layer.filter;
535
327
  this.captureDeclaredBaseFilter(layer.id, declared);
536
328
  const baseFilter = this.baseFilters[layer.id];
@@ -543,18 +335,6 @@ export class InternalMapVXMap extends Loggeable {
543
335
  }
544
336
  });
545
337
  }
546
- /**
547
- * Records a layer's declared (base) filter the first time the layer is seen, from an
548
- * explicit value (a style-spec `filter`) when one is available, otherwise by reading
549
- * the live filter — which is only pristine for layers this class has never written to.
550
- *
551
- * Marking happens even when no filter exists, so the layer is never revisited: on a
552
- * second visit its live filter is one we produced, and storing that as the "declared"
553
- * filter is what freezes a layer to a stale floor.
554
- *
555
- * @param layerId Id of the layer whose base filter should be resolved.
556
- * @param declared Declared filter straight from the style spec, when the caller has it.
557
- */
558
338
  captureDeclaredBaseFilter(layerId, declared) {
559
339
  if (this.capturedBaseFilters.has(layerId))
560
340
  return;
@@ -566,7 +346,6 @@ export class InternalMapVXMap extends Loggeable {
566
346
  }
567
347
  setLayersForLanguage(lang) {
568
348
  var _a, _b;
569
- // outdoor layers
570
349
  const layersName = [
571
350
  "aerodrome_label",
572
351
  "mountain_peak",
@@ -607,7 +386,6 @@ export class InternalMapVXMap extends Loggeable {
607
386
  this.debugLog("Layer language update failed (layer may not exist)", error);
608
387
  }
609
388
  });
610
- // indoor layers
611
389
  const indoorLayerIds = layers
612
390
  .filter((layer) => {
613
391
  var _a;
@@ -632,11 +410,6 @@ export class InternalMapVXMap extends Loggeable {
632
410
  }
633
411
  });
634
412
  }
635
- /**
636
- * Add values to identify the client.
637
- * @param segmentation The pair values to use as segmentation.
638
- * @returns The segmentation with the added values.
639
- */
640
413
  prepareSegmentation(segmentation) {
641
414
  var _a;
642
415
  return Object.assign(Object.assign({}, segmentation), { token: this.token, parentPlaceId: (_a = this.parentPlaceId) !== null && _a !== void 0 ? _a : "None" });
@@ -645,32 +418,20 @@ export class InternalMapVXMap extends Loggeable {
645
418
  var _a;
646
419
  this.circles = [];
647
420
  this.markerLayoutController.destroy();
648
- // Drop any in-flight `setStyle` bookkeeping while the map still exists: the
649
- // listener has to be detached before `map.remove()`, and the safety timer must not
650
- // outlive the map and call `onStyleReady` for a map that is already gone.
651
421
  this.clearPendingStyleSwapListener();
652
422
  if (this.styleReadyTimer) {
653
423
  clearTimeout(this.styleReadyTimer);
654
424
  this.styleReadyTimer = undefined;
655
425
  }
656
- // Drop any floor-settle poll in flight: bumping the token makes the next
657
- // `requestAnimationFrame` callback return instead of re-queueing itself and
658
- // re-attaching markers to a map that has already been removed.
659
426
  this.floorSettleToken++;
660
427
  this.floorSettleDeadline = null;
661
- // Dispose the 3D scene's GPU resources before the map (and its shared WebGL context) go away —
662
- // MapLibre's own teardown never calls the custom GLB layer's `onRemove`.
663
428
  (_a = this.scene3D) === null || _a === void 0 ? void 0 : _a.dispose();
664
429
  this.map.remove();
665
430
  this.unsubscribeFromFailedTiles();
666
431
  }
667
432
  clearTileCache() {
668
433
  try {
669
- // Clear the failed tiles tracking set
670
434
  this.failedTiles.clear();
671
- // Force MapLibre to reload all visible tiles by triggering a repaint
672
- // Note: MapLibre doesn't expose a direct cache clear method, so we
673
- // trigger a style refresh which causes tiles to be re-requested
674
435
  if (this.map) {
675
436
  this.map.triggerRepaint();
676
437
  }
@@ -680,18 +441,6 @@ export class InternalMapVXMap extends Loggeable {
680
441
  this.debugLog("Tile cache clear failed (cache may not exist)", error);
681
442
  }
682
443
  }
683
- /**
684
- * Whether 3D scene features (deck.gl overlay, declarative GLB custom layer, etc.) are active.
685
- * Requires {@link MapConfig.mode} `"3D"`, {@link Scene3DConfig.enabled} not `false`, and a style
686
- * that actually publishes `fill-extrusion` layers ({@link styleSupports3D}).
687
- *
688
- * That last condition is what keeps a caller from asking for 3D on a flat style: the overlay
689
- * would float above the ground while `hideLayers` removed the 2D labels underneath, leaving a
690
- * map with no labels at all — worse than the plain 2D map the caller would otherwise get.
691
- *
692
- * The heavy WebGL / deck.gl work lives in {@link Scene3DController}; this only decides whether one
693
- * is created and wired up. When `scene3D` is omitted, 3D features remain available.
694
- */
695
444
  is3DSceneActive() {
696
445
  var _a;
697
446
  return this.mode === "3D" && ((_a = this.scene3DConfig) === null || _a === void 0 ? void 0 : _a.enabled) !== false && this.styleSupports3D;
@@ -700,14 +449,6 @@ export class InternalMapVXMap extends Loggeable {
700
449
  var _a;
701
450
  return (_a = this.currentFloor) !== null && _a !== void 0 ? _a : "";
702
451
  }
703
- /**
704
- * Sets the route path used for GLB route-transparency collision, so 3D models a route passes
705
- * through fade and reveal the floor plan underneath. Called by {@link RouteController} whenever
706
- * the set of drawn routes changes. Points are tagged with the floor their segment is drawn on;
707
- * only points on the displayed floor participate. Pass an empty array to clear.
708
- *
709
- * No-op unless the 3D scene is active.
710
- */
711
452
  setRouteCollisionPath(points) {
712
453
  var _a;
713
454
  if (!this.is3DSceneActive()) {
@@ -715,11 +456,6 @@ export class InternalMapVXMap extends Loggeable {
715
456
  }
716
457
  (_a = this.scene3D) === null || _a === void 0 ? void 0 : _a.setRouteCollisionPath(points);
717
458
  }
718
- /**
719
- * Performs changes when parent place is updated
720
- * @param place new parent place
721
- * @param updateStyle defines if new parent place style must be set
722
- */
723
459
  changeParentPlaceTo(place, updateStyle = false, onStyleReady) {
724
460
  var _a, _b, _c, _d, _e, _f, _g;
725
461
  this.parentPlace = place;
@@ -737,52 +473,21 @@ export class InternalMapVXMap extends Loggeable {
737
473
  const useServiceWorkerCaching = this.tileCacheConfig.enabled && this.tileCacheConfig.persistToServiceWorker;
738
474
  const finalStyle = useServiceWorkerCaching ? this.transformStyleForCaching(style) : style;
739
475
  this.map.setStyle(finalStyle);
740
- // The new place's style declares its own filters for the same `indoor-*` layer
741
- // ids. Without this reset every id is still marked captured from the previous
742
- // place, so `captureDeclaredBaseFilter` early-returns for all of them and the
743
- // previous place's expressions keep filtering the new style forever. (The
744
- // `switch (layer.type)` block that used to re-read them on every style load was
745
- // removed when capture became once-per-id, which is what made this necessary.)
746
476
  this.resetBaseFilters();
747
477
  this.whenStyleUpdates(finalStyle);
748
478
  onStyleReady === null || onStyleReady === void 0 ? void 0 : onStyleReady();
749
479
  })
750
480
  .catch((error) => {
751
481
  this.logError(error, { functionName: "changeParentPlaceTo" });
752
- // Release the caller either way. `onStyleReady` is what a consumer
753
- // hides its loading overlay on, so swallowing the failure here left
754
- // the overlay up for good rather than merely unstyled.
755
482
  onStyleReady === null || onStyleReady === void 0 ? void 0 : onStyleReady();
756
483
  });
757
484
  }
758
485
  }
759
- /**
760
- * Fetch the venue style over whichever endpoint this map is authorized on.
761
- *
762
- * A bearer token authorizes by the user's client access rather than the api
763
- * key's scopes, so a client's branded style resolves without granting that
764
- * place to a shared api key; api-key consumers keep the
765
- * `/api/sdk/v2/mapStyleJson` path.
766
- *
767
- * Both callers go through here so they cannot disagree. They used to: once
768
- * `setStyle` had stored a `styleRef` it resolved over bearer, the next
769
- * parent-place change refetched that same ref over the api-key path, whose
770
- * key does not scope it — a non-ok response, a rejected promise, and a style
771
- * that was never applied, with `onStyleReady` left unfired under a caller's
772
- * loading overlay.
773
- */
774
486
  fetchVenueStyle(placeId, styleRef, styleTheme) {
775
487
  return this.authToken
776
488
  ? this.repository.fetchAndParseMapStyleByBearer(placeId, this.authToken, styleRef, styleTheme)
777
489
  : this.repository.fetchAndParseMapStyle(placeId, styleRef, styleTheme);
778
490
  }
779
- /**
780
- * Update the parent place and the current floor.
781
- * Does not update layers, markers, etc.
782
- * @param parentPlaceId
783
- * @param floorId
784
- * @throws A error if the parent place is not one of the allowed places to show.
785
- */
786
491
  updatePlaceAndFloor(parentPlaceId, floorId) {
787
492
  var _a, _b, _c, _d, _e, _f;
788
493
  const place = this.potentialParentPlaces.find((place) => place.mapvxId === parentPlaceId);
@@ -810,10 +515,6 @@ export class InternalMapVXMap extends Loggeable {
810
515
  setLang(lang) {
811
516
  this.repository.setLang(lang);
812
517
  this.currentLang = lang;
813
- // setLayersForLanguage reads this.map.getStyle()?.layers, which is empty
814
- // until the style finishes loading. If setLang is called right after
815
- // createMap (before the "load" event), apply it once the style is ready
816
- // so the language change is not silently dropped.
817
518
  if (this.map.isStyleLoaded()) {
818
519
  this.setLayersForLanguage(lang);
819
520
  }
@@ -825,10 +526,6 @@ export class InternalMapVXMap extends Loggeable {
825
526
  this.changeParentPlaceTo(place, updateStyle, onStyleReady);
826
527
  }
827
528
  setStyle(styleRef, styleTheme, onStyleReady) {
828
- // Every swap gets a generation. All shared bookkeeping below is touched only while
829
- // this swap is still the current one, so two overlapping calls cannot release each
830
- // other's overlay or apply an obsolete style. `readied` stays per-call because each
831
- // caller's callback must still fire exactly once.
832
529
  const generation = ++this.styleSwapGeneration;
833
530
  const isCurrent = () => this.styleSwapGeneration === generation;
834
531
  let readied = false;
@@ -836,30 +533,16 @@ export class InternalMapVXMap extends Loggeable {
836
533
  if (readied)
837
534
  return;
838
535
  readied = true;
839
- // Only the current swap owns the shared timer; a superseded swap clearing it here
840
- // would leave the live swap with no safety net (and its caller hidden forever).
841
536
  if (isCurrent() && this.styleReadyTimer) {
842
537
  clearTimeout(this.styleReadyTimer);
843
538
  this.styleReadyTimer = undefined;
844
539
  }
845
540
  onStyleReady === null || onStyleReady === void 0 ? void 0 : onStyleReady(error);
846
541
  };
847
- // `onStyleReady` must fire on EVERY path — success, a rejected style request, or a
848
- // swap that never settles — because callers keep the map hidden behind a loading
849
- // overlay until it arrives. The safety timer is therefore armed before the request
850
- // instead of inside `.then()`.
851
542
  if (this.styleReadyTimer)
852
543
  clearTimeout(this.styleReadyTimer);
853
544
  this.styleReadyTimer = setTimeout(reportReady, STYLE_READY_TIMEOUT_MS);
854
- // A previous swap may still hold a `styledata` listener whose style never reached the
855
- // loaded state. Drop it before starting a new one: it captured an obsolete style and
856
- // would otherwise fire on this swap, wiping `baseFilters` and calling `setFilter`
857
- // with layer ids the new style does not have.
858
545
  this.clearPendingStyleSwapListener();
859
- // `this.map` is created asynchronously (see `onMapStyleLoaded`), so a `setStyle` call
860
- // made right after `createMap` can land before it exists. Fail loudly instead of
861
- // letting `this.map.setStyle` throw into `.catch`, which reported READY and left the
862
- // caller revealing the previous style as if the swap had succeeded.
863
546
  if (!this.map) {
864
547
  const error = new Error("setStyle called before the map finished initializing; wait for the map's load event");
865
548
  this.logError(error, { functionName: "setStyle" });
@@ -869,40 +552,15 @@ export class InternalMapVXMap extends Loggeable {
869
552
  const stylePromise = this.fetchVenueStyle(this.parentPlaceId, styleRef, styleTheme);
870
553
  stylePromise
871
554
  .then((style) => {
872
- // A newer swap started while this style was in flight. Applying this one now
873
- // would fight the newer style layer by layer, so drop it and let the newer swap
874
- // own the map and its caller's callback.
875
555
  if (!isCurrent())
876
556
  return;
877
- // Remember what is actually on screen: `changeParentPlaceTo` refetches the
878
- // style with these, so without this an explicitly applied style would be
879
- // silently reverted to the constructor's on the next parent-place change.
880
- // After the generation check: a superseded swap never reached the map, so it
881
- // must not claim to be what is on it.
882
557
  this.styleRef = styleRef;
883
558
  this.styleTheme = styleTheme;
884
559
  const useServiceWorkerCaching = this.tileCacheConfig.enabled && this.tileCacheConfig.persistToServiceWorker;
885
560
  const finalStyle = useServiceWorkerCaching ? this.transformStyleForCaching(style) : style;
886
- // Full (non-diff) swap so the previewed style completely replaces the base —
887
- // a diff would keep old base layers and reappear on the next floor change.
888
561
  this.map.setStyle(finalStyle, { diff: false });
889
- // Drop the previous style's base filters SYNCHRONOUSLY, right where the layers
890
- // they describe stop existing. They are keyed by layer id and persist across
891
- // swaps, so any code reading them before the apply pass below (the `idle`
892
- // handler's `filterByFloorKey`, a floor change racing the swap) would AND the
893
- // previous style's discriminator into the new style's layers — the stale-filter
894
- // washout this reset exists to prevent. Gating it on `isStyleLoaded` left exactly
895
- // that window open. Fresh declared filters are re-captured lazily in
896
- // `applyLayerFilters` as each indoor layer is first touched.
897
562
  this.resetBaseFilters();
898
- // Re-apply floor filters, route/circle layers and markers ONLY once the new
899
- // style's sources/layers have finished loading; running them mid-reload throws
900
- // (`getSource` on an undefined style) and the floor filter would not stick.
901
563
  const applyOnceLoaded = () => {
902
- // Superseded: detach and leave the map to the newer swap. Without this the
903
- // listener stays attached (the slot it was tracked in has been overwritten)
904
- // and re-seeds filters from layer ids the current style does not have, which
905
- // makes maplibre throw and aborts the newer swap's own listener.
906
564
  if (!isCurrent()) {
907
565
  this.map.off("styledata", applyOnceLoaded);
908
566
  return;
@@ -914,28 +572,13 @@ export class InternalMapVXMap extends Loggeable {
914
572
  this.pendingStyleSwapListener = undefined;
915
573
  }
916
574
  this.whenStyleUpdates(finalStyle);
917
- // A non-diff swap replaces every layer, so anything applied ON TOP of the
918
- // style — label language, caller-requested place highlights, the 3D scene's
919
- // GLB layer and hidden-layer overrides — is gone and has to be replayed.
920
- // `whenStyleUpdates` covers only floor filters, routes and circles.
921
575
  this.restoreStyleOverlays();
922
576
  this.logEvent("setStyle");
923
577
  };
924
578
  this.pendingStyleSwapListener = applyOnceLoaded;
925
579
  this.map.on("styledata", applyOnceLoaded);
926
580
  applyOnceLoaded();
927
- // Re-apply the floor filter and report ready once the map is idle. This is
928
- // intentionally OUTSIDE applyOnceLoaded's `isStyleLoaded` gate: the indoor
929
- // polygon layers settle a beat after the swap (so the floor filter in
930
- // whenStyleUpdates misses them and the venue paints every floor at once), and
931
- // `idle` only fires once the style is loaded and its first tiles rendered — so
932
- // filterByFloorKey is safe here and does not depend on the sometimes-flaky
933
- // isStyleLoaded check. onStyleReady lets callers reveal the map only once it is
934
- // settled; the timer armed above just clears a hanging overlay if idle never fires.
935
581
  this.map.once("idle", () => {
936
- // `once` cannot be cancelled, so a superseded swap's handler still fires —
937
- // filtering here keeps it from re-filtering the newer style's floors and from
938
- // reporting the newer swap's caller ready ahead of time.
939
582
  if (!isCurrent())
940
583
  return;
941
584
  this.filterByFloorKey(this.currentFloor);
@@ -943,46 +586,18 @@ export class InternalMapVXMap extends Loggeable {
943
586
  });
944
587
  })
945
588
  .catch((error) => {
946
- // A superseded swap must not tear down the listener the CURRENT swap installed.
947
589
  if (isCurrent()) {
948
590
  this.clearPendingStyleSwapListener();
949
591
  }
950
592
  this.logError(error, { functionName: "setStyle" });
951
- // Release the caller immediately instead of making it wait out the safety timer:
952
- // the style will never arrive, so the overlay has nothing to wait for. The error
953
- // is handed to the callback so a caller can tell a failed swap from an applied
954
- // one — the previous style is still on screen either way.
955
593
  reportReady(error instanceof Error ? error : new Error(String(error)));
956
594
  });
957
595
  }
958
- /**
959
- * Forgets every captured base filter so the next style's declared filters are read
960
- * fresh from that style instead of inherited from the previous one.
961
- *
962
- * Both halves must move together: `baseFilters` holds the expressions and
963
- * `capturedBaseFilters` records which layer ids have already been resolved, so
964
- * clearing only the first would leave every id marked "already captured" and the new
965
- * style's filters would never be read at all.
966
- */
967
596
  resetBaseFilters() {
968
597
  this.baseFilters = {};
969
598
  this.capturedBaseFilters.clear();
970
599
  }
971
- /**
972
- * Replays everything that lives ON TOP of the map style after a full (non-diff) swap
973
- * has deleted it: label language expressions, caller-requested place highlights and
974
- * the 3D scene's GLB layer / hidden-layer overrides.
975
- *
976
- * These are deliberately not part of `whenStyleUpdates`, which restores only
977
- * style-derived state. These are decisions the SDK's callers made through `setLang`,
978
- * `setPlacesAsSelected`, `addBorderToPlaces` and the 3D config, and nothing else would
979
- * ever restore them.
980
- */
981
600
  restoreStyleOverlays() {
982
- // Each step is isolated: the style itself has already been applied by the time we get
983
- // here, so one failing restore must neither skip the others nor bubble out into
984
- // `setStyle`'s `.catch`, which would report the successful swap to `onStyleReady` as
985
- // a failure. `setPlacesAsSelected` / `addBorderToPlaces` throw by contract.
986
601
  const restore = (what, step) => {
987
602
  try {
988
603
  step();
@@ -1000,13 +615,7 @@ export class InternalMapVXMap extends Loggeable {
1000
615
  const { placeIds, color, width } = this.borderedPlacesRequest;
1001
616
  restore("borderedPlaces", () => this.addBorderToPlaces(placeIds, color, width));
1002
617
  }
1003
- // A style swap can cross the 3D/2D line: `changeParentPlaceTo` refetches `mapStyleJson`, and
1004
- // the new venue's style may publish no extrusions. Re-read it from the live style before
1005
- // deciding, or the reattach below would put the overlay back on flat ground.
1006
618
  this.styleSupports3D = this.is3DStyle();
1007
- // The swap removed the GLB custom layer, and MapLibre called its `onRemove`, which
1008
- // disposes the whole three.js scene. Nothing else re-adds it, so without this every
1009
- // 3D model disappears permanently and `hideLayers` stops being applied.
1010
619
  restore("scene3D", () => {
1011
620
  var _a;
1012
621
  if (!this.is3DSceneActive())
@@ -1014,31 +623,16 @@ export class InternalMapVXMap extends Loggeable {
1014
623
  (_a = this.scene3D) === null || _a === void 0 ? void 0 : _a.reattachToStyle();
1015
624
  });
1016
625
  }
1017
- /**
1018
- * Removes the `styledata` listener left by an in-flight {@link setStyle} swap, if any.
1019
- * Called before starting a new swap and when one fails, so a listener holding an
1020
- * obsolete style can never fire against a different style's layers.
1021
- */
1022
626
  clearPendingStyleSwapListener() {
1023
627
  var _a;
1024
628
  if (!this.pendingStyleSwapListener)
1025
629
  return;
1026
- // `this.map?` — a listener can only have been installed while the map existed, but
1027
- // this also runs from `destroyMap` and from `setStyle` before the map is created.
1028
630
  (_a = this.map) === null || _a === void 0 ? void 0 : _a.off("styledata", this.pendingStyleSwapListener);
1029
631
  this.pendingStyleSwapListener = undefined;
1030
632
  }
1031
- /**
1032
- * Removes current parent place and updates style to default
1033
- */
1034
633
  removeParentPlace() {
1035
634
  this.changeParentPlaceTo(undefined, true);
1036
635
  }
1037
- /**
1038
- * Applies filters and changes to layers according to given style.
1039
- * Expected to be called every time a new style is loaded
1040
- * @param newStyle
1041
- */
1042
636
  whenStyleUpdates(newStyle) {
1043
637
  var _a;
1044
638
  if (newStyle) {
@@ -1049,17 +643,6 @@ export class InternalMapVXMap extends Loggeable {
1049
643
  this.filterByFloorKey(this.currentFloor);
1050
644
  (_a = this.scene3D) === null || _a === void 0 ? void 0 : _a.refreshOverlay(this.currentFloor);
1051
645
  }
1052
- /**
1053
- * Internal accessor for every marker currently on the map, used by
1054
- * {@link MarkerLayoutController} to compute collision avoidance. Not part
1055
- * of the public `MapVXMap` interface.
1056
- *
1057
- * The user-location marker and the route controller's markers live outside
1058
- * `this.markers`, but they still occupy screen space — leaving them out
1059
- * would let labels be placed straight on top of them. They carry no label
1060
- * of their own, so they only ever act as obstacles.
1061
- * @internal
1062
- */
1063
646
  getMarkers() {
1064
647
  const unmanaged = this.routeController.getRouteMarkers();
1065
648
  if (this.userLocationMarker)
@@ -1069,7 +652,6 @@ export class InternalMapVXMap extends Loggeable {
1069
652
  addMarker(marker) {
1070
653
  var _a;
1071
654
  try {
1072
- // Check if a marker with the same ID already exists and remove it
1073
655
  if (marker.id) {
1074
656
  const existingMarkerIndex = this.markers.findIndex((m) => m.id === marker.id);
1075
657
  if (existingMarkerIndex !== -1) {
@@ -1083,8 +665,6 @@ export class InternalMapVXMap extends Loggeable {
1083
665
  }
1084
666
  }
1085
667
  const markerCreated = new MarkerAttribute(Object.assign(Object.assign({}, marker), { maxLabelWidthPx: (_a = marker.maxLabelWidthPx) !== null && _a !== void 0 ? _a : this.markerLayoutConfig.maxLabelWidthPx }));
1086
- // While a floor change is still being rebuilt, the marker is shown by that
1087
- // change's settle step, together with the new floor.
1088
668
  if (!this.floorSettlePending) {
1089
669
  markerCreated.changeFloor(this.currentFloor, this.map, this.isOutdoorFloor(this.currentFloor));
1090
670
  }
@@ -1181,11 +761,9 @@ export class InternalMapVXMap extends Loggeable {
1181
761
  }
1182
762
  addCircle(circle) {
1183
763
  try {
1184
- // Check if a circle with the same ID already exists and replace it
1185
764
  if (circle.id) {
1186
765
  this.circles = this.circles.filter((c) => c.id !== circle.id);
1187
766
  }
1188
- // resolveCircleConfig validates radiusMeters and coordinates
1189
767
  const record = resolveCircleConfig(circle);
1190
768
  this.circles.push(record);
1191
769
  this.refreshCircles();
@@ -1201,7 +779,6 @@ export class InternalMapVXMap extends Loggeable {
1201
779
  const index = this.circles.findIndex((c) => c.id === circleConfig.id);
1202
780
  if (index === -1)
1203
781
  return null;
1204
- // resolveCircleConfig validates radiusMeters and coordinates
1205
782
  this.circles[index] = resolveCircleConfig(circleConfig, this.circles[index].hidden);
1206
783
  this.refreshCircles();
1207
784
  this.logEvent("updateCircle");
@@ -1226,7 +803,6 @@ export class InternalMapVXMap extends Loggeable {
1226
803
  const circle = this.circles.find((c) => c.id === circleId);
1227
804
  if (circle === undefined)
1228
805
  return false;
1229
- // Validate inputs before modifying
1230
806
  if (!center) {
1231
807
  throw new Error("Circle center is required");
1232
808
  }
@@ -1259,7 +835,6 @@ export class InternalMapVXMap extends Loggeable {
1259
835
  const circle = this.circles.find((c) => c.id === circleId);
1260
836
  if (circle === undefined)
1261
837
  return false;
1262
- // Update only style properties, clamp opacities
1263
838
  if (style.fillColor !== undefined)
1264
839
  circle.fillColor = style.fillColor;
1265
840
  if (style.fillOpacity !== undefined)
@@ -1330,12 +905,6 @@ export class InternalMapVXMap extends Loggeable {
1330
905
  return false;
1331
906
  }
1332
907
  }
1333
- /**
1334
- * Builds the GeoJSON FeatureCollection for every currently visible circle.
1335
- * Visibility mirrors marker semantics: a circle with a floor is shown only
1336
- * while that floor is displayed, and a circle without a floor is shown only
1337
- * in outdoor contexts. Hidden circles are always omitted.
1338
- */
1339
908
  circleFeatureCollection() {
1340
909
  var _a;
1341
910
  const floorId = (_a = this.currentFloor) !== null && _a !== void 0 ? _a : "";
@@ -1368,24 +937,6 @@ export class InternalMapVXMap extends Loggeable {
1368
937
  }));
1369
938
  return { type: "FeatureCollection", features };
1370
939
  }
1371
- /**
1372
- * Idempotently adds the shared circle source and its fill/line layers.
1373
- * Layers are inserted below the first symbol layer so place labels and
1374
- * markers stay readable above the translucent fill. Safe to call at any
1375
- * time: a style that is still loading simply rejects the calls, and the
1376
- * styledata listener retries once the style is ready.
1377
- */
1378
- /**
1379
- * Resolves the layer id to insert circle layers before, for one render
1380
- * order. `undefined` means "append on top".
1381
- *
1382
- * `aboveBasemap` finds the topmost non-symbol layer of the style and
1383
- * inserts before the first symbol layer that follows it. On indoor styles
1384
- * the floor-plate and building polygons are ordered after the first symbol
1385
- * layer, so anchoring on the topmost geometry layer — instead of the first
1386
- * symbol layer — guarantees circles are never occluded by basemap fills
1387
- * while still rendering below the labels that follow them.
1388
- */
1389
940
  circleBeforeIdFor(order) {
1390
941
  var _a, _b, _c, _d;
1391
942
  if (order === "top")
@@ -1394,7 +945,6 @@ export class InternalMapVXMap extends Loggeable {
1394
945
  if (order === "belowLabels") {
1395
946
  return (_c = layers.find((layer) => layer.type === "symbol")) === null || _c === void 0 ? void 0 : _c.id;
1396
947
  }
1397
- // aboveBasemap
1398
948
  let lastNonSymbolIndex = -1;
1399
949
  layers.forEach((layer, index) => {
1400
950
  if (layer.type !== "symbol")
@@ -1402,15 +952,6 @@ export class InternalMapVXMap extends Loggeable {
1402
952
  });
1403
953
  return (_d = layers.slice(lastNonSymbolIndex + 1).find((layer) => layer.type === "symbol")) === null || _d === void 0 ? void 0 : _d.id;
1404
954
  }
1405
- /**
1406
- * Idempotently ensures the shared circle source and one fill/line layer
1407
- * pair per render order in use, at the placement that order requires.
1408
- * Placement is recomputed and re-asserted (via moveLayer) on every call,
1409
- * so circles regain their correct z-order after any style reload or
1410
- * floor/parent-place change. Safe to call at any time: a style that is
1411
- * still loading simply rejects the calls, and the styledata listener
1412
- * retries once the style is ready.
1413
- */
1414
955
  ensureCircleLayers() {
1415
956
  if (!this.map)
1416
957
  return;
@@ -1422,14 +963,7 @@ export class InternalMapVXMap extends Loggeable {
1422
963
  });
1423
964
  }
1424
965
  const ordersInUse = new Set(this.circles.map((c) => c.renderOrder));
1425
- // Always keep the default bucket alive so an empty map still renders
1426
- // newly added circles without a layer rebuild
1427
966
  ordersInUse.add("aboveBasemap");
1428
- // Process buckets lowest-first (CIRCLE_RENDER_ORDERS is canonical):
1429
- // when two buckets resolve to the same anchor, each addLayer/moveLayer
1430
- // lands immediately before it, so a bucket processed later paints above
1431
- // the ones processed earlier. Canonical order keeps
1432
- // belowLabels < aboveBasemap < top regardless of circle insertion order.
1433
967
  for (const order of CIRCLE_RENDER_ORDERS) {
1434
968
  if (!ordersInUse.has(order))
1435
969
  continue;
@@ -1475,11 +1009,6 @@ export class InternalMapVXMap extends Loggeable {
1475
1009
  this.debugLog("Layers not added: style not loaded yet, the styledata listener will re-add them", error);
1476
1010
  }
1477
1011
  }
1478
- /**
1479
- * Re-renders all circles: ensures the source and layers exist, then pushes
1480
- * the current FeatureCollection. Called after every mutation of the circle
1481
- * list, on floor changes, and when the map style reloads.
1482
- */
1483
1012
  refreshCircles() {
1484
1013
  if (!this.map)
1485
1014
  return;
@@ -1494,21 +1023,12 @@ export class InternalMapVXMap extends Loggeable {
1494
1023
  this.debugLog("Source not found (a new style may still be loading)", error);
1495
1024
  }
1496
1025
  }
1497
- /**
1498
- * Use it to change the current layer
1499
- * @param floorKey floor id
1500
- */
1501
1026
  filterByFloorKey(floorKey) {
1502
1027
  this.currentFloor = floorKey;
1503
1028
  const floorKeyString = floorKey !== null && floorKey !== void 0 ? floorKey : "";
1504
1029
  if (this.innerFloors.every((floor) => floor.key !== floorKey) && floorKey !== "") {
1505
1030
  this.logEvent("invalidFloorKey", { floorKey: floorKeyString });
1506
1031
  }
1507
- // One style read for the whole floor change. `getStyle()` serializes every
1508
- // source and layer of the venue style, and the second read is the expensive
1509
- // one: `updateFiltersTo` writes filters and layout properties in between,
1510
- // and each write nulls maplibre's `_serializedLayers` cache, so anything
1511
- // that reads the style afterwards rebuilds it from scratch.
1512
1032
  const layers = this.safeStyleLayers();
1513
1033
  this.updateFiltersTo(floorKeyString, layers);
1514
1034
  this.updateMarkersWhenFloorSettles(floorKeyString, layers);
@@ -1516,28 +1036,10 @@ export class InternalMapVXMap extends Loggeable {
1516
1036
  this.routeController.updateRouteLayers(floorKeyString);
1517
1037
  this.routeController.updateRouteMarkerVisibility(floorKeyString);
1518
1038
  }
1519
- /**
1520
- * Show/hide the HTML markers for `floorId` once the indoor tiles have been
1521
- * rebuilt with the new floor filters.
1522
- *
1523
- * A floor change is a `setFilter` on every indoor layer: MapLibre rebuilds the
1524
- * tile buckets in its worker, so the new floor appears a few frames later
1525
- * (hundreds of ms on a low-end panel) while a marker is a DOM element that
1526
- * would move instantly. Waiting for the source to report loaded makes floor
1527
- * polygons and markers switch in the same frame. The wait is bounded, is
1528
- * dropped when a newer floor change arrives, and is skipped outside a
1529
- * browser (no `requestAnimationFrame`).
1530
- */
1531
1039
  updateMarkersWhenFloorSettles(floorId, styleLayers) {
1532
1040
  const token = ++this.floorSettleToken;
1533
- // Resolved rather than probed with `hasStyle()`, which is another full
1534
- // `getStyle()` — and by this point the most expensive kind, because
1535
- // `updateFiltersTo` has just invalidated the serialized-layer cache.
1536
1041
  const layers = styleLayers === undefined ? this.safeStyleLayers() : styleLayers;
1537
1042
  if (typeof requestAnimationFrame !== "function" || layers === null) {
1538
- // No poll will run for this floor change, so nothing would ever clear the
1539
- // flag later: leaving it set makes every subsequent `addMarker` skip
1540
- // `changeFloor` and the marker is never attached to the map.
1541
1043
  this.floorSettleDeadline = null;
1542
1044
  this.updateMarkersTo(floorId);
1543
1045
  return;
@@ -1554,9 +1056,6 @@ export class InternalMapVXMap extends Loggeable {
1554
1056
  const loaded = sourceIds.every((id) => this.isSourceSettled(id));
1555
1057
  if (!loaded)
1556
1058
  sawReloading = true;
1557
- // The reload is dispatched on the map's next render, which may run after
1558
- // this callback within the same frame: give it a couple of frames to be
1559
- // observed before concluding there was nothing to reload.
1560
1059
  const settled = loaded && (sawReloading || frames >= FLOOR_SETTLE_MIN_FRAMES);
1561
1060
  if (settled || this.now() >= deadline) {
1562
1061
  this.floorSettleDeadline = null;
@@ -1567,19 +1066,6 @@ export class InternalMapVXMap extends Loggeable {
1567
1066
  };
1568
1067
  requestAnimationFrame(poll);
1569
1068
  }
1570
- /**
1571
- * Sources whose tiles a switch to `floorId` actually reloads, and which the
1572
- * marker settle therefore has to wait on.
1573
- *
1574
- * With a vector basemap that is the source the `indoor-*` layers draw from,
1575
- * because the floor change is a `setFilter` over those layers. An offline
1576
- * bundle's raster basemap switches floors by making `raster-floor-<key>`
1577
- * visible instead, and those tiles only begin loading at that moment — while
1578
- * its `indoor-*` layers carry labels and hover, are already loaded, and would
1579
- * report settled at once, letting the markers switch a floor before its image
1580
- * had painted. That is the configuration this wait exists for, so both are
1581
- * waited on.
1582
- */
1583
1069
  floorSettleSourceIds(floorId, layers) {
1584
1070
  const ids = new Set();
1585
1071
  const rasterFloor = layers.find((layer) => layer.id === `raster-floor-${floorId}`);
@@ -1589,7 +1075,6 @@ export class InternalMapVXMap extends Loggeable {
1589
1075
  ids.add(this.indoorSourceId(layers));
1590
1076
  return [...ids];
1591
1077
  }
1592
- /** The vector source the `indoor-*` layers draw from (`indoorequal` by default). */
1593
1078
  indoorSourceId(layers) {
1594
1079
  for (const layer of layers) {
1595
1080
  if (layer.id.startsWith("indoor-") && "source" in layer && typeof layer.source === "string") {
@@ -1633,21 +1118,8 @@ export class InternalMapVXMap extends Loggeable {
1633
1118
  var _a, _b, _c;
1634
1119
  if (!this.map)
1635
1120
  return;
1636
- // `null` means the caller looked and there was no style; only `undefined`
1637
- // means it did not look.
1638
1121
  const layers = (_a = (styleLayers === undefined ? this.safeStyleLayers() : styleLayers)) !== null && _a !== void 0 ? _a : [];
1639
- // Raster basemap (offline bundles baked with one raster archive per floor):
1640
- // a floor is switched by showing its `raster-floor-<key>` layer and hiding
1641
- // the others. The remaining `indoor-*` layers (labels, hover, highlights)
1642
- // are still vector and keep going through the filter logic below.
1643
1122
  const rasterFloorPrefix = "raster-floor-";
1644
- // Only switch the raster basemap when there is a baked layer to switch to.
1645
- // Hiding every raster floor leaves the basemap blank, and no id can match in
1646
- // two cases: no floor at all (an outdoor place, or a venue with no floors,
1647
- // where `currentFloor` is `""`), and a floor the bundle has no raster
1648
- // archive for — a venue where only some floors are baked, or a floor added
1649
- // after the bundle was built. Keeping the current one visible is the safe
1650
- // fallback for both.
1651
1123
  const rasterFloorLayerIds = layers
1652
1124
  .filter((l) => l.id.startsWith(rasterFloorPrefix))
1653
1125
  .map((l) => l.id);
@@ -1664,14 +1136,6 @@ export class InternalMapVXMap extends Loggeable {
1664
1136
  });
1665
1137
  const baseFloorId = (_b = this.innerFloors.find((floor) => floor.key === floorId)) === null || _b === void 0 ? void 0 : _b.baseFloor;
1666
1138
  const indoorLayers = layers.filter((layer) => layer.id.startsWith("indoor-"));
1667
- // Resolve each indoor layer's declared (base) filter before we start folding floor
1668
- // filters into it — and before cloning it into a `base-indoor-*` layer, which copies
1669
- // the base filter across. Layers added asynchronously after a `setStyle` swap are
1670
- // missing when `setBaseFilters` runs, so this is where their still-pristine filter
1671
- // is captured; without it the layer loses its own discrimination and repaints every
1672
- // feature (the washed-out / blue-outline look after changing floors). Layers already
1673
- // resolved are skipped, so a filter this class wrote is never mistaken for a
1674
- // declared one.
1675
1139
  indoorLayers.forEach((layer) => this.captureDeclaredBaseFilter(layer.id));
1676
1140
  if (baseFloorId != undefined) {
1677
1141
  const firstLayerId = (_c = indoorLayers[0]) === null || _c === void 0 ? void 0 : _c.id;
@@ -1689,11 +1153,6 @@ export class InternalMapVXMap extends Loggeable {
1689
1153
  this.applyLayerFilters(layer, floorId);
1690
1154
  });
1691
1155
  }
1692
- /**
1693
- * Reads a layer's current filter, tolerating the layer having been removed or the
1694
- * style being mid-swap (maplibre `getFilter` throws in those cases). Returns
1695
- * `undefined` instead of throwing so base-filter capture never aborts floor filtering.
1696
- */
1697
1156
  safeGetFilter(layerId) {
1698
1157
  try {
1699
1158
  return this.map.getFilter(layerId);
@@ -1704,15 +1163,6 @@ export class InternalMapVXMap extends Loggeable {
1704
1163
  }
1705
1164
  applyLayerFilters(layer, floorId) {
1706
1165
  var _a;
1707
- // Resolve the layer's declared (base) filter the first time we touch it. Indoor
1708
- // layers such as `indoor-polygon-room` share one source and are told apart only by
1709
- // their own filter (e.g. `["in","room",["get","tags"]]`); we must fold that into the
1710
- // floor filter or the layer repaints every feature. Some of these layers are added
1711
- // asynchronously after a `setStyle` swap, so they are absent when `setBaseFilters`
1712
- // runs — capturing here, while their live filter is still pristine, is what keeps a
1713
- // floor change from wiping the style (the washed-out, blue-outline look).
1714
- // `base-indoor-*` clones inherit their base filter from the layer they were cloned
1715
- // from, so they are never read back.
1716
1166
  if (!layer.id.startsWith("base-indoor-")) {
1717
1167
  this.captureDeclaredBaseFilter(layer.id);
1718
1168
  }
@@ -1748,9 +1198,6 @@ export class InternalMapVXMap extends Loggeable {
1748
1198
  (layer.type == "fill" || layer.type === "fill-extrusion")) {
1749
1199
  customFilters.push(["!", ["in", this.hoveredId, ["get", "ref"]]]);
1750
1200
  }
1751
- // From here on this layer's live filter is ours, never the style's declared one.
1752
- // Marking it keeps any later pass from reading it back as a base filter — that is
1753
- // what used to AND the previous floor into the next one and blank the layer out.
1754
1201
  this.capturedBaseFilters.add(layer.id);
1755
1202
  if (baseFilter != null) {
1756
1203
  const finalFilter = ["all", baseFilter, customFilters];
@@ -1760,21 +1207,9 @@ export class InternalMapVXMap extends Loggeable {
1760
1207
  this.map.setFilter(layer.id, customFilters);
1761
1208
  }
1762
1209
  }
1763
- /**
1764
- * Floors of the parent place
1765
- * @returns Inner floors of the parent place
1766
- */
1767
1210
  getInnerFloors() {
1768
1211
  return this.innerFloors;
1769
1212
  }
1770
- /**
1771
- * Whether `floorId` shows the venue's outdoors, and so whether entities that
1772
- * carry no floor of their own belong on screen with it.
1773
- *
1774
- * A map without a parent place is outdoors throughout; inside one, only a
1775
- * floor reachable from GPS is. Markers, circles and the route marker all hang
1776
- * their visibility on this, so they answer it the same way.
1777
- */
1778
1213
  isOutdoorFloor(floorId) {
1779
1214
  var _a, _b;
1780
1215
  return (!this.parentPlace ||
@@ -1886,11 +1321,9 @@ export class InternalMapVXMap extends Loggeable {
1886
1321
  maxLng !== null && maxLng !== void 0 ? maxLng : 0,
1887
1322
  maxLat !== null && maxLat !== void 0 ? maxLat : 0,
1888
1323
  ];
1889
- // Get container dimensions for percentage-based padding calculations
1890
1324
  const container = this.map.getContainer();
1891
1325
  const containerWidth = container.clientWidth;
1892
1326
  const containerHeight = container.clientHeight;
1893
- // Convert padding values with units to pixels
1894
1327
  const padding = convertPaddingToPixels(options === null || options === void 0 ? void 0 : options.padding, containerWidth, containerHeight);
1895
1328
  const fitOptions = Object.assign(Object.assign({}, options), { padding });
1896
1329
  const bearing = this.map.getBearing();
@@ -1909,11 +1342,9 @@ export class InternalMapVXMap extends Loggeable {
1909
1342
  return;
1910
1343
  }
1911
1344
  const onComplete = options === null || options === void 0 ? void 0 : options.onComplete;
1912
- // Get container dimensions for percentage-based padding calculations
1913
1345
  const container = this.map.getContainer();
1914
1346
  const containerWidth = container.clientWidth;
1915
1347
  const containerHeight = container.clientHeight;
1916
- // Convert padding values with units to pixels
1917
1348
  const padding = convertPaddingToPixels(options === null || options === void 0 ? void 0 : options.padding, containerWidth, containerHeight);
1918
1349
  if (coordinates.length === 1) {
1919
1350
  const [coord] = coordinates;
@@ -1933,17 +1364,8 @@ export class InternalMapVXMap extends Loggeable {
1933
1364
  maxZoom: (_c = options === null || options === void 0 ? void 0 : options.maxZoom) !== null && _c !== void 0 ? _c : this.map.getMaxZoom(),
1934
1365
  minZoom: this.map.getMinZoom(),
1935
1366
  };
1936
- // Orthographic oriented fit (exact for pitch 0). maplibre's fitBounds only
1937
- // fits a north-up LngLatBounds, which wastes viewport space for diagonal
1938
- // geometries under a bearing.
1939
1367
  let camera = computeOrientedCamera(coordinates, cameraParams);
1940
- // With a tilted camera the orthographic zoom is off due to perspective, so
1941
- // refine it against maplibre's real projection on a cloned transform.
1942
1368
  if (pitch > 0) {
1943
- // Simulated on the live map through its public API rather than on `map.transform.clone()`:
1944
- // MapLibre v6 removes the internal transform and exposes no replacement. The whole loop is
1945
- // synchronous and ends in `restore()`, so no intermediate frame is ever painted.
1946
- // See DEVELOPER_DOCS/MAPLIBRE_V6_MIGRATION.md.
1947
1369
  const fitTransform = new LiveMapFitTransform(this.map);
1948
1370
  try {
1949
1371
  camera = refineCameraForPitch(fitTransform, coordinates, camera, Object.assign(Object.assign({}, cameraParams), { pitch }));
@@ -1960,12 +1382,10 @@ export class InternalMapVXMap extends Loggeable {
1960
1382
  padding }));
1961
1383
  }
1962
1384
  fitRouteByPlace(route, placeId, options) {
1963
- // Filter steps that belong to the specified place
1964
1385
  const stepsInPlace = route.steps.filter((step) => step.startInsidePlace === placeId || step.endInsidePlace === placeId);
1965
1386
  if (stepsInPlace.length === 0) {
1966
1387
  return;
1967
1388
  }
1968
- // Extract all coordinates from the filtered steps
1969
1389
  const coords = stepsInPlace.flatMap((step) => extractStepCoordinates(step));
1970
1390
  if (coords.length > 0) {
1971
1391
  this.fitCoordinates(coords, options);
@@ -2019,27 +1439,14 @@ export class InternalMapVXMap extends Loggeable {
2019
1439
  this.logEvent("addLiveRoute");
2020
1440
  const fetchRouteConfig = new InternalGetRouteConfiguration(config);
2021
1441
  const drawRouteConfig = new InternalDrawRouteConfiguration(drawConfig);
2022
- // Take a ticket BEFORE awaiting: refreshes overlap, and an older response
2023
- // resolving after a newer one must not clobber it (stale route drawn,
2024
- // liveRouteId pointing at the wrong instance).
2025
1442
  const ticket = ++this.liveRouteTicket;
2026
1443
  const route = await this.repository.fetchAndParseLiveRoute(fetchRouteConfig);
2027
1444
  if (ticket !== this.liveRouteTicket) {
2028
- // Superseded while in flight — the map shows (or will show) the newer
2029
- // route. Return the fetched data without drawing it.
2030
1445
  return route;
2031
1446
  }
2032
- // Replace the previous live route so repeated refreshes don't stack paths
2033
- // on the map. Removal happens AFTER the fetch, so a failed refresh leaves
2034
- // the current route on screen. Targeted by id, so routes drawn with
2035
- // addRoute are untouched.
2036
1447
  if (this.liveRouteId !== undefined && this.liveRouteId !== route.id) {
2037
1448
  this.routeController.removeRoute(this.liveRouteId);
2038
1449
  }
2039
- // Clear any instance already using this id (a same-id refresh, or the same
2040
- // route previously drawn via addRoute) — the controller derives its
2041
- // source/layer ids from the route id, so re-adding without removing would
2042
- // throw "Source already exists".
2043
1450
  if (this.routeController.getRouteIds().includes(route.id)) {
2044
1451
  this.routeController.removeRoute(route.id);
2045
1452
  }
@@ -2093,13 +1500,6 @@ export class InternalMapVXMap extends Loggeable {
2093
1500
  }
2094
1501
  this.syncLiveRouteId();
2095
1502
  }
2096
- /**
2097
- * Drop {@link liveRouteId} when the instance it points at is no longer on the
2098
- * map (removed via removeRoute/removeRouteById/removeAllRoutes — including the
2099
- * no-arg removeRoute, which removes the last-added route). Keeps the live
2100
- * bookkeeping in sync so a later {@link addLiveRoute} doesn't act on a
2101
- * dangling id.
2102
- */
2103
1503
  syncLiveRouteId() {
2104
1504
  if (this.liveRouteId !== undefined &&
2105
1505
  !this.routeController.getRouteIds().includes(this.liveRouteId)) {
@@ -2134,15 +1534,12 @@ export class InternalMapVXMap extends Loggeable {
2134
1534
  this.map.on("click", async (e) => {
2135
1535
  var _a, _b;
2136
1536
  const features = this.map.queryRenderedFeatures(e.point);
2137
- // Filter room features by current floor
2138
1537
  const roomFeatures = features.filter((feature) => { var _a; return feature.properties.class === "room" && ((_a = feature.properties) === null || _a === void 0 ? void 0 : _a.floor_key) === this.currentFloor; });
2139
1538
  const touchedFeature = roomFeatures[0];
2140
1539
  const ref = touchedFeature === null || touchedFeature === void 0 ? void 0 : touchedFeature.properties.ref;
2141
1540
  if (ref != null && typeof ref === "string" && ref.length > 0) {
2142
1541
  console.log("touchedFeature", ref);
2143
- // First, search in current subPlaces
2144
1542
  let clickedPlace = this.subPlaces.find((subPlace) => subPlace.mapvxId === ref);
2145
- // If not found, search in subplaces of potential parent places
2146
1543
  if (clickedPlace === undefined) {
2147
1544
  for (const potentialParentPlace of this.potentialParentPlaces) {
2148
1545
  const cachedSubPlaces = this.repository.getCachedSubPlaces(potentialParentPlace.mapvxId);
@@ -2154,7 +1551,6 @@ export class InternalMapVXMap extends Loggeable {
2154
1551
  }
2155
1552
  }
2156
1553
  }
2157
- // As last resort, search in general cache
2158
1554
  if (clickedPlace === undefined) {
2159
1555
  const cachedPlaces = this.repository.getCachedPlaces([ref]);
2160
1556
  if (cachedPlaces.length === 0) {
@@ -2190,8 +1586,6 @@ export class InternalMapVXMap extends Loggeable {
2190
1586
  this.updateFiltersTo(this.currentFloor);
2191
1587
  }
2192
1588
  });
2193
- // When the mouse leaves the state-fill layer, update the feature state of the
2194
- // previously hovered feature.
2195
1589
  this.map.on("mouseleave", "hoverable", () => {
2196
1590
  this.hoveredId = "unselected";
2197
1591
  this.updateFiltersTo(this.currentFloor);
@@ -2211,8 +1605,6 @@ export class InternalMapVXMap extends Loggeable {
2211
1605
  const placeFilter = ["any", ...coloredPlacesFilters];
2212
1606
  const condition = ["all", placeFilter, basicFilter];
2213
1607
  this.map.setFilter("indoor-colored-places", condition);
2214
- // Caller-defined base filter: mark it resolved so no later capture can
2215
- // overwrite this customization with the layer's style-declared filter.
2216
1608
  this.capturedBaseFilters.add("indoor-colored-places");
2217
1609
  this.baseFilters["indoor-colored-places"] = placeFilter;
2218
1610
  if (color !== undefined) {
@@ -2233,10 +1625,6 @@ export class InternalMapVXMap extends Loggeable {
2233
1625
  this.debugLog("Place selection failed (layer may not exist)", error);
2234
1626
  }
2235
1627
  }
2236
- /**
2237
- * Same question as {@link styleHasExtrusions}, asked of the style the map is currently showing
2238
- * rather than one about to be applied. Used after load, when `map.getStyle()` is available.
2239
- */
2240
1628
  is3DStyle() {
2241
1629
  return styleHasExtrusions(this.map.getStyle());
2242
1630
  }
@@ -2303,8 +1691,6 @@ export class InternalMapVXMap extends Loggeable {
2303
1691
  this.coloredPlacesRequest = undefined;
2304
1692
  if (this.hasLayer("indoor-colored-places")) {
2305
1693
  const condition = ["==", ["get", "ref"], "unselected"];
2306
- // Caller-defined base filter: mark it resolved so no later capture can
2307
- // overwrite this customization with the layer's style-declared filter.
2308
1694
  this.capturedBaseFilters.add("indoor-colored-places");
2309
1695
  this.baseFilters["indoor-colored-places"] = condition;
2310
1696
  this.map.setFilter("indoor-colored-places", condition);
@@ -2488,7 +1874,6 @@ export class InternalMapVXMap extends Loggeable {
2488
1874
  this.userLocationMarker.remove();
2489
1875
  this.userLocationMarker = undefined;
2490
1876
  this.markerLayoutController.scheduleRelayout();
2491
- // Check if watchPosition ID is valid and stop tracking
2492
1877
  if (this.watchPositionID) {
2493
1878
  this.geoLocation.clearWatch(this.watchPositionID);
2494
1879
  this.watchPositionID = undefined;
@@ -2512,8 +1897,6 @@ export class InternalMapVXMap extends Loggeable {
2512
1897
  const placeFilter = ["any", ...coloredPlacesFilters];
2513
1898
  const condition = ["all", placeFilter, basicFilter];
2514
1899
  this.map.setFilter("indoor-bordered-places", condition);
2515
- // Caller-defined base filter: mark it resolved so no later capture can
2516
- // overwrite this customization with the layer's style-declared filter.
2517
1900
  this.capturedBaseFilters.add("indoor-bordered-places");
2518
1901
  this.baseFilters["indoor-bordered-places"] = placeFilter;
2519
1902
  if (color !== undefined && width !== undefined) {
@@ -2543,8 +1926,6 @@ export class InternalMapVXMap extends Loggeable {
2543
1926
  this.borderedPlacesRequest = undefined;
2544
1927
  if (this.hasLayer("indoor-bordered-places")) {
2545
1928
  const condition = ["==", ["get", "ref"], "unselected"];
2546
- // Caller-defined base filter: mark it resolved so no later capture can
2547
- // overwrite this customization with the layer's style-declared filter.
2548
1929
  this.capturedBaseFilters.add("indoor-bordered-places");
2549
1930
  this.baseFilters["indoor-bordered-places"] = condition;
2550
1931
  this.map.setFilter("indoor-bordered-places", condition);
@@ -2554,30 +1935,26 @@ export class InternalMapVXMap extends Loggeable {
2554
1935
  var _a, _b;
2555
1936
  e.originalEvent.preventDefault();
2556
1937
  console.warn("Contexto WebGL perdido 😢");
2557
- // Intentar restaurar el contexto automáticamente
2558
1938
  const canvas = (_a = this === null || this === void 0 ? void 0 : this.map) === null || _a === void 0 ? void 0 : _a.getCanvas();
2559
1939
  const gl = (canvas === null || canvas === void 0 ? void 0 : canvas.getContext("webgl")) || (canvas === null || canvas === void 0 ? void 0 : canvas.getContext("webgl2"));
2560
1940
  if (gl && gl.isContextLost()) {
2561
1941
  canvas.addEventListener("webglcontextrestored", () => {
2562
1942
  console.debug("Contexto WebGL restaurado, forzando re-render");
2563
- this.map.triggerRepaint(); // forzar repaint
1943
+ this.map.triggerRepaint();
2564
1944
  this.failedTiles.clear();
2565
1945
  }, { once: true });
2566
1946
  const ext = gl.getExtension("WEBGL_lose_context");
2567
- (_b = ext === null || ext === void 0 ? void 0 : ext.restoreContext) === null || _b === void 0 ? void 0 : _b.call(ext); // si aplica
1947
+ (_b = ext === null || ext === void 0 ? void 0 : ext.restoreContext) === null || _b === void 0 ? void 0 : _b.call(ext);
2568
1948
  }
2569
1949
  }
2570
1950
  onWebGLContextRestored() {
2571
1951
  console.debug("Evento webglcontextrestored recibido, haciendo map.redraw()");
2572
- this.map.redraw(); // fuerza un redraw síncrono [oai_citation:0‡maplibre.org](https://www.maplibre.org/maplibre-gl-js/docs/API/classes/Map/?utm_source=chatgpt.com)
1952
+ this.map.redraw();
2573
1953
  this.failedTiles.clear();
2574
1954
  }
2575
1955
  onSourceData(e) {
2576
1956
  var _a;
2577
- // Only track tiles that actually failed to load (not aborted or never loaded)
2578
1957
  if (e.source.type === "vector" && e.sourceId === "indoorequal" && e.tile && !e.isSourceLoaded) {
2579
- // Check if tile has an error state before adding to retry queue
2580
- // Access state property safely as it may not always be available
2581
1958
  const tileState = (_a = e.tile) === null || _a === void 0 ? void 0 : _a.state;
2582
1959
  if (tileState === "errored" || tileState === "expired") {
2583
1960
  this.failedTiles.add(e.tile);
@@ -2585,25 +1962,10 @@ export class InternalMapVXMap extends Loggeable {
2585
1962
  }
2586
1963
  }
2587
1964
  onSourceDataAbort(e) {
2588
- // Remove aborted tiles from retry queue as they shouldn't be retried
2589
1965
  if (e.source.type === "vector" && e.sourceId === "indoorequal" && e.tile) {
2590
1966
  this.failedTiles.delete(e.tile);
2591
1967
  }
2592
1968
  }
2593
- /**
2594
- * True when a style object is attached to the map. During a full `setStyle` swap the
2595
- * map is momentarily style-less and any `getSource`/`getFilter` call throws
2596
- * ("Cannot read properties of undefined"), so call sites that only need the style to
2597
- * exist should gate on this rather than on `isStyleLoaded()`.
2598
- */
2599
- /**
2600
- * This style's layers, or `null` when the map has no style right now.
2601
- *
2602
- * The one place the style is read for a floor change, so callers can pass the
2603
- * result on instead of each probing again — `getStyle()` serializes every
2604
- * source and layer, and `Style._updateLayer` drops the cache behind it on
2605
- * every filter or layout write.
2606
- */
2607
1969
  safeStyleLayers() {
2608
1970
  var _a, _b, _c;
2609
1971
  try {
@@ -2615,12 +1977,6 @@ export class InternalMapVXMap extends Loggeable {
2615
1977
  }
2616
1978
  hasStyle() {
2617
1979
  var _a;
2618
- // `map.getStyle()` is the PUBLIC probe: it returns the serialized style, or throws
2619
- // while the map is momentarily style-less mid-swap. Reading maplibre's internal
2620
- // `style` field instead (it is absent from the public typings, so it needed a double
2621
- // cast) would fail closed and silently forever the moment a maplibre upgrade renames
2622
- // or privatizes it — disabling both the tile-retry loop and `setStyle`'s apply pass
2623
- // with no throw and no log. `safeGetFilter` already uses this try/catch shape.
2624
1980
  try {
2625
1981
  return ((_a = this.map) === null || _a === void 0 ? void 0 : _a.getStyle()) != null;
2626
1982
  }
@@ -2628,12 +1984,6 @@ export class InternalMapVXMap extends Loggeable {
2628
1984
  return false;
2629
1985
  }
2630
1986
  }
2631
- /**
2632
- * True when the map has a style object attached and fully loaded. Unlike
2633
- * `map.isStyleLoaded()`, this does not emit maplibre's "There is no style
2634
- * added to the map" warning when the style is momentarily absent (e.g. during
2635
- * a `setStyle` swap), because it checks for the style object first.
2636
- */
2637
1987
  hasLoadedStyle() {
2638
1988
  if (!this.hasStyle())
2639
1989
  return false;
@@ -2642,20 +1992,11 @@ export class InternalMapVXMap extends Loggeable {
2642
1992
  subscribeToFailedTiles() {
2643
1993
  if (this.retryTimer)
2644
1994
  return;
2645
- // Store bound functions for proper cleanup
2646
1995
  this.boundOnSourceData = this.onSourceData.bind(this);
2647
1996
  this.boundOnSourceDataAbort = this.onSourceDataAbort.bind(this);
2648
1997
  this.boundOnWebGLContextLost = this.onWebGLContextLost.bind(this);
2649
1998
  this.boundOnWebGLContextRestored = this.onWebGLContextRestored.bind(this);
2650
1999
  this.retryTimer = setInterval(() => {
2651
- // During a full style swap (`setStyle` with `diff: false`) the map can
2652
- // momentarily have no style object attached. Calling `getSource` then
2653
- // throws ("Cannot read properties of undefined (reading 'getSource')").
2654
- // Only the style's PRESENCE is checked here, never `isStyleLoaded()`:
2655
- // that is false while any source still has tiles in flight, which is
2656
- // exactly when tiles fail — gating on it would skip every tick during a
2657
- // bad-network burst. The queue is left untouched so the tiles queued
2658
- // mid-swap are still retried on the next tick.
2659
2000
  if (!this.hasStyle()) {
2660
2001
  return;
2661
2002
  }
@@ -2668,27 +2009,21 @@ export class InternalMapVXMap extends Loggeable {
2668
2009
  this.failedTiles.clear();
2669
2010
  return;
2670
2011
  }
2671
- // Process tiles and remove invalid ones
2672
2012
  const tilesToRetry = [];
2673
2013
  const tilesToRemove = [];
2674
2014
  this.failedTiles.forEach((tile) => {
2675
- // Check if tile is still valid before attempting reload
2676
2015
  if (!tile || tile.state === "unloaded" || tile.state === "loading") {
2677
2016
  tilesToRemove.push(tile);
2678
2017
  return;
2679
2018
  }
2680
- // Only retry tiles that are in an error state
2681
2019
  if (tile.state === "errored" || tile.state === "expired") {
2682
2020
  tilesToRetry.push(tile);
2683
2021
  }
2684
2022
  else {
2685
- // Tile is in a valid state, remove from retry queue
2686
2023
  tilesToRemove.push(tile);
2687
2024
  }
2688
2025
  });
2689
- // Remove invalid tiles from the set
2690
2026
  tilesToRemove.forEach((tile) => this.failedTiles.delete(tile));
2691
- // Attempt to reload valid failed tiles
2692
2027
  const now = Date.now();
2693
2028
  tilesToRetry.forEach((tile) => {
2694
2029
  var _a;
@@ -2697,7 +2032,6 @@ export class InternalMapVXMap extends Loggeable {
2697
2032
  nextAttemptAt: 0,
2698
2033
  pending: false,
2699
2034
  };
2700
- // Skip tiles with a reload still in flight or still inside their backoff window.
2701
2035
  if (retry.pending || now < retry.nextAttemptAt)
2702
2036
  return;
2703
2037
  const onFailure = (error) => {
@@ -2708,7 +2042,6 @@ export class InternalMapVXMap extends Loggeable {
2708
2042
  this.tileRetryState.delete(tile);
2709
2043
  return;
2710
2044
  }
2711
- // Stay in the queue and try again once the backoff has elapsed.
2712
2045
  const backoffMs = TILE_RETRY_BASE_DELAY_MS * 2 ** (attempts - 1);
2713
2046
  this.debugLog(`Tile reload failed (attempt ${attempts}/${MAX_TILE_RETRIES}), retrying in ${backoffMs}ms`, error);
2714
2047
  this.tileRetryState.set(tile, {
@@ -2718,18 +2051,11 @@ export class InternalMapVXMap extends Loggeable {
2718
2051
  });
2719
2052
  };
2720
2053
  try {
2721
- // Verify tile still exists and is in a retryable state
2722
2054
  if (tile && (tile.state === "errored" || tile.state === "expired")) {
2723
2055
  this.tileRetryState.set(tile, Object.assign(Object.assign({}, retry), { pending: true }));
2724
- // loadTile is async, so a rejection escapes this try/catch and has to be handled
2725
- // on the promise itself - otherwise it surfaces as an unhandled rejection and the
2726
- // tile is retried on every tick regardless of how often it has already failed.
2727
2056
  source
2728
2057
  .loadTile(tile)
2729
2058
  .then(() => {
2730
- // Loaded: forget the attempt history so a later failure starts from zero. The
2731
- // tile leaves the queue through the tilesToRemove branch on the next tick,
2732
- // once its state is no longer errored/expired.
2733
2059
  this.tileRetryState.delete(tile);
2734
2060
  })
2735
2061
  .catch(onFailure);
@@ -2742,9 +2068,7 @@ export class InternalMapVXMap extends Loggeable {
2742
2068
  }, 1000);
2743
2069
  this.map.on("sourcedata", this.boundOnSourceData);
2744
2070
  this.map.on("sourcedataabort", this.boundOnSourceDataAbort);
2745
- // Escucha el evento de contexto perdido
2746
2071
  this.map.on("webglcontextlost", this.boundOnWebGLContextLost);
2747
- // Adicional: escucha evento restauración
2748
2072
  this.map.on("webglcontextrestored", this.boundOnWebGLContextRestored);
2749
2073
  }
2750
2074
  unsubscribeFromFailedTiles() {
@@ -2771,4 +2095,3 @@ export class InternalMapVXMap extends Loggeable {
2771
2095
  this.failedTiles.clear();
2772
2096
  }
2773
2097
  }
2774
- //# sourceMappingURL=map.js.map