@sakuzu/maplibre-gl-draw 1.0.0 → 2.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 (540) hide show
  1. package/CHANGELOG.md +1016 -2
  2. package/README.ja.md +39 -19
  3. package/README.md +41 -21
  4. package/dist/api/datasets.d.ts +258 -0
  5. package/dist/api/document.d.ts +66 -0
  6. package/dist/api/draw.d.ts +135 -0
  7. package/dist/api/draw.js +18 -0
  8. package/dist/api/drawing.d.ts +87 -0
  9. package/dist/api/errors.d.ts +35 -0
  10. package/dist/api/errors.js +35 -0
  11. package/dist/api/events.d.ts +306 -0
  12. package/dist/api/extension/context.d.ts +247 -0
  13. package/dist/api/extension/feature-type.d.ts +129 -0
  14. package/dist/api/extension/mode.d.ts +123 -0
  15. package/dist/api/extension/plugin.d.ts +51 -0
  16. package/dist/api/extension/plugin.js +3 -0
  17. package/dist/api/extension/provider.d.ts +119 -0
  18. package/dist/api/extension/provider.js +3 -0
  19. package/dist/api/extension/render.d.ts +176 -0
  20. package/dist/api/extension/render.js +3 -0
  21. package/dist/api/extension/store.d.ts +190 -0
  22. package/dist/api/extension/store.js +3 -0
  23. package/dist/api/extensions.d.ts +306 -0
  24. package/dist/api/extensions.js +3 -0
  25. package/dist/api/features.d.ts +188 -0
  26. package/dist/api/features.js +3 -0
  27. package/dist/api/groups.d.ts +111 -0
  28. package/dist/api/groups.js +3 -0
  29. package/dist/api/hidden.d.ts +45 -0
  30. package/dist/api/hidden.js +3 -0
  31. package/dist/api/impl/adapters.js +463 -0
  32. package/dist/api/impl/contexts.js +466 -0
  33. package/dist/api/impl/create-draw.js +124 -0
  34. package/dist/api/impl/datasets.js +404 -0
  35. package/dist/api/impl/destroy-guard.js +74 -0
  36. package/dist/api/impl/document.js +280 -0
  37. package/dist/api/impl/drawing.js +180 -0
  38. package/dist/api/impl/engine-context.d.ts +7 -0
  39. package/dist/api/{context.js → impl/engine-context.js} +49 -38
  40. package/dist/{maplibre-gl-draw.js → api/impl/engine.js} +145 -177
  41. package/dist/api/impl/events.js +422 -0
  42. package/dist/api/impl/extension-host.js +361 -0
  43. package/dist/api/impl/extensions.js +229 -0
  44. package/dist/api/impl/features.js +445 -0
  45. package/dist/api/impl/geometry/apply.d.ts +32 -0
  46. package/dist/api/{geometry → impl/geometry}/apply.js +10 -27
  47. package/dist/api/{geometry → impl/geometry}/buffer.d.ts +4 -3
  48. package/dist/api/{geometry → impl/geometry}/buffer.js +12 -23
  49. package/dist/api/{geometry → impl/geometry}/split.d.ts +4 -3
  50. package/dist/api/{geometry → impl/geometry}/split.js +10 -21
  51. package/dist/api/{geometry → impl/geometry}/targets.d.ts +2 -20
  52. package/dist/api/{geometry → impl/geometry}/targets.js +8 -35
  53. package/dist/api/impl/geometry/types.js +3 -0
  54. package/dist/api/impl/groups.d.ts +3 -0
  55. package/dist/api/impl/groups.js +268 -0
  56. package/dist/api/impl/hidden.js +60 -0
  57. package/dist/api/impl/import-export/constants.d.ts +22 -0
  58. package/dist/api/impl/import-export/constants.js +24 -0
  59. package/dist/api/{import-export → impl/import-export}/embedded-file.js +2 -2
  60. package/dist/api/{import-export → impl/import-export}/format-detection.d.ts +1 -1
  61. package/dist/api/{import-export → impl/import-export}/format-detection.js +2 -1
  62. package/dist/api/impl/import-export/geojson-export.d.ts +19 -0
  63. package/dist/api/{import-export → impl/import-export}/geojson-export.js +71 -104
  64. package/dist/api/{import-export → impl/import-export}/geojson-import.d.ts +11 -7
  65. package/dist/api/{import-export → impl/import-export}/geojson-import.js +139 -97
  66. package/dist/api/{import-export → impl/import-export}/geometry-validation.d.ts +14 -0
  67. package/dist/api/{import-export → impl/import-export}/geometry-validation.js +45 -0
  68. package/dist/api/impl/import-export/image-import.d.ts +16 -0
  69. package/dist/api/impl/import-export/image-import.js +73 -0
  70. package/dist/api/impl/import-export/legacy-image-style.d.ts +16 -0
  71. package/dist/api/impl/import-export/legacy-image-style.js +49 -0
  72. package/dist/api/impl/import-export/native-format.d.ts +14 -0
  73. package/dist/api/{import-export → impl/import-export}/native-format.js +32 -22
  74. package/dist/api/impl/import-export/native-upgrade.d.ts +8 -0
  75. package/dist/api/impl/import-export/native-upgrade.js +139 -0
  76. package/dist/api/{import-export → impl/import-export}/native-validation.d.ts +1 -1
  77. package/dist/api/{import-export → impl/import-export}/native-validation.js +15 -14
  78. package/dist/api/impl/import-export/style-validation.d.ts +24 -0
  79. package/dist/api/impl/import-export/style-validation.js +86 -0
  80. package/dist/api/impl/import-export/types.d.ts +52 -0
  81. package/dist/api/impl/import-export/types.js +3 -0
  82. package/dist/api/impl/input.js +180 -0
  83. package/dist/api/impl/layers.js +307 -0
  84. package/dist/api/impl/metadata.d.ts +1 -0
  85. package/dist/api/impl/metadata.js +22 -0
  86. package/dist/api/impl/options.d.ts +1 -0
  87. package/dist/api/impl/options.js +822 -0
  88. package/dist/api/impl/placement.d.ts +1 -0
  89. package/dist/api/impl/placement.js +138 -0
  90. package/dist/api/impl/render-context.d.ts +13 -0
  91. package/dist/api/impl/render-context.js +272 -0
  92. package/dist/api/impl/rows.d.ts +1 -0
  93. package/dist/api/impl/rows.js +46 -0
  94. package/dist/api/impl/selection.d.ts +1 -0
  95. package/dist/api/impl/selection.js +186 -0
  96. package/dist/api/impl/shared.d.ts +64 -0
  97. package/dist/api/impl/shared.js +178 -0
  98. package/dist/api/impl/validate-extension.d.ts +1 -0
  99. package/dist/api/impl/validate-extension.js +159 -0
  100. package/dist/api/layers.d.ts +130 -0
  101. package/dist/api/layers.js +3 -0
  102. package/dist/api/metadata.d.ts +18 -0
  103. package/dist/api/metadata.js +3 -0
  104. package/dist/api/model.d.ts +487 -0
  105. package/dist/api/model.js +47 -0
  106. package/dist/api/options.d.ts +466 -0
  107. package/dist/api/options.js +3 -0
  108. package/dist/api/selection.d.ts +94 -0
  109. package/dist/api/selection.js +3 -0
  110. package/dist/api/state.d.ts +155 -0
  111. package/dist/api/state.js +12 -0
  112. package/dist/{display → dataset}/chunk.d.ts +1 -1
  113. package/dist/{display → dataset}/chunk.js +4 -3
  114. package/dist/{display → dataset}/dataset.js +18 -21
  115. package/dist/dataset/interaction.d.ts +1 -0
  116. package/dist/{display → dataset}/interaction.js +18 -6
  117. package/dist/dataset/manager.d.ts +1 -0
  118. package/dist/dataset/provider.d.ts +1 -0
  119. package/dist/{display → dataset}/retained.d.ts +1 -1
  120. package/dist/{display → dataset}/retained.js +8 -7
  121. package/dist/dataset/source.d.ts +1 -0
  122. package/dist/{display → dataset}/source.js +17 -4
  123. package/dist/dataset/spatial.d.ts +1 -0
  124. package/dist/{display → dataset}/spatial.js +1 -1
  125. package/dist/dataset/style.d.ts +1 -0
  126. package/dist/{display → dataset}/style.js +1 -1
  127. package/dist/dataset/table-source.d.ts +1 -0
  128. package/dist/{display/columnar/source.js → dataset/table-source.js} +53 -25
  129. package/dist/{display → dataset}/thinning.d.ts +0 -10
  130. package/dist/{display → dataset}/thinning.js +3 -2
  131. package/dist/dataset/triangulation.d.ts +1 -0
  132. package/dist/{display → dataset}/triangulation.js +0 -0
  133. package/dist/{display → dataset}/types.d.ts +82 -121
  134. package/dist/dataset/types.js +61 -0
  135. package/dist/dispatcher/hit-test/box-strategies.js +13 -13
  136. package/dist/dispatcher/hit-test/box-strategy.d.ts +2 -15
  137. package/dist/dispatcher/hit-test/globe-shape.js +5 -4
  138. package/dist/dispatcher/hit-test/service.d.ts +17 -0
  139. package/dist/dispatcher/hit-test/service.js +80 -16
  140. package/dist/dispatcher/hit-test/strategies/base.d.ts +13 -19
  141. package/dist/dispatcher/hit-test/strategies/circle.js +3 -2
  142. package/dist/dispatcher/hit-test/strategies/image.js +6 -18
  143. package/dist/dispatcher/hit-test/strategies/line.d.ts +0 -6
  144. package/dist/dispatcher/hit-test/strategies/line.js +9 -2
  145. package/dist/dispatcher/hit-test/strategies/multi.d.ts +0 -8
  146. package/dist/dispatcher/hit-test/strategies/multi.js +17 -8
  147. package/dist/dispatcher/hit-test/strategies/point.d.ts +9 -7
  148. package/dist/dispatcher/hit-test/strategies/point.js +8 -4
  149. package/dist/dispatcher/hit-test/strategies/polygon.d.ts +0 -7
  150. package/dist/dispatcher/hit-test/strategies/polygon.js +11 -3
  151. package/dist/dispatcher/hit-test/topmost.d.ts +1 -1
  152. package/dist/dispatcher/input-router.js +152 -69
  153. package/dist/dispatcher/normalizer.js +6 -2
  154. package/dist/dispatcher/types.d.ts +6 -1
  155. package/dist/extension/feature-handler.d.ts +1 -182
  156. package/dist/extension/index.d.ts +4 -7
  157. package/dist/extension/renderers.d.ts +1 -208
  158. package/dist/geometry/angle.d.ts +0 -8
  159. package/dist/geometry/angle.js +0 -8
  160. package/dist/geometry/bbox.d.ts +4 -12
  161. package/dist/geometry/bbox.js +4 -12
  162. package/dist/geometry/boolean.d.ts +0 -51
  163. package/dist/geometry/boolean.js +0 -51
  164. package/dist/geometry/buffer.d.ts +0 -26
  165. package/dist/geometry/buffer.js +0 -26
  166. package/dist/geometry/circle.d.ts +0 -9
  167. package/dist/geometry/circle.js +0 -9
  168. package/dist/geometry/coords.d.ts +0 -16
  169. package/dist/geometry/coords.js +0 -16
  170. package/dist/geometry/distance.d.ts +0 -24
  171. package/dist/geometry/distance.js +0 -24
  172. package/dist/geometry/errors.d.ts +21 -36
  173. package/dist/geometry/errors.js +49 -29
  174. package/dist/geometry/geojson.d.ts +81 -0
  175. package/dist/geometry/geojson.js +164 -0
  176. package/dist/geometry/index.d.ts +38 -23
  177. package/dist/geometry/index.js +43 -31
  178. package/dist/geometry/measure.d.ts +0 -27
  179. package/dist/geometry/measure.js +0 -27
  180. package/dist/geometry/predicates.d.ts +0 -9
  181. package/dist/geometry/predicates.js +0 -9
  182. package/dist/geometry/public-bounds.d.ts +26 -0
  183. package/dist/geometry/public-bounds.js +30 -0
  184. package/dist/geometry/public-combine.d.ts +78 -0
  185. package/dist/geometry/public-combine.js +82 -0
  186. package/dist/geometry/public-create.d.ts +54 -0
  187. package/dist/geometry/public-create.js +70 -0
  188. package/dist/geometry/public-measure.d.ts +170 -0
  189. package/dist/geometry/public-measure.js +283 -0
  190. package/dist/geometry/public-predicates.d.ts +54 -0
  191. package/dist/geometry/public-predicates.js +144 -0
  192. package/dist/geometry/public-repair.d.ts +75 -0
  193. package/dist/geometry/public-repair.js +77 -0
  194. package/dist/geometry/simplify.d.ts +0 -7
  195. package/dist/geometry/simplify.js +0 -7
  196. package/dist/geometry/split.d.ts +0 -20
  197. package/dist/geometry/split.js +0 -20
  198. package/dist/geometry/units.d.ts +20 -12
  199. package/dist/geometry/units.js +20 -12
  200. package/dist/index.d.ts +52 -66
  201. package/dist/index.js +6 -18
  202. package/dist/messages.d.ts +7 -7
  203. package/dist/modes/draw/circle.js +83 -207
  204. package/dist/modes/draw/commit-layer.d.ts +5 -16
  205. package/dist/modes/draw/commit-layer.js +2 -13
  206. package/dist/modes/draw/freehand.js +108 -246
  207. package/dist/modes/draw/image.js +4 -2
  208. package/dist/modes/draw/index.d.ts +5 -5
  209. package/dist/modes/draw/index.js +5 -5
  210. package/dist/modes/draw/line.js +18 -354
  211. package/dist/modes/draw/point.js +29 -78
  212. package/dist/modes/draw/polygon.js +23 -368
  213. package/dist/modes/draw/trace-support.d.ts +43 -36
  214. package/dist/modes/draw/trace-support.js +95 -98
  215. package/dist/modes/draw/vertex-drawing.d.ts +1 -0
  216. package/dist/modes/draw/vertex-drawing.js +176 -0
  217. package/dist/modes/handler.d.ts +1 -285
  218. package/dist/modes/manager.d.ts +2 -2
  219. package/dist/modes/manager.js +3 -0
  220. package/dist/modes/select/box-selection.d.ts +3 -3
  221. package/dist/modes/select/box-selection.js +2 -1
  222. package/dist/modes/select/click-handler.d.ts +5 -5
  223. package/dist/modes/select/click-handler.js +22 -20
  224. package/dist/modes/select/cursor-handler.d.ts +2 -2
  225. package/dist/modes/select/drag/intermediate-writes.js +1 -1
  226. package/dist/modes/select/drag/move.js +3 -3
  227. package/dist/modes/select/drag/operation.d.ts +3 -3
  228. package/dist/modes/select/drag/radius.js +5 -4
  229. package/dist/modes/select/drag/transform.d.ts +2 -2
  230. package/dist/modes/select/drag/transform.js +11 -5
  231. package/dist/modes/select/drag/vertex.d.ts +2 -2
  232. package/dist/modes/select/drag/vertex.js +13 -8
  233. package/dist/modes/select/drag-handler.js +44 -25
  234. package/dist/modes/select/mode.js +17 -17
  235. package/dist/modes/select/shortcut-handler.d.ts +8 -8
  236. package/dist/modes/select/shortcut-handler.js +9 -7
  237. package/dist/operations/layer-operations.js +29 -168
  238. package/dist/operations/resize.d.ts +2 -2
  239. package/dist/operations/resize.js +5 -5
  240. package/dist/operations/rotate.js +5 -5
  241. package/dist/operations/selection-operations.d.ts +16 -1
  242. package/dist/operations/selection-operations.js +28 -13
  243. package/dist/operations/shared-vertex.js +4 -2
  244. package/dist/operations/trace-graph.d.ts +0 -18
  245. package/dist/operations/trace-graph.js +0 -18
  246. package/dist/operations/vertex.js +36 -35
  247. package/dist/shared/color.d.ts +1 -0
  248. package/dist/shared/color.js +245 -0
  249. package/dist/shared/config/constants.d.ts +1 -54
  250. package/dist/shared/config/constants.js +1 -58
  251. package/dist/shared/config/feature-style.d.ts +16 -13
  252. package/dist/shared/config/feature-style.js +9 -0
  253. package/dist/shared/config/rendering.d.ts +3 -3
  254. package/dist/shared/config/selection-highlight.d.ts +0 -15
  255. package/dist/shared/config/selection-highlight.js +4 -7
  256. package/dist/shared/config/selection.d.ts +2 -32
  257. package/dist/shared/config/selection.js +0 -18
  258. package/dist/shared/config/topology.d.ts +2 -2
  259. package/dist/shared/config/trace.d.ts +4 -4
  260. package/dist/shared/math/angle.d.ts +1 -1
  261. package/dist/shared/math/angle.js +1 -1
  262. package/dist/shared/math/circle.d.ts +1 -1
  263. package/dist/shared/math/circle.js +1 -1
  264. package/dist/shared/math/distance.d.ts +2 -1
  265. package/dist/shared/math/distance.js +3 -2
  266. package/dist/shared/math/index.d.ts +1 -1
  267. package/dist/shared/math/index.js +1 -1
  268. package/dist/shared/math/transform.d.ts +23 -0
  269. package/dist/shared/math/transform.js +47 -28
  270. package/dist/shared/properties.d.ts +18 -0
  271. package/dist/shared/properties.js +129 -0
  272. package/dist/shared/types/events.d.ts +15 -7
  273. package/dist/shared/types/model.d.ts +109 -159
  274. package/dist/shared/types/style.d.ts +1 -1
  275. package/dist/shared/utils/color.d.ts +2 -36
  276. package/dist/shared/utils/color.js +13 -70
  277. package/dist/shared/utils/coordinates.d.ts +30 -4
  278. package/dist/shared/utils/coordinates.js +56 -10
  279. package/dist/shared/utils/event-emitter.d.ts +1 -262
  280. package/dist/shared/utils/event-emitter.js +4 -3
  281. package/dist/shared/utils/feature-bbox.js +8 -7
  282. package/dist/shared/utils/feature-segments.js +5 -4
  283. package/dist/shared/utils/image.d.ts +0 -4
  284. package/dist/shared/utils/image.js +0 -6
  285. package/dist/shared/utils/name-generator.d.ts +14 -20
  286. package/dist/shared/utils/name-generator.js +20 -3
  287. package/dist/shared/utils/pixel-ratio.d.ts +9 -3
  288. package/dist/shared/utils/pixel-ratio.js +13 -4
  289. package/dist/shared/utils/property.d.ts +7 -50
  290. package/dist/shared/utils/property.js +22 -87
  291. package/dist/snapping/custom-targets.js +21 -4
  292. package/dist/snapping/indicator.js +20 -11
  293. package/dist/snapping/providers/display.d.ts +6 -1
  294. package/dist/snapping/providers/display.js +2 -1
  295. package/dist/snapping/providers/guide.d.ts +3 -43
  296. package/dist/snapping/providers/guide.js +1 -44
  297. package/dist/snapping/providers/intersection.js +1 -1
  298. package/dist/snapping/providers/store.js +3 -3
  299. package/dist/snapping/service.js +18 -7
  300. package/dist/snapping/types.d.ts +9 -35
  301. package/dist/store/draw-store.js +233 -142
  302. package/dist/store/local-visibility.d.ts +11 -6
  303. package/dist/store/local-visibility.js +38 -7
  304. package/dist/store/lock.d.ts +0 -6
  305. package/dist/store/lock.js +0 -6
  306. package/dist/store/memory/change-bus.d.ts +3 -3
  307. package/dist/store/memory/change-bus.js +12 -0
  308. package/dist/store/memory/file-store.d.ts +2 -2
  309. package/dist/store/memory/ui-state.d.ts +1 -51
  310. package/dist/store/memory/ui-state.js +122 -134
  311. package/dist/store/memory.d.ts +1 -8
  312. package/dist/store/memory.js +249 -45
  313. package/dist/store/ordering.d.ts +9 -0
  314. package/dist/store/ordering.js +17 -0
  315. package/dist/store/spatial/spatial-index.d.ts +1 -1
  316. package/dist/store/spatial/spatial-index.js +1 -1
  317. package/dist/store/spatial/store-spatial-index.d.ts +3 -1
  318. package/dist/store/spatial/store-spatial-index.js +9 -3
  319. package/dist/store/store.d.ts +66 -107
  320. package/dist/store/types.d.ts +1 -1
  321. package/dist/store/writable-layer.d.ts +1 -1
  322. package/dist/store/writable-layer.js +2 -2
  323. package/dist/table/builder.d.ts +83 -0
  324. package/dist/table/builder.js +381 -0
  325. package/dist/table/index.d.ts +37 -0
  326. package/dist/table/index.js +5 -0
  327. package/dist/table/packed-rtree.d.ts +1 -0
  328. package/dist/{display → table}/packed-rtree.js +1 -1
  329. package/dist/table/partition.d.ts +1 -0
  330. package/dist/{display → table}/partition.js +3 -3
  331. package/dist/table/prepare.d.ts +44 -0
  332. package/dist/table/prepare.js +136 -0
  333. package/dist/table/table.d.ts +1 -0
  334. package/dist/{display/columnar → table}/table.js +29 -25
  335. package/dist/{display/columnar → table}/types.d.ts +68 -72
  336. package/dist/table/types.js +3 -0
  337. package/dist/view/coordinator.js +4 -3
  338. package/dist/view/feature-companion.d.ts +13 -7
  339. package/dist/view/feature-companion.js +11 -3
  340. package/dist/view/globe-subdivision.js +3 -3
  341. package/dist/view/layer/attach.d.ts +1 -1
  342. package/dist/view/layer/attach.js +1 -1
  343. package/dist/view/layer/custom-layer.js +40 -11
  344. package/dist/view/layer/display-list.js +2 -1
  345. package/dist/view/layer/drape-planner.d.ts +2 -2
  346. package/dist/view/layer/frame-render.d.ts +3 -3
  347. package/dist/view/layer/frame-render.js +7 -2
  348. package/dist/view/layer/frame-state.d.ts +6 -6
  349. package/dist/view/layer/index.d.ts +2 -2
  350. package/dist/view/layer/index.js +1 -1
  351. package/dist/view/layer/render.d.ts +4 -4
  352. package/dist/view/layer/render.js +3 -8
  353. package/dist/view/layer/renderers.d.ts +2 -2
  354. package/dist/view/layer/renderers.js +1 -1
  355. package/dist/view/layer/slot-manager.d.ts +2 -2
  356. package/dist/view/layer/slot-manager.js +4 -4
  357. package/dist/view/layer/slots.d.ts +2 -2
  358. package/dist/view/layer/slots.js +1 -1
  359. package/dist/view/layer/store-retained-bbox.js +3 -2
  360. package/dist/view/layer/store-retained-classify.d.ts +5 -7
  361. package/dist/view/layer/store-retained-classify.js +19 -7
  362. package/dist/view/layer/store-retained-collect.js +8 -7
  363. package/dist/view/layer/store-retained-coord-patch.d.ts +0 -8
  364. package/dist/view/layer/store-retained-coord-patch.js +13 -4
  365. package/dist/view/layer/store-retained-immediate.d.ts +3 -3
  366. package/dist/view/layer/store-retained-immediate.js +3 -8
  367. package/dist/view/layer/store-retained-invalidation.d.ts +2 -2
  368. package/dist/view/layer/store-retained.d.ts +2 -2
  369. package/dist/view/layer/store-retained.js +1 -1
  370. package/dist/view/renderers/batch-manager.js +8 -7
  371. package/dist/view/renderers/drawer.js +21 -15
  372. package/dist/view/renderers/image.js +13 -39
  373. package/dist/view/renderers/line/line-types.d.ts +3 -3
  374. package/dist/view/renderers/line/sdf-line.js +3 -1
  375. package/dist/view/renderers/point/billboard-depth.js +1 -1
  376. package/dist/view/renderers/point/point-instance.js +1 -1
  377. package/dist/view/renderers/point/point-shape.js +2 -2
  378. package/dist/view/renderers/point/point-style.js +48 -4
  379. package/dist/view/renderers/polygon/batch.js +1 -2
  380. package/dist/view/renderers/polygon/fill.js +3 -1
  381. package/dist/view/renderers/polygon/sdf-polygon.js +2 -3
  382. package/dist/view/renderers/polygon/triangulator.d.ts +1 -1
  383. package/dist/view/renderers/stroke.js +3 -1
  384. package/dist/view/shaders/helpers.d.ts +2 -42
  385. package/dist/view/shaders/helpers.js +0 -6
  386. package/dist/view/shaders/projection.d.ts +15 -7
  387. package/dist/view/shaders/projection.js +23 -6
  388. package/dist/view/shaders/quad.d.ts +16 -12
  389. package/dist/view/shaders/quad.js +34 -13
  390. package/dist/view/style-rule.d.ts +5 -42
  391. package/dist/view/style-rule.js +20 -44
  392. package/dist/view/terrain/binding.d.ts +1 -0
  393. package/dist/view/terrain/binding.js +29 -0
  394. package/dist/view/terrain/context.d.ts +3 -4
  395. package/dist/view/terrain/context.js +4 -5
  396. package/dist/view/terrain/drape/geometry.js +1 -1
  397. package/dist/view/terrain/drape/pass.d.ts +1 -1
  398. package/dist/view/terrain/drape/pass.js +8 -7
  399. package/dist/view/terrain/polygon.d.ts +9 -5
  400. package/dist/view/terrain/polygon.js +16 -2
  401. package/dist/view/terrain/state.d.ts +1 -1
  402. package/dist/view/terrain/state.js +1 -1
  403. package/dist/view/terrain/tessellation.d.ts +2 -2
  404. package/dist/view/terrain/tessellation.js +1 -1
  405. package/dist/view/ui/auxiliary-handles.d.ts +6 -29
  406. package/dist/view/ui/bounds.js +8 -12
  407. package/dist/view/ui/handle-test.js +2 -2
  408. package/dist/view/ui/handle-thinning.js +17 -17
  409. package/dist/view/ui/handles.js +21 -13
  410. package/dist/view/ui/helper.d.ts +1 -1
  411. package/dist/view/ui/helper.js +1 -1
  412. package/dist/view/ui/index.d.ts +1 -1
  413. package/dist/view/ui/selection-scope.js +4 -2
  414. package/dist/view/ui/selection-ui/bounding-box.js +6 -6
  415. package/dist/view/ui/selection-ui/extension-registry.d.ts +31 -20
  416. package/dist/view/ui/selection-ui/extension-registry.js +70 -7
  417. package/dist/view/ui/selection-ui/index.d.ts +2 -2
  418. package/dist/view/ui/selection-ui/index.js +1 -1
  419. package/dist/view/ui/selection-ui/renderer.js +15 -38
  420. package/dist/view/ui/selection-ui/types.d.ts +17 -2
  421. package/dist/view/ui/selection-ui-drawer.d.ts +8 -0
  422. package/dist/view/ui/selection-ui-drawer.js +63 -2
  423. package/dist/view/ui/tentative.js +1 -1
  424. package/dist/webgl/index.d.ts +65 -0
  425. package/dist/webgl/index.js +62 -0
  426. package/package.json +20 -9
  427. package/dist/api/api.d.ts +0 -1259
  428. package/dist/api/api.js +0 -86
  429. package/dist/api/context.d.ts +0 -173
  430. package/dist/api/display-api.js +0 -23
  431. package/dist/api/event-api.d.ts +0 -13
  432. package/dist/api/event-api.js +0 -17
  433. package/dist/api/extension-api.d.ts +0 -46
  434. package/dist/api/extension-api.js +0 -85
  435. package/dist/api/feature-api.d.ts +0 -11
  436. package/dist/api/feature-api.js +0 -101
  437. package/dist/api/geometry/apply.d.ts +0 -51
  438. package/dist/api/geometry/boolean.d.ts +0 -28
  439. package/dist/api/geometry/boolean.js +0 -65
  440. package/dist/api/geometry/types.d.ts +0 -31
  441. package/dist/api/geometry-operations.d.ts +0 -162
  442. package/dist/api/geometry-operations.js +0 -94
  443. package/dist/api/group-api.d.ts +0 -10
  444. package/dist/api/group-api.js +0 -78
  445. package/dist/api/import-export/constants.d.ts +0 -29
  446. package/dist/api/import-export/constants.js +0 -40
  447. package/dist/api/import-export/file-name.d.ts +0 -10
  448. package/dist/api/import-export/file-name.js +0 -20
  449. package/dist/api/import-export/geojson-export.d.ts +0 -19
  450. package/dist/api/import-export/image-import.d.ts +0 -12
  451. package/dist/api/import-export/image-import.js +0 -53
  452. package/dist/api/import-export/index.d.ts +0 -9
  453. package/dist/api/import-export/index.js +0 -107
  454. package/dist/api/import-export/native-format.d.ts +0 -15
  455. package/dist/api/import-export/style-validation.d.ts +0 -27
  456. package/dist/api/import-export/style-validation.js +0 -49
  457. package/dist/api/import-export/types.d.ts +0 -26
  458. package/dist/api/index.d.ts +0 -15
  459. package/dist/api/index.js +0 -3
  460. package/dist/api/input-api.d.ts +0 -158
  461. package/dist/api/input-api.js +0 -144
  462. package/dist/api/instance-api.d.ts +0 -38
  463. package/dist/api/instance-api.js +0 -136
  464. package/dist/api/layer-api.d.ts +0 -12
  465. package/dist/api/layer-api.js +0 -62
  466. package/dist/api/selection-api.d.ts +0 -7
  467. package/dist/api/selection-api.js +0 -78
  468. package/dist/api/snapping-api.d.ts +0 -125
  469. package/dist/api/snapping-api.js +0 -50
  470. package/dist/api/topology-api.d.ts +0 -30
  471. package/dist/api/topology-api.js +0 -16
  472. package/dist/api/tracing-api.d.ts +0 -31
  473. package/dist/api/tracing-api.js +0 -16
  474. package/dist/dispatcher/hit-test/index.d.ts +0 -14
  475. package/dist/dispatcher/hit-test/index.js +0 -9
  476. package/dist/dispatcher/index.d.ts +0 -15
  477. package/dist/dispatcher/index.js +0 -3
  478. package/dist/display/columnar/index.d.ts +0 -12
  479. package/dist/display/columnar/index.js +0 -13
  480. package/dist/display/columnar/prepare.d.ts +0 -42
  481. package/dist/display/columnar/prepare.js +0 -116
  482. package/dist/display/index.d.ts +0 -13
  483. package/dist/display/types.js +0 -43
  484. package/dist/maplibre-gl-draw.d.ts +0 -47
  485. package/dist/modes/cursor.js +0 -72
  486. package/dist/modes/index.d.ts +0 -7
  487. package/dist/operations/index.d.ts +0 -9
  488. package/dist/operations/index.js +0 -3
  489. package/dist/plugins/index.d.ts +0 -10
  490. package/dist/plugins/mutation-hooks.d.ts +0 -28
  491. package/dist/plugins/mutation-hooks.js +0 -84
  492. package/dist/plugins/plugin-context.js +0 -367
  493. package/dist/plugins/plugin-manager.d.ts +0 -103
  494. package/dist/plugins/plugin-manager.js +0 -316
  495. package/dist/plugins/plugin.d.ts +0 -529
  496. package/dist/shared/config/index.d.ts +0 -17
  497. package/dist/shared/config/index.js +0 -8
  498. package/dist/shared/utils/index.d.ts +0 -15
  499. package/dist/shared/utils/index.js +0 -24
  500. package/dist/snapping/index.d.ts +0 -14
  501. package/dist/snapping/index.js +0 -4
  502. package/dist/store/change-merger.js +0 -102
  503. package/dist/store/event-bridge.js +0 -161
  504. package/dist/store/index.d.ts +0 -12
  505. package/dist/store/index.js +0 -4
  506. package/dist/view/index.d.ts +0 -47
  507. package/dist/view/index.js +0 -20
  508. /package/dist/api/{geometry/types.js → datasets.js} +0 -0
  509. /package/dist/api/{import-export/types.js → document.js} +0 -0
  510. /package/dist/{display/columnar/types.js → api/drawing.js} +0 -0
  511. /package/dist/{display/index.js → api/events.js} +0 -0
  512. /package/dist/{modes/index.js → api/extension/context.js} +0 -0
  513. /package/dist/{plugins/index.js → api/extension/feature-type.js} +0 -0
  514. /package/dist/{plugins/plugin.js → api/extension/mode.js} +0 -0
  515. /package/dist/api/{display-api.d.ts → impl/adapters.d.ts} +0 -0
  516. /package/dist/{display/columnar/source.d.ts → api/impl/contexts.d.ts} +0 -0
  517. /package/dist/{display/columnar/table.d.ts → api/impl/create-draw.d.ts} +0 -0
  518. /package/dist/{display/interaction.d.ts → api/impl/datasets.d.ts} +0 -0
  519. /package/dist/{display/manager.d.ts → api/impl/destroy-guard.d.ts} +0 -0
  520. /package/dist/{display/packed-rtree.d.ts → api/impl/document.d.ts} +0 -0
  521. /package/dist/{display/partition.d.ts → api/impl/drawing.d.ts} +0 -0
  522. /package/dist/{display/provider.d.ts → api/impl/engine.d.ts} +0 -0
  523. /package/dist/{display/source.d.ts → api/impl/events.d.ts} +0 -0
  524. /package/dist/{display/spatial.d.ts → api/impl/extension-host.d.ts} +0 -0
  525. /package/dist/{display/style.d.ts → api/impl/extensions.d.ts} +0 -0
  526. /package/dist/{display/triangulation.d.ts → api/impl/features.d.ts} +0 -0
  527. /package/dist/{modes/cursor.d.ts → api/impl/geometry/types.d.ts} +0 -0
  528. /package/dist/{plugins/plugin-context.d.ts → api/impl/hidden.d.ts} +0 -0
  529. /package/dist/api/{import-export → impl/import-export}/embedded-file.d.ts +0 -0
  530. /package/dist/api/{import-export → impl/import-export}/own-property.d.ts +0 -0
  531. /package/dist/api/{import-export → impl/import-export}/own-property.js +0 -0
  532. /package/dist/{store/change-merger.d.ts → api/impl/input.d.ts} +0 -0
  533. /package/dist/{store/event-bridge.d.ts → api/impl/layers.d.ts} +0 -0
  534. /package/dist/{display → dataset}/chunk-set.d.ts +0 -0
  535. /package/dist/{display → dataset}/chunk-set.js +0 -0
  536. /package/dist/{display → dataset}/dataset.d.ts +0 -0
  537. /package/dist/{display → dataset}/manager.js +0 -0
  538. /package/dist/{display → dataset}/provider.js +0 -0
  539. /package/dist/{display → dataset}/selection.d.ts +0 -0
  540. /package/dist/{display → dataset}/selection.js +0 -0
@@ -1,6 +1,11 @@
1
1
  // SPDX-FileCopyrightText: 2026 SAKAIDA Atsushi
2
2
  // SPDX-License-Identifier: AGPL-3.0-only
3
+ /**
4
+ * Import / export of the native format
5
+ */
6
+ import { getDrawProperty } from '../../../shared/properties.js';
3
7
  import { NATIVE_VERSION } from './constants.js';
8
+ import { upgradeNativeData } from './native-upgrade.js';
4
9
  import { validateNativeData } from './native-validation.js';
5
10
  /** The layer that survives the replacement (it is updated in place when the data has it) */
6
11
  const DEFAULT_LAYER_ID = 'default-layer';
@@ -8,9 +13,9 @@ const DEFAULT_LAYER_ID = 'default-layer';
8
13
  * Exports the current data in the native format
9
14
  */
10
15
  export function exportNative(store, options) {
11
- let features = store.getAllFeatures();
12
- const layers = store.getAllLayers();
13
- const groups = store.getAllGroups();
16
+ let features = store.listFeatures();
17
+ const layers = store.listLayers();
18
+ const groups = store.listGroups();
14
19
  if (options?.featureIds && options.featureIds.length > 0) {
15
20
  const featureIdSet = new Set(options.featureIds);
16
21
  features = features.filter((f) => featureIdSet.has(f.id));
@@ -22,11 +27,12 @@ export function exportNative(store, options) {
22
27
  // Get only the files that are in use
23
28
  const usedFileIds = new Set();
24
29
  for (const feature of features) {
25
- if (feature.type === 'Image' && feature.properties.imageFileId) {
26
- usedFileIds.add(feature.properties.imageFileId);
30
+ const imageFileId = getDrawProperty(feature, 'imageFileId');
31
+ if (feature.type === 'Image' && imageFileId) {
32
+ usedFileIds.add(imageFileId);
27
33
  }
28
34
  }
29
- const files = store.getAllFiles();
35
+ const files = store.listFiles();
30
36
  const filesRecord = {};
31
37
  for (const file of files) {
32
38
  if (usedFileIds.has(file.id)) {
@@ -49,9 +55,10 @@ export function exportNative(store, options) {
49
55
  };
50
56
  }
51
57
  /**
52
- * Imports the native format (replaces the existing data)
58
+ * Reads the native format for a load that replaces the existing data: everything is checked
59
+ * here, and the writes are left to the transaction of the caller
53
60
  */
54
- export async function loadNative(data, deps) {
61
+ export async function prepareNative(data, deps) {
55
62
  const { store } = deps;
56
63
  // Validate before applying. Since store.transact does not roll back, if an exception
57
64
  // is thrown on invalid data after the existing data has been cleared, the existing data
@@ -62,23 +69,25 @@ export async function loadNative(data, deps) {
62
69
  const retainedLayerIds = new Set();
63
70
  if (store.getLayer(DEFAULT_LAYER_ID))
64
71
  retainedLayerIds.add(DEFAULT_LAYER_ID);
65
- const { layers, layerOrder, groups, features, files } = await validateNativeData(data, retainedLayerIds);
72
+ // Data of an earlier major version is brought to the current one first
73
+ const upgraded = upgradeNativeData(data);
74
+ const { layers, layerOrder, groups, features, files } = await validateNativeData(upgraded, retainedLayerIds);
66
75
  const featureIds = features.map((f) => f.id);
67
76
  // A kept layer the data does not list goes to the back, where it stays when the data does
68
77
  // not mention it (every layer must be on the stacking order to be drawn)
69
78
  const retainedUnlisted = [...retainedLayerIds].filter((id) => !layerOrder.includes(id));
70
- // Import atomically (silent, so a subscriber that records changes leaves it out)
71
- store.transact(() => {
79
+ // The writes, in the transaction of the caller, which makes them one change
80
+ const write = () => {
72
81
  // 1. Clear the existing data
73
- const existingFeatures = store.getAllFeatures();
82
+ const existingFeatures = store.listFeatures();
74
83
  for (const feature of existingFeatures) {
75
84
  store.deleteFeature(feature.id);
76
85
  }
77
- const existingGroups = store.getAllGroups();
86
+ const existingGroups = store.listGroups();
78
87
  for (const group of existingGroups) {
79
88
  store.deleteGroup(group.id);
80
89
  }
81
- const existingLayers = store.getAllLayers();
90
+ const existingLayers = store.listLayers();
82
91
  for (const layer of existingLayers) {
83
92
  if (layer.id !== DEFAULT_LAYER_ID) {
84
93
  store.deleteLayer(layer.id);
@@ -86,7 +95,7 @@ export async function loadNative(data, deps) {
86
95
  }
87
96
  // The files belong to the features that were just removed, and the data brings its own
88
97
  // (leaving them would also make a file id of the data collide)
89
- for (const file of store.getAllFiles()) {
98
+ for (const file of store.listFiles()) {
90
99
  store.deleteFile(file.id);
91
100
  }
92
101
  // 2. Import the layers
@@ -114,13 +123,14 @@ export async function loadNative(data, deps) {
114
123
  // nothing of the previous document is left on it
115
124
  store.setLayerOrder([...retainedUnlisted, ...layerOrder]);
116
125
  // 7. Import the metadata
117
- if (data.metadata) {
118
- store.setMetadata(data.metadata);
126
+ if (upgraded.metadata) {
127
+ store.setMetadata(upgraded.metadata);
119
128
  }
120
- }, 'silent');
121
- return {
122
- format: 'native',
123
- featureIds,
124
- replaced: true,
129
+ return {
130
+ format: 'native',
131
+ featureIds,
132
+ replaced: true,
133
+ };
125
134
  };
135
+ return { write };
126
136
  }
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Upgrades native data of an earlier major version to the version this library writes
3
+ *
4
+ * @param data - the data as it was read
5
+ * @returns the upgraded data, or the data as it is when it is of the current major version,
6
+ * of a version without an upgrade, or not an object
7
+ */
8
+ export declare function upgradeNativeData(data: unknown): unknown;
@@ -0,0 +1,139 @@
1
+ // SPDX-FileCopyrightText: 2026 SAKAIDA Atsushi
2
+ // SPDX-License-Identifier: AGPL-3.0-only
3
+ /**
4
+ * Upgrades native data written by an earlier major version to the current one
5
+ *
6
+ * Each step takes data of one major version to the next, and the steps run in a chain until
7
+ * the data reaches the version this library writes. A step only renames and moves fields; it
8
+ * checks nothing, and leaves a value it does not understand as it is, so that the validation
9
+ * that follows reports it. Data of a major version without a step is returned as it is, and
10
+ * the validation rejects its version.
11
+ */
12
+ import { DRAW_PROPERTY_NAMES, drawPropertyKey } from '../../../shared/properties.js';
13
+ import { geometryFromCoordinates } from '../../../shared/utils/coordinates.js';
14
+ import { NATIVE_VERSION } from './constants.js';
15
+ import { foldLegacyImageStyle } from './legacy-image-style.js';
16
+ function isRecord(value) {
17
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
18
+ }
19
+ /** Whether the object has the key as an own property */
20
+ function hasOwnKey(value, key) {
21
+ return Object.getOwnPropertyDescriptor(value, key) !== undefined;
22
+ }
23
+ /** The major version of a semantic version, or null when it is not one */
24
+ function majorOf(version) {
25
+ if (typeof version !== 'string')
26
+ return null;
27
+ const match = /^(\d+)\.\d+\.\d+(?:[-+].*)?$/.exec(version);
28
+ return match ? Number(match[1]) : null;
29
+ }
30
+ /**
31
+ * 2.x to 3.0.0: the document model of the 2.0 API
32
+ *
33
+ * - a feature holds a GeoJSON `geometry` instead of `coordinates`
34
+ * - the values of the library in `properties` get the `maplibre-gl-draw:` prefix
35
+ * - the `order` of a layer becomes `items`
36
+ * - the size, the rotation and the opacity in the style of an Image move to the prefixed
37
+ * `imageWidth`, `imageHeight` and `rotation` in `properties` and to `imageOpacity`
38
+ * - a group gets the `layerId` of the layer whose items list it (or of its first member, and
39
+ * `''` when it has neither)
40
+ */
41
+ function upgradeFrom2(data) {
42
+ const layers = Array.isArray(data.layers)
43
+ ? data.layers.map((layer) => {
44
+ if (!isRecord(layer) || !('order' in layer) || 'items' in layer)
45
+ return layer;
46
+ const { order, ...rest } = layer;
47
+ return { ...rest, items: order };
48
+ })
49
+ : data.layers;
50
+ const features = Array.isArray(data.features)
51
+ ? data.features.map((feature) => isRecord(feature) ? upgradeFeature(feature) : feature)
52
+ : data.features;
53
+ const layerOfItem = new Map();
54
+ if (Array.isArray(layers)) {
55
+ for (const layer of layers) {
56
+ if (!isRecord(layer) || typeof layer.id !== 'string' || !Array.isArray(layer.items))
57
+ continue;
58
+ for (const item of layer.items) {
59
+ if (typeof item === 'string' && !layerOfItem.has(item))
60
+ layerOfItem.set(item, layer.id);
61
+ }
62
+ }
63
+ }
64
+ const layerOfFeature = new Map();
65
+ if (Array.isArray(features)) {
66
+ for (const feature of features) {
67
+ if (isRecord(feature) && typeof feature.id === 'string') {
68
+ if (typeof feature.layerId === 'string')
69
+ layerOfFeature.set(feature.id, feature.layerId);
70
+ }
71
+ }
72
+ }
73
+ const groups = Array.isArray(data.groups)
74
+ ? data.groups.map((group) => {
75
+ if (!isRecord(group) || 'layerId' in group || typeof group.id !== 'string')
76
+ return group;
77
+ const members = Array.isArray(group.featureIds) ? group.featureIds : [];
78
+ const layerId = layerOfItem.get(group.id) ??
79
+ members
80
+ .map((id) => (typeof id === 'string' ? layerOfFeature.get(id) : undefined))
81
+ .find((id) => id !== undefined);
82
+ // A group that no layer lists and that has no member belongs to no layer
83
+ return { ...group, layerId: layerId ?? '' };
84
+ })
85
+ : data.groups;
86
+ return { ...data, version: '3.0.0', layers, groups, features };
87
+ }
88
+ /** A feature of version 2 in the shape of version 3 */
89
+ function upgradeFeature(feature) {
90
+ let result = feature;
91
+ if ('coordinates' in feature && !('geometry' in feature)) {
92
+ const { coordinates, ...rest } = feature;
93
+ const geometry = typeof feature.type === 'string' && Array.isArray(coordinates)
94
+ ? geometryFromCoordinates(feature.type, coordinates)
95
+ : // Left for the validation to report
96
+ { type: undefined, coordinates };
97
+ result = { ...rest, geometry };
98
+ }
99
+ if (isRecord(feature.properties)) {
100
+ const properties = { ...feature.properties };
101
+ for (const name of DRAW_PROPERTY_NAMES) {
102
+ const key = drawPropertyKey(name);
103
+ if (hasOwnKey(properties, name) && !hasOwnKey(properties, key)) {
104
+ properties[key] = properties[name];
105
+ delete properties[name];
106
+ }
107
+ }
108
+ result = { ...result, properties };
109
+ if (feature.type === 'Image' && isRecord(feature.style)) {
110
+ const style = { ...feature.style };
111
+ if (foldLegacyImageStyle(properties, style))
112
+ result = { ...result, style };
113
+ }
114
+ }
115
+ return result;
116
+ }
117
+ /** The step that takes data of each major version to the next */
118
+ const UPGRADES = new Map([[2, upgradeFrom2]]);
119
+ /**
120
+ * Upgrades native data of an earlier major version to the version this library writes
121
+ *
122
+ * @param data - the data as it was read
123
+ * @returns the upgraded data, or the data as it is when it is of the current major version,
124
+ * of a version without an upgrade, or not an object
125
+ */
126
+ export function upgradeNativeData(data) {
127
+ if (!isRecord(data))
128
+ return data;
129
+ const current = majorOf(NATIVE_VERSION);
130
+ let result = data;
131
+ for (let major = majorOf(result.version); major !== null && major !== current;) {
132
+ const step = UPGRADES.get(major);
133
+ if (!step)
134
+ break;
135
+ result = step(result);
136
+ major = majorOf(result.version);
137
+ }
138
+ return result;
139
+ }
@@ -6,7 +6,7 @@
6
6
  * deleted: a problem throws while the existing data is still intact. The checks follow the
7
7
  * native format described in docs/reference/data-format.md.
8
8
  */
9
- import type { Data, Feature, FileData, Group, Layer } from '../../store/types.js';
9
+ import type { Data, Feature, FileData, Group, Layer } from '../../../store/types.js';
10
10
  /** Native data that passed validation, with the files normalized */
11
11
  export interface ValidatedNativeData {
12
12
  layers: Layer[];
@@ -1,11 +1,12 @@
1
1
  // SPDX-FileCopyrightText: 2026 SAKAIDA Atsushi
2
2
  // SPDX-License-Identifier: AGPL-3.0-only
3
+ import { DrawError } from '../../errors.js';
3
4
  import { NATIVE_VERSION } from './constants.js';
4
5
  import { normalizeEmbeddedFile } from './embedded-file.js';
5
- import { describeCoordinateProblem } from './geometry-validation.js';
6
+ import { describeGeometryProblem } from './geometry-validation.js';
6
7
  import { sanitizeFeatureStyle } from './style-validation.js';
7
8
  function fail(message) {
8
- throw new Error(`Invalid native data: ${message}`);
9
+ throw new DrawError('invalid-input', `Invalid native data: ${message}`);
9
10
  }
10
11
  function isRecord(value) {
11
12
  return typeof value === 'object' && value !== null && !Array.isArray(value);
@@ -28,8 +29,8 @@ function validateLayer(layer, index) {
28
29
  if (typeof layer.opacity !== 'number' || !Number.isFinite(layer.opacity)) {
29
30
  fail(`${where} has no finite opacity`);
30
31
  }
31
- if (!Array.isArray(layer.order) || !layer.order.every((id) => typeof id === 'string')) {
32
- fail(`${where} has no order array of strings`);
32
+ if (!Array.isArray(layer.items) || !layer.items.every((id) => typeof id === 'string')) {
33
+ fail(`${where} has no items array of strings`);
33
34
  }
34
35
  if (layer.metadata !== undefined && !isRecord(layer.metadata)) {
35
36
  fail(`${where} has a metadata that is not an object`);
@@ -51,6 +52,8 @@ function validateGroup(group, index) {
51
52
  fail(`${where} has no boolean visible`);
52
53
  if (typeof group.locked !== 'boolean')
53
54
  fail(`${where} has no boolean locked`);
55
+ if (typeof group.layerId !== 'string')
56
+ fail(`${where} has no string layerId`);
54
57
  if (!Array.isArray(group.featureIds) || !group.featureIds.every((id) => typeof id === 'string')) {
55
58
  fail(`${where} has no featureIds array of strings`);
56
59
  }
@@ -95,9 +98,9 @@ function validateFeature(feature, index, layerIds, groupIds) {
95
98
  const where = `feature "${feature.id}"`;
96
99
  if (!isNonEmptyString(feature.type))
97
100
  fail(`${where} has no string type`);
98
- const coordinateProblem = describeCoordinateProblem(feature.type, feature.coordinates);
99
- if (coordinateProblem)
100
- fail(`${where} has ${coordinateProblem}`);
101
+ const geometryProblem = describeGeometryProblem(feature.type, feature.geometry);
102
+ if (geometryProblem)
103
+ fail(`${where} has ${geometryProblem}`);
101
104
  if (typeof feature.layerId !== 'string' || !layerIds.has(feature.layerId)) {
102
105
  fail(`${where} refers to a layer that does not exist`);
103
106
  }
@@ -115,12 +118,10 @@ function validateFeature(feature, index, layerIds, groupIds) {
115
118
  if (typeof feature.locked !== 'boolean')
116
119
  fail(`${where} has no boolean locked`);
117
120
  // A style key of the wrong type or form is dropped rather than rejecting the file: the
118
- // store accepts any value through its API, so the library's own export can carry one
119
- if (feature.style === undefined)
120
- return feature;
121
- const { style: _style, ...rest } = feature;
122
- const style = sanitizeFeatureStyle(feature.style);
123
- return (style === undefined ? rest : { ...rest, style });
121
+ // store accepts any value through its API, so the library's own export can carry one. A
122
+ // feature without a usable style gets the empty style
123
+ const style = feature.style === undefined ? undefined : sanitizeFeatureStyle(feature.style);
124
+ return { ...feature, style: style ?? {} };
124
125
  }
125
126
  async function validateFiles(files) {
126
127
  if (files === undefined)
@@ -190,7 +191,7 @@ export async function validateNativeData(data, retainedLayerIds) {
190
191
  layerIds.add(layer.id);
191
192
  }
192
193
  const layerOrder = validateLayerOrder(data.layerOrder, layers);
193
- // Feature and group IDs share the entries of layer.order, so they must not collide either
194
+ // Feature and group IDs share the entries of layer.items, so they must not collide either
194
195
  const itemIds = new Set();
195
196
  const groups = (data.groups ?? []).map(validateGroup);
196
197
  const groupIds = new Set();
@@ -0,0 +1,24 @@
1
+ import type { FeatureStyle } from '../../../store/types.js';
2
+ type Check = (value: unknown) => boolean;
3
+ /** A CSS color */
4
+ export declare const isCssColor: Check;
5
+ /**
6
+ * Returns the usable part of an imported style
7
+ *
8
+ * A key of FeatureStyle whose value fails its check is dropped; every other key is kept.
9
+ *
10
+ * @param value The style as read from the file
11
+ * @returns The style, or undefined when the value is not an object or nothing is left
12
+ */
13
+ export declare function sanitizeFeatureStyle(value: unknown): FeatureStyle | undefined;
14
+ /**
15
+ * Describes the first key of a style whose value fails its check
16
+ *
17
+ * A key given as `undefined` is not checked (it removes the key in a patch), and a key this
18
+ * library does not define is not checked either.
19
+ *
20
+ * @param value The style
21
+ * @returns A short description of the problem, or null when there is none
22
+ */
23
+ export declare function describeStyleProblem(value: unknown): string | null;
24
+ export {};
@@ -0,0 +1,86 @@
1
+ // SPDX-FileCopyrightText: 2026 SAKAIDA Atsushi
2
+ // SPDX-License-Identifier: AGPL-3.0-only
3
+ /**
4
+ * Validation of an imported feature style
5
+ *
6
+ * A style arrives from a file (the maplibre-gl-draw:style property of GeoJSON, the style of a
7
+ * native feature, the simplestyle-spec keys) and reaches the renderer, which parses the
8
+ * colors as CSS colors and uses the numbers as they are. A value of the wrong type or form (a
9
+ * number or null for a color, a string that is not a CSS color, an opacity of 5) would be
10
+ * drawn wrong, so each known key is checked here and a key that fails is dropped. Keys this
11
+ * library does not define are kept unchanged, whatever their value: they belong to the host or
12
+ * to an extension, which gives features keys of its own and checks their values where it reads
13
+ * them (values reach the Store through updateFeature and a replaced store as well, without
14
+ * passing here).
15
+ */
16
+ import { isColor } from '../../../shared/color.js';
17
+ import { setOwnProperty } from './own-property.js';
18
+ /** A CSS color */
19
+ export const isCssColor = isColor;
20
+ const isFiniteNumber = (value) => typeof value === 'number' && Number.isFinite(value);
21
+ const isOpacity = (value) => isFiniteNumber(value) && value >= 0 && value <= 1;
22
+ const isNonNegative = (value) => isFiniteNumber(value) && value >= 0;
23
+ const oneOf = (...values) => (value) => typeof value === 'string' && values.includes(value);
24
+ /** The check of every key of FeatureStyle */
25
+ const STYLE_CHECK_TABLE = {
26
+ fillColor: isCssColor,
27
+ fillOpacity: isOpacity,
28
+ strokeColor: isCssColor,
29
+ strokeWidth: isNonNegative,
30
+ strokeOpacity: isOpacity,
31
+ lineStyle: oneOf('solid', 'dashed', 'dotted'),
32
+ pointRadius: isNonNegative,
33
+ pointColor: isCssColor,
34
+ pointShape: oneOf('circle', 'square', 'triangle', 'star'),
35
+ pointOpacity: isOpacity,
36
+ pointStrokeColor: isCssColor,
37
+ pointStrokeWidth: isNonNegative,
38
+ imageOpacity: isOpacity,
39
+ };
40
+ const STYLE_CHECKS = new Map(Object.entries(STYLE_CHECK_TABLE));
41
+ function isRecord(value) {
42
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
43
+ }
44
+ /**
45
+ * Returns the usable part of an imported style
46
+ *
47
+ * A key of FeatureStyle whose value fails its check is dropped; every other key is kept.
48
+ *
49
+ * @param value The style as read from the file
50
+ * @returns The style, or undefined when the value is not an object or nothing is left
51
+ */
52
+ export function sanitizeFeatureStyle(value) {
53
+ if (!isRecord(value))
54
+ return undefined;
55
+ const style = {};
56
+ let kept = 0;
57
+ for (const [key, entry] of Object.entries(value)) {
58
+ const check = STYLE_CHECKS.get(key);
59
+ if (check && !check(entry))
60
+ continue;
61
+ setOwnProperty(style, key, entry);
62
+ kept++;
63
+ }
64
+ return kept > 0 ? style : undefined;
65
+ }
66
+ /**
67
+ * Describes the first key of a style whose value fails its check
68
+ *
69
+ * A key given as `undefined` is not checked (it removes the key in a patch), and a key this
70
+ * library does not define is not checked either.
71
+ *
72
+ * @param value The style
73
+ * @returns A short description of the problem, or null when there is none
74
+ */
75
+ export function describeStyleProblem(value) {
76
+ if (!isRecord(value))
77
+ return 'a style that is not an object';
78
+ for (const [key, entry] of Object.entries(value)) {
79
+ if (entry === undefined)
80
+ continue;
81
+ const check = STYLE_CHECKS.get(key);
82
+ if (check && !check(entry))
83
+ return `a style whose ${key} is not valid`;
84
+ }
85
+ return null;
86
+ }
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Types internal to the Import/Export module
3
+ */
4
+ import type { Feature, FileData, LoadResult } from '../../../store/types.js';
5
+ /**
6
+ * A load whose source is read, checked and decoded: what is left is to write it, inside the
7
+ * transaction of the caller. Nothing that can fail is left to `write`, because a transaction
8
+ * does not roll back.
9
+ */
10
+ export interface PreparedLoad {
11
+ /** Writes what was read and returns what was loaded */
12
+ write(): LoadResult;
13
+ }
14
+ /**
15
+ * GeoJSON import result (internal use).
16
+ *
17
+ * For a feature that contains image data, fileData is returned alongside it.
18
+ */
19
+ export interface ConvertedFeatureResult {
20
+ feature: Feature;
21
+ fileData?: FileData;
22
+ }
23
+ /**
24
+ * Options for GeoJSON import
25
+ */
26
+ export interface GeoJSONImportOptions {
27
+ /**
28
+ * Whether to expand Multi* geometries into features with a single geometry
29
+ *
30
+ * The default is false, which keeps MultiPoint / MultiLineString / MultiPolygon
31
+ * as Multi features as they are (so properties are not duplicated).
32
+ * Setting it to true expands them as before, assigning a new ID to each part.
33
+ */
34
+ flattenMulti?: boolean;
35
+ /**
36
+ * The layer every feature goes into, over the layer a feature names itself with
37
+ * `maplibre-gl-draw:layerId`. A group of another layer is then dropped from the feature
38
+ */
39
+ layerId?: string;
40
+ /**
41
+ * Whether the features and the groups of the document are replaced: they are deleted in the
42
+ * same transaction that writes the features of the file, and the layers stay
43
+ */
44
+ replace?: boolean;
45
+ /**
46
+ * Whether every feature goes into one layer (the one of `layerId`, else the current one) and
47
+ * leaves the group it names, because the load puts them all into a new group
48
+ */
49
+ oneGroup?: boolean;
50
+ /** IDs the features must not take, such as those of a layer and a group the load creates */
51
+ reservedIds?: ReadonlySet<string>;
52
+ }
@@ -0,0 +1,3 @@
1
+ // SPDX-FileCopyrightText: 2026 SAKAIDA Atsushi
2
+ // SPDX-License-Identifier: AGPL-3.0-only
3
+ export {};