@sakuzu/maplibre-gl-draw 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (636) hide show
  1. package/CHANGELOG.md +43 -0
  2. package/LICENSE +661 -0
  3. package/README.ja.md +248 -0
  4. package/README.md +255 -0
  5. package/THIRD_PARTY_NOTICES.md +275 -0
  6. package/dist/api/api.d.ts +1259 -0
  7. package/dist/api/api.js +86 -0
  8. package/dist/api/context.d.ts +173 -0
  9. package/dist/api/context.js +193 -0
  10. package/dist/api/display-api.d.ts +1 -0
  11. package/dist/api/display-api.js +23 -0
  12. package/dist/api/event-api.d.ts +13 -0
  13. package/dist/api/event-api.js +17 -0
  14. package/dist/api/extension-api.d.ts +46 -0
  15. package/dist/api/extension-api.js +85 -0
  16. package/dist/api/feature-api.d.ts +11 -0
  17. package/dist/api/feature-api.js +101 -0
  18. package/dist/api/geometry/apply.d.ts +51 -0
  19. package/dist/api/geometry/apply.js +114 -0
  20. package/dist/api/geometry/boolean.d.ts +28 -0
  21. package/dist/api/geometry/boolean.js +65 -0
  22. package/dist/api/geometry/buffer.d.ts +11 -0
  23. package/dist/api/geometry/buffer.js +105 -0
  24. package/dist/api/geometry/split.d.ts +16 -0
  25. package/dist/api/geometry/split.js +75 -0
  26. package/dist/api/geometry/targets.d.ts +76 -0
  27. package/dist/api/geometry/targets.js +158 -0
  28. package/dist/api/geometry/types.d.ts +31 -0
  29. package/dist/api/geometry/types.js +3 -0
  30. package/dist/api/geometry-operations.d.ts +162 -0
  31. package/dist/api/geometry-operations.js +94 -0
  32. package/dist/api/group-api.d.ts +10 -0
  33. package/dist/api/group-api.js +78 -0
  34. package/dist/api/import-export/constants.d.ts +29 -0
  35. package/dist/api/import-export/constants.js +40 -0
  36. package/dist/api/import-export/embedded-file.d.ts +13 -0
  37. package/dist/api/import-export/embedded-file.js +31 -0
  38. package/dist/api/import-export/file-name.d.ts +10 -0
  39. package/dist/api/import-export/file-name.js +20 -0
  40. package/dist/api/import-export/format-detection.d.ts +12 -0
  41. package/dist/api/import-export/format-detection.js +29 -0
  42. package/dist/api/import-export/geojson-export.d.ts +19 -0
  43. package/dist/api/import-export/geojson-export.js +262 -0
  44. package/dist/api/import-export/geojson-import.d.ts +34 -0
  45. package/dist/api/import-export/geojson-import.js +538 -0
  46. package/dist/api/import-export/geometry-validation.d.ts +20 -0
  47. package/dist/api/import-export/geometry-validation.js +107 -0
  48. package/dist/api/import-export/image-import.d.ts +12 -0
  49. package/dist/api/import-export/image-import.js +53 -0
  50. package/dist/api/import-export/index.d.ts +9 -0
  51. package/dist/api/import-export/index.js +107 -0
  52. package/dist/api/import-export/native-format.d.ts +15 -0
  53. package/dist/api/import-export/native-format.js +126 -0
  54. package/dist/api/import-export/native-validation.d.ts +28 -0
  55. package/dist/api/import-export/native-validation.js +212 -0
  56. package/dist/api/import-export/own-property.d.ts +10 -0
  57. package/dist/api/import-export/own-property.js +19 -0
  58. package/dist/api/import-export/style-validation.d.ts +27 -0
  59. package/dist/api/import-export/style-validation.js +49 -0
  60. package/dist/api/import-export/types.d.ts +26 -0
  61. package/dist/api/import-export/types.js +3 -0
  62. package/dist/api/index.d.ts +15 -0
  63. package/dist/api/index.js +3 -0
  64. package/dist/api/input-api.d.ts +158 -0
  65. package/dist/api/input-api.js +144 -0
  66. package/dist/api/instance-api.d.ts +38 -0
  67. package/dist/api/instance-api.js +136 -0
  68. package/dist/api/layer-api.d.ts +12 -0
  69. package/dist/api/layer-api.js +62 -0
  70. package/dist/api/selection-api.d.ts +7 -0
  71. package/dist/api/selection-api.js +78 -0
  72. package/dist/api/snapping-api.d.ts +125 -0
  73. package/dist/api/snapping-api.js +50 -0
  74. package/dist/api/topology-api.d.ts +30 -0
  75. package/dist/api/topology-api.js +16 -0
  76. package/dist/api/tracing-api.d.ts +31 -0
  77. package/dist/api/tracing-api.js +16 -0
  78. package/dist/dispatcher/hit-test/box-strategies.d.ts +19 -0
  79. package/dist/dispatcher/hit-test/box-strategies.js +275 -0
  80. package/dist/dispatcher/hit-test/box-strategy.d.ts +59 -0
  81. package/dist/dispatcher/hit-test/box-strategy.js +37 -0
  82. package/dist/dispatcher/hit-test/globe-shape.d.ts +46 -0
  83. package/dist/dispatcher/hit-test/globe-shape.js +70 -0
  84. package/dist/dispatcher/hit-test/index.d.ts +14 -0
  85. package/dist/dispatcher/hit-test/index.js +9 -0
  86. package/dist/dispatcher/hit-test/local-frame.d.ts +77 -0
  87. package/dist/dispatcher/hit-test/local-frame.js +112 -0
  88. package/dist/dispatcher/hit-test/segment-grid.d.ts +32 -0
  89. package/dist/dispatcher/hit-test/segment-grid.js +79 -0
  90. package/dist/dispatcher/hit-test/service.d.ts +120 -0
  91. package/dist/dispatcher/hit-test/service.js +333 -0
  92. package/dist/dispatcher/hit-test/strategies/base.d.ts +136 -0
  93. package/dist/dispatcher/hit-test/strategies/base.js +66 -0
  94. package/dist/dispatcher/hit-test/strategies/circle.d.ts +10 -0
  95. package/dist/dispatcher/hit-test/strategies/circle.js +56 -0
  96. package/dist/dispatcher/hit-test/strategies/image.d.ts +22 -0
  97. package/dist/dispatcher/hit-test/strategies/image.js +115 -0
  98. package/dist/dispatcher/hit-test/strategies/index.d.ts +11 -0
  99. package/dist/dispatcher/hit-test/strategies/index.js +10 -0
  100. package/dist/dispatcher/hit-test/strategies/line.d.ts +17 -0
  101. package/dist/dispatcher/hit-test/strategies/line.js +30 -0
  102. package/dist/dispatcher/hit-test/strategies/multi.d.ts +44 -0
  103. package/dist/dispatcher/hit-test/strategies/multi.js +141 -0
  104. package/dist/dispatcher/hit-test/strategies/point.d.ts +20 -0
  105. package/dist/dispatcher/hit-test/strategies/point.js +29 -0
  106. package/dist/dispatcher/hit-test/strategies/polygon.d.ts +52 -0
  107. package/dist/dispatcher/hit-test/strategies/polygon.js +138 -0
  108. package/dist/dispatcher/hit-test/topmost.d.ts +48 -0
  109. package/dist/dispatcher/hit-test/topmost.js +157 -0
  110. package/dist/dispatcher/hit-test/visibility-lookup.d.ts +23 -0
  111. package/dist/dispatcher/hit-test/visibility-lookup.js +40 -0
  112. package/dist/dispatcher/index.d.ts +15 -0
  113. package/dist/dispatcher/index.js +3 -0
  114. package/dist/dispatcher/input-router.d.ts +1 -0
  115. package/dist/dispatcher/input-router.js +288 -0
  116. package/dist/dispatcher/normalizer.d.ts +1 -0
  117. package/dist/dispatcher/normalizer.js +513 -0
  118. package/dist/dispatcher/types.d.ts +144 -0
  119. package/dist/dispatcher/types.js +15 -0
  120. package/dist/display/chunk-set.d.ts +24 -0
  121. package/dist/display/chunk-set.js +533 -0
  122. package/dist/display/chunk.d.ts +1 -0
  123. package/dist/display/chunk.js +104 -0
  124. package/dist/display/columnar/index.d.ts +12 -0
  125. package/dist/display/columnar/index.js +13 -0
  126. package/dist/display/columnar/prepare.d.ts +42 -0
  127. package/dist/display/columnar/prepare.js +116 -0
  128. package/dist/display/columnar/source.d.ts +1 -0
  129. package/dist/display/columnar/source.js +531 -0
  130. package/dist/display/columnar/table.d.ts +1 -0
  131. package/dist/display/columnar/table.js +471 -0
  132. package/dist/display/columnar/types.d.ts +223 -0
  133. package/dist/display/columnar/types.js +3 -0
  134. package/dist/display/dataset.d.ts +2 -0
  135. package/dist/display/dataset.js +891 -0
  136. package/dist/display/index.d.ts +13 -0
  137. package/dist/display/index.js +3 -0
  138. package/dist/display/interaction.d.ts +1 -0
  139. package/dist/display/interaction.js +90 -0
  140. package/dist/display/manager.d.ts +1 -0
  141. package/dist/display/manager.js +440 -0
  142. package/dist/display/packed-rtree.d.ts +1 -0
  143. package/dist/display/packed-rtree.js +244 -0
  144. package/dist/display/partition.d.ts +1 -0
  145. package/dist/display/partition.js +226 -0
  146. package/dist/display/provider.d.ts +1 -0
  147. package/dist/display/provider.js +342 -0
  148. package/dist/display/retained.d.ts +40 -0
  149. package/dist/display/retained.js +898 -0
  150. package/dist/display/selection.d.ts +13 -0
  151. package/dist/display/selection.js +226 -0
  152. package/dist/display/source.d.ts +1 -0
  153. package/dist/display/source.js +119 -0
  154. package/dist/display/spatial.d.ts +1 -0
  155. package/dist/display/spatial.js +71 -0
  156. package/dist/display/style.d.ts +1 -0
  157. package/dist/display/style.js +126 -0
  158. package/dist/display/thinning.d.ts +65 -0
  159. package/dist/display/thinning.js +910 -0
  160. package/dist/display/triangulation.d.ts +1 -0
  161. package/dist/display/triangulation.js +0 -0
  162. package/dist/display/types.d.ts +561 -0
  163. package/dist/display/types.js +43 -0
  164. package/dist/extension/feature-handler.d.ts +182 -0
  165. package/dist/extension/feature-handler.js +3 -0
  166. package/dist/extension/index.d.ts +9 -0
  167. package/dist/extension/index.js +3 -0
  168. package/dist/extension/renderers.d.ts +208 -0
  169. package/dist/extension/renderers.js +3 -0
  170. package/dist/geometry/angle.d.ts +47 -0
  171. package/dist/geometry/angle.js +44 -0
  172. package/dist/geometry/bbox.d.ts +48 -0
  173. package/dist/geometry/bbox.js +83 -0
  174. package/dist/geometry/boolean.d.ts +162 -0
  175. package/dist/geometry/boolean.js +331 -0
  176. package/dist/geometry/buffer.d.ts +72 -0
  177. package/dist/geometry/buffer.js +218 -0
  178. package/dist/geometry/circle.d.ts +55 -0
  179. package/dist/geometry/circle.js +107 -0
  180. package/dist/geometry/coords.d.ts +97 -0
  181. package/dist/geometry/coords.js +149 -0
  182. package/dist/geometry/distance.d.ts +79 -0
  183. package/dist/geometry/distance.js +111 -0
  184. package/dist/geometry/errors.d.ts +74 -0
  185. package/dist/geometry/errors.js +104 -0
  186. package/dist/geometry/index.d.ts +28 -0
  187. package/dist/geometry/index.js +38 -0
  188. package/dist/geometry/measure.d.ts +81 -0
  189. package/dist/geometry/measure.js +236 -0
  190. package/dist/geometry/predicates.d.ts +62 -0
  191. package/dist/geometry/predicates.js +132 -0
  192. package/dist/geometry/simplify.d.ts +74 -0
  193. package/dist/geometry/simplify.js +159 -0
  194. package/dist/geometry/split.d.ts +68 -0
  195. package/dist/geometry/split.js +430 -0
  196. package/dist/geometry/types.d.ts +95 -0
  197. package/dist/geometry/types.js +3 -0
  198. package/dist/geometry/units.d.ts +35 -0
  199. package/dist/geometry/units.js +41 -0
  200. package/dist/index.d.ts +72 -0
  201. package/dist/index.js +20 -0
  202. package/dist/maplibre-gl-draw.d.ts +47 -0
  203. package/dist/maplibre-gl-draw.js +407 -0
  204. package/dist/messages.d.ts +64 -0
  205. package/dist/messages.js +36 -0
  206. package/dist/modes/cursor.d.ts +1 -0
  207. package/dist/modes/cursor.js +72 -0
  208. package/dist/modes/draw/circle.d.ts +1 -0
  209. package/dist/modes/draw/circle.js +222 -0
  210. package/dist/modes/draw/commit-layer.d.ts +26 -0
  211. package/dist/modes/draw/commit-layer.js +31 -0
  212. package/dist/modes/draw/freehand.d.ts +1 -0
  213. package/dist/modes/draw/freehand.js +264 -0
  214. package/dist/modes/draw/image.d.ts +1 -0
  215. package/dist/modes/draw/image.js +60 -0
  216. package/dist/modes/draw/index.d.ts +9 -0
  217. package/dist/modes/draw/index.js +11 -0
  218. package/dist/modes/draw/line.d.ts +1 -0
  219. package/dist/modes/draw/line.js +363 -0
  220. package/dist/modes/draw/point.d.ts +1 -0
  221. package/dist/modes/draw/point.js +87 -0
  222. package/dist/modes/draw/polygon.d.ts +1 -0
  223. package/dist/modes/draw/polygon.js +378 -0
  224. package/dist/modes/draw/trace-support.d.ts +79 -0
  225. package/dist/modes/draw/trace-support.js +161 -0
  226. package/dist/modes/handler.d.ts +285 -0
  227. package/dist/modes/handler.js +3 -0
  228. package/dist/modes/index.d.ts +7 -0
  229. package/dist/modes/index.js +3 -0
  230. package/dist/modes/manager.d.ts +15 -0
  231. package/dist/modes/manager.js +196 -0
  232. package/dist/modes/select/box-selection.d.ts +52 -0
  233. package/dist/modes/select/box-selection.js +140 -0
  234. package/dist/modes/select/click-handler.d.ts +32 -0
  235. package/dist/modes/select/click-handler.js +166 -0
  236. package/dist/modes/select/cursor-handler.d.ts +15 -0
  237. package/dist/modes/select/cursor-handler.js +59 -0
  238. package/dist/modes/select/drag/auxiliary.d.ts +26 -0
  239. package/dist/modes/select/drag/auxiliary.js +56 -0
  240. package/dist/modes/select/drag/intermediate-writes.d.ts +1 -0
  241. package/dist/modes/select/drag/intermediate-writes.js +171 -0
  242. package/dist/modes/select/drag/move.d.ts +24 -0
  243. package/dist/modes/select/drag/move.js +59 -0
  244. package/dist/modes/select/drag/operation.d.ts +30 -0
  245. package/dist/modes/select/drag/operation.js +18 -0
  246. package/dist/modes/select/drag/radius.d.ts +15 -0
  247. package/dist/modes/select/drag/radius.js +49 -0
  248. package/dist/modes/select/drag/transform.d.ts +17 -0
  249. package/dist/modes/select/drag/transform.js +155 -0
  250. package/dist/modes/select/drag/vertex.d.ts +17 -0
  251. package/dist/modes/select/drag/vertex.js +163 -0
  252. package/dist/modes/select/drag-handler.d.ts +1 -0
  253. package/dist/modes/select/drag-handler.js +254 -0
  254. package/dist/modes/select/hit-helpers.d.ts +40 -0
  255. package/dist/modes/select/hit-helpers.js +51 -0
  256. package/dist/modes/select/mode.d.ts +1 -0
  257. package/dist/modes/select/mode.js +397 -0
  258. package/dist/modes/select/shortcut-handler.d.ts +40 -0
  259. package/dist/modes/select/shortcut-handler.js +128 -0
  260. package/dist/operations/index.d.ts +9 -0
  261. package/dist/operations/index.js +3 -0
  262. package/dist/operations/layer-operations.d.ts +1 -0
  263. package/dist/operations/layer-operations.js +350 -0
  264. package/dist/operations/resize.d.ts +71 -0
  265. package/dist/operations/resize.js +252 -0
  266. package/dist/operations/rotate.d.ts +17 -0
  267. package/dist/operations/rotate.js +166 -0
  268. package/dist/operations/selection-operations.d.ts +20 -0
  269. package/dist/operations/selection-operations.js +159 -0
  270. package/dist/operations/shared-vertex.d.ts +1 -0
  271. package/dist/operations/shared-vertex.js +210 -0
  272. package/dist/operations/trace-graph.d.ts +96 -0
  273. package/dist/operations/trace-graph.js +283 -0
  274. package/dist/operations/vertex.d.ts +1 -0
  275. package/dist/operations/vertex.js +538 -0
  276. package/dist/plugins/index.d.ts +10 -0
  277. package/dist/plugins/index.js +3 -0
  278. package/dist/plugins/mutation-hooks.d.ts +28 -0
  279. package/dist/plugins/mutation-hooks.js +84 -0
  280. package/dist/plugins/plugin-context.d.ts +1 -0
  281. package/dist/plugins/plugin-context.js +367 -0
  282. package/dist/plugins/plugin-manager.d.ts +103 -0
  283. package/dist/plugins/plugin-manager.js +316 -0
  284. package/dist/plugins/plugin.d.ts +529 -0
  285. package/dist/plugins/plugin.js +3 -0
  286. package/dist/shared/config/constants.d.ts +66 -0
  287. package/dist/shared/config/constants.js +60 -0
  288. package/dist/shared/config/feature-style.d.ts +155 -0
  289. package/dist/shared/config/feature-style.js +154 -0
  290. package/dist/shared/config/index.d.ts +17 -0
  291. package/dist/shared/config/index.js +8 -0
  292. package/dist/shared/config/rendering.d.ts +107 -0
  293. package/dist/shared/config/rendering.js +33 -0
  294. package/dist/shared/config/selection-highlight.d.ts +29 -0
  295. package/dist/shared/config/selection-highlight.js +35 -0
  296. package/dist/shared/config/selection.d.ts +273 -0
  297. package/dist/shared/config/selection.js +266 -0
  298. package/dist/shared/config/topology.d.ts +33 -0
  299. package/dist/shared/config/topology.js +17 -0
  300. package/dist/shared/config/trace.d.ts +40 -0
  301. package/dist/shared/config/trace.js +17 -0
  302. package/dist/shared/math/angle.d.ts +21 -0
  303. package/dist/shared/math/angle.js +34 -0
  304. package/dist/shared/math/circle.d.ts +6 -0
  305. package/dist/shared/math/circle.js +10 -0
  306. package/dist/shared/math/constants.d.ts +48 -0
  307. package/dist/shared/math/constants.js +59 -0
  308. package/dist/shared/math/distance.d.ts +78 -0
  309. package/dist/shared/math/distance.js +147 -0
  310. package/dist/shared/math/globe-subdivision.d.ts +62 -0
  311. package/dist/shared/math/globe-subdivision.js +99 -0
  312. package/dist/shared/math/index.d.ts +17 -0
  313. package/dist/shared/math/index.js +21 -0
  314. package/dist/shared/math/intersection.d.ts +63 -0
  315. package/dist/shared/math/intersection.js +236 -0
  316. package/dist/shared/math/longitude.d.ts +20 -0
  317. package/dist/shared/math/longitude.js +31 -0
  318. package/dist/shared/math/mercator-plane.d.ts +27 -0
  319. package/dist/shared/math/mercator-plane.js +26 -0
  320. package/dist/shared/math/obb.d.ts +65 -0
  321. package/dist/shared/math/obb.js +107 -0
  322. package/dist/shared/math/rotation.d.ts +93 -0
  323. package/dist/shared/math/rotation.js +186 -0
  324. package/dist/shared/math/segment-grid.d.ts +69 -0
  325. package/dist/shared/math/segment-grid.js +159 -0
  326. package/dist/shared/math/transform.d.ts +140 -0
  327. package/dist/shared/math/transform.js +189 -0
  328. package/dist/shared/types/events.d.ts +128 -0
  329. package/dist/shared/types/events.js +3 -0
  330. package/dist/shared/types/model.d.ts +950 -0
  331. package/dist/shared/types/model.js +3 -0
  332. package/dist/shared/types/selection-box.d.ts +23 -0
  333. package/dist/shared/types/selection-box.js +3 -0
  334. package/dist/shared/types/style.d.ts +68 -0
  335. package/dist/shared/types/style.js +3 -0
  336. package/dist/shared/utils/color.d.ts +49 -0
  337. package/dist/shared/utils/color.js +180 -0
  338. package/dist/shared/utils/coordinates.d.ts +52 -0
  339. package/dist/shared/utils/coordinates.js +75 -0
  340. package/dist/shared/utils/embedded-image.d.ts +34 -0
  341. package/dist/shared/utils/embedded-image.js +161 -0
  342. package/dist/shared/utils/event-emitter.d.ts +262 -0
  343. package/dist/shared/utils/event-emitter.js +44 -0
  344. package/dist/shared/utils/feature-bbox.d.ts +8 -0
  345. package/dist/shared/utils/feature-bbox.js +207 -0
  346. package/dist/shared/utils/feature-segments.d.ts +23 -0
  347. package/dist/shared/utils/feature-segments.js +179 -0
  348. package/dist/shared/utils/id.d.ts +1 -0
  349. package/dist/shared/utils/id.js +35 -0
  350. package/dist/shared/utils/image.d.ts +34 -0
  351. package/dist/shared/utils/image.js +106 -0
  352. package/dist/shared/utils/index.d.ts +15 -0
  353. package/dist/shared/utils/index.js +24 -0
  354. package/dist/shared/utils/map.d.ts +26 -0
  355. package/dist/shared/utils/map.js +35 -0
  356. package/dist/shared/utils/name-generator.d.ts +197 -0
  357. package/dist/shared/utils/name-generator.js +337 -0
  358. package/dist/shared/utils/pixel-ratio.d.ts +111 -0
  359. package/dist/shared/utils/pixel-ratio.js +85 -0
  360. package/dist/shared/utils/property.d.ts +88 -0
  361. package/dist/shared/utils/property.js +140 -0
  362. package/dist/shared/utils/vertex-ref.d.ts +23 -0
  363. package/dist/shared/utils/vertex-ref.js +20 -0
  364. package/dist/snapping/custom-targets.d.ts +1 -0
  365. package/dist/snapping/custom-targets.js +21 -0
  366. package/dist/snapping/geometry.d.ts +1 -0
  367. package/dist/snapping/geometry.js +61 -0
  368. package/dist/snapping/index.d.ts +14 -0
  369. package/dist/snapping/index.js +4 -0
  370. package/dist/snapping/indicator.d.ts +19 -0
  371. package/dist/snapping/indicator.js +145 -0
  372. package/dist/snapping/providers/display.d.ts +72 -0
  373. package/dist/snapping/providers/display.js +268 -0
  374. package/dist/snapping/providers/guide.d.ts +69 -0
  375. package/dist/snapping/providers/guide.js +187 -0
  376. package/dist/snapping/providers/intersection.d.ts +1 -0
  377. package/dist/snapping/providers/intersection.js +92 -0
  378. package/dist/snapping/providers/shared.d.ts +39 -0
  379. package/dist/snapping/providers/shared.js +146 -0
  380. package/dist/snapping/providers/store.d.ts +1 -0
  381. package/dist/snapping/providers/store.js +132 -0
  382. package/dist/snapping/service.d.ts +1 -0
  383. package/dist/snapping/service.js +272 -0
  384. package/dist/snapping/types.d.ts +267 -0
  385. package/dist/snapping/types.js +66 -0
  386. package/dist/store/change-merger.d.ts +1 -0
  387. package/dist/store/change-merger.js +102 -0
  388. package/dist/store/draw-store.d.ts +1 -0
  389. package/dist/store/draw-store.js +396 -0
  390. package/dist/store/event-bridge.d.ts +1 -0
  391. package/dist/store/event-bridge.js +161 -0
  392. package/dist/store/index.d.ts +12 -0
  393. package/dist/store/index.js +4 -0
  394. package/dist/store/local-visibility.d.ts +21 -0
  395. package/dist/store/local-visibility.js +27 -0
  396. package/dist/store/lock.d.ts +67 -0
  397. package/dist/store/lock.js +54 -0
  398. package/dist/store/memory/change-bus.d.ts +60 -0
  399. package/dist/store/memory/change-bus.js +232 -0
  400. package/dist/store/memory/file-store.d.ts +15 -0
  401. package/dist/store/memory/file-store.js +33 -0
  402. package/dist/store/memory/frozen.d.ts +21 -0
  403. package/dist/store/memory/frozen.js +51 -0
  404. package/dist/store/memory/ui-state.d.ts +51 -0
  405. package/dist/store/memory/ui-state.js +223 -0
  406. package/dist/store/memory.d.ts +26 -0
  407. package/dist/store/memory.js +708 -0
  408. package/dist/store/spatial/index.d.ts +6 -0
  409. package/dist/store/spatial/index.js +4 -0
  410. package/dist/store/spatial/spatial-index.d.ts +90 -0
  411. package/dist/store/spatial/spatial-index.js +148 -0
  412. package/dist/store/spatial/store-spatial-index.d.ts +60 -0
  413. package/dist/store/spatial/store-spatial-index.js +125 -0
  414. package/dist/store/store.d.ts +417 -0
  415. package/dist/store/store.js +3 -0
  416. package/dist/store/types.d.ts +8 -0
  417. package/dist/store/types.js +3 -0
  418. package/dist/store/writable-layer.d.ts +35 -0
  419. package/dist/store/writable-layer.js +20 -0
  420. package/dist/view/cache/buffer.d.ts +28 -0
  421. package/dist/view/cache/buffer.js +176 -0
  422. package/dist/view/cache/earcut.d.ts +1 -0
  423. package/dist/view/cache/earcut.js +122 -0
  424. package/dist/view/cache/style-rule.d.ts +1 -0
  425. package/dist/view/cache/style-rule.js +97 -0
  426. package/dist/view/cache/terrain-fill.d.ts +30 -0
  427. package/dist/view/cache/terrain-fill.js +60 -0
  428. package/dist/view/cache/texture.d.ts +14 -0
  429. package/dist/view/cache/texture.js +292 -0
  430. package/dist/view/coordinator.d.ts +27 -0
  431. package/dist/view/coordinator.js +72 -0
  432. package/dist/view/feature-companion.d.ts +173 -0
  433. package/dist/view/feature-companion.js +108 -0
  434. package/dist/view/globe-subdivision.d.ts +78 -0
  435. package/dist/view/globe-subdivision.js +128 -0
  436. package/dist/view/index.d.ts +47 -0
  437. package/dist/view/index.js +20 -0
  438. package/dist/view/layer/attach.d.ts +20 -0
  439. package/dist/view/layer/attach.js +47 -0
  440. package/dist/view/layer/blend.d.ts +57 -0
  441. package/dist/view/layer/blend.js +14 -0
  442. package/dist/view/layer/custom-layer.d.ts +1 -0
  443. package/dist/view/layer/custom-layer.js +509 -0
  444. package/dist/view/layer/depth-state.d.ts +14 -0
  445. package/dist/view/layer/depth-state.js +44 -0
  446. package/dist/view/layer/display-list.d.ts +1 -0
  447. package/dist/view/layer/display-list.js +111 -0
  448. package/dist/view/layer/drape-planner.d.ts +139 -0
  449. package/dist/view/layer/drape-planner.js +726 -0
  450. package/dist/view/layer/frame-render.d.ts +57 -0
  451. package/dist/view/layer/frame-render.js +209 -0
  452. package/dist/view/layer/frame-state.d.ts +147 -0
  453. package/dist/view/layer/frame-state.js +484 -0
  454. package/dist/view/layer/gl-state.d.ts +77 -0
  455. package/dist/view/layer/gl-state.js +132 -0
  456. package/dist/view/layer/index.d.ts +6 -0
  457. package/dist/view/layer/index.js +5 -0
  458. package/dist/view/layer/render-scope.d.ts +30 -0
  459. package/dist/view/layer/render-scope.js +28 -0
  460. package/dist/view/layer/render.d.ts +87 -0
  461. package/dist/view/layer/render.js +187 -0
  462. package/dist/view/layer/renderers.d.ts +81 -0
  463. package/dist/view/layer/renderers.js +142 -0
  464. package/dist/view/layer/slot-manager.d.ts +26 -0
  465. package/dist/view/layer/slot-manager.js +133 -0
  466. package/dist/view/layer/slots.d.ts +33 -0
  467. package/dist/view/layer/slots.js +50 -0
  468. package/dist/view/layer/store-retained-bbox.d.ts +36 -0
  469. package/dist/view/layer/store-retained-bbox.js +188 -0
  470. package/dist/view/layer/store-retained-chunk.d.ts +97 -0
  471. package/dist/view/layer/store-retained-chunk.js +94 -0
  472. package/dist/view/layer/store-retained-classify.d.ts +34 -0
  473. package/dist/view/layer/store-retained-classify.js +88 -0
  474. package/dist/view/layer/store-retained-collect.d.ts +24 -0
  475. package/dist/view/layer/store-retained-collect.js +121 -0
  476. package/dist/view/layer/store-retained-coord-patch.d.ts +119 -0
  477. package/dist/view/layer/store-retained-coord-patch.js +168 -0
  478. package/dist/view/layer/store-retained-immediate.d.ts +63 -0
  479. package/dist/view/layer/store-retained-immediate.js +49 -0
  480. package/dist/view/layer/store-retained-invalidation.d.ts +96 -0
  481. package/dist/view/layer/store-retained-invalidation.js +192 -0
  482. package/dist/view/layer/store-retained.d.ts +198 -0
  483. package/dist/view/layer/store-retained.js +430 -0
  484. package/dist/view/layer/terrain-resolver.d.ts +1 -0
  485. package/dist/view/layer/terrain-resolver.js +174 -0
  486. package/dist/view/renderers/batch-manager.d.ts +61 -0
  487. package/dist/view/renderers/batch-manager.js +718 -0
  488. package/dist/view/renderers/draw-factors.d.ts +60 -0
  489. package/dist/view/renderers/draw-factors.js +35 -0
  490. package/dist/view/renderers/drawer.d.ts +1 -0
  491. package/dist/view/renderers/drawer.js +346 -0
  492. package/dist/view/renderers/image.d.ts +1 -0
  493. package/dist/view/renderers/image.js +255 -0
  494. package/dist/view/renderers/line/dash.d.ts +31 -0
  495. package/dist/view/renderers/line/dash.js +152 -0
  496. package/dist/view/renderers/line/line-geometry.d.ts +39 -0
  497. package/dist/view/renderers/line/line-geometry.js +460 -0
  498. package/dist/view/renderers/line/line-gl.d.ts +1 -0
  499. package/dist/view/renderers/line/line-gl.js +236 -0
  500. package/dist/view/renderers/line/line-shader.d.ts +1 -0
  501. package/dist/view/renderers/line/line-shader.js +364 -0
  502. package/dist/view/renderers/line/line-types.d.ts +43 -0
  503. package/dist/view/renderers/line/line-types.js +3 -0
  504. package/dist/view/renderers/line/line-uniforms.d.ts +1 -0
  505. package/dist/view/renderers/line/line-uniforms.js +390 -0
  506. package/dist/view/renderers/line/sdf-line.d.ts +92 -0
  507. package/dist/view/renderers/line/sdf-line.js +567 -0
  508. package/dist/view/renderers/point/billboard-depth.d.ts +10 -0
  509. package/dist/view/renderers/point/billboard-depth.js +56 -0
  510. package/dist/view/renderers/point/point-instance.d.ts +124 -0
  511. package/dist/view/renderers/point/point-instance.js +738 -0
  512. package/dist/view/renderers/point/point-sdf.d.ts +58 -0
  513. package/dist/view/renderers/point/point-sdf.js +170 -0
  514. package/dist/view/renderers/point/point-shape.d.ts +99 -0
  515. package/dist/view/renderers/point/point-shape.js +504 -0
  516. package/dist/view/renderers/point/point-style.d.ts +1 -0
  517. package/dist/view/renderers/point/point-style.js +46 -0
  518. package/dist/view/renderers/polygon/batch.d.ts +26 -0
  519. package/dist/view/renderers/polygon/batch.js +336 -0
  520. package/dist/view/renderers/polygon/earcut-input.d.ts +37 -0
  521. package/dist/view/renderers/polygon/earcut-input.js +55 -0
  522. package/dist/view/renderers/polygon/earcut-sliced.d.ts +69 -0
  523. package/dist/view/renderers/polygon/earcut-sliced.js +960 -0
  524. package/dist/view/renderers/polygon/fill.d.ts +74 -0
  525. package/dist/view/renderers/polygon/fill.js +251 -0
  526. package/dist/view/renderers/polygon/sdf-polygon.d.ts +62 -0
  527. package/dist/view/renderers/polygon/sdf-polygon.js +919 -0
  528. package/dist/view/renderers/polygon/terrain-cull.d.ts +3 -0
  529. package/dist/view/renderers/polygon/terrain-cull.js +14 -0
  530. package/dist/view/renderers/polygon/triangulator.d.ts +41 -0
  531. package/dist/view/renderers/polygon/triangulator.js +3 -0
  532. package/dist/view/renderers/retained.d.ts +43 -0
  533. package/dist/view/renderers/retained.js +3 -0
  534. package/dist/view/renderers/stroke.d.ts +121 -0
  535. package/dist/view/renderers/stroke.js +621 -0
  536. package/dist/view/shaders/frame.d.ts +8 -0
  537. package/dist/view/shaders/frame.js +37 -0
  538. package/dist/view/shaders/helpers.d.ts +238 -0
  539. package/dist/view/shaders/helpers.js +611 -0
  540. package/dist/view/shaders/initializer.d.ts +27 -0
  541. package/dist/view/shaders/initializer.js +125 -0
  542. package/dist/view/shaders/projection.d.ts +123 -0
  543. package/dist/view/shaders/projection.js +299 -0
  544. package/dist/view/shaders/quad-grid.d.ts +77 -0
  545. package/dist/view/shaders/quad-grid.js +128 -0
  546. package/dist/view/shaders/quad.d.ts +189 -0
  547. package/dist/view/shaders/quad.js +582 -0
  548. package/dist/view/shaders/retained-origin.d.ts +50 -0
  549. package/dist/view/shaders/retained-origin.js +67 -0
  550. package/dist/view/shaders/terrain-shade.d.ts +23 -0
  551. package/dist/view/shaders/terrain-shade.js +93 -0
  552. package/dist/view/style-rule.d.ts +166 -0
  553. package/dist/view/style-rule.js +300 -0
  554. package/dist/view/terrain/anchor.d.ts +135 -0
  555. package/dist/view/terrain/anchor.js +226 -0
  556. package/dist/view/terrain/context.d.ts +132 -0
  557. package/dist/view/terrain/context.js +437 -0
  558. package/dist/view/terrain/dem-atlas.d.ts +97 -0
  559. package/dist/view/terrain/dem-atlas.js +534 -0
  560. package/dist/view/terrain/detect.d.ts +126 -0
  561. package/dist/view/terrain/detect.js +198 -0
  562. package/dist/view/terrain/drape/bin-store.d.ts +179 -0
  563. package/dist/view/terrain/drape/bin-store.js +529 -0
  564. package/dist/view/terrain/drape/binning.d.ts +259 -0
  565. package/dist/view/terrain/drape/binning.js +604 -0
  566. package/dist/view/terrain/drape/edge-constrain.d.ts +37 -0
  567. package/dist/view/terrain/drape/edge-constrain.js +175 -0
  568. package/dist/view/terrain/drape/geometry.d.ts +95 -0
  569. package/dist/view/terrain/drape/geometry.js +260 -0
  570. package/dist/view/terrain/drape/mesh.d.ts +50 -0
  571. package/dist/view/terrain/drape/mesh.js +86 -0
  572. package/dist/view/terrain/drape/pass.d.ts +122 -0
  573. package/dist/view/terrain/drape/pass.js +379 -0
  574. package/dist/view/terrain/drape/quad-glyphs.d.ts +64 -0
  575. package/dist/view/terrain/drape/quad-glyphs.js +117 -0
  576. package/dist/view/terrain/drape/quad.d.ts +249 -0
  577. package/dist/view/terrain/drape/quad.js +835 -0
  578. package/dist/view/terrain/drape/renderer.d.ts +184 -0
  579. package/dist/view/terrain/drape/renderer.js +706 -0
  580. package/dist/view/terrain/drape/shared.d.ts +80 -0
  581. package/dist/view/terrain/drape/shared.js +173 -0
  582. package/dist/view/terrain/drape/stitch.d.ts +155 -0
  583. package/dist/view/terrain/drape/stitch.js +228 -0
  584. package/dist/view/terrain/ground.d.ts +72 -0
  585. package/dist/view/terrain/ground.js +151 -0
  586. package/dist/view/terrain/metrics.d.ts +180 -0
  587. package/dist/view/terrain/metrics.js +231 -0
  588. package/dist/view/terrain/occlusion.d.ts +11 -0
  589. package/dist/view/terrain/occlusion.js +129 -0
  590. package/dist/view/terrain/polygon.d.ts +86 -0
  591. package/dist/view/terrain/polygon.js +301 -0
  592. package/dist/view/terrain/shade.d.ts +48 -0
  593. package/dist/view/terrain/shade.js +45 -0
  594. package/dist/view/terrain/state.d.ts +99 -0
  595. package/dist/view/terrain/state.js +186 -0
  596. package/dist/view/terrain/tessellation.d.ts +265 -0
  597. package/dist/view/terrain/tessellation.js +924 -0
  598. package/dist/view/terrain/tiling.d.ts +56 -0
  599. package/dist/view/terrain/tiling.js +155 -0
  600. package/dist/view/terrain/upstream-terrain.d.ts +82 -0
  601. package/dist/view/terrain/upstream-terrain.js +116 -0
  602. package/dist/view/ui/auxiliary-handles.d.ts +151 -0
  603. package/dist/view/ui/auxiliary-handles.js +22 -0
  604. package/dist/view/ui/bounds.d.ts +53 -0
  605. package/dist/view/ui/bounds.js +149 -0
  606. package/dist/view/ui/box-selection.d.ts +1 -0
  607. package/dist/view/ui/box-selection.js +83 -0
  608. package/dist/view/ui/handle-test.d.ts +1 -0
  609. package/dist/view/ui/handle-test.js +437 -0
  610. package/dist/view/ui/handle-thinning.d.ts +122 -0
  611. package/dist/view/ui/handle-thinning.js +430 -0
  612. package/dist/view/ui/handles.d.ts +25 -0
  613. package/dist/view/ui/handles.js +673 -0
  614. package/dist/view/ui/helper.d.ts +19 -0
  615. package/dist/view/ui/helper.js +76 -0
  616. package/dist/view/ui/index.d.ts +15 -0
  617. package/dist/view/ui/index.js +15 -0
  618. package/dist/view/ui/selection-scope.d.ts +25 -0
  619. package/dist/view/ui/selection-scope.js +34 -0
  620. package/dist/view/ui/selection-ui/bounding-box.d.ts +44 -0
  621. package/dist/view/ui/selection-ui/bounding-box.js +240 -0
  622. package/dist/view/ui/selection-ui/extension-registry.d.ts +76 -0
  623. package/dist/view/ui/selection-ui/extension-registry.js +78 -0
  624. package/dist/view/ui/selection-ui/index.d.ts +12 -0
  625. package/dist/view/ui/selection-ui/index.js +12 -0
  626. package/dist/view/ui/selection-ui/renderer.d.ts +29 -0
  627. package/dist/view/ui/selection-ui/renderer.js +227 -0
  628. package/dist/view/ui/selection-ui/types.d.ts +55 -0
  629. package/dist/view/ui/selection-ui/types.js +3 -0
  630. package/dist/view/ui/selection-ui-drawer.d.ts +52 -0
  631. package/dist/view/ui/selection-ui-drawer.js +329 -0
  632. package/dist/view/ui/tentative.d.ts +1 -0
  633. package/dist/view/ui/tentative.js +320 -0
  634. package/dist/view/viewport.d.ts +119 -0
  635. package/dist/view/viewport.js +254 -0
  636. package/package.json +113 -0
@@ -0,0 +1,891 @@
1
+ // SPDX-FileCopyrightText: 2026 SAKAIDA Atsushi
2
+ // SPDX-License-Identifier: AGPL-3.0-only
3
+ import { DEFAULT_FEATURE_STYLE_CONFIG } from '../shared/config/feature-style.js';
4
+ import { sanitizeDrawFactors } from '../view/renderers/draw-factors.js';
5
+ import { TerrainContext } from '../view/terrain/context.js';
6
+ import { DisplayChunkSet } from './chunk-set.js';
7
+ import { ColumnarSource } from './columnar/source.js';
8
+ import { DisplayProviderLoader } from './provider.js';
9
+ import { drawSelectionHighlight, hitTestDisplayFeatures, sameFeatureIds, } from './selection.js';
10
+ import { FeatureArraySource } from './source.js';
11
+ import { DisplayFeatureStyler } from './style.js';
12
+ import { CollisionThinningState, pointMarkerRadiusPx } from './thinning.js';
13
+ import { normalizeDisplayFeature } from './types.js';
14
+ // The importers of these moved names keep their path (the definitions live in the parts)
15
+ export { needsRetessellation } from './chunk-set.js';
16
+ /**
17
+ * Implementation of a dataset
18
+ *
19
+ * @internal
20
+ */
21
+ export class DatasetImpl {
22
+ constructor(options, deps) {
23
+ Object.defineProperty(this, "id", {
24
+ enumerable: true,
25
+ configurable: true,
26
+ writable: true,
27
+ value: void 0
28
+ });
29
+ Object.defineProperty(this, "interactive", {
30
+ enumerable: true,
31
+ configurable: true,
32
+ writable: true,
33
+ value: void 0
34
+ });
35
+ /** The current side. It is rewritten by the reordering of the manager */
36
+ Object.defineProperty(this, "currentOrder", {
37
+ enumerable: true,
38
+ configurable: true,
39
+ writable: true,
40
+ value: void 0
41
+ });
42
+ /** Whether it is shown. While it is false, neither rendering nor hit testing happens */
43
+ Object.defineProperty(this, "isVisible", {
44
+ enumerable: true,
45
+ configurable: true,
46
+ writable: true,
47
+ value: true
48
+ });
49
+ /** The contents (the rows, their chunks and their spatial index) */
50
+ Object.defineProperty(this, "source", {
51
+ enumerable: true,
52
+ configurable: true,
53
+ writable: true,
54
+ value: new FeatureArraySource([])
55
+ });
56
+ Object.defineProperty(this, "styler", {
57
+ enumerable: true,
58
+ configurable: true,
59
+ writable: true,
60
+ value: void 0
61
+ });
62
+ /** Zoom-dependent drawing factors (no factors when not set) */
63
+ Object.defineProperty(this, "zoomScale", {
64
+ enumerable: true,
65
+ configurable: true,
66
+ writable: true,
67
+ value: null
68
+ });
69
+ /**
70
+ * Whether the polygons and lines are handed to the analytic drape (decided per frame by the
71
+ * rendering side)
72
+ *
73
+ * While they are handed over, the solid polygons and lines are not pushed onto the retained
74
+ * batches. This is so that the same thing is not drawn twice and so that the whole cost of the
75
+ * subdivision that matches the terrain mesh is skipped.
76
+ */
77
+ Object.defineProperty(this, "drapedFills", {
78
+ enumerable: true,
79
+ configurable: true,
80
+ writable: true,
81
+ value: false
82
+ });
83
+ /** The terrain used when the draw target provides none (inactive: draws flat) */
84
+ Object.defineProperty(this, "flatTerrain", {
85
+ enumerable: true,
86
+ configurable: true,
87
+ writable: true,
88
+ value: new TerrainContext()
89
+ });
90
+ /**
91
+ * The revision that triggers rebuilding the index of the drape
92
+ *
93
+ * It advances only when the contents, the style or the visibility changed. It does not advance
94
+ * on a zoom, on the view or on the thinning (the drape draws no point; if it advanced on a
95
+ * pan or a zoom band, the index would be rebuilt on every gesture).
96
+ */
97
+ Object.defineProperty(this, "contentRevision", {
98
+ enumerable: true,
99
+ configurable: true,
100
+ writable: true,
101
+ value: 0
102
+ });
103
+ /** Advances whenever the drawn rows change (`getDrawnRowsRevision`) */
104
+ Object.defineProperty(this, "drawnRowsRevision", {
105
+ enumerable: true,
106
+ configurable: true,
107
+ writable: true,
108
+ value: 0
109
+ });
110
+ /**
111
+ * The zoom of the most recent frame drawn (the zoom the sizes are drawn with; null before the
112
+ * first frame). The band of the thinning is decided from it
113
+ */
114
+ Object.defineProperty(this, "frameZoom", {
115
+ enumerable: true,
116
+ configurable: true,
117
+ writable: true,
118
+ value: null
119
+ });
120
+ /** Whether this dataset was drawn in the most recent frame */
121
+ Object.defineProperty(this, "drawnInFrame", {
122
+ enumerable: true,
123
+ configurable: true,
124
+ writable: true,
125
+ value: false
126
+ });
127
+ /**
128
+ * Revision number of the style
129
+ *
130
+ * The footprint of the thinning is decided by the style (the rule, the base style, the zoom
131
+ * factors), so the winners are picked again once it advances. It is part of the cache key.
132
+ */
133
+ Object.defineProperty(this, "styleRevision", {
134
+ enumerable: true,
135
+ configurable: true,
136
+ writable: true,
137
+ value: 0
138
+ });
139
+ /** The retained chunks */
140
+ Object.defineProperty(this, "chunks", {
141
+ enumerable: true,
142
+ configurable: true,
143
+ writable: true,
144
+ value: void 0
145
+ });
146
+ /** The collision thinning */
147
+ Object.defineProperty(this, "thinning", {
148
+ enumerable: true,
149
+ configurable: true,
150
+ writable: true,
151
+ value: void 0
152
+ });
153
+ /** The loading through the provider (null without a provider) */
154
+ Object.defineProperty(this, "loader", {
155
+ enumerable: true,
156
+ configurable: true,
157
+ writable: true,
158
+ value: void 0
159
+ });
160
+ Object.defineProperty(this, "listeners", {
161
+ enumerable: true,
162
+ configurable: true,
163
+ writable: true,
164
+ value: new Map()
165
+ });
166
+ /** The features of the selected rows (in draw order; only the ids that exist are held) */
167
+ Object.defineProperty(this, "selected", {
168
+ enumerable: true,
169
+ configurable: true,
170
+ writable: true,
171
+ value: []
172
+ });
173
+ Object.defineProperty(this, "removed", {
174
+ enumerable: true,
175
+ configurable: true,
176
+ writable: true,
177
+ value: false
178
+ });
179
+ /** Whether the 'change' of a band followed by a frame is waiting to be sent */
180
+ Object.defineProperty(this, "thinningNoticePending", {
181
+ enumerable: true,
182
+ configurable: true,
183
+ writable: true,
184
+ value: false
185
+ });
186
+ /** Cancels the waiting picking of the winners of the nearby bands (null = nothing waits) */
187
+ Object.defineProperty(this, "cancelPrefetch", {
188
+ enumerable: true,
189
+ configurable: true,
190
+ writable: true,
191
+ value: null
192
+ });
193
+ Object.defineProperty(this, "deps", {
194
+ enumerable: true,
195
+ configurable: true,
196
+ writable: true,
197
+ value: void 0
198
+ });
199
+ /** Predicate that picks out the points drawn by an external renderer (null when not injected) */
200
+ Object.defineProperty(this, "externalPointRender", {
201
+ enumerable: true,
202
+ configurable: true,
203
+ writable: true,
204
+ value: void 0
205
+ });
206
+ /**
207
+ * Whether it is a point drawn by an external renderer (core does not draw it)
208
+ *
209
+ * The three paths (retained, immediate, selection) look only at this one. Scattering the test
210
+ * across each path would produce a disagreement such as "the circle comes back only when it is
211
+ * selected" the moment one of them is forgotten. The line that puts `MultiPoint` out of scope
212
+ * is also closed in here (when one feature has several points far apart, the unit to delegate
213
+ * to the external renderer is undefined; it is the same line as the collision thinning).
214
+ */
215
+ Object.defineProperty(this, "isExternallyRenderedPoint", {
216
+ enumerable: true,
217
+ configurable: true,
218
+ writable: true,
219
+ value: (feature) => feature.type === 'Point' && this.externalPointRender?.(feature) === true
220
+ });
221
+ const given = [options.features, options.columnar, options.provider].filter((input) => input !== undefined);
222
+ if (given.length > 1) {
223
+ throw new Error(`Dataset "${options.id}": only one of features, columnar and provider can be given`);
224
+ }
225
+ if (options.prepared && !options.columnar) {
226
+ throw new Error(`Dataset "${options.id}": prepared is given without columnar`);
227
+ }
228
+ this.id = options.id;
229
+ this.currentOrder = options.order ?? 'below-store';
230
+ this.interactive = options.interactive ?? false;
231
+ this.styler = new DisplayFeatureStyler(options.styleRule, options.baseStyle);
232
+ this.zoomScale = options.zoomScale ?? null;
233
+ this.externalPointRender = options.externalPointRender ?? null;
234
+ this.deps = deps;
235
+ this.chunks = new DisplayChunkSet({
236
+ collector: (rows, collect, drawn) => this.source.collector(rows, this.collectContext(collect, drawn)),
237
+ drawnRows: () => this.thinning.mask,
238
+ // Not passed when it is not injected (the path without a predicate is as before)
239
+ externalPointFilter: () => this.externalPointRender ? this.isExternallyRenderedPoint : undefined,
240
+ drapedFills: () => this.drapedFills,
241
+ requestRepaint: () => this.deps.requestRepaint(),
242
+ onInvalidateAll: () => {
243
+ this.contentRevision++;
244
+ },
245
+ pixelRatio: deps.pixelRatio,
246
+ triangulationScheduler: deps.triangulationScheduler,
247
+ buildBudgetMs: deps.timeSlicing === false ? Number.POSITIVE_INFINITY : undefined,
248
+ });
249
+ this.thinning = new CollisionThinningState({
250
+ rows: () => this.source,
251
+ featuresGeneration: () => this.chunks.generation,
252
+ styleRevision: () => this.styleRevision,
253
+ footprintPx: (band, marginPx) => {
254
+ const defaults = this.pointDefaults();
255
+ const scale = sanitizeDrawFactors(this.zoomScale?.(band)).scale;
256
+ const baseStyle = this.styler.base;
257
+ return (styleRadius) => pointMarkerRadiusPx(styleRadius, baseStyle, defaults, scale) + marginPx;
258
+ },
259
+ }, options.collisionThinning);
260
+ this.loader = options.provider
261
+ ? new DisplayProviderLoader(options.provider, {
262
+ id: this.id,
263
+ debounceMs: deps.providerDebounceMs,
264
+ apply: (features) => {
265
+ this.applySource(new FeatureArraySource(features));
266
+ this.deps.requestRepaint();
267
+ },
268
+ })
269
+ : null;
270
+ if (options.features) {
271
+ this.setFeatures(options.features);
272
+ }
273
+ else if (options.columnar) {
274
+ this.setColumnar(options.columnar, options.prepared);
275
+ }
276
+ }
277
+ /** Draw order (the current side) */
278
+ get order() {
279
+ return this.currentOrder;
280
+ }
281
+ /** Whether it is shown */
282
+ get visible() {
283
+ return this.isVisible;
284
+ }
285
+ /** Whether it has a provider */
286
+ get hasProvider() {
287
+ return this.loader !== null;
288
+ }
289
+ /**
290
+ * Whether it needs to know about the changes of the displayed range (moveend): only to call
291
+ * its provider (the band of the thinning follows the frames drawn)
292
+ */
293
+ get needsViewportUpdates() {
294
+ return this.loader !== null;
295
+ }
296
+ /** Whether it has been removed */
297
+ get isRemoved() {
298
+ return this.removed;
299
+ }
300
+ // === Public API ===
301
+ setVisible(visible) {
302
+ if (this.isVisible === visible)
303
+ return;
304
+ this.isVisible = visible;
305
+ this.contentRevision++;
306
+ // The retained batches are not discarded, so showing it again draws at once without a rebuild
307
+ this.emit('change', { reason: 'visibility' });
308
+ this.deps.requestRepaint();
309
+ }
310
+ setFeatures(features) {
311
+ this.applySource(new FeatureArraySource(features.map(normalizeDisplayFeature)));
312
+ this.deps.requestRepaint();
313
+ }
314
+ setColumnar(input, prepared) {
315
+ this.applySource(new ColumnarSource(input, prepared));
316
+ this.deps.requestRepaint();
317
+ }
318
+ setStyleRule(rule) {
319
+ this.styler.setRule(rule);
320
+ // The colors change, so the retained batches of every chunk are rebuilt
321
+ this.restyle();
322
+ }
323
+ setBaseStyle(style) {
324
+ this.styler.setBase(style);
325
+ // The appearance changes, so the retained batches of every chunk are rebuilt
326
+ this.restyle();
327
+ }
328
+ setExternalPointRender(predicate) {
329
+ this.externalPointRender = predicate ?? null;
330
+ // "Which points are not drawn" is baked into the retained batches, so as much is discarded as
331
+ // in setStyleRule / setBaseStyle. Without discarding it, the picture of the external renderer
332
+ // would be laid over the old circles that remain (or the points would stay gone even after
333
+ // the predicate is removed)
334
+ this.styler.clear();
335
+ this.restyle();
336
+ }
337
+ setZoomScale(zoomScale) {
338
+ // The factors are only multiplied in at draw time, so the retained batches are untouched
339
+ this.zoomScale = zoomScale;
340
+ // The footprint of the thinning does change with the factors, so the winners are picked
341
+ // again (the next draw rebuilds the points when they changed)
342
+ this.styleRevision++;
343
+ this.syncThinning('change');
344
+ this.schedulePrefetch();
345
+ this.deps.requestRepaint();
346
+ }
347
+ getZoomScale() {
348
+ return this.zoomScale;
349
+ }
350
+ getBaseStyle() {
351
+ return this.styler.base;
352
+ }
353
+ getFeatures() {
354
+ return this.source.features();
355
+ }
356
+ setSelectedIds(ids) {
357
+ // Keep the draw order and drop the ids that do not exist
358
+ const rows = ids.length === 0 ? [] : this.source.rowsOfIds(new Set(ids));
359
+ const next = rows.map((row) => this.source.featureAt(row));
360
+ if (sameFeatureIds(this.selected, next))
361
+ return;
362
+ this.selected = next;
363
+ this.emit('change', { reason: 'selection' });
364
+ this.deps.requestRepaint();
365
+ }
366
+ getSelectedIds() {
367
+ return this.selected.map((feature) => feature.id);
368
+ }
369
+ setCollisionThinning(options) {
370
+ const result = this.thinning.setOptions(options, this.thinningZoom());
371
+ if (!result)
372
+ return;
373
+ // The next draw rebuilds the points only when the drawn rows changed
374
+ if (result.drawnChanged)
375
+ this.drawnRowsChanged('change');
376
+ this.schedulePrefetch();
377
+ }
378
+ getCollisionThinning() {
379
+ return this.thinning.options;
380
+ }
381
+ getVisibleFeatureIds() {
382
+ return this.thinning.drawable;
383
+ }
384
+ getThinningStats() {
385
+ return this.thinning.stats(this.source.length);
386
+ }
387
+ getDrawnRowsRevision() {
388
+ return this.drawnRowsRevision;
389
+ }
390
+ findRow(id) {
391
+ const row = this.source.rowOfId(id);
392
+ return row >= 0 ? row : null;
393
+ }
394
+ invalidateProviderCache() {
395
+ if (!this.loader || this.removed)
396
+ return;
397
+ const { bounds, zoom } = this.deps.getViewportState();
398
+ this.loader.invalidate(bounds, zoom);
399
+ }
400
+ on(event, handler) {
401
+ let set = this.listeners.get(event);
402
+ if (!set) {
403
+ set = new Set();
404
+ this.listeners.set(event, set);
405
+ }
406
+ set.add(handler);
407
+ return () => this.off(event, handler);
408
+ }
409
+ off(event, handler) {
410
+ this.listeners.get(event)?.delete(handler);
411
+ }
412
+ remove() {
413
+ if (this.removed)
414
+ return;
415
+ this.removed = true;
416
+ this.dispose();
417
+ this.deps.onRemove(this.id);
418
+ this.deps.requestRepaint();
419
+ }
420
+ // === Internal API (called from the manager) ===
421
+ /**
422
+ * Rewrites the side (the path of the reordering)
423
+ *
424
+ * Only where it is drawn changes, so neither the retained batches, nor the visibility, nor the
425
+ * state of the provider is touched. The repaint is requested by the manager.
426
+ */
427
+ setOrder(order) {
428
+ this.currentOrder = order;
429
+ }
430
+ /**
431
+ * Fires an event
432
+ *
433
+ * click / hover are called only when interactive. change is called regardless of interactive
434
+ * when the contents, the style or the visibility changed.
435
+ */
436
+ emit(event, payload) {
437
+ const set = this.listeners.get(event);
438
+ if (!set)
439
+ return;
440
+ // An exception in one handler is isolated so that it does not drag in the others or the
441
+ // rendering path
442
+ for (const handler of [...set]) {
443
+ try {
444
+ handler(payload);
445
+ }
446
+ catch (error) {
447
+ console.error(`Error in Dataset "${this.id}" listener for "${event}":`, error);
448
+ }
449
+ }
450
+ }
451
+ // === Hand-off with the analytic drape ===
452
+ /**
453
+ * The revision that triggers rebuilding the index of the drape
454
+ *
455
+ * It advances only when the contents, the style, the thinning or the visibility changed.
456
+ */
457
+ get drapeRevision() {
458
+ return this.contentRevision;
459
+ }
460
+ /**
461
+ * The features handed to the analytic drape (with the rule colors applied, in draw order)
462
+ *
463
+ * The drape draws polygons and lines, and the thinning removes only points, so the drawn rows
464
+ * play no part here (a change of the zoom band does not rebuild the index of the drape). They
465
+ * are not narrowed by the view either. Narrowing them would change the order of the elements
466
+ * whenever the view moves and force the tile index to be rebuilt (the narrowing is done with
467
+ * the bounding box of each tile; `view/terrain/drape/binning.ts`).
468
+ */
469
+ drapeFeatures() {
470
+ if (!this.isVisible)
471
+ return [];
472
+ const source = this.source;
473
+ // A table of points has nothing for it (and its rows are not built into features for
474
+ // nothing)
475
+ if (source instanceof ColumnarSource && source.table.onlyPoints)
476
+ return [];
477
+ const features = [];
478
+ for (let row = 0; row < source.length; row++) {
479
+ const type = source.typeOf(row);
480
+ if (type === null || type === 'Point' || type === 'MultiPoint')
481
+ continue;
482
+ features.push(source.featureAt(row));
483
+ }
484
+ return this.styler.prepareAll(features);
485
+ }
486
+ /**
487
+ * Reports whether the polygons and lines are handed to the analytic drape (decided per frame by
488
+ * the rendering side)
489
+ *
490
+ * A chunk whose way of handing over changed is re-baked the next time things settle. The
491
+ * previous version keeps being drawn until then, so the picture never disappears at the switch.
492
+ */
493
+ setDrapedFills(draped) {
494
+ this.drapedFills = draped;
495
+ }
496
+ /**
497
+ * Zoom-dependent drawing factors (passed to the uniforms of the analytic drape)
498
+ *
499
+ * They are the same values that the retained batch path passes to `drawChunkBatches`.
500
+ */
501
+ drapeFactors(zoom) {
502
+ return sanitizeDrawFactors(this.zoomScale?.(zoom));
503
+ }
504
+ /**
505
+ * Returns the features inside the viewport in draw order (with the rule colors and the base
506
+ * style applied)
507
+ */
508
+ collectVisible(bounds) {
509
+ return this.styler.prepareAll(this.featuresOf(this.source.index.search(bounds)));
510
+ }
511
+ collectDrawnRows(bounds) {
512
+ const source = this.source;
513
+ const thinning = this.thinning;
514
+ // The index holds only the rows with a geometry. `skip` is a hidden feature (a table has no
515
+ // hidden rows)
516
+ return source.index.searchWhere(bounds, (row) => thinning.isDrawnRow(row) && source.thinningRole(row) !== 'skip');
517
+ }
518
+ getRowFeature(row) {
519
+ if (!this.hasRow(row))
520
+ return null;
521
+ return this.styler.prepareIfStyled(this.source.featureAt(row));
522
+ }
523
+ getRowId(row) {
524
+ return this.hasRow(row) ? this.source.idOf(row) : null;
525
+ }
526
+ getRowType(row) {
527
+ return this.hasRow(row) ? this.source.typeOf(row) : null;
528
+ }
529
+ getRowBounds(row) {
530
+ if (!this.hasRow(row) || !this.source.hasGeometry(row))
531
+ return null;
532
+ const bounds = this.source.bounds;
533
+ const at = row * 4;
534
+ return { minX: bounds[at], minY: bounds[at + 1], maxX: bounds[at + 2], maxY: bounds[at + 3] };
535
+ }
536
+ getRowPoint(row) {
537
+ if (this.getRowType(row) !== 'Point')
538
+ return null;
539
+ const point = this.source.pointOf(row);
540
+ return [point[0], point[1]];
541
+ }
542
+ /**
543
+ * Whether the most recent draw left a chunk unbuilt
544
+ *
545
+ * It turns false at the first frame that leaves nothing unbuilt (a measurement reads it to know
546
+ * when everything in view is drawn).
547
+ */
548
+ get hasPendingBuild() {
549
+ return this.chunks.hasPendingBuild;
550
+ }
551
+ /**
552
+ * Whether work remains that will change what this dataset draws without the host doing
553
+ * anything: a chunk the most recent frame left unbuilt (only when it drew this dataset), or
554
+ * a call of the provider waiting for its debounce or its response. A hidden dataset draws
555
+ * nothing, so it has none
556
+ */
557
+ get hasPendingWork() {
558
+ if (!this.isVisible)
559
+ return false;
560
+ return this.loader?.busy === true || (this.drawnInFrame && this.chunks.hasPendingBuild);
561
+ }
562
+ /**
563
+ * The start of a frame (called by the manager before anything is drawn)
564
+ *
565
+ * The frame decides the zoom band of the thinning, once, from the zoom it draws with, before
566
+ * any layer draws: every layer of the frame that reads the drawn rows then reads the rows this
567
+ * frame draws. A hidden dataset only records the zoom (its rows follow once it is drawn).
568
+ *
569
+ * @param zoom The zoom the frame draws with
570
+ */
571
+ beginFrame(zoom) {
572
+ this.frameZoom = zoom;
573
+ this.drawnInFrame = false;
574
+ if (this.isVisible && !this.removed)
575
+ this.syncThinning('frame');
576
+ }
577
+ /**
578
+ * Draws the chunks that intersect the viewport
579
+ *
580
+ * In retained mode it only draws the retained batches of the chunks that intersect (building
581
+ * them the first time when necessary; `DisplayChunkSet.draw`). In an environment where the
582
+ * retained-mode renderers are not available, features are narrowed one at a time with the
583
+ * spatial index and fed to the batches, as before.
584
+ *
585
+ * Nothing happens while it is hidden. The retained batches are kept, so showing it again takes
586
+ * effect without a build in between.
587
+ *
588
+ * The zoom-dependent factors are evaluated once per frame and the same values are passed to
589
+ * every batch of that frame. At a zoom where the opacity becomes 0, the drawing itself is
590
+ * skipped.
591
+ */
592
+ draw(target, projectionData, zoom, bounds) {
593
+ if (!this.isVisible)
594
+ return;
595
+ // The rows follow the band of the zoom drawn (the manager normally did it at the start of
596
+ // the frame, with the same zoom, and this finds nothing to do)
597
+ this.frameZoom = zoom;
598
+ this.syncThinning('frame');
599
+ const factors = sanitizeDrawFactors(this.zoomScale?.(zoom));
600
+ // Completely transparent means there is nothing to draw (the immediate path is skipped too)
601
+ if (factors.opacity <= 0)
602
+ return;
603
+ this.drawnInFrame = true;
604
+ // The terrain state of the draw instance this dataset is drawn into
605
+ const terrain = target.getTerrain?.() ?? this.flatTerrain;
606
+ const renderers = target.getRetainedRenderers?.();
607
+ if (renderers) {
608
+ this.chunks.draw({ target, renderers, terrain, projectionData, zoom, bounds, factors });
609
+ }
610
+ else {
611
+ this.drawImmediate(target, projectionData, zoom, bounds);
612
+ }
613
+ drawSelectionHighlight({
614
+ target,
615
+ projectionData,
616
+ zoom,
617
+ bounds,
618
+ selected: this.selected,
619
+ styles: this.chunks.retainedRenderers?.styles,
620
+ terrain,
621
+ datasetId: this.id,
622
+ drapedFills: this.drapedFills,
623
+ prepare: (feature) => this.styler.prepareIfStyled(feature),
624
+ isExternalPoint: this.isExternallyRenderedPoint,
625
+ });
626
+ }
627
+ /**
628
+ * Returns the frontmost hit (`hitTestDisplayFeatures`)
629
+ *
630
+ * While it is hidden it always misses (what is not visible cannot be grabbed).
631
+ */
632
+ hitTest(coordinate, toleranceLngLat, test) {
633
+ return this.hitTestRow(coordinate, toleranceLngLat, test)?.feature ?? null;
634
+ }
635
+ /**
636
+ * Returns the frontmost hit with its row (`hitTestDisplayFeatures`)
637
+ *
638
+ * The feature carries the rule colors and the base style. While it is hidden it always misses.
639
+ */
640
+ hitTestRow(coordinate, toleranceLngLat, test) {
641
+ if (!this.isVisible)
642
+ return null;
643
+ // The hit radius of a point changes with the zoom, so it is computed from the current zoom on
644
+ // every test
645
+ const zoom = this.deps.getZoom();
646
+ const source = this.source;
647
+ const hit = hitTestDisplayFeatures({
648
+ coordinate,
649
+ toleranceLngLat,
650
+ test,
651
+ zoom,
652
+ scale: sanitizeDrawFactors(this.zoomScale?.(zoom)).scale,
653
+ baseStyle: this.styler.base,
654
+ pointDefaults: this.pointDefaults(),
655
+ maxStylePointRadius: source.maxStylePointRadius,
656
+ search: (bounds) => source.index.search(bounds),
657
+ featureAt: (row) => source.featureAt(row),
658
+ isDrawn: (row) => this.thinning.isDrawnRow(row),
659
+ });
660
+ return hit ? { feature: this.styler.prepareIfStyled(hit.feature), row: hit.row } : null;
661
+ }
662
+ /**
663
+ * Schedules the call of the provider according to the changes of the displayed range
664
+ *
665
+ * The range is handled through a key rounded to a zoom stage plus tile coordinates. Nothing
666
+ * happens when it equals the key already applied; when it is in the cache it is applied at
667
+ * once; otherwise the call is debounced. While a fetch is in flight, the previous result keeps
668
+ * being shown.
669
+ */
670
+ scheduleProviderUpdate(bounds, zoom) {
671
+ if (!this.loader || this.removed)
672
+ return;
673
+ this.loader.schedule(bounds, zoom);
674
+ }
675
+ /**
676
+ * Releases the resources (timers, index, subscriptions)
677
+ *
678
+ * After it is disposed, a response in flight is not applied either (the path called directly
679
+ * from the destroy of the manager is treated the same way).
680
+ */
681
+ dispose() {
682
+ this.cancelPrefetch?.();
683
+ this.cancelPrefetch = null;
684
+ this.removed = true;
685
+ this.loader?.dispose();
686
+ this.chunks.dispose();
687
+ this.source = new FeatureArraySource([]);
688
+ this.selected = [];
689
+ this.thinning.clear();
690
+ this.styler.clear();
691
+ this.listeners.clear();
692
+ }
693
+ /**
694
+ * Releases only the GPU resources of retained mode
695
+ *
696
+ * It is called when the rendering layer is disposed (onRemove). The dataset itself stays
697
+ * alive and the chunks are built again on the next draw once the layer is recreated.
698
+ */
699
+ disposeRetained() {
700
+ this.chunks.releaseRetained();
701
+ }
702
+ // === Internals ===
703
+ /**
704
+ * Default style of a point (the default of core when not injected)
705
+ */
706
+ pointDefaults() {
707
+ return this.deps.pointStyle ?? DEFAULT_FEATURE_STYLE_CONFIG.point.point;
708
+ }
709
+ /**
710
+ * Draws in immediate mode (the path for an environment without the retained-mode renderers)
711
+ *
712
+ * The frame of the batch is started without passing a layer. The rules have already been
713
+ * evaluated here, so the rule evaluation of the rendering side (FeatureDrawer) is not used.
714
+ */
715
+ drawImmediate(target, projectionData, zoom, bounds) {
716
+ const rows = this.source.index.search(bounds).filter((row) => this.thinning.isDrawnRow(row));
717
+ let visible = this.styler.prepareAll(this.featuresOf(rows));
718
+ // A point drawn by an external renderer is not drawn by core (without a predicate it passes
719
+ // straight through)
720
+ if (this.externalPointRender) {
721
+ visible = visible.filter((feature) => !this.isExternallyRenderedPoint(feature));
722
+ }
723
+ if (visible.length === 0)
724
+ return;
725
+ target.beginFrame(projectionData, zoom);
726
+ for (const feature of visible) {
727
+ target.processFeature(feature, false);
728
+ }
729
+ target.endFrame();
730
+ }
731
+ /**
732
+ * Applies new contents (the chunks, the index and the caches come with them)
733
+ *
734
+ * The only triggers for rebuilding the retained batches are this path (setFeatures,
735
+ * setColumnar and applying a provider result) and setStyleRule / setBaseStyle.
736
+ */
737
+ applySource(source) {
738
+ this.source = source;
739
+ this.styler.clear();
740
+ // An id that disappeared in the replacement is dropped from the selection (an id that
741
+ // remained points at the row of the new contents)
742
+ if (this.selected.length > 0) {
743
+ const selectedIds = new Set(this.selected.map((feature) => feature.id));
744
+ this.selected = source.rowsOfIds(selectedIds).map((row) => source.featureAt(row));
745
+ }
746
+ this.chunks.replace(source.chunks);
747
+ // The winners are picked again together with the replacement (it is done before emit so that
748
+ // a host receiving change does not read the old set). The rows themselves are new
749
+ this.syncDrawnRows();
750
+ this.drawnRowsRevision++;
751
+ this.schedulePrefetch();
752
+ this.emit('change', { reason: 'features' });
753
+ }
754
+ /** Whether a number is a row of the current contents */
755
+ hasRow(row) {
756
+ return Number.isInteger(row) && row >= 0 && row < this.source.length;
757
+ }
758
+ /** The features of rows (without the rule colors) */
759
+ featuresOf(rows) {
760
+ const features = new Array(rows.length);
761
+ for (let i = 0; i < rows.length; i++)
762
+ features[i] = this.source.featureAt(rows[i]);
763
+ return features;
764
+ }
765
+ /**
766
+ * What the source needs to collect the rows of a chunk
767
+ *
768
+ * @param drawn The rows to collect (a build reads the mask of the moment it starts, never a
769
+ * later one, so the chunk knows exactly which rows its points were built with)
770
+ */
771
+ collectContext(options, drawn) {
772
+ return {
773
+ ...options,
774
+ styler: this.styler,
775
+ isDrawn: drawn === null ? () => true : (row) => drawn[row] === 1,
776
+ styleKey: this.styleRevision,
777
+ };
778
+ }
779
+ /** The appearance changed: pick the winners again, rebuild every chunk and tell the listeners */
780
+ restyle() {
781
+ this.styleRevision++;
782
+ // The chunks are rebuilt anyway; the change of the drawn rows is part of this change
783
+ if (this.syncDrawnRows())
784
+ this.drawnRowsRevision++;
785
+ this.schedulePrefetch();
786
+ this.chunks.invalidateAll();
787
+ this.emit('change', { reason: 'style' });
788
+ this.deps.requestRepaint();
789
+ }
790
+ /**
791
+ * The zoom the band of the thinning is decided from: the zoom of the most recent frame (the
792
+ * zoom the frame draws with; the zoom of the map before the first frame), lowered by the drop
793
+ * of the pitch correction
794
+ *
795
+ * One zoom decides the band. The zoom of the map itself is not read again: the elevation
796
+ * settlement of the terrain changes it without changing the picture, and the band would flip
797
+ * while nothing moved.
798
+ */
799
+ thinningZoom() {
800
+ return (this.frameZoom ?? this.deps.getZoom()) - this.deps.getPitchZoomDrop();
801
+ }
802
+ /**
803
+ * Brings the drawn rows up to the band of the zoom (`CollisionThinningState.sync`)
804
+ *
805
+ * @param cause `frame` for a frame about to draw, `change` for a change made by the host
806
+ */
807
+ syncThinning(cause) {
808
+ if (this.syncDrawnRows())
809
+ this.drawnRowsChanged(cause);
810
+ }
811
+ /**
812
+ * `CollisionThinningState.sync` with the zoom of `thinningZoom` (nothing is measured while the
813
+ * thinning is off)
814
+ *
815
+ * @returns Whether the drawn rows changed
816
+ */
817
+ syncDrawnRows() {
818
+ if (!this.thinning.enabled && !this.thinning.active)
819
+ return false;
820
+ return this.thinning.sync(this.thinningZoom());
821
+ }
822
+ /**
823
+ * The drawn rows changed through the thinning (the only place that handles it)
824
+ *
825
+ * Nothing is discarded: the draw rebuilds the point part of each chunk it draws before it
826
+ * draws it (`DisplayChunkSet.draw`). The drawn rows, the hit testing and the queries switch
827
+ * together, and the `change` event (`thinning`) is sent:
828
+ *
829
+ * - `frame`: the frame that picked them draws them; the event is sent after that frame, so a
830
+ * listener never runs in the middle of drawing and reads the rows that are on screen
831
+ * - `change`: a change made by the host (the settings, the zoom factors); the event is sent at
832
+ * once, like the other events of a change, and the next frame draws them
833
+ */
834
+ drawnRowsChanged(cause) {
835
+ this.drawnRowsRevision++;
836
+ this.schedulePrefetch();
837
+ if (cause === 'change') {
838
+ this.emit('change', { reason: 'thinning' });
839
+ this.deps.requestRepaint();
840
+ return;
841
+ }
842
+ if (this.thinningNoticePending)
843
+ return;
844
+ this.thinningNoticePending = true;
845
+ queueMicrotask(() => {
846
+ this.thinningNoticePending = false;
847
+ if (!this.removed)
848
+ this.emit('change', { reason: 'thinning' });
849
+ });
850
+ }
851
+ /**
852
+ * Picks the winners of the bands near the current one while the page is idle, in slices that
853
+ * end with the idle period (`CollisionThinningState.prefetch`)
854
+ */
855
+ schedulePrefetch() {
856
+ if (this.cancelPrefetch || this.removed || !this.thinning.enabled)
857
+ return;
858
+ this.cancelPrefetch = whenIdle((deadline) => {
859
+ this.cancelPrefetch = null;
860
+ if (this.removed)
861
+ return;
862
+ if (this.thinning.prefetch(deadline, idleNow))
863
+ this.schedulePrefetch();
864
+ });
865
+ }
866
+ }
867
+ /**
868
+ * The time given to one idle task where `requestIdleCallback` is missing (ms): a slice that
869
+ * does not blow a frame
870
+ */
871
+ const IDLE_FALLBACK_BUDGET_MS = 8;
872
+ /** How long to wait for an idle period where `requestIdleCallback` is missing (ms) */
873
+ const IDLE_FALLBACK_MS = 100;
874
+ /** The clock the idle deadlines are measured with */
875
+ function idleNow() {
876
+ return typeof performance !== 'undefined' ? performance.now() : Date.now();
877
+ }
878
+ /**
879
+ * Runs `task` when the page is idle, with the time at which the idle period ends (a timer and a
880
+ * fixed budget where `requestIdleCallback` is missing)
881
+ *
882
+ * @returns Cancels it
883
+ */
884
+ function whenIdle(task) {
885
+ if (typeof globalThis.requestIdleCallback === 'function') {
886
+ const handle = globalThis.requestIdleCallback((idle) => task(idleNow() + idle.timeRemaining()));
887
+ return () => globalThis.cancelIdleCallback(handle);
888
+ }
889
+ const handle = setTimeout(() => task(idleNow() + IDLE_FALLBACK_BUDGET_MS), IDLE_FALLBACK_MS);
890
+ return () => clearTimeout(handle);
891
+ }