@sakuzu/maplibre-gl-draw 1.0.0 → 2.1.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 (541) hide show
  1. package/CHANGELOG.md +1109 -2
  2. package/README.ja.md +83 -50
  3. package/README.md +89 -53
  4. package/THIRD_PARTY_NOTICES.md +29 -0
  5. package/dist/api/datasets.d.ts +263 -0
  6. package/dist/api/document.d.ts +66 -0
  7. package/dist/api/draw.d.ts +137 -0
  8. package/dist/api/draw.js +20 -0
  9. package/dist/api/drawing.d.ts +87 -0
  10. package/dist/api/errors.d.ts +35 -0
  11. package/dist/api/errors.js +35 -0
  12. package/dist/api/events.d.ts +316 -0
  13. package/dist/api/extension/context.d.ts +247 -0
  14. package/dist/api/extension/feature-type.d.ts +129 -0
  15. package/dist/api/extension/mode.d.ts +123 -0
  16. package/dist/api/extension/plugin.d.ts +51 -0
  17. package/dist/api/extension/plugin.js +3 -0
  18. package/dist/api/extension/provider.d.ts +119 -0
  19. package/dist/api/extension/provider.js +3 -0
  20. package/dist/api/extension/render.d.ts +176 -0
  21. package/dist/api/extension/render.js +3 -0
  22. package/dist/api/extension/store.d.ts +190 -0
  23. package/dist/api/extension/store.js +3 -0
  24. package/dist/api/extensions.d.ts +306 -0
  25. package/dist/api/extensions.js +3 -0
  26. package/dist/api/features.d.ts +188 -0
  27. package/dist/api/features.js +3 -0
  28. package/dist/api/groups.d.ts +111 -0
  29. package/dist/api/groups.js +3 -0
  30. package/dist/api/hidden.d.ts +45 -0
  31. package/dist/api/hidden.js +3 -0
  32. package/dist/api/impl/adapters.js +463 -0
  33. package/dist/api/impl/contexts.js +466 -0
  34. package/dist/api/impl/create-draw.js +124 -0
  35. package/dist/api/impl/datasets.js +405 -0
  36. package/dist/api/impl/destroy-guard.js +74 -0
  37. package/dist/api/impl/document.js +280 -0
  38. package/dist/api/impl/drawing.js +180 -0
  39. package/dist/api/impl/engine-context.d.ts +7 -0
  40. package/dist/api/{context.js → impl/engine-context.js} +49 -38
  41. package/dist/{maplibre-gl-draw.js → api/impl/engine.js} +145 -177
  42. package/dist/api/impl/events.js +423 -0
  43. package/dist/api/impl/extension-host.js +364 -0
  44. package/dist/api/impl/extensions.js +229 -0
  45. package/dist/api/impl/features.js +445 -0
  46. package/dist/api/impl/geometry/apply.d.ts +32 -0
  47. package/dist/api/{geometry → impl/geometry}/apply.js +10 -27
  48. package/dist/api/{geometry → impl/geometry}/buffer.d.ts +4 -3
  49. package/dist/api/{geometry → impl/geometry}/buffer.js +12 -23
  50. package/dist/api/{geometry → impl/geometry}/split.d.ts +4 -3
  51. package/dist/api/{geometry → impl/geometry}/split.js +10 -21
  52. package/dist/api/{geometry → impl/geometry}/targets.d.ts +2 -20
  53. package/dist/api/{geometry → impl/geometry}/targets.js +8 -35
  54. package/dist/api/impl/geometry/types.js +3 -0
  55. package/dist/api/impl/groups.d.ts +3 -0
  56. package/dist/api/impl/groups.js +268 -0
  57. package/dist/api/impl/hidden.js +60 -0
  58. package/dist/api/impl/import-export/constants.d.ts +22 -0
  59. package/dist/api/impl/import-export/constants.js +24 -0
  60. package/dist/api/{import-export → impl/import-export}/embedded-file.js +2 -2
  61. package/dist/api/{import-export → impl/import-export}/format-detection.d.ts +1 -1
  62. package/dist/api/{import-export → impl/import-export}/format-detection.js +2 -1
  63. package/dist/api/impl/import-export/geojson-export.d.ts +19 -0
  64. package/dist/api/{import-export → impl/import-export}/geojson-export.js +71 -104
  65. package/dist/api/{import-export → impl/import-export}/geojson-import.d.ts +11 -7
  66. package/dist/api/{import-export → impl/import-export}/geojson-import.js +139 -97
  67. package/dist/api/{import-export → impl/import-export}/geometry-validation.d.ts +14 -0
  68. package/dist/api/{import-export → impl/import-export}/geometry-validation.js +45 -0
  69. package/dist/api/impl/import-export/image-import.d.ts +16 -0
  70. package/dist/api/impl/import-export/image-import.js +73 -0
  71. package/dist/api/impl/import-export/legacy-image-style.d.ts +16 -0
  72. package/dist/api/impl/import-export/legacy-image-style.js +49 -0
  73. package/dist/api/impl/import-export/native-format.d.ts +14 -0
  74. package/dist/api/{import-export → impl/import-export}/native-format.js +32 -22
  75. package/dist/api/impl/import-export/native-upgrade.d.ts +8 -0
  76. package/dist/api/impl/import-export/native-upgrade.js +139 -0
  77. package/dist/api/{import-export → impl/import-export}/native-validation.d.ts +1 -1
  78. package/dist/api/{import-export → impl/import-export}/native-validation.js +15 -14
  79. package/dist/api/impl/import-export/style-validation.d.ts +24 -0
  80. package/dist/api/impl/import-export/style-validation.js +86 -0
  81. package/dist/api/impl/import-export/types.d.ts +52 -0
  82. package/dist/api/impl/import-export/types.js +3 -0
  83. package/dist/api/impl/input.js +180 -0
  84. package/dist/api/impl/layers.js +307 -0
  85. package/dist/api/impl/metadata.d.ts +1 -0
  86. package/dist/api/impl/metadata.js +22 -0
  87. package/dist/api/impl/options.d.ts +1 -0
  88. package/dist/api/impl/options.js +851 -0
  89. package/dist/api/impl/placement.d.ts +1 -0
  90. package/dist/api/impl/placement.js +138 -0
  91. package/dist/api/impl/render-context.d.ts +13 -0
  92. package/dist/api/impl/render-context.js +272 -0
  93. package/dist/api/impl/rows.d.ts +1 -0
  94. package/dist/api/impl/rows.js +46 -0
  95. package/dist/api/impl/selection.d.ts +1 -0
  96. package/dist/api/impl/selection.js +186 -0
  97. package/dist/api/impl/shared.d.ts +64 -0
  98. package/dist/api/impl/shared.js +178 -0
  99. package/dist/api/impl/validate-extension.d.ts +1 -0
  100. package/dist/api/impl/validate-extension.js +159 -0
  101. package/dist/api/layers.d.ts +130 -0
  102. package/dist/api/layers.js +3 -0
  103. package/dist/api/metadata.d.ts +18 -0
  104. package/dist/api/metadata.js +3 -0
  105. package/dist/api/model.d.ts +487 -0
  106. package/dist/api/model.js +47 -0
  107. package/dist/api/options.d.ts +466 -0
  108. package/dist/api/options.js +3 -0
  109. package/dist/api/selection.d.ts +94 -0
  110. package/dist/api/selection.js +3 -0
  111. package/dist/api/state.d.ts +155 -0
  112. package/dist/api/state.js +12 -0
  113. package/dist/{display → dataset}/chunk.d.ts +1 -1
  114. package/dist/{display → dataset}/chunk.js +4 -3
  115. package/dist/{display → dataset}/dataset.js +21 -21
  116. package/dist/dataset/interaction.d.ts +1 -0
  117. package/dist/{display → dataset}/interaction.js +18 -6
  118. package/dist/dataset/manager.d.ts +1 -0
  119. package/dist/dataset/provider.d.ts +1 -0
  120. package/dist/{display → dataset}/retained.d.ts +1 -1
  121. package/dist/{display → dataset}/retained.js +8 -7
  122. package/dist/dataset/source.d.ts +1 -0
  123. package/dist/{display → dataset}/source.js +17 -4
  124. package/dist/dataset/spatial.d.ts +1 -0
  125. package/dist/{display → dataset}/spatial.js +1 -1
  126. package/dist/dataset/style.d.ts +1 -0
  127. package/dist/{display → dataset}/style.js +1 -1
  128. package/dist/dataset/table-source.d.ts +1 -0
  129. package/dist/{display/columnar/source.js → dataset/table-source.js} +53 -25
  130. package/dist/{display → dataset}/thinning.d.ts +0 -10
  131. package/dist/{display → dataset}/thinning.js +3 -2
  132. package/dist/dataset/triangulation.d.ts +1 -0
  133. package/dist/{display → dataset}/triangulation.js +0 -0
  134. package/dist/{display → dataset}/types.d.ts +84 -121
  135. package/dist/dataset/types.js +61 -0
  136. package/dist/dispatcher/hit-test/box-strategies.js +13 -13
  137. package/dist/dispatcher/hit-test/box-strategy.d.ts +2 -15
  138. package/dist/dispatcher/hit-test/globe-shape.js +5 -4
  139. package/dist/dispatcher/hit-test/service.d.ts +17 -0
  140. package/dist/dispatcher/hit-test/service.js +80 -16
  141. package/dist/dispatcher/hit-test/strategies/base.d.ts +13 -19
  142. package/dist/dispatcher/hit-test/strategies/circle.js +3 -2
  143. package/dist/dispatcher/hit-test/strategies/image.js +6 -18
  144. package/dist/dispatcher/hit-test/strategies/line.d.ts +0 -6
  145. package/dist/dispatcher/hit-test/strategies/line.js +9 -2
  146. package/dist/dispatcher/hit-test/strategies/multi.d.ts +0 -8
  147. package/dist/dispatcher/hit-test/strategies/multi.js +17 -8
  148. package/dist/dispatcher/hit-test/strategies/point.d.ts +9 -7
  149. package/dist/dispatcher/hit-test/strategies/point.js +8 -4
  150. package/dist/dispatcher/hit-test/strategies/polygon.d.ts +0 -7
  151. package/dist/dispatcher/hit-test/strategies/polygon.js +11 -3
  152. package/dist/dispatcher/hit-test/topmost.d.ts +1 -1
  153. package/dist/dispatcher/input-router.js +154 -70
  154. package/dist/dispatcher/normalizer.js +25 -4
  155. package/dist/dispatcher/types.d.ts +6 -1
  156. package/dist/extension/feature-handler.d.ts +1 -182
  157. package/dist/extension/index.d.ts +4 -7
  158. package/dist/extension/renderers.d.ts +1 -208
  159. package/dist/geometry/angle.d.ts +0 -8
  160. package/dist/geometry/angle.js +0 -8
  161. package/dist/geometry/bbox.d.ts +4 -12
  162. package/dist/geometry/bbox.js +4 -12
  163. package/dist/geometry/boolean.d.ts +0 -51
  164. package/dist/geometry/boolean.js +0 -51
  165. package/dist/geometry/buffer.d.ts +0 -26
  166. package/dist/geometry/buffer.js +0 -26
  167. package/dist/geometry/circle.d.ts +0 -9
  168. package/dist/geometry/circle.js +0 -9
  169. package/dist/geometry/coords.d.ts +0 -16
  170. package/dist/geometry/coords.js +0 -16
  171. package/dist/geometry/distance.d.ts +0 -24
  172. package/dist/geometry/distance.js +0 -24
  173. package/dist/geometry/errors.d.ts +21 -36
  174. package/dist/geometry/errors.js +49 -29
  175. package/dist/geometry/geojson.d.ts +85 -0
  176. package/dist/geometry/geojson.js +173 -0
  177. package/dist/geometry/index.d.ts +38 -23
  178. package/dist/geometry/index.js +43 -31
  179. package/dist/geometry/measure.d.ts +0 -27
  180. package/dist/geometry/measure.js +0 -27
  181. package/dist/geometry/predicates.d.ts +0 -9
  182. package/dist/geometry/predicates.js +0 -9
  183. package/dist/geometry/public-bounds.d.ts +26 -0
  184. package/dist/geometry/public-bounds.js +30 -0
  185. package/dist/geometry/public-combine.d.ts +78 -0
  186. package/dist/geometry/public-combine.js +82 -0
  187. package/dist/geometry/public-create.d.ts +54 -0
  188. package/dist/geometry/public-create.js +70 -0
  189. package/dist/geometry/public-measure.d.ts +170 -0
  190. package/dist/geometry/public-measure.js +283 -0
  191. package/dist/geometry/public-predicates.d.ts +54 -0
  192. package/dist/geometry/public-predicates.js +144 -0
  193. package/dist/geometry/public-repair.d.ts +75 -0
  194. package/dist/geometry/public-repair.js +77 -0
  195. package/dist/geometry/simplify.d.ts +0 -7
  196. package/dist/geometry/simplify.js +0 -7
  197. package/dist/geometry/split.d.ts +0 -20
  198. package/dist/geometry/split.js +0 -20
  199. package/dist/geometry/units.d.ts +20 -12
  200. package/dist/geometry/units.js +20 -12
  201. package/dist/index.d.ts +66 -66
  202. package/dist/index.js +6 -18
  203. package/dist/messages.d.ts +7 -7
  204. package/dist/modes/draw/circle.js +83 -207
  205. package/dist/modes/draw/commit-layer.d.ts +5 -16
  206. package/dist/modes/draw/commit-layer.js +2 -13
  207. package/dist/modes/draw/freehand.js +108 -246
  208. package/dist/modes/draw/image.js +4 -2
  209. package/dist/modes/draw/index.d.ts +5 -5
  210. package/dist/modes/draw/index.js +5 -5
  211. package/dist/modes/draw/line.js +18 -354
  212. package/dist/modes/draw/point.js +29 -78
  213. package/dist/modes/draw/polygon.js +23 -368
  214. package/dist/modes/draw/trace-support.d.ts +43 -36
  215. package/dist/modes/draw/trace-support.js +95 -98
  216. package/dist/modes/draw/vertex-drawing.d.ts +1 -0
  217. package/dist/modes/draw/vertex-drawing.js +176 -0
  218. package/dist/modes/handler.d.ts +1 -285
  219. package/dist/modes/manager.d.ts +2 -2
  220. package/dist/modes/manager.js +3 -0
  221. package/dist/modes/select/box-selection.d.ts +3 -3
  222. package/dist/modes/select/box-selection.js +2 -1
  223. package/dist/modes/select/click-handler.d.ts +5 -5
  224. package/dist/modes/select/click-handler.js +22 -20
  225. package/dist/modes/select/cursor-handler.d.ts +2 -2
  226. package/dist/modes/select/drag/intermediate-writes.js +1 -1
  227. package/dist/modes/select/drag/move.js +3 -3
  228. package/dist/modes/select/drag/operation.d.ts +3 -3
  229. package/dist/modes/select/drag/radius.js +5 -4
  230. package/dist/modes/select/drag/transform.d.ts +2 -2
  231. package/dist/modes/select/drag/transform.js +11 -5
  232. package/dist/modes/select/drag/vertex.d.ts +2 -2
  233. package/dist/modes/select/drag/vertex.js +13 -8
  234. package/dist/modes/select/drag-handler.js +44 -25
  235. package/dist/modes/select/mode.js +17 -17
  236. package/dist/modes/select/shortcut-handler.d.ts +8 -8
  237. package/dist/modes/select/shortcut-handler.js +9 -7
  238. package/dist/operations/layer-operations.js +29 -168
  239. package/dist/operations/resize.d.ts +2 -2
  240. package/dist/operations/resize.js +5 -5
  241. package/dist/operations/rotate.js +5 -5
  242. package/dist/operations/selection-operations.d.ts +16 -1
  243. package/dist/operations/selection-operations.js +28 -13
  244. package/dist/operations/shared-vertex.js +4 -2
  245. package/dist/operations/trace-graph.d.ts +0 -18
  246. package/dist/operations/trace-graph.js +0 -18
  247. package/dist/operations/vertex.js +36 -35
  248. package/dist/shared/color.d.ts +1 -0
  249. package/dist/shared/color.js +245 -0
  250. package/dist/shared/config/constants.d.ts +1 -54
  251. package/dist/shared/config/constants.js +1 -58
  252. package/dist/shared/config/feature-style.d.ts +16 -13
  253. package/dist/shared/config/feature-style.js +9 -0
  254. package/dist/shared/config/rendering.d.ts +3 -3
  255. package/dist/shared/config/selection-highlight.d.ts +0 -15
  256. package/dist/shared/config/selection-highlight.js +4 -7
  257. package/dist/shared/config/selection.d.ts +2 -32
  258. package/dist/shared/config/selection.js +0 -18
  259. package/dist/shared/config/topology.d.ts +2 -2
  260. package/dist/shared/config/trace.d.ts +4 -4
  261. package/dist/shared/math/angle.d.ts +1 -1
  262. package/dist/shared/math/angle.js +1 -1
  263. package/dist/shared/math/circle.d.ts +1 -1
  264. package/dist/shared/math/circle.js +1 -1
  265. package/dist/shared/math/distance.d.ts +2 -1
  266. package/dist/shared/math/distance.js +3 -2
  267. package/dist/shared/math/index.d.ts +1 -1
  268. package/dist/shared/math/index.js +1 -1
  269. package/dist/shared/math/transform.d.ts +23 -0
  270. package/dist/shared/math/transform.js +47 -28
  271. package/dist/shared/properties.d.ts +18 -0
  272. package/dist/shared/properties.js +129 -0
  273. package/dist/shared/types/events.d.ts +15 -7
  274. package/dist/shared/types/model.d.ts +109 -159
  275. package/dist/shared/types/style.d.ts +1 -1
  276. package/dist/shared/utils/color.d.ts +2 -36
  277. package/dist/shared/utils/color.js +13 -70
  278. package/dist/shared/utils/coordinates.d.ts +30 -4
  279. package/dist/shared/utils/coordinates.js +56 -10
  280. package/dist/shared/utils/event-emitter.d.ts +1 -262
  281. package/dist/shared/utils/event-emitter.js +4 -3
  282. package/dist/shared/utils/feature-bbox.js +8 -7
  283. package/dist/shared/utils/feature-segments.js +5 -4
  284. package/dist/shared/utils/image.d.ts +0 -4
  285. package/dist/shared/utils/image.js +0 -6
  286. package/dist/shared/utils/name-generator.d.ts +14 -20
  287. package/dist/shared/utils/name-generator.js +20 -3
  288. package/dist/shared/utils/pixel-ratio.d.ts +9 -3
  289. package/dist/shared/utils/pixel-ratio.js +13 -4
  290. package/dist/shared/utils/property.d.ts +7 -50
  291. package/dist/shared/utils/property.js +22 -87
  292. package/dist/snapping/custom-targets.js +21 -4
  293. package/dist/snapping/indicator.js +20 -11
  294. package/dist/snapping/providers/display.d.ts +6 -1
  295. package/dist/snapping/providers/display.js +2 -1
  296. package/dist/snapping/providers/guide.d.ts +3 -43
  297. package/dist/snapping/providers/guide.js +1 -44
  298. package/dist/snapping/providers/intersection.js +1 -1
  299. package/dist/snapping/providers/store.js +3 -3
  300. package/dist/snapping/service.js +18 -7
  301. package/dist/snapping/types.d.ts +9 -35
  302. package/dist/store/draw-store.js +233 -142
  303. package/dist/store/local-visibility.d.ts +11 -6
  304. package/dist/store/local-visibility.js +38 -7
  305. package/dist/store/lock.d.ts +0 -6
  306. package/dist/store/lock.js +0 -6
  307. package/dist/store/memory/change-bus.d.ts +3 -3
  308. package/dist/store/memory/change-bus.js +12 -0
  309. package/dist/store/memory/file-store.d.ts +2 -2
  310. package/dist/store/memory/ui-state.d.ts +1 -51
  311. package/dist/store/memory/ui-state.js +122 -134
  312. package/dist/store/memory.d.ts +1 -8
  313. package/dist/store/memory.js +249 -45
  314. package/dist/store/ordering.d.ts +9 -0
  315. package/dist/store/ordering.js +17 -0
  316. package/dist/store/spatial/spatial-index.d.ts +1 -1
  317. package/dist/store/spatial/spatial-index.js +1 -1
  318. package/dist/store/spatial/store-spatial-index.d.ts +3 -1
  319. package/dist/store/spatial/store-spatial-index.js +9 -3
  320. package/dist/store/store.d.ts +66 -107
  321. package/dist/store/types.d.ts +1 -1
  322. package/dist/store/writable-layer.d.ts +1 -1
  323. package/dist/store/writable-layer.js +2 -2
  324. package/dist/table/builder.d.ts +83 -0
  325. package/dist/table/builder.js +381 -0
  326. package/dist/table/index.d.ts +37 -0
  327. package/dist/table/index.js +5 -0
  328. package/dist/table/packed-rtree.d.ts +1 -0
  329. package/dist/{display → table}/packed-rtree.js +1 -1
  330. package/dist/table/partition.d.ts +1 -0
  331. package/dist/{display → table}/partition.js +3 -3
  332. package/dist/table/prepare.d.ts +44 -0
  333. package/dist/table/prepare.js +136 -0
  334. package/dist/table/table.d.ts +1 -0
  335. package/dist/{display/columnar → table}/table.js +29 -25
  336. package/dist/{display/columnar → table}/types.d.ts +68 -72
  337. package/dist/table/types.js +3 -0
  338. package/dist/view/coordinator.js +4 -3
  339. package/dist/view/feature-companion.d.ts +13 -7
  340. package/dist/view/feature-companion.js +11 -3
  341. package/dist/view/globe-subdivision.js +3 -3
  342. package/dist/view/layer/attach.d.ts +12 -6
  343. package/dist/view/layer/attach.js +86 -10
  344. package/dist/view/layer/custom-layer.js +40 -11
  345. package/dist/view/layer/display-list.js +2 -1
  346. package/dist/view/layer/drape-planner.d.ts +2 -2
  347. package/dist/view/layer/frame-render.d.ts +3 -3
  348. package/dist/view/layer/frame-render.js +7 -2
  349. package/dist/view/layer/frame-state.d.ts +6 -6
  350. package/dist/view/layer/index.d.ts +2 -2
  351. package/dist/view/layer/index.js +1 -1
  352. package/dist/view/layer/render.d.ts +4 -4
  353. package/dist/view/layer/render.js +3 -8
  354. package/dist/view/layer/renderers.d.ts +2 -2
  355. package/dist/view/layer/renderers.js +1 -1
  356. package/dist/view/layer/slot-manager.d.ts +2 -2
  357. package/dist/view/layer/slot-manager.js +4 -4
  358. package/dist/view/layer/slots.d.ts +2 -2
  359. package/dist/view/layer/slots.js +1 -1
  360. package/dist/view/layer/store-retained-bbox.js +3 -2
  361. package/dist/view/layer/store-retained-classify.d.ts +5 -7
  362. package/dist/view/layer/store-retained-classify.js +19 -7
  363. package/dist/view/layer/store-retained-collect.js +8 -7
  364. package/dist/view/layer/store-retained-coord-patch.d.ts +0 -8
  365. package/dist/view/layer/store-retained-coord-patch.js +13 -4
  366. package/dist/view/layer/store-retained-immediate.d.ts +3 -3
  367. package/dist/view/layer/store-retained-immediate.js +3 -8
  368. package/dist/view/layer/store-retained-invalidation.d.ts +2 -2
  369. package/dist/view/layer/store-retained.d.ts +2 -2
  370. package/dist/view/layer/store-retained.js +1 -1
  371. package/dist/view/renderers/batch-manager.js +8 -7
  372. package/dist/view/renderers/drawer.js +21 -15
  373. package/dist/view/renderers/image.js +13 -39
  374. package/dist/view/renderers/line/line-types.d.ts +3 -3
  375. package/dist/view/renderers/line/sdf-line.js +3 -1
  376. package/dist/view/renderers/point/billboard-depth.js +1 -1
  377. package/dist/view/renderers/point/point-instance.js +1 -1
  378. package/dist/view/renderers/point/point-shape.js +2 -2
  379. package/dist/view/renderers/point/point-style.js +48 -4
  380. package/dist/view/renderers/polygon/batch.js +1 -2
  381. package/dist/view/renderers/polygon/fill.js +3 -1
  382. package/dist/view/renderers/polygon/sdf-polygon.js +2 -3
  383. package/dist/view/renderers/polygon/triangulator.d.ts +1 -1
  384. package/dist/view/renderers/stroke.js +3 -1
  385. package/dist/view/shaders/helpers.d.ts +2 -42
  386. package/dist/view/shaders/helpers.js +0 -6
  387. package/dist/view/shaders/projection.d.ts +15 -7
  388. package/dist/view/shaders/projection.js +23 -6
  389. package/dist/view/shaders/quad.d.ts +16 -12
  390. package/dist/view/shaders/quad.js +34 -13
  391. package/dist/view/style-rule.d.ts +5 -42
  392. package/dist/view/style-rule.js +20 -44
  393. package/dist/view/terrain/binding.d.ts +1 -0
  394. package/dist/view/terrain/binding.js +29 -0
  395. package/dist/view/terrain/context.d.ts +3 -4
  396. package/dist/view/terrain/context.js +4 -5
  397. package/dist/view/terrain/drape/geometry.js +1 -1
  398. package/dist/view/terrain/drape/pass.d.ts +1 -1
  399. package/dist/view/terrain/drape/pass.js +8 -7
  400. package/dist/view/terrain/polygon.d.ts +9 -5
  401. package/dist/view/terrain/polygon.js +16 -2
  402. package/dist/view/terrain/state.d.ts +1 -1
  403. package/dist/view/terrain/state.js +1 -1
  404. package/dist/view/terrain/tessellation.d.ts +2 -2
  405. package/dist/view/terrain/tessellation.js +1 -1
  406. package/dist/view/ui/auxiliary-handles.d.ts +6 -29
  407. package/dist/view/ui/bounds.js +8 -12
  408. package/dist/view/ui/handle-test.js +2 -2
  409. package/dist/view/ui/handle-thinning.js +17 -17
  410. package/dist/view/ui/handles.js +21 -13
  411. package/dist/view/ui/helper.d.ts +1 -1
  412. package/dist/view/ui/helper.js +1 -1
  413. package/dist/view/ui/index.d.ts +1 -1
  414. package/dist/view/ui/selection-scope.js +4 -2
  415. package/dist/view/ui/selection-ui/bounding-box.js +6 -6
  416. package/dist/view/ui/selection-ui/extension-registry.d.ts +31 -20
  417. package/dist/view/ui/selection-ui/extension-registry.js +70 -7
  418. package/dist/view/ui/selection-ui/index.d.ts +2 -2
  419. package/dist/view/ui/selection-ui/index.js +1 -1
  420. package/dist/view/ui/selection-ui/renderer.js +15 -38
  421. package/dist/view/ui/selection-ui/types.d.ts +17 -2
  422. package/dist/view/ui/selection-ui-drawer.d.ts +8 -0
  423. package/dist/view/ui/selection-ui-drawer.js +63 -2
  424. package/dist/view/ui/tentative.js +1 -1
  425. package/dist/webgl/index.d.ts +65 -0
  426. package/dist/webgl/index.js +62 -0
  427. package/package.json +38 -15
  428. package/dist/api/api.d.ts +0 -1259
  429. package/dist/api/api.js +0 -86
  430. package/dist/api/context.d.ts +0 -173
  431. package/dist/api/display-api.js +0 -23
  432. package/dist/api/event-api.d.ts +0 -13
  433. package/dist/api/event-api.js +0 -17
  434. package/dist/api/extension-api.d.ts +0 -46
  435. package/dist/api/extension-api.js +0 -85
  436. package/dist/api/feature-api.d.ts +0 -11
  437. package/dist/api/feature-api.js +0 -101
  438. package/dist/api/geometry/apply.d.ts +0 -51
  439. package/dist/api/geometry/boolean.d.ts +0 -28
  440. package/dist/api/geometry/boolean.js +0 -65
  441. package/dist/api/geometry/types.d.ts +0 -31
  442. package/dist/api/geometry-operations.d.ts +0 -162
  443. package/dist/api/geometry-operations.js +0 -94
  444. package/dist/api/group-api.d.ts +0 -10
  445. package/dist/api/group-api.js +0 -78
  446. package/dist/api/import-export/constants.d.ts +0 -29
  447. package/dist/api/import-export/constants.js +0 -40
  448. package/dist/api/import-export/file-name.d.ts +0 -10
  449. package/dist/api/import-export/file-name.js +0 -20
  450. package/dist/api/import-export/geojson-export.d.ts +0 -19
  451. package/dist/api/import-export/image-import.d.ts +0 -12
  452. package/dist/api/import-export/image-import.js +0 -53
  453. package/dist/api/import-export/index.d.ts +0 -9
  454. package/dist/api/import-export/index.js +0 -107
  455. package/dist/api/import-export/native-format.d.ts +0 -15
  456. package/dist/api/import-export/style-validation.d.ts +0 -27
  457. package/dist/api/import-export/style-validation.js +0 -49
  458. package/dist/api/import-export/types.d.ts +0 -26
  459. package/dist/api/index.d.ts +0 -15
  460. package/dist/api/index.js +0 -3
  461. package/dist/api/input-api.d.ts +0 -158
  462. package/dist/api/input-api.js +0 -144
  463. package/dist/api/instance-api.d.ts +0 -38
  464. package/dist/api/instance-api.js +0 -136
  465. package/dist/api/layer-api.d.ts +0 -12
  466. package/dist/api/layer-api.js +0 -62
  467. package/dist/api/selection-api.d.ts +0 -7
  468. package/dist/api/selection-api.js +0 -78
  469. package/dist/api/snapping-api.d.ts +0 -125
  470. package/dist/api/snapping-api.js +0 -50
  471. package/dist/api/topology-api.d.ts +0 -30
  472. package/dist/api/topology-api.js +0 -16
  473. package/dist/api/tracing-api.d.ts +0 -31
  474. package/dist/api/tracing-api.js +0 -16
  475. package/dist/dispatcher/hit-test/index.d.ts +0 -14
  476. package/dist/dispatcher/hit-test/index.js +0 -9
  477. package/dist/dispatcher/index.d.ts +0 -15
  478. package/dist/dispatcher/index.js +0 -3
  479. package/dist/display/columnar/index.d.ts +0 -12
  480. package/dist/display/columnar/index.js +0 -13
  481. package/dist/display/columnar/prepare.d.ts +0 -42
  482. package/dist/display/columnar/prepare.js +0 -116
  483. package/dist/display/index.d.ts +0 -13
  484. package/dist/display/types.js +0 -43
  485. package/dist/maplibre-gl-draw.d.ts +0 -47
  486. package/dist/modes/cursor.js +0 -72
  487. package/dist/modes/index.d.ts +0 -7
  488. package/dist/operations/index.d.ts +0 -9
  489. package/dist/operations/index.js +0 -3
  490. package/dist/plugins/index.d.ts +0 -10
  491. package/dist/plugins/mutation-hooks.d.ts +0 -28
  492. package/dist/plugins/mutation-hooks.js +0 -84
  493. package/dist/plugins/plugin-context.js +0 -367
  494. package/dist/plugins/plugin-manager.d.ts +0 -103
  495. package/dist/plugins/plugin-manager.js +0 -316
  496. package/dist/plugins/plugin.d.ts +0 -529
  497. package/dist/shared/config/index.d.ts +0 -17
  498. package/dist/shared/config/index.js +0 -8
  499. package/dist/shared/utils/index.d.ts +0 -15
  500. package/dist/shared/utils/index.js +0 -24
  501. package/dist/snapping/index.d.ts +0 -14
  502. package/dist/snapping/index.js +0 -4
  503. package/dist/store/change-merger.js +0 -102
  504. package/dist/store/event-bridge.js +0 -161
  505. package/dist/store/index.d.ts +0 -12
  506. package/dist/store/index.js +0 -4
  507. package/dist/view/index.d.ts +0 -47
  508. package/dist/view/index.js +0 -20
  509. /package/dist/api/{geometry/types.js → datasets.js} +0 -0
  510. /package/dist/api/{import-export/types.js → document.js} +0 -0
  511. /package/dist/{display/columnar/types.js → api/drawing.js} +0 -0
  512. /package/dist/{display/index.js → api/events.js} +0 -0
  513. /package/dist/{modes/index.js → api/extension/context.js} +0 -0
  514. /package/dist/{plugins/index.js → api/extension/feature-type.js} +0 -0
  515. /package/dist/{plugins/plugin.js → api/extension/mode.js} +0 -0
  516. /package/dist/api/{display-api.d.ts → impl/adapters.d.ts} +0 -0
  517. /package/dist/{display/columnar/source.d.ts → api/impl/contexts.d.ts} +0 -0
  518. /package/dist/{display/columnar/table.d.ts → api/impl/create-draw.d.ts} +0 -0
  519. /package/dist/{display/interaction.d.ts → api/impl/datasets.d.ts} +0 -0
  520. /package/dist/{display/manager.d.ts → api/impl/destroy-guard.d.ts} +0 -0
  521. /package/dist/{display/packed-rtree.d.ts → api/impl/document.d.ts} +0 -0
  522. /package/dist/{display/partition.d.ts → api/impl/drawing.d.ts} +0 -0
  523. /package/dist/{display/provider.d.ts → api/impl/engine.d.ts} +0 -0
  524. /package/dist/{display/source.d.ts → api/impl/events.d.ts} +0 -0
  525. /package/dist/{display/spatial.d.ts → api/impl/extension-host.d.ts} +0 -0
  526. /package/dist/{display/style.d.ts → api/impl/extensions.d.ts} +0 -0
  527. /package/dist/{display/triangulation.d.ts → api/impl/features.d.ts} +0 -0
  528. /package/dist/{modes/cursor.d.ts → api/impl/geometry/types.d.ts} +0 -0
  529. /package/dist/{plugins/plugin-context.d.ts → api/impl/hidden.d.ts} +0 -0
  530. /package/dist/api/{import-export → impl/import-export}/embedded-file.d.ts +0 -0
  531. /package/dist/api/{import-export → impl/import-export}/own-property.d.ts +0 -0
  532. /package/dist/api/{import-export → impl/import-export}/own-property.js +0 -0
  533. /package/dist/{store/change-merger.d.ts → api/impl/input.d.ts} +0 -0
  534. /package/dist/{store/event-bridge.d.ts → api/impl/layers.d.ts} +0 -0
  535. /package/dist/{display → dataset}/chunk-set.d.ts +0 -0
  536. /package/dist/{display → dataset}/chunk-set.js +0 -0
  537. /package/dist/{display → dataset}/dataset.d.ts +0 -0
  538. /package/dist/{display → dataset}/manager.js +0 -0
  539. /package/dist/{display → dataset}/provider.js +0 -0
  540. /package/dist/{display → dataset}/selection.d.ts +0 -0
  541. /package/dist/{display → dataset}/selection.js +0 -0
@@ -0,0 +1,405 @@
1
+ // SPDX-FileCopyrightText: 2026 SAKAIDA Atsushi
2
+ // SPDX-License-Identifier: AGPL-3.0-only
3
+ import { DrawError } from '../errors.js';
4
+ import { describeStyleProblem } from './import-export/style-validation.js';
5
+ import { toBBox, toBoundingBox, toDatasetRow } from './rows.js';
6
+ import { invalidInput, isRecord, notFound, onlyKeys, optionalIndex, requireId, requireIds, } from './shared.js';
7
+ /**
8
+ * The range a query of the rows takes: a `BBox` of four or six finite numbers (it is required,
9
+ * so a call without one is an invalid input rather than a TypeError from deep inside)
10
+ */
11
+ function requireBBox(bbox) {
12
+ if (!Array.isArray(bbox) ||
13
+ (bbox.length !== 4 && bbox.length !== 6) ||
14
+ bbox.some((value) => typeof value !== 'number' || !Number.isFinite(value))) {
15
+ throw invalidInput('bbox must be [west, south, east, north] in degrees');
16
+ }
17
+ return bbox;
18
+ }
19
+ const ORDERS = ['below-store', 'above-store', 'layer-order'];
20
+ const OPTION_KEYS = [
21
+ 'id',
22
+ 'rows',
23
+ 'table',
24
+ 'provider',
25
+ 'styleRule',
26
+ 'baseStyle',
27
+ 'interactive',
28
+ 'order',
29
+ 'zoomScale',
30
+ 'collisionThinning',
31
+ 'externalPointRender',
32
+ ];
33
+ /** The names of the events of a dataset of the engine for those of the API */
34
+ const EVENT_NAMES = {
35
+ clicked: 'click',
36
+ hovered: 'hover',
37
+ changed: 'change',
38
+ };
39
+ // ============================================================================
40
+ // Checks
41
+ // ============================================================================
42
+ function checkBaseStyle(value) {
43
+ if (value === undefined)
44
+ return;
45
+ if (!isRecord(value))
46
+ throw invalidInput('baseStyle must be an object');
47
+ onlyKeys(value, ['point', 'stroke', 'fill'], 'baseStyle');
48
+ for (const [key, style] of Object.entries(value)) {
49
+ if (style === undefined)
50
+ continue;
51
+ const problem = describeStyleProblem(style);
52
+ if (problem)
53
+ throw invalidInput(`baseStyle.${key} is ${problem}`);
54
+ }
55
+ }
56
+ function checkThinning(value) {
57
+ if (value === undefined || value === null)
58
+ return;
59
+ if (!isRecord(value))
60
+ throw invalidInput('collisionThinning must be an object');
61
+ onlyKeys(value, ['enabled', 'fullDisplayZoom', 'marginPx'], 'collisionThinning');
62
+ if (value.enabled !== undefined && typeof value.enabled !== 'boolean') {
63
+ throw invalidInput('collisionThinning.enabled must be a boolean');
64
+ }
65
+ for (const key of ['fullDisplayZoom', 'marginPx']) {
66
+ const number = value[key];
67
+ if (number !== undefined && (typeof number !== 'number' || !Number.isFinite(number))) {
68
+ throw invalidInput(`collisionThinning.${key} must be a number`);
69
+ }
70
+ }
71
+ }
72
+ function checkFunction(value, what) {
73
+ if (value !== undefined && typeof value !== 'function') {
74
+ throw invalidInput(`${what} must be a function`);
75
+ }
76
+ }
77
+ function checkRows(value) {
78
+ if (!Array.isArray(value) || value.some((row) => !isRecord(row))) {
79
+ throw invalidInput('The rows must be an array of GeoJSON features');
80
+ }
81
+ }
82
+ function checkTable(value) {
83
+ if (!isRecord(value))
84
+ throw invalidInput('The table must be a table or a prepared table');
85
+ }
86
+ /** Checks what `datasets.add` takes */
87
+ function checkOptions(options) {
88
+ if (!isRecord(options))
89
+ throw invalidInput('The options of a dataset must be an object');
90
+ onlyKeys(options, OPTION_KEYS, 'The options of a dataset');
91
+ requireId(options.id);
92
+ const sources = ['rows', 'table', 'provider'].filter((key) => options[key] !== undefined);
93
+ if (sources.length > 1) {
94
+ throw invalidInput('A dataset takes at most one of rows, table and provider');
95
+ }
96
+ if (options.rows !== undefined)
97
+ checkRows(options.rows);
98
+ if (options.table !== undefined)
99
+ checkTable(options.table);
100
+ checkFunction(options.provider, 'provider');
101
+ if (options.styleRule !== undefined && !isRecord(options.styleRule)) {
102
+ throw invalidInput('styleRule must be an object');
103
+ }
104
+ checkBaseStyle(options.baseStyle);
105
+ if (options.interactive !== undefined && typeof options.interactive !== 'boolean') {
106
+ throw invalidInput('interactive must be a boolean');
107
+ }
108
+ if (options.order !== undefined && !ORDERS.includes(options.order)) {
109
+ throw invalidInput(`order must be one of ${ORDERS.join(', ')}`);
110
+ }
111
+ checkFunction(options.zoomScale, 'zoomScale');
112
+ checkThinning(options.collisionThinning);
113
+ checkFunction(options.externalPointRender, 'externalPointRender');
114
+ }
115
+ /** Checks where a dataset goes */
116
+ function checkPlacement(placement) {
117
+ if (!isRecord(placement))
118
+ throw invalidInput('The placement must be an object');
119
+ onlyKeys(placement, ['order', 'index'], 'The placement');
120
+ if (placement.order !== undefined && !ORDERS.includes(placement.order)) {
121
+ throw invalidInput(`order must be one of ${ORDERS.join(', ')}`);
122
+ }
123
+ optionalIndex(placement.index);
124
+ return placement;
125
+ }
126
+ // ============================================================================
127
+ // The conversions
128
+ // ============================================================================
129
+ /** A predicate on rows as a predicate on the features of the engine */
130
+ function onFeatures(predicate) {
131
+ return predicate ? (feature) => predicate(toDatasetRow(feature)) : undefined;
132
+ }
133
+ /** The options of the engine for the options of the API */
134
+ function toEngineOptions(options) {
135
+ const result = { id: options.id };
136
+ if ('rows' in options && options.rows !== undefined) {
137
+ result.rows = options.rows;
138
+ }
139
+ if ('table' in options && options.table !== undefined)
140
+ result.table = options.table;
141
+ if ('provider' in options && options.provider !== undefined) {
142
+ const provider = options.provider;
143
+ result.provider = async (bounds, zoom) => (await provider(toBBox(bounds), zoom));
144
+ }
145
+ if (options.styleRule !== undefined)
146
+ result.styleRule = options.styleRule;
147
+ if (options.baseStyle !== undefined)
148
+ result.baseStyle = options.baseStyle;
149
+ if (options.interactive !== undefined)
150
+ result.interactive = options.interactive;
151
+ if (options.order !== undefined)
152
+ result.order = options.order;
153
+ if (options.zoomScale !== undefined)
154
+ result.zoomScale = options.zoomScale;
155
+ if (options.collisionThinning !== undefined) {
156
+ result.collisionThinning = options.collisionThinning;
157
+ }
158
+ if (options.externalPointRender !== undefined) {
159
+ result.externalPointRender = onFeatures(options.externalPointRender);
160
+ }
161
+ return result;
162
+ }
163
+ /** A point on the screen of a payload of the engine */
164
+ function toScreenPoint(point) {
165
+ return point ? [point.x, point.y] : [Number.NaN, Number.NaN];
166
+ }
167
+ function toClicked(payload) {
168
+ return {
169
+ datasetId: payload.datasetId,
170
+ rowIndex: payload.row,
171
+ row: toDatasetRow(payload.feature),
172
+ lngLat: [payload.lngLat[0], payload.lngLat[1]],
173
+ point: toScreenPoint(payload.point),
174
+ };
175
+ }
176
+ function toHovered(payload) {
177
+ return {
178
+ datasetId: payload.datasetId,
179
+ rowIndex: payload.row,
180
+ row: payload.feature ? toDatasetRow(payload.feature) : null,
181
+ lngLat: [payload.lngLat[0], payload.lngLat[1]],
182
+ point: toScreenPoint(payload.point),
183
+ };
184
+ }
185
+ function toChanged(payload) {
186
+ return { reason: payload.reason === 'features' ? 'rows' : payload.reason };
187
+ }
188
+ // ============================================================================
189
+ // Dataset
190
+ // ============================================================================
191
+ /**
192
+ * A dataset of the API over a dataset of the engine
193
+ *
194
+ * @internal
195
+ */
196
+ export function wrapDataset(dataset) {
197
+ /** The handlers given to the engine, by event and listener, so that off finds them */
198
+ const handlers = new Map();
199
+ const on = (event, listener) => {
200
+ const name = EVENT_NAMES[event];
201
+ if (!name)
202
+ throw invalidInput(`There is no event ${JSON.stringify(event)} of a dataset`);
203
+ if (typeof listener !== 'function')
204
+ throw invalidInput('The listener must be a function');
205
+ const convert = (payload) => {
206
+ if (event === 'clicked')
207
+ return toClicked(payload);
208
+ if (event === 'hovered')
209
+ return toHovered(payload);
210
+ return toChanged(payload);
211
+ };
212
+ const handler = (payload) => listener(convert(payload));
213
+ const byListener = handlers.get(event) ?? new Map();
214
+ handlers.set(event, byListener);
215
+ const previous = byListener.get(listener);
216
+ if (previous)
217
+ dataset.off(name, previous);
218
+ byListener.set(listener, handler);
219
+ dataset.on(name, handler);
220
+ return () => off(event, listener);
221
+ };
222
+ const off = (event, listener) => {
223
+ const name = EVENT_NAMES[event];
224
+ const handler = handlers.get(event)?.get(listener);
225
+ if (!name || !handler)
226
+ return;
227
+ handlers.get(event)?.delete(listener);
228
+ dataset.off(name, handler);
229
+ };
230
+ return {
231
+ get id() {
232
+ return dataset.id;
233
+ },
234
+ get order() {
235
+ return dataset.order;
236
+ },
237
+ get interactive() {
238
+ return dataset.interactive;
239
+ },
240
+ get visible() {
241
+ return dataset.visible;
242
+ },
243
+ setVisible(visible) {
244
+ if (typeof visible !== 'boolean')
245
+ throw invalidInput('visible must be a boolean');
246
+ dataset.setVisible(visible);
247
+ },
248
+ setRows(rows) {
249
+ checkRows(rows);
250
+ dataset.setRows(rows);
251
+ },
252
+ setTable(table) {
253
+ checkTable(table);
254
+ dataset.setTable(table);
255
+ },
256
+ setStyleRule(rule) {
257
+ if (rule !== undefined && !isRecord(rule))
258
+ throw invalidInput('The rule must be an object');
259
+ dataset.setStyleRule(rule);
260
+ },
261
+ getStyleRule: () => dataset.getStyleRule(),
262
+ setZoomScale(zoomScale) {
263
+ if (zoomScale !== null)
264
+ checkFunction(zoomScale, 'zoomScale');
265
+ dataset.setZoomScale(zoomScale ?? null);
266
+ },
267
+ getZoomScale: () => dataset.getZoomScale(),
268
+ setBaseStyle(style) {
269
+ checkBaseStyle(style);
270
+ dataset.setBaseStyle(style);
271
+ },
272
+ setExternalPointRender(predicate) {
273
+ checkFunction(predicate, 'The predicate');
274
+ dataset.setExternalPointRender(onFeatures(predicate));
275
+ },
276
+ getBaseStyle: () => dataset.getBaseStyle(),
277
+ listRows: () => dataset.getFeatures().map(toDatasetRow),
278
+ listVisibleRows: (bbox) => dataset.collectVisible(toBoundingBox(requireBBox(bbox))).map(toDatasetRow),
279
+ listDrawnRows: (bbox) => dataset.collectDrawnRows(toBoundingBox(requireBBox(bbox))),
280
+ getRow(index) {
281
+ const feature = dataset.getRow(index);
282
+ return feature ? toDatasetRow(feature) : undefined;
283
+ },
284
+ getRowId: (index) => dataset.getRowId(index),
285
+ getRowType: (index) => dataset.getRowType(index),
286
+ getRowBounds(index) {
287
+ const bounds = dataset.getRowBounds(index);
288
+ return bounds ? toBBox(bounds) : null;
289
+ },
290
+ getRowPoint(index) {
291
+ const point = dataset.getRowPoint(index);
292
+ return point ? [point[0], point[1]] : null;
293
+ },
294
+ findRow: (id) => dataset.findRow(id),
295
+ setSelectedRowIds(ids) {
296
+ dataset.setSelectedIds(requireIds(ids));
297
+ },
298
+ getSelectedRowIds: () => dataset.getSelectedIds(),
299
+ setCollisionThinning(options) {
300
+ checkThinning(options);
301
+ dataset.setCollisionThinning(options ?? null);
302
+ },
303
+ getCollisionThinning() {
304
+ const thinning = dataset.getCollisionThinning();
305
+ return thinning ? { ...thinning } : null;
306
+ },
307
+ listVisibleRowIds: () => dataset.getVisibleFeatureIds(),
308
+ getThinningStats: () => dataset.getThinningStats(),
309
+ getDrawnRowsRevision: () => dataset.getDrawnRowsRevision(),
310
+ refresh: () => dataset.invalidateProviderCache(),
311
+ on,
312
+ off,
313
+ };
314
+ }
315
+ // ============================================================================
316
+ // draw.datasets
317
+ // ============================================================================
318
+ /**
319
+ * Creates `draw.datasets` and announces the datasets that come, go and move as events
320
+ *
321
+ * @param manager - The dataset manager of the engine
322
+ * @param events - The emitter of the events of the instance
323
+ * @param signals - The internal emitter the manager announces the datasets on
324
+ * @internal
325
+ */
326
+ export function createDatasets(manager, events, signals) {
327
+ const wrappers = new WeakMap();
328
+ const wrap = (dataset) => {
329
+ let wrapper = wrappers.get(dataset);
330
+ if (!wrapper) {
331
+ wrapper = wrapDataset(dataset);
332
+ wrappers.set(dataset, wrapper);
333
+ }
334
+ return wrapper;
335
+ };
336
+ let order = manager.list().map((dataset) => dataset.id);
337
+ signals.on('dataset.add', ({ datasetId }) => {
338
+ order = manager.list().map((dataset) => dataset.id);
339
+ const dataset = manager.get(datasetId);
340
+ if (dataset)
341
+ events.emit('dataset.added', { dataset: wrap(dataset) });
342
+ });
343
+ signals.on('dataset.remove', ({ datasetId }) => {
344
+ order = manager.list().map((dataset) => dataset.id);
345
+ events.emit('dataset.removed', { datasetId });
346
+ });
347
+ signals.on('dataset.reorder', ({ order: next }) => {
348
+ const previous = order;
349
+ order = [...next];
350
+ events.emit('dataset.reordered', { order: [...next], previous });
351
+ });
352
+ const require = (id) => {
353
+ const dataset = manager.get(requireId(id));
354
+ if (!dataset)
355
+ throw notFound('dataset', id);
356
+ return dataset;
357
+ };
358
+ const checkNew = (options, taken) => {
359
+ checkOptions(options);
360
+ if (manager.get(options.id) || taken.has(options.id)) {
361
+ throw new DrawError('already-exists', `A dataset with the ID ${options.id} exists`, {
362
+ id: options.id,
363
+ });
364
+ }
365
+ taken.add(options.id);
366
+ return options;
367
+ };
368
+ const collection = {
369
+ get(id) {
370
+ const dataset = manager.get(requireId(id));
371
+ return dataset ? wrap(dataset) : undefined;
372
+ },
373
+ list: () => manager.list().map(wrap),
374
+ count: () => manager.list().length,
375
+ has: (id) => manager.get(requireId(id)) !== undefined,
376
+ add(options) {
377
+ const checked = checkNew(options, new Set());
378
+ return wrap(manager.add(toEngineOptions(checked)));
379
+ },
380
+ addMany(options) {
381
+ if (!Array.isArray(options))
382
+ throw invalidInput('The options must be an array');
383
+ const taken = new Set();
384
+ const checked = options.map((entry) => checkNew(entry, taken));
385
+ return checked.map((entry) => wrap(manager.add(toEngineOptions(entry))));
386
+ },
387
+ remove(id) {
388
+ require(id);
389
+ return manager.remove(id);
390
+ },
391
+ removeMany(ids) {
392
+ const unique = requireIds(ids);
393
+ for (const id of unique)
394
+ require(id);
395
+ for (const id of unique)
396
+ manager.remove(id);
397
+ return true;
398
+ },
399
+ move(id, placement) {
400
+ require(id);
401
+ return manager.move(id, checkPlacement(placement));
402
+ },
403
+ };
404
+ return collection;
405
+ }
@@ -0,0 +1,74 @@
1
+ // SPDX-FileCopyrightText: 2026 SAKAIDA Atsushi
2
+ // SPDX-License-Identifier: AGPL-3.0-only
3
+ /**
4
+ * The guard of a destroyed instance: once `destroy()` has run, every method of the draw instance
5
+ * and of its collections throws `DrawError('invalid-state')` instead of reaching an engine that
6
+ * has released everything
7
+ */
8
+ import { DrawError } from '../errors.js';
9
+ /** The error of a call made after destroy */
10
+ function destroyedError(path) {
11
+ return new DrawError('invalid-state', `The draw instance is destroyed: ${path} cannot be called`, {
12
+ member: path,
13
+ });
14
+ }
15
+ /** Whether the value is a plain object whose members are guarded in turn */
16
+ function isPlainObject(value) {
17
+ if (typeof value !== 'object' || value === null || Array.isArray(value))
18
+ return false;
19
+ const prototype = Object.getPrototypeOf(value);
20
+ return prototype === Object.prototype || prototype === null;
21
+ }
22
+ /**
23
+ * Copies an object with every method (at any depth of plain objects) guarded: a call after
24
+ * `isDestroyed()` turned true throws `DrawError('invalid-state')`, or rejects with it for a
25
+ * method that returns a promise. A getter is guarded the same way.
26
+ *
27
+ * @param target - The object to guard
28
+ * @param isDestroyed - Whether the instance is destroyed
29
+ * @param options - `asyncMembers` names the methods (by their path, such as `document.load`)
30
+ * that reject instead of throwing; `skip` names the members that are copied unguarded
31
+ * @internal
32
+ */
33
+ export function guardAfterDestroy(target, isDestroyed, options = {}, prefix = '') {
34
+ const guarded = {};
35
+ for (const [key, descriptor] of Object.entries(Object.getOwnPropertyDescriptors(target))) {
36
+ const path = `${prefix}${key}`;
37
+ if (options.skip?.has(path)) {
38
+ Object.defineProperty(guarded, key, descriptor);
39
+ continue;
40
+ }
41
+ if (descriptor.get) {
42
+ const get = descriptor.get;
43
+ Object.defineProperty(guarded, key, {
44
+ enumerable: descriptor.enumerable,
45
+ get() {
46
+ if (isDestroyed())
47
+ throw destroyedError(path);
48
+ return get.call(target);
49
+ },
50
+ });
51
+ continue;
52
+ }
53
+ const value = descriptor.value;
54
+ if (typeof value === 'function') {
55
+ const rejects = options.asyncMembers?.has(path) === true;
56
+ guarded[key] = (...args) => {
57
+ if (isDestroyed()) {
58
+ const error = destroyedError(path);
59
+ if (rejects)
60
+ return Promise.reject(error);
61
+ throw error;
62
+ }
63
+ return value.apply(target, args);
64
+ };
65
+ }
66
+ else if (isPlainObject(value)) {
67
+ guarded[key] = guardAfterDestroy(value, isDestroyed, options, `${path}.`);
68
+ }
69
+ else {
70
+ guarded[key] = value;
71
+ }
72
+ }
73
+ return guarded;
74
+ }