@sakuzu/maplibre-gl-draw 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +43 -0
- package/LICENSE +661 -0
- package/README.ja.md +248 -0
- package/README.md +255 -0
- package/THIRD_PARTY_NOTICES.md +275 -0
- package/dist/api/api.d.ts +1259 -0
- package/dist/api/api.js +86 -0
- package/dist/api/context.d.ts +173 -0
- package/dist/api/context.js +193 -0
- package/dist/api/display-api.d.ts +1 -0
- package/dist/api/display-api.js +23 -0
- package/dist/api/event-api.d.ts +13 -0
- package/dist/api/event-api.js +17 -0
- package/dist/api/extension-api.d.ts +46 -0
- package/dist/api/extension-api.js +85 -0
- package/dist/api/feature-api.d.ts +11 -0
- package/dist/api/feature-api.js +101 -0
- package/dist/api/geometry/apply.d.ts +51 -0
- package/dist/api/geometry/apply.js +114 -0
- package/dist/api/geometry/boolean.d.ts +28 -0
- package/dist/api/geometry/boolean.js +65 -0
- package/dist/api/geometry/buffer.d.ts +11 -0
- package/dist/api/geometry/buffer.js +105 -0
- package/dist/api/geometry/split.d.ts +16 -0
- package/dist/api/geometry/split.js +75 -0
- package/dist/api/geometry/targets.d.ts +76 -0
- package/dist/api/geometry/targets.js +158 -0
- package/dist/api/geometry/types.d.ts +31 -0
- package/dist/api/geometry/types.js +3 -0
- package/dist/api/geometry-operations.d.ts +162 -0
- package/dist/api/geometry-operations.js +94 -0
- package/dist/api/group-api.d.ts +10 -0
- package/dist/api/group-api.js +78 -0
- package/dist/api/import-export/constants.d.ts +29 -0
- package/dist/api/import-export/constants.js +40 -0
- package/dist/api/import-export/embedded-file.d.ts +13 -0
- package/dist/api/import-export/embedded-file.js +31 -0
- package/dist/api/import-export/file-name.d.ts +10 -0
- package/dist/api/import-export/file-name.js +20 -0
- package/dist/api/import-export/format-detection.d.ts +12 -0
- package/dist/api/import-export/format-detection.js +29 -0
- package/dist/api/import-export/geojson-export.d.ts +19 -0
- package/dist/api/import-export/geojson-export.js +262 -0
- package/dist/api/import-export/geojson-import.d.ts +34 -0
- package/dist/api/import-export/geojson-import.js +538 -0
- package/dist/api/import-export/geometry-validation.d.ts +20 -0
- package/dist/api/import-export/geometry-validation.js +107 -0
- package/dist/api/import-export/image-import.d.ts +12 -0
- package/dist/api/import-export/image-import.js +53 -0
- package/dist/api/import-export/index.d.ts +9 -0
- package/dist/api/import-export/index.js +107 -0
- package/dist/api/import-export/native-format.d.ts +15 -0
- package/dist/api/import-export/native-format.js +126 -0
- package/dist/api/import-export/native-validation.d.ts +28 -0
- package/dist/api/import-export/native-validation.js +212 -0
- package/dist/api/import-export/own-property.d.ts +10 -0
- package/dist/api/import-export/own-property.js +19 -0
- package/dist/api/import-export/style-validation.d.ts +27 -0
- package/dist/api/import-export/style-validation.js +49 -0
- package/dist/api/import-export/types.d.ts +26 -0
- package/dist/api/import-export/types.js +3 -0
- package/dist/api/index.d.ts +15 -0
- package/dist/api/index.js +3 -0
- package/dist/api/input-api.d.ts +158 -0
- package/dist/api/input-api.js +144 -0
- package/dist/api/instance-api.d.ts +38 -0
- package/dist/api/instance-api.js +136 -0
- package/dist/api/layer-api.d.ts +12 -0
- package/dist/api/layer-api.js +62 -0
- package/dist/api/selection-api.d.ts +7 -0
- package/dist/api/selection-api.js +78 -0
- package/dist/api/snapping-api.d.ts +125 -0
- package/dist/api/snapping-api.js +50 -0
- package/dist/api/topology-api.d.ts +30 -0
- package/dist/api/topology-api.js +16 -0
- package/dist/api/tracing-api.d.ts +31 -0
- package/dist/api/tracing-api.js +16 -0
- package/dist/dispatcher/hit-test/box-strategies.d.ts +19 -0
- package/dist/dispatcher/hit-test/box-strategies.js +275 -0
- package/dist/dispatcher/hit-test/box-strategy.d.ts +59 -0
- package/dist/dispatcher/hit-test/box-strategy.js +37 -0
- package/dist/dispatcher/hit-test/globe-shape.d.ts +46 -0
- package/dist/dispatcher/hit-test/globe-shape.js +70 -0
- package/dist/dispatcher/hit-test/index.d.ts +14 -0
- package/dist/dispatcher/hit-test/index.js +9 -0
- package/dist/dispatcher/hit-test/local-frame.d.ts +77 -0
- package/dist/dispatcher/hit-test/local-frame.js +112 -0
- package/dist/dispatcher/hit-test/segment-grid.d.ts +32 -0
- package/dist/dispatcher/hit-test/segment-grid.js +79 -0
- package/dist/dispatcher/hit-test/service.d.ts +120 -0
- package/dist/dispatcher/hit-test/service.js +333 -0
- package/dist/dispatcher/hit-test/strategies/base.d.ts +136 -0
- package/dist/dispatcher/hit-test/strategies/base.js +66 -0
- package/dist/dispatcher/hit-test/strategies/circle.d.ts +10 -0
- package/dist/dispatcher/hit-test/strategies/circle.js +56 -0
- package/dist/dispatcher/hit-test/strategies/image.d.ts +22 -0
- package/dist/dispatcher/hit-test/strategies/image.js +115 -0
- package/dist/dispatcher/hit-test/strategies/index.d.ts +11 -0
- package/dist/dispatcher/hit-test/strategies/index.js +10 -0
- package/dist/dispatcher/hit-test/strategies/line.d.ts +17 -0
- package/dist/dispatcher/hit-test/strategies/line.js +30 -0
- package/dist/dispatcher/hit-test/strategies/multi.d.ts +44 -0
- package/dist/dispatcher/hit-test/strategies/multi.js +141 -0
- package/dist/dispatcher/hit-test/strategies/point.d.ts +20 -0
- package/dist/dispatcher/hit-test/strategies/point.js +29 -0
- package/dist/dispatcher/hit-test/strategies/polygon.d.ts +52 -0
- package/dist/dispatcher/hit-test/strategies/polygon.js +138 -0
- package/dist/dispatcher/hit-test/topmost.d.ts +48 -0
- package/dist/dispatcher/hit-test/topmost.js +157 -0
- package/dist/dispatcher/hit-test/visibility-lookup.d.ts +23 -0
- package/dist/dispatcher/hit-test/visibility-lookup.js +40 -0
- package/dist/dispatcher/index.d.ts +15 -0
- package/dist/dispatcher/index.js +3 -0
- package/dist/dispatcher/input-router.d.ts +1 -0
- package/dist/dispatcher/input-router.js +288 -0
- package/dist/dispatcher/normalizer.d.ts +1 -0
- package/dist/dispatcher/normalizer.js +513 -0
- package/dist/dispatcher/types.d.ts +144 -0
- package/dist/dispatcher/types.js +15 -0
- package/dist/display/chunk-set.d.ts +24 -0
- package/dist/display/chunk-set.js +533 -0
- package/dist/display/chunk.d.ts +1 -0
- package/dist/display/chunk.js +104 -0
- package/dist/display/columnar/index.d.ts +12 -0
- package/dist/display/columnar/index.js +13 -0
- package/dist/display/columnar/prepare.d.ts +42 -0
- package/dist/display/columnar/prepare.js +116 -0
- package/dist/display/columnar/source.d.ts +1 -0
- package/dist/display/columnar/source.js +531 -0
- package/dist/display/columnar/table.d.ts +1 -0
- package/dist/display/columnar/table.js +471 -0
- package/dist/display/columnar/types.d.ts +223 -0
- package/dist/display/columnar/types.js +3 -0
- package/dist/display/dataset.d.ts +2 -0
- package/dist/display/dataset.js +891 -0
- package/dist/display/index.d.ts +13 -0
- package/dist/display/index.js +3 -0
- package/dist/display/interaction.d.ts +1 -0
- package/dist/display/interaction.js +90 -0
- package/dist/display/manager.d.ts +1 -0
- package/dist/display/manager.js +440 -0
- package/dist/display/packed-rtree.d.ts +1 -0
- package/dist/display/packed-rtree.js +244 -0
- package/dist/display/partition.d.ts +1 -0
- package/dist/display/partition.js +226 -0
- package/dist/display/provider.d.ts +1 -0
- package/dist/display/provider.js +342 -0
- package/dist/display/retained.d.ts +40 -0
- package/dist/display/retained.js +898 -0
- package/dist/display/selection.d.ts +13 -0
- package/dist/display/selection.js +226 -0
- package/dist/display/source.d.ts +1 -0
- package/dist/display/source.js +119 -0
- package/dist/display/spatial.d.ts +1 -0
- package/dist/display/spatial.js +71 -0
- package/dist/display/style.d.ts +1 -0
- package/dist/display/style.js +126 -0
- package/dist/display/thinning.d.ts +65 -0
- package/dist/display/thinning.js +910 -0
- package/dist/display/triangulation.d.ts +1 -0
- package/dist/display/triangulation.js +0 -0
- package/dist/display/types.d.ts +561 -0
- package/dist/display/types.js +43 -0
- package/dist/extension/feature-handler.d.ts +182 -0
- package/dist/extension/feature-handler.js +3 -0
- package/dist/extension/index.d.ts +9 -0
- package/dist/extension/index.js +3 -0
- package/dist/extension/renderers.d.ts +208 -0
- package/dist/extension/renderers.js +3 -0
- package/dist/geometry/angle.d.ts +47 -0
- package/dist/geometry/angle.js +44 -0
- package/dist/geometry/bbox.d.ts +48 -0
- package/dist/geometry/bbox.js +83 -0
- package/dist/geometry/boolean.d.ts +162 -0
- package/dist/geometry/boolean.js +331 -0
- package/dist/geometry/buffer.d.ts +72 -0
- package/dist/geometry/buffer.js +218 -0
- package/dist/geometry/circle.d.ts +55 -0
- package/dist/geometry/circle.js +107 -0
- package/dist/geometry/coords.d.ts +97 -0
- package/dist/geometry/coords.js +149 -0
- package/dist/geometry/distance.d.ts +79 -0
- package/dist/geometry/distance.js +111 -0
- package/dist/geometry/errors.d.ts +74 -0
- package/dist/geometry/errors.js +104 -0
- package/dist/geometry/index.d.ts +28 -0
- package/dist/geometry/index.js +38 -0
- package/dist/geometry/measure.d.ts +81 -0
- package/dist/geometry/measure.js +236 -0
- package/dist/geometry/predicates.d.ts +62 -0
- package/dist/geometry/predicates.js +132 -0
- package/dist/geometry/simplify.d.ts +74 -0
- package/dist/geometry/simplify.js +159 -0
- package/dist/geometry/split.d.ts +68 -0
- package/dist/geometry/split.js +430 -0
- package/dist/geometry/types.d.ts +95 -0
- package/dist/geometry/types.js +3 -0
- package/dist/geometry/units.d.ts +35 -0
- package/dist/geometry/units.js +41 -0
- package/dist/index.d.ts +72 -0
- package/dist/index.js +20 -0
- package/dist/maplibre-gl-draw.d.ts +47 -0
- package/dist/maplibre-gl-draw.js +407 -0
- package/dist/messages.d.ts +64 -0
- package/dist/messages.js +36 -0
- package/dist/modes/cursor.d.ts +1 -0
- package/dist/modes/cursor.js +72 -0
- package/dist/modes/draw/circle.d.ts +1 -0
- package/dist/modes/draw/circle.js +222 -0
- package/dist/modes/draw/commit-layer.d.ts +26 -0
- package/dist/modes/draw/commit-layer.js +31 -0
- package/dist/modes/draw/freehand.d.ts +1 -0
- package/dist/modes/draw/freehand.js +264 -0
- package/dist/modes/draw/image.d.ts +1 -0
- package/dist/modes/draw/image.js +60 -0
- package/dist/modes/draw/index.d.ts +9 -0
- package/dist/modes/draw/index.js +11 -0
- package/dist/modes/draw/line.d.ts +1 -0
- package/dist/modes/draw/line.js +363 -0
- package/dist/modes/draw/point.d.ts +1 -0
- package/dist/modes/draw/point.js +87 -0
- package/dist/modes/draw/polygon.d.ts +1 -0
- package/dist/modes/draw/polygon.js +378 -0
- package/dist/modes/draw/trace-support.d.ts +79 -0
- package/dist/modes/draw/trace-support.js +161 -0
- package/dist/modes/handler.d.ts +285 -0
- package/dist/modes/handler.js +3 -0
- package/dist/modes/index.d.ts +7 -0
- package/dist/modes/index.js +3 -0
- package/dist/modes/manager.d.ts +15 -0
- package/dist/modes/manager.js +196 -0
- package/dist/modes/select/box-selection.d.ts +52 -0
- package/dist/modes/select/box-selection.js +140 -0
- package/dist/modes/select/click-handler.d.ts +32 -0
- package/dist/modes/select/click-handler.js +166 -0
- package/dist/modes/select/cursor-handler.d.ts +15 -0
- package/dist/modes/select/cursor-handler.js +59 -0
- package/dist/modes/select/drag/auxiliary.d.ts +26 -0
- package/dist/modes/select/drag/auxiliary.js +56 -0
- package/dist/modes/select/drag/intermediate-writes.d.ts +1 -0
- package/dist/modes/select/drag/intermediate-writes.js +171 -0
- package/dist/modes/select/drag/move.d.ts +24 -0
- package/dist/modes/select/drag/move.js +59 -0
- package/dist/modes/select/drag/operation.d.ts +30 -0
- package/dist/modes/select/drag/operation.js +18 -0
- package/dist/modes/select/drag/radius.d.ts +15 -0
- package/dist/modes/select/drag/radius.js +49 -0
- package/dist/modes/select/drag/transform.d.ts +17 -0
- package/dist/modes/select/drag/transform.js +155 -0
- package/dist/modes/select/drag/vertex.d.ts +17 -0
- package/dist/modes/select/drag/vertex.js +163 -0
- package/dist/modes/select/drag-handler.d.ts +1 -0
- package/dist/modes/select/drag-handler.js +254 -0
- package/dist/modes/select/hit-helpers.d.ts +40 -0
- package/dist/modes/select/hit-helpers.js +51 -0
- package/dist/modes/select/mode.d.ts +1 -0
- package/dist/modes/select/mode.js +397 -0
- package/dist/modes/select/shortcut-handler.d.ts +40 -0
- package/dist/modes/select/shortcut-handler.js +128 -0
- package/dist/operations/index.d.ts +9 -0
- package/dist/operations/index.js +3 -0
- package/dist/operations/layer-operations.d.ts +1 -0
- package/dist/operations/layer-operations.js +350 -0
- package/dist/operations/resize.d.ts +71 -0
- package/dist/operations/resize.js +252 -0
- package/dist/operations/rotate.d.ts +17 -0
- package/dist/operations/rotate.js +166 -0
- package/dist/operations/selection-operations.d.ts +20 -0
- package/dist/operations/selection-operations.js +159 -0
- package/dist/operations/shared-vertex.d.ts +1 -0
- package/dist/operations/shared-vertex.js +210 -0
- package/dist/operations/trace-graph.d.ts +96 -0
- package/dist/operations/trace-graph.js +283 -0
- package/dist/operations/vertex.d.ts +1 -0
- package/dist/operations/vertex.js +538 -0
- package/dist/plugins/index.d.ts +10 -0
- package/dist/plugins/index.js +3 -0
- package/dist/plugins/mutation-hooks.d.ts +28 -0
- package/dist/plugins/mutation-hooks.js +84 -0
- package/dist/plugins/plugin-context.d.ts +1 -0
- package/dist/plugins/plugin-context.js +367 -0
- package/dist/plugins/plugin-manager.d.ts +103 -0
- package/dist/plugins/plugin-manager.js +316 -0
- package/dist/plugins/plugin.d.ts +529 -0
- package/dist/plugins/plugin.js +3 -0
- package/dist/shared/config/constants.d.ts +66 -0
- package/dist/shared/config/constants.js +60 -0
- package/dist/shared/config/feature-style.d.ts +155 -0
- package/dist/shared/config/feature-style.js +154 -0
- package/dist/shared/config/index.d.ts +17 -0
- package/dist/shared/config/index.js +8 -0
- package/dist/shared/config/rendering.d.ts +107 -0
- package/dist/shared/config/rendering.js +33 -0
- package/dist/shared/config/selection-highlight.d.ts +29 -0
- package/dist/shared/config/selection-highlight.js +35 -0
- package/dist/shared/config/selection.d.ts +273 -0
- package/dist/shared/config/selection.js +266 -0
- package/dist/shared/config/topology.d.ts +33 -0
- package/dist/shared/config/topology.js +17 -0
- package/dist/shared/config/trace.d.ts +40 -0
- package/dist/shared/config/trace.js +17 -0
- package/dist/shared/math/angle.d.ts +21 -0
- package/dist/shared/math/angle.js +34 -0
- package/dist/shared/math/circle.d.ts +6 -0
- package/dist/shared/math/circle.js +10 -0
- package/dist/shared/math/constants.d.ts +48 -0
- package/dist/shared/math/constants.js +59 -0
- package/dist/shared/math/distance.d.ts +78 -0
- package/dist/shared/math/distance.js +147 -0
- package/dist/shared/math/globe-subdivision.d.ts +62 -0
- package/dist/shared/math/globe-subdivision.js +99 -0
- package/dist/shared/math/index.d.ts +17 -0
- package/dist/shared/math/index.js +21 -0
- package/dist/shared/math/intersection.d.ts +63 -0
- package/dist/shared/math/intersection.js +236 -0
- package/dist/shared/math/longitude.d.ts +20 -0
- package/dist/shared/math/longitude.js +31 -0
- package/dist/shared/math/mercator-plane.d.ts +27 -0
- package/dist/shared/math/mercator-plane.js +26 -0
- package/dist/shared/math/obb.d.ts +65 -0
- package/dist/shared/math/obb.js +107 -0
- package/dist/shared/math/rotation.d.ts +93 -0
- package/dist/shared/math/rotation.js +186 -0
- package/dist/shared/math/segment-grid.d.ts +69 -0
- package/dist/shared/math/segment-grid.js +159 -0
- package/dist/shared/math/transform.d.ts +140 -0
- package/dist/shared/math/transform.js +189 -0
- package/dist/shared/types/events.d.ts +128 -0
- package/dist/shared/types/events.js +3 -0
- package/dist/shared/types/model.d.ts +950 -0
- package/dist/shared/types/model.js +3 -0
- package/dist/shared/types/selection-box.d.ts +23 -0
- package/dist/shared/types/selection-box.js +3 -0
- package/dist/shared/types/style.d.ts +68 -0
- package/dist/shared/types/style.js +3 -0
- package/dist/shared/utils/color.d.ts +49 -0
- package/dist/shared/utils/color.js +180 -0
- package/dist/shared/utils/coordinates.d.ts +52 -0
- package/dist/shared/utils/coordinates.js +75 -0
- package/dist/shared/utils/embedded-image.d.ts +34 -0
- package/dist/shared/utils/embedded-image.js +161 -0
- package/dist/shared/utils/event-emitter.d.ts +262 -0
- package/dist/shared/utils/event-emitter.js +44 -0
- package/dist/shared/utils/feature-bbox.d.ts +8 -0
- package/dist/shared/utils/feature-bbox.js +207 -0
- package/dist/shared/utils/feature-segments.d.ts +23 -0
- package/dist/shared/utils/feature-segments.js +179 -0
- package/dist/shared/utils/id.d.ts +1 -0
- package/dist/shared/utils/id.js +35 -0
- package/dist/shared/utils/image.d.ts +34 -0
- package/dist/shared/utils/image.js +106 -0
- package/dist/shared/utils/index.d.ts +15 -0
- package/dist/shared/utils/index.js +24 -0
- package/dist/shared/utils/map.d.ts +26 -0
- package/dist/shared/utils/map.js +35 -0
- package/dist/shared/utils/name-generator.d.ts +197 -0
- package/dist/shared/utils/name-generator.js +337 -0
- package/dist/shared/utils/pixel-ratio.d.ts +111 -0
- package/dist/shared/utils/pixel-ratio.js +85 -0
- package/dist/shared/utils/property.d.ts +88 -0
- package/dist/shared/utils/property.js +140 -0
- package/dist/shared/utils/vertex-ref.d.ts +23 -0
- package/dist/shared/utils/vertex-ref.js +20 -0
- package/dist/snapping/custom-targets.d.ts +1 -0
- package/dist/snapping/custom-targets.js +21 -0
- package/dist/snapping/geometry.d.ts +1 -0
- package/dist/snapping/geometry.js +61 -0
- package/dist/snapping/index.d.ts +14 -0
- package/dist/snapping/index.js +4 -0
- package/dist/snapping/indicator.d.ts +19 -0
- package/dist/snapping/indicator.js +145 -0
- package/dist/snapping/providers/display.d.ts +72 -0
- package/dist/snapping/providers/display.js +268 -0
- package/dist/snapping/providers/guide.d.ts +69 -0
- package/dist/snapping/providers/guide.js +187 -0
- package/dist/snapping/providers/intersection.d.ts +1 -0
- package/dist/snapping/providers/intersection.js +92 -0
- package/dist/snapping/providers/shared.d.ts +39 -0
- package/dist/snapping/providers/shared.js +146 -0
- package/dist/snapping/providers/store.d.ts +1 -0
- package/dist/snapping/providers/store.js +132 -0
- package/dist/snapping/service.d.ts +1 -0
- package/dist/snapping/service.js +272 -0
- package/dist/snapping/types.d.ts +267 -0
- package/dist/snapping/types.js +66 -0
- package/dist/store/change-merger.d.ts +1 -0
- package/dist/store/change-merger.js +102 -0
- package/dist/store/draw-store.d.ts +1 -0
- package/dist/store/draw-store.js +396 -0
- package/dist/store/event-bridge.d.ts +1 -0
- package/dist/store/event-bridge.js +161 -0
- package/dist/store/index.d.ts +12 -0
- package/dist/store/index.js +4 -0
- package/dist/store/local-visibility.d.ts +21 -0
- package/dist/store/local-visibility.js +27 -0
- package/dist/store/lock.d.ts +67 -0
- package/dist/store/lock.js +54 -0
- package/dist/store/memory/change-bus.d.ts +60 -0
- package/dist/store/memory/change-bus.js +232 -0
- package/dist/store/memory/file-store.d.ts +15 -0
- package/dist/store/memory/file-store.js +33 -0
- package/dist/store/memory/frozen.d.ts +21 -0
- package/dist/store/memory/frozen.js +51 -0
- package/dist/store/memory/ui-state.d.ts +51 -0
- package/dist/store/memory/ui-state.js +223 -0
- package/dist/store/memory.d.ts +26 -0
- package/dist/store/memory.js +708 -0
- package/dist/store/spatial/index.d.ts +6 -0
- package/dist/store/spatial/index.js +4 -0
- package/dist/store/spatial/spatial-index.d.ts +90 -0
- package/dist/store/spatial/spatial-index.js +148 -0
- package/dist/store/spatial/store-spatial-index.d.ts +60 -0
- package/dist/store/spatial/store-spatial-index.js +125 -0
- package/dist/store/store.d.ts +417 -0
- package/dist/store/store.js +3 -0
- package/dist/store/types.d.ts +8 -0
- package/dist/store/types.js +3 -0
- package/dist/store/writable-layer.d.ts +35 -0
- package/dist/store/writable-layer.js +20 -0
- package/dist/view/cache/buffer.d.ts +28 -0
- package/dist/view/cache/buffer.js +176 -0
- package/dist/view/cache/earcut.d.ts +1 -0
- package/dist/view/cache/earcut.js +122 -0
- package/dist/view/cache/style-rule.d.ts +1 -0
- package/dist/view/cache/style-rule.js +97 -0
- package/dist/view/cache/terrain-fill.d.ts +30 -0
- package/dist/view/cache/terrain-fill.js +60 -0
- package/dist/view/cache/texture.d.ts +14 -0
- package/dist/view/cache/texture.js +292 -0
- package/dist/view/coordinator.d.ts +27 -0
- package/dist/view/coordinator.js +72 -0
- package/dist/view/feature-companion.d.ts +173 -0
- package/dist/view/feature-companion.js +108 -0
- package/dist/view/globe-subdivision.d.ts +78 -0
- package/dist/view/globe-subdivision.js +128 -0
- package/dist/view/index.d.ts +47 -0
- package/dist/view/index.js +20 -0
- package/dist/view/layer/attach.d.ts +20 -0
- package/dist/view/layer/attach.js +47 -0
- package/dist/view/layer/blend.d.ts +57 -0
- package/dist/view/layer/blend.js +14 -0
- package/dist/view/layer/custom-layer.d.ts +1 -0
- package/dist/view/layer/custom-layer.js +509 -0
- package/dist/view/layer/depth-state.d.ts +14 -0
- package/dist/view/layer/depth-state.js +44 -0
- package/dist/view/layer/display-list.d.ts +1 -0
- package/dist/view/layer/display-list.js +111 -0
- package/dist/view/layer/drape-planner.d.ts +139 -0
- package/dist/view/layer/drape-planner.js +726 -0
- package/dist/view/layer/frame-render.d.ts +57 -0
- package/dist/view/layer/frame-render.js +209 -0
- package/dist/view/layer/frame-state.d.ts +147 -0
- package/dist/view/layer/frame-state.js +484 -0
- package/dist/view/layer/gl-state.d.ts +77 -0
- package/dist/view/layer/gl-state.js +132 -0
- package/dist/view/layer/index.d.ts +6 -0
- package/dist/view/layer/index.js +5 -0
- package/dist/view/layer/render-scope.d.ts +30 -0
- package/dist/view/layer/render-scope.js +28 -0
- package/dist/view/layer/render.d.ts +87 -0
- package/dist/view/layer/render.js +187 -0
- package/dist/view/layer/renderers.d.ts +81 -0
- package/dist/view/layer/renderers.js +142 -0
- package/dist/view/layer/slot-manager.d.ts +26 -0
- package/dist/view/layer/slot-manager.js +133 -0
- package/dist/view/layer/slots.d.ts +33 -0
- package/dist/view/layer/slots.js +50 -0
- package/dist/view/layer/store-retained-bbox.d.ts +36 -0
- package/dist/view/layer/store-retained-bbox.js +188 -0
- package/dist/view/layer/store-retained-chunk.d.ts +97 -0
- package/dist/view/layer/store-retained-chunk.js +94 -0
- package/dist/view/layer/store-retained-classify.d.ts +34 -0
- package/dist/view/layer/store-retained-classify.js +88 -0
- package/dist/view/layer/store-retained-collect.d.ts +24 -0
- package/dist/view/layer/store-retained-collect.js +121 -0
- package/dist/view/layer/store-retained-coord-patch.d.ts +119 -0
- package/dist/view/layer/store-retained-coord-patch.js +168 -0
- package/dist/view/layer/store-retained-immediate.d.ts +63 -0
- package/dist/view/layer/store-retained-immediate.js +49 -0
- package/dist/view/layer/store-retained-invalidation.d.ts +96 -0
- package/dist/view/layer/store-retained-invalidation.js +192 -0
- package/dist/view/layer/store-retained.d.ts +198 -0
- package/dist/view/layer/store-retained.js +430 -0
- package/dist/view/layer/terrain-resolver.d.ts +1 -0
- package/dist/view/layer/terrain-resolver.js +174 -0
- package/dist/view/renderers/batch-manager.d.ts +61 -0
- package/dist/view/renderers/batch-manager.js +718 -0
- package/dist/view/renderers/draw-factors.d.ts +60 -0
- package/dist/view/renderers/draw-factors.js +35 -0
- package/dist/view/renderers/drawer.d.ts +1 -0
- package/dist/view/renderers/drawer.js +346 -0
- package/dist/view/renderers/image.d.ts +1 -0
- package/dist/view/renderers/image.js +255 -0
- package/dist/view/renderers/line/dash.d.ts +31 -0
- package/dist/view/renderers/line/dash.js +152 -0
- package/dist/view/renderers/line/line-geometry.d.ts +39 -0
- package/dist/view/renderers/line/line-geometry.js +460 -0
- package/dist/view/renderers/line/line-gl.d.ts +1 -0
- package/dist/view/renderers/line/line-gl.js +236 -0
- package/dist/view/renderers/line/line-shader.d.ts +1 -0
- package/dist/view/renderers/line/line-shader.js +364 -0
- package/dist/view/renderers/line/line-types.d.ts +43 -0
- package/dist/view/renderers/line/line-types.js +3 -0
- package/dist/view/renderers/line/line-uniforms.d.ts +1 -0
- package/dist/view/renderers/line/line-uniforms.js +390 -0
- package/dist/view/renderers/line/sdf-line.d.ts +92 -0
- package/dist/view/renderers/line/sdf-line.js +567 -0
- package/dist/view/renderers/point/billboard-depth.d.ts +10 -0
- package/dist/view/renderers/point/billboard-depth.js +56 -0
- package/dist/view/renderers/point/point-instance.d.ts +124 -0
- package/dist/view/renderers/point/point-instance.js +738 -0
- package/dist/view/renderers/point/point-sdf.d.ts +58 -0
- package/dist/view/renderers/point/point-sdf.js +170 -0
- package/dist/view/renderers/point/point-shape.d.ts +99 -0
- package/dist/view/renderers/point/point-shape.js +504 -0
- package/dist/view/renderers/point/point-style.d.ts +1 -0
- package/dist/view/renderers/point/point-style.js +46 -0
- package/dist/view/renderers/polygon/batch.d.ts +26 -0
- package/dist/view/renderers/polygon/batch.js +336 -0
- package/dist/view/renderers/polygon/earcut-input.d.ts +37 -0
- package/dist/view/renderers/polygon/earcut-input.js +55 -0
- package/dist/view/renderers/polygon/earcut-sliced.d.ts +69 -0
- package/dist/view/renderers/polygon/earcut-sliced.js +960 -0
- package/dist/view/renderers/polygon/fill.d.ts +74 -0
- package/dist/view/renderers/polygon/fill.js +251 -0
- package/dist/view/renderers/polygon/sdf-polygon.d.ts +62 -0
- package/dist/view/renderers/polygon/sdf-polygon.js +919 -0
- package/dist/view/renderers/polygon/terrain-cull.d.ts +3 -0
- package/dist/view/renderers/polygon/terrain-cull.js +14 -0
- package/dist/view/renderers/polygon/triangulator.d.ts +41 -0
- package/dist/view/renderers/polygon/triangulator.js +3 -0
- package/dist/view/renderers/retained.d.ts +43 -0
- package/dist/view/renderers/retained.js +3 -0
- package/dist/view/renderers/stroke.d.ts +121 -0
- package/dist/view/renderers/stroke.js +621 -0
- package/dist/view/shaders/frame.d.ts +8 -0
- package/dist/view/shaders/frame.js +37 -0
- package/dist/view/shaders/helpers.d.ts +238 -0
- package/dist/view/shaders/helpers.js +611 -0
- package/dist/view/shaders/initializer.d.ts +27 -0
- package/dist/view/shaders/initializer.js +125 -0
- package/dist/view/shaders/projection.d.ts +123 -0
- package/dist/view/shaders/projection.js +299 -0
- package/dist/view/shaders/quad-grid.d.ts +77 -0
- package/dist/view/shaders/quad-grid.js +128 -0
- package/dist/view/shaders/quad.d.ts +189 -0
- package/dist/view/shaders/quad.js +582 -0
- package/dist/view/shaders/retained-origin.d.ts +50 -0
- package/dist/view/shaders/retained-origin.js +67 -0
- package/dist/view/shaders/terrain-shade.d.ts +23 -0
- package/dist/view/shaders/terrain-shade.js +93 -0
- package/dist/view/style-rule.d.ts +166 -0
- package/dist/view/style-rule.js +300 -0
- package/dist/view/terrain/anchor.d.ts +135 -0
- package/dist/view/terrain/anchor.js +226 -0
- package/dist/view/terrain/context.d.ts +132 -0
- package/dist/view/terrain/context.js +437 -0
- package/dist/view/terrain/dem-atlas.d.ts +97 -0
- package/dist/view/terrain/dem-atlas.js +534 -0
- package/dist/view/terrain/detect.d.ts +126 -0
- package/dist/view/terrain/detect.js +198 -0
- package/dist/view/terrain/drape/bin-store.d.ts +179 -0
- package/dist/view/terrain/drape/bin-store.js +529 -0
- package/dist/view/terrain/drape/binning.d.ts +259 -0
- package/dist/view/terrain/drape/binning.js +604 -0
- package/dist/view/terrain/drape/edge-constrain.d.ts +37 -0
- package/dist/view/terrain/drape/edge-constrain.js +175 -0
- package/dist/view/terrain/drape/geometry.d.ts +95 -0
- package/dist/view/terrain/drape/geometry.js +260 -0
- package/dist/view/terrain/drape/mesh.d.ts +50 -0
- package/dist/view/terrain/drape/mesh.js +86 -0
- package/dist/view/terrain/drape/pass.d.ts +122 -0
- package/dist/view/terrain/drape/pass.js +379 -0
- package/dist/view/terrain/drape/quad-glyphs.d.ts +64 -0
- package/dist/view/terrain/drape/quad-glyphs.js +117 -0
- package/dist/view/terrain/drape/quad.d.ts +249 -0
- package/dist/view/terrain/drape/quad.js +835 -0
- package/dist/view/terrain/drape/renderer.d.ts +184 -0
- package/dist/view/terrain/drape/renderer.js +706 -0
- package/dist/view/terrain/drape/shared.d.ts +80 -0
- package/dist/view/terrain/drape/shared.js +173 -0
- package/dist/view/terrain/drape/stitch.d.ts +155 -0
- package/dist/view/terrain/drape/stitch.js +228 -0
- package/dist/view/terrain/ground.d.ts +72 -0
- package/dist/view/terrain/ground.js +151 -0
- package/dist/view/terrain/metrics.d.ts +180 -0
- package/dist/view/terrain/metrics.js +231 -0
- package/dist/view/terrain/occlusion.d.ts +11 -0
- package/dist/view/terrain/occlusion.js +129 -0
- package/dist/view/terrain/polygon.d.ts +86 -0
- package/dist/view/terrain/polygon.js +301 -0
- package/dist/view/terrain/shade.d.ts +48 -0
- package/dist/view/terrain/shade.js +45 -0
- package/dist/view/terrain/state.d.ts +99 -0
- package/dist/view/terrain/state.js +186 -0
- package/dist/view/terrain/tessellation.d.ts +265 -0
- package/dist/view/terrain/tessellation.js +924 -0
- package/dist/view/terrain/tiling.d.ts +56 -0
- package/dist/view/terrain/tiling.js +155 -0
- package/dist/view/terrain/upstream-terrain.d.ts +82 -0
- package/dist/view/terrain/upstream-terrain.js +116 -0
- package/dist/view/ui/auxiliary-handles.d.ts +151 -0
- package/dist/view/ui/auxiliary-handles.js +22 -0
- package/dist/view/ui/bounds.d.ts +53 -0
- package/dist/view/ui/bounds.js +149 -0
- package/dist/view/ui/box-selection.d.ts +1 -0
- package/dist/view/ui/box-selection.js +83 -0
- package/dist/view/ui/handle-test.d.ts +1 -0
- package/dist/view/ui/handle-test.js +437 -0
- package/dist/view/ui/handle-thinning.d.ts +122 -0
- package/dist/view/ui/handle-thinning.js +430 -0
- package/dist/view/ui/handles.d.ts +25 -0
- package/dist/view/ui/handles.js +673 -0
- package/dist/view/ui/helper.d.ts +19 -0
- package/dist/view/ui/helper.js +76 -0
- package/dist/view/ui/index.d.ts +15 -0
- package/dist/view/ui/index.js +15 -0
- package/dist/view/ui/selection-scope.d.ts +25 -0
- package/dist/view/ui/selection-scope.js +34 -0
- package/dist/view/ui/selection-ui/bounding-box.d.ts +44 -0
- package/dist/view/ui/selection-ui/bounding-box.js +240 -0
- package/dist/view/ui/selection-ui/extension-registry.d.ts +76 -0
- package/dist/view/ui/selection-ui/extension-registry.js +78 -0
- package/dist/view/ui/selection-ui/index.d.ts +12 -0
- package/dist/view/ui/selection-ui/index.js +12 -0
- package/dist/view/ui/selection-ui/renderer.d.ts +29 -0
- package/dist/view/ui/selection-ui/renderer.js +227 -0
- package/dist/view/ui/selection-ui/types.d.ts +55 -0
- package/dist/view/ui/selection-ui/types.js +3 -0
- package/dist/view/ui/selection-ui-drawer.d.ts +52 -0
- package/dist/view/ui/selection-ui-drawer.js +329 -0
- package/dist/view/ui/tentative.d.ts +1 -0
- package/dist/view/ui/tentative.js +320 -0
- package/dist/view/viewport.d.ts +119 -0
- package/dist/view/viewport.js +254 -0
- package/package.json +113 -0
|
@@ -0,0 +1,538 @@
|
|
|
1
|
+
// SPDX-FileCopyrightText: 2026 SAKAIDA Atsushi
|
|
2
|
+
// SPDX-License-Identifier: AGPL-3.0-only
|
|
3
|
+
/**
|
|
4
|
+
* Vertex operations
|
|
5
|
+
*
|
|
6
|
+
* The operations that edit the vertices of a feature
|
|
7
|
+
*
|
|
8
|
+
* A vertex is pointed to by a part number + a ring number + a vertex index
|
|
9
|
+
* (VertexRef). A Polygon can have inner rings (holes, ring 1 onwards) in addition to
|
|
10
|
+
* its outer ring (ring 0), so every operation can work across rings. The Multi
|
|
11
|
+
* variants (MultiPoint / MultiLineString / MultiPolygon) can work across parts as
|
|
12
|
+
* well.
|
|
13
|
+
*
|
|
14
|
+
* When part is omitted it means 0. For a single geometry that has no parts
|
|
15
|
+
* (Point / LineString / Polygon) only part 0 is valid, and any part other than 0 is
|
|
16
|
+
* regarded as an invalid reference. Likewise, for LineString / Point, which have no
|
|
17
|
+
* rings, ring is always treated as 0, and any ring other than 0 is regarded as an
|
|
18
|
+
* invalid reference.
|
|
19
|
+
*/
|
|
20
|
+
import { getVertexPart } from '../shared/utils/vertex-ref.js';
|
|
21
|
+
/**
|
|
22
|
+
* Whether the ring is closed (first = last)
|
|
23
|
+
*/
|
|
24
|
+
function isClosedRing(ring) {
|
|
25
|
+
return (ring.length >= 2 &&
|
|
26
|
+
ring[0][0] === ring[ring.length - 1][0] &&
|
|
27
|
+
ring[0][1] === ring[ring.length - 1][1]);
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Picks out only the vertex references that belong to the given part
|
|
31
|
+
*/
|
|
32
|
+
function refsOfPart(refs, part) {
|
|
33
|
+
return refs.filter((r) => getVertexPart(r) === part);
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Sorts the vertex references into the order in which vertex deletion is applied
|
|
37
|
+
*
|
|
38
|
+
* Within one ring, unless the larger index is deleted first, the following indices
|
|
39
|
+
* shift by the number already removed. The same holds for parts and rings (deleting
|
|
40
|
+
* from a MultiPoint removes the part itself, so the part numbers shift). They are
|
|
41
|
+
* therefore sorted in descending lexicographic order of (part, ring, index). That
|
|
42
|
+
* way, within the same part and the same ring the order is descending by index as
|
|
43
|
+
* before, and references in different parts or rings do not affect each other's
|
|
44
|
+
* indices.
|
|
45
|
+
*
|
|
46
|
+
* @internal
|
|
47
|
+
*/
|
|
48
|
+
export function sortVertexRefsForDeletion(refs) {
|
|
49
|
+
return [...refs].sort((a, b) => {
|
|
50
|
+
const partDiff = getVertexPart(b) - getVertexPart(a);
|
|
51
|
+
if (partDiff !== 0)
|
|
52
|
+
return partDiff;
|
|
53
|
+
const ringDiff = b.ring - a.ring;
|
|
54
|
+
if (ringDiff !== 0)
|
|
55
|
+
return ringDiff;
|
|
56
|
+
return b.index - a.index;
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Groups the vertex references by part number
|
|
61
|
+
*
|
|
62
|
+
* For copy-on-write, only "the parts that have references" need to be known. Calling
|
|
63
|
+
* refsOfPart for each part would scan the references times the number of parts, so
|
|
64
|
+
* they are sorted out in a single pass.
|
|
65
|
+
*/
|
|
66
|
+
function groupRefsByPart(refs) {
|
|
67
|
+
const grouped = new Map();
|
|
68
|
+
for (const ref of refs) {
|
|
69
|
+
const part = getVertexPart(ref);
|
|
70
|
+
const list = grouped.get(part);
|
|
71
|
+
if (list) {
|
|
72
|
+
list.push(ref);
|
|
73
|
+
}
|
|
74
|
+
else {
|
|
75
|
+
grouped.set(part, [ref]);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
return grouped;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Copies an array of rings with copy-on-write
|
|
82
|
+
*
|
|
83
|
+
* Only the rings that have references are replaced with new arrays; the other rings
|
|
84
|
+
* keep sharing the original arrays. movePolygonVertices updates the array of rings
|
|
85
|
+
* destructively (the contents of a vertex are assigned as a new pair array, so the
|
|
86
|
+
* original pairs are not mutated), so the rings that may be rewritten have to be cut
|
|
87
|
+
* out in advance. The synchronization of a closed ring also touches only the rings
|
|
88
|
+
* that have references.
|
|
89
|
+
*/
|
|
90
|
+
function copyRingsForRefs(initialRings, refs) {
|
|
91
|
+
const rings = initialRings.slice();
|
|
92
|
+
for (const ref of refs) {
|
|
93
|
+
if (ref.ring < 0 || ref.ring >= rings.length)
|
|
94
|
+
continue;
|
|
95
|
+
if (rings[ref.ring] === initialRings[ref.ring]) {
|
|
96
|
+
rings[ref.ring] = initialRings[ref.ring].slice();
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
return rings;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Moves the vertices of a line (a single coordinate sequence)
|
|
103
|
+
*
|
|
104
|
+
* It has no rings, so any reference other than ring 0 is ignored.
|
|
105
|
+
* coords is updated destructively, so the caller must pass a copied array.
|
|
106
|
+
* A vertex is always rewritten by assigning a new pair array (the original pairs are
|
|
107
|
+
* shared, so [0] / [1] must not be rewritten directly).
|
|
108
|
+
*/
|
|
109
|
+
function moveLineVertices(coords, refs, dx, dy) {
|
|
110
|
+
for (const ref of refs) {
|
|
111
|
+
if (ref.ring !== 0)
|
|
112
|
+
continue;
|
|
113
|
+
if (ref.index >= 0 && ref.index < coords.length) {
|
|
114
|
+
coords[ref.index] = [coords[ref.index][0] + dx, coords[ref.index][1] + dy];
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Moves the vertices of a polygon (an array of rings) and keeps the rings closed
|
|
120
|
+
*
|
|
121
|
+
* Keeping a ring closed is done ring by ring. Only the rings that were closed before
|
|
122
|
+
* the move are targeted, and when only one of the first and the last vertex moved,
|
|
123
|
+
* it is synchronized to the other one (when both moved, the amount of movement is
|
|
124
|
+
* the same, so it stays closed).
|
|
125
|
+
*
|
|
126
|
+
* rings and the rings within it that have references are updated destructively, so
|
|
127
|
+
* the caller must pass what was copied by copyRingsForRefs. A vertex is always
|
|
128
|
+
* rewritten by assigning a new pair array (the original pairs are shared with
|
|
129
|
+
* initialRings).
|
|
130
|
+
*/
|
|
131
|
+
function movePolygonVertices(rings, initialRings, refs, dx, dy) {
|
|
132
|
+
for (const ref of refs) {
|
|
133
|
+
if (ref.ring < 0 || ref.ring >= rings.length)
|
|
134
|
+
continue;
|
|
135
|
+
const ring = rings[ref.ring];
|
|
136
|
+
if (ref.index >= 0 && ref.index < ring.length) {
|
|
137
|
+
ring[ref.index] = [ring[ref.index][0] + dx, ring[ref.index][1] + dy];
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
for (let ringIndex = 0; ringIndex < rings.length; ringIndex++) {
|
|
141
|
+
const ring = rings[ringIndex];
|
|
142
|
+
if (!isClosedRing(initialRings[ringIndex]))
|
|
143
|
+
continue;
|
|
144
|
+
// refs has already been narrowed down by part, so only the ring and the index are
|
|
145
|
+
// looked at here
|
|
146
|
+
const lastIndex = ring.length - 1;
|
|
147
|
+
const movedFirst = refs.some((r) => r.ring === ringIndex && r.index === 0);
|
|
148
|
+
const movedLast = refs.some((r) => r.ring === ringIndex && r.index === lastIndex);
|
|
149
|
+
if (movedFirst && !movedLast) {
|
|
150
|
+
ring[lastIndex] = [...ring[0]];
|
|
151
|
+
}
|
|
152
|
+
else if (movedLast && !movedFirst) {
|
|
153
|
+
ring[0] = [...ring[lastIndex]];
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Computes the movement of vertices
|
|
159
|
+
*
|
|
160
|
+
* The coordinates are built with copy-on-write. initialCoordinates is not copied as
|
|
161
|
+
* a whole; only the levels the moving vertices belong to (the top-level array and
|
|
162
|
+
* the parts / rings that have references) are replaced with new arrays, and the
|
|
163
|
+
* other elements keep sharing references with initialCoordinates. This function runs
|
|
164
|
+
* once per movement during a drag, so with a full copy the cost would be
|
|
165
|
+
* proportional to the number of vertices. The shared elements are not rewritten, so
|
|
166
|
+
* initialCoordinates is not mutated.
|
|
167
|
+
*
|
|
168
|
+
* The top-level array is always returned as a new array even when nothing changed
|
|
169
|
+
* (the caller assumes that "new coordinates are returned").
|
|
170
|
+
*
|
|
171
|
+
* @internal
|
|
172
|
+
*/
|
|
173
|
+
export function computeVertexMove(state, currentLngLat, feature) {
|
|
174
|
+
const { vertexIndices, startLngLat, initialCoordinates } = state;
|
|
175
|
+
// Compute the amount of movement
|
|
176
|
+
const dx = currentLngLat.lng - startLngLat.lng;
|
|
177
|
+
const dy = currentLngLat.lat - startLngLat.lat;
|
|
178
|
+
if (feature.type === 'Point') {
|
|
179
|
+
// A Point is a single coordinate
|
|
180
|
+
const coord = initialCoordinates;
|
|
181
|
+
return [coord[0] + dx, coord[1] + dy];
|
|
182
|
+
}
|
|
183
|
+
// For a single geometry, only the references of part 0 are looked at (part > 0 is an
|
|
184
|
+
// invalid reference)
|
|
185
|
+
if (feature.type === 'LineString') {
|
|
186
|
+
const coords = initialCoordinates.slice();
|
|
187
|
+
moveLineVertices(coords, refsOfPart(vertexIndices, 0), dx, dy);
|
|
188
|
+
return coords;
|
|
189
|
+
}
|
|
190
|
+
if (feature.type === 'Polygon') {
|
|
191
|
+
const initialRings = initialCoordinates;
|
|
192
|
+
const refs = refsOfPart(vertexIndices, 0);
|
|
193
|
+
const rings = copyRingsForRefs(initialRings, refs);
|
|
194
|
+
movePolygonVertices(rings, initialRings, refs, dx, dy);
|
|
195
|
+
return rings;
|
|
196
|
+
}
|
|
197
|
+
if (feature.type === 'MultiPoint') {
|
|
198
|
+
// Each coordinate is one part. In a reference, part = the part number, and
|
|
199
|
+
// ring / index are 0
|
|
200
|
+
const points = initialCoordinates.slice();
|
|
201
|
+
for (const ref of vertexIndices) {
|
|
202
|
+
if (ref.ring !== 0 || ref.index !== 0)
|
|
203
|
+
continue;
|
|
204
|
+
const part = getVertexPart(ref);
|
|
205
|
+
if (part < 0 || part >= points.length)
|
|
206
|
+
continue;
|
|
207
|
+
points[part] = [points[part][0] + dx, points[part][1] + dy];
|
|
208
|
+
}
|
|
209
|
+
return points;
|
|
210
|
+
}
|
|
211
|
+
if (feature.type === 'MultiLineString') {
|
|
212
|
+
// Copy only the parts that have references. A part without references shares the
|
|
213
|
+
// original array
|
|
214
|
+
const initialParts = initialCoordinates;
|
|
215
|
+
const parts = initialParts.slice();
|
|
216
|
+
for (const [part, refs] of groupRefsByPart(vertexIndices)) {
|
|
217
|
+
if (part < 0 || part >= parts.length)
|
|
218
|
+
continue;
|
|
219
|
+
const coords = initialParts[part].slice();
|
|
220
|
+
moveLineVertices(coords, refs, dx, dy);
|
|
221
|
+
parts[part] = coords;
|
|
222
|
+
}
|
|
223
|
+
return parts;
|
|
224
|
+
}
|
|
225
|
+
if (feature.type === 'MultiPolygon') {
|
|
226
|
+
const initialParts = initialCoordinates;
|
|
227
|
+
const parts = initialParts.slice();
|
|
228
|
+
for (const [part, refs] of groupRefsByPart(vertexIndices)) {
|
|
229
|
+
if (part < 0 || part >= parts.length)
|
|
230
|
+
continue;
|
|
231
|
+
const initialRings = initialParts[part];
|
|
232
|
+
const rings = copyRingsForRefs(initialRings, refs);
|
|
233
|
+
movePolygonVertices(rings, initialRings, refs, dx, dy);
|
|
234
|
+
parts[part] = rings;
|
|
235
|
+
}
|
|
236
|
+
return parts;
|
|
237
|
+
}
|
|
238
|
+
// Types without vertex movement (Circle / Image and so on). startVertexMove creates
|
|
239
|
+
// no state for them so control does not reach here, but even if it does the
|
|
240
|
+
// coordinates are not changed
|
|
241
|
+
return initialCoordinates;
|
|
242
|
+
}
|
|
243
|
+
/**
|
|
244
|
+
* Makes only the top-level array of the coordinates new
|
|
245
|
+
*
|
|
246
|
+
* A copy that keeps the current contract, "a new top-level array is returned", even
|
|
247
|
+
* on a branch that does not change the coordinates. The elements (parts / rings /
|
|
248
|
+
* coordinate pairs) keep sharing references with the input.
|
|
249
|
+
*/
|
|
250
|
+
function copyTopLevelCoordinates(coordinates) {
|
|
251
|
+
return coordinates.slice();
|
|
252
|
+
}
|
|
253
|
+
/**
|
|
254
|
+
* Adds a vertex (an addition from a midpoint handle)
|
|
255
|
+
*
|
|
256
|
+
* A MultiPoint has no edges, so there is no addition from a midpoint, and the
|
|
257
|
+
* coordinates are never changed.
|
|
258
|
+
*
|
|
259
|
+
* The coordinates are built with copy-on-write (the same manner as
|
|
260
|
+
* computeVertexMove). The top-level array is always made new, only the container
|
|
261
|
+
* that splice changes (the target ring / part) is copied, and the other parts /
|
|
262
|
+
* rings / coordinate pairs keep sharing references with the input. The input
|
|
263
|
+
* feature.coordinates is never rewritten. For a feature on the order of 100,000
|
|
264
|
+
* vertices a full copy took more than ten milliseconds each time, which produced a
|
|
265
|
+
* hitch on a single click that added a vertex.
|
|
266
|
+
*
|
|
267
|
+
* @param after The vertex reference just before the position where the new vertex is
|
|
268
|
+
* inserted
|
|
269
|
+
*
|
|
270
|
+
* @internal
|
|
271
|
+
*/
|
|
272
|
+
export function addVertex(feature, after, newCoord) {
|
|
273
|
+
const part = getVertexPart(after);
|
|
274
|
+
if (feature.type === 'LineString') {
|
|
275
|
+
const lineCoords = feature.coordinates.slice();
|
|
276
|
+
// It has neither rings nor parts, so nothing is added other than ring 0 / part 0
|
|
277
|
+
if (after.ring !== 0 || part !== 0)
|
|
278
|
+
return lineCoords;
|
|
279
|
+
lineCoords.splice(after.index + 1, 0, newCoord);
|
|
280
|
+
return lineCoords;
|
|
281
|
+
}
|
|
282
|
+
if (feature.type === 'Polygon') {
|
|
283
|
+
const initialRings = feature.coordinates;
|
|
284
|
+
const rings = initialRings.slice();
|
|
285
|
+
if (part !== 0)
|
|
286
|
+
return rings;
|
|
287
|
+
if (after.ring < 0 || after.ring >= rings.length)
|
|
288
|
+
return rings;
|
|
289
|
+
const ring = initialRings[after.ring].slice();
|
|
290
|
+
ring.splice(after.index + 1, 0, newCoord);
|
|
291
|
+
rings[after.ring] = ring;
|
|
292
|
+
return rings;
|
|
293
|
+
}
|
|
294
|
+
if (feature.type === 'MultiLineString') {
|
|
295
|
+
const initialParts = feature.coordinates;
|
|
296
|
+
const parts = initialParts.slice();
|
|
297
|
+
if (after.ring !== 0)
|
|
298
|
+
return parts;
|
|
299
|
+
if (part < 0 || part >= parts.length)
|
|
300
|
+
return parts;
|
|
301
|
+
const line = initialParts[part].slice();
|
|
302
|
+
line.splice(after.index + 1, 0, newCoord);
|
|
303
|
+
parts[part] = line;
|
|
304
|
+
return parts;
|
|
305
|
+
}
|
|
306
|
+
if (feature.type === 'MultiPolygon') {
|
|
307
|
+
const initialParts = feature.coordinates;
|
|
308
|
+
const parts = initialParts.slice();
|
|
309
|
+
if (part < 0 || part >= parts.length)
|
|
310
|
+
return parts;
|
|
311
|
+
const initialRings = initialParts[part];
|
|
312
|
+
if (after.ring < 0 || after.ring >= initialRings.length)
|
|
313
|
+
return parts;
|
|
314
|
+
const rings = initialRings.slice();
|
|
315
|
+
const ring = initialRings[after.ring].slice();
|
|
316
|
+
ring.splice(after.index + 1, 0, newCoord);
|
|
317
|
+
rings[after.ring] = ring;
|
|
318
|
+
parts[part] = rings;
|
|
319
|
+
return parts;
|
|
320
|
+
}
|
|
321
|
+
return copyTopLevelCoordinates(feature.coordinates);
|
|
322
|
+
}
|
|
323
|
+
/**
|
|
324
|
+
* Returns an array of rings with one vertex deleted from a ring of the polygon
|
|
325
|
+
*
|
|
326
|
+
* The tests for the minimum vertex count and for a closed ring are done per ring. For
|
|
327
|
+
* a MultiPolygon they are done per part and ring (even if a ring of one part is at
|
|
328
|
+
* the minimum vertex count, the other parts are unaffected).
|
|
329
|
+
*
|
|
330
|
+
* copy-on-write: only the array of rings and the target ring are copied, and the
|
|
331
|
+
* other rings and the coordinate pairs keep sharing references with initialRings.
|
|
332
|
+
* initialRings is not rewritten.
|
|
333
|
+
*
|
|
334
|
+
* @returns The new array of rings when the deletion succeeded, null when it did not
|
|
335
|
+
*/
|
|
336
|
+
function deleteVertexFromRings(initialRings, ref) {
|
|
337
|
+
if (ref.ring < 0 || ref.ring >= initialRings.length)
|
|
338
|
+
return null;
|
|
339
|
+
const initialRing = initialRings[ref.ring];
|
|
340
|
+
const isClosed = isClosedRing(initialRing);
|
|
341
|
+
// A polygon needs at least 3 points (4 counting the closing point). An inner ring
|
|
342
|
+
// has the same condition, and a ring that cannot be reduced any further refuses the
|
|
343
|
+
// deletion (no collapsed ring is created).
|
|
344
|
+
const minPoints = isClosed ? 4 : 3;
|
|
345
|
+
if (initialRing.length <= minPoints)
|
|
346
|
+
return null;
|
|
347
|
+
// Out of range is refused
|
|
348
|
+
if (ref.index < 0 || ref.index >= initialRing.length)
|
|
349
|
+
return null;
|
|
350
|
+
// The last vertex of a closed ring is a duplicate of the first one (the closing
|
|
351
|
+
// point) and is not an independent vertex. Deleting it would break the ring (the
|
|
352
|
+
// first one would be overwritten by the value of the last one), so it is refused.
|
|
353
|
+
// To remove the closing point, delete the first one (index 0).
|
|
354
|
+
if (isClosed && ref.index === initialRing.length - 1)
|
|
355
|
+
return null;
|
|
356
|
+
// Delete (this is done on the copied ring)
|
|
357
|
+
const ring = initialRing.slice();
|
|
358
|
+
ring.splice(ref.index, 1);
|
|
359
|
+
// When the first vertex of a closed ring was removed, the new last one (= the old
|
|
360
|
+
// closing point) is synchronized to the new first one so that it stays closed. For
|
|
361
|
+
// any other vertex deletion the first and the last ones do not change, so no
|
|
362
|
+
// synchronization is needed.
|
|
363
|
+
// The rewrite is done by assigning a new pair array (because the coordinate pairs
|
|
364
|
+
// are shared with the input).
|
|
365
|
+
if (isClosed && ref.index === 0) {
|
|
366
|
+
ring[ring.length - 1] = [...ring[0]];
|
|
367
|
+
}
|
|
368
|
+
const rings = initialRings.slice();
|
|
369
|
+
rings[ref.ring] = ring;
|
|
370
|
+
return rings;
|
|
371
|
+
}
|
|
372
|
+
/**
|
|
373
|
+
* Deletes a vertex
|
|
374
|
+
*
|
|
375
|
+
* The coordinates are built with copy-on-write (the same manner as
|
|
376
|
+
* computeVertexMove). The top-level array is always made new, only the container
|
|
377
|
+
* that splice changes (the target ring / part) is copied, and the other parts /
|
|
378
|
+
* rings / coordinate pairs keep sharing references with the input. The input
|
|
379
|
+
* feature.coordinates is never rewritten.
|
|
380
|
+
*
|
|
381
|
+
* @internal
|
|
382
|
+
*/
|
|
383
|
+
export function deleteVertex(feature, ref) {
|
|
384
|
+
const part = getVertexPart(ref);
|
|
385
|
+
if (feature.type === 'Point') {
|
|
386
|
+
// The vertex of a Point cannot be deleted
|
|
387
|
+
return null;
|
|
388
|
+
}
|
|
389
|
+
if (feature.type === 'LineString') {
|
|
390
|
+
// It has neither rings nor parts, so anything other than ring 0 / part 0 is an
|
|
391
|
+
// invalid reference
|
|
392
|
+
if (ref.ring !== 0 || part !== 0)
|
|
393
|
+
return null;
|
|
394
|
+
const initialCoords = feature.coordinates;
|
|
395
|
+
// At least 2 points are needed
|
|
396
|
+
if (initialCoords.length <= 2)
|
|
397
|
+
return null;
|
|
398
|
+
const lineCoords = initialCoords.slice();
|
|
399
|
+
lineCoords.splice(ref.index, 1);
|
|
400
|
+
return lineCoords;
|
|
401
|
+
}
|
|
402
|
+
if (feature.type === 'Polygon') {
|
|
403
|
+
if (part !== 0)
|
|
404
|
+
return null;
|
|
405
|
+
return deleteVertexFromRings(feature.coordinates, ref);
|
|
406
|
+
}
|
|
407
|
+
if (feature.type === 'MultiPoint') {
|
|
408
|
+
// Deleting a vertex removes the part itself. The last remaining part cannot be
|
|
409
|
+
// removed
|
|
410
|
+
const initialPoints = feature.coordinates;
|
|
411
|
+
if (ref.ring !== 0 || ref.index !== 0)
|
|
412
|
+
return null;
|
|
413
|
+
if (part < 0 || part >= initialPoints.length)
|
|
414
|
+
return null;
|
|
415
|
+
if (initialPoints.length <= 1)
|
|
416
|
+
return null;
|
|
417
|
+
const points = initialPoints.slice();
|
|
418
|
+
points.splice(part, 1);
|
|
419
|
+
return points;
|
|
420
|
+
}
|
|
421
|
+
if (feature.type === 'MultiLineString') {
|
|
422
|
+
const initialParts = feature.coordinates;
|
|
423
|
+
if (ref.ring !== 0)
|
|
424
|
+
return null;
|
|
425
|
+
if (part < 0 || part >= initialParts.length)
|
|
426
|
+
return null;
|
|
427
|
+
const initialLine = initialParts[part];
|
|
428
|
+
// At least 2 points are needed (this is decided per part)
|
|
429
|
+
if (initialLine.length <= 2)
|
|
430
|
+
return null;
|
|
431
|
+
const line = initialLine.slice();
|
|
432
|
+
line.splice(ref.index, 1);
|
|
433
|
+
const parts = initialParts.slice();
|
|
434
|
+
parts[part] = line;
|
|
435
|
+
return parts;
|
|
436
|
+
}
|
|
437
|
+
if (feature.type === 'MultiPolygon') {
|
|
438
|
+
const initialParts = feature.coordinates;
|
|
439
|
+
if (part < 0 || part >= initialParts.length)
|
|
440
|
+
return null;
|
|
441
|
+
const rings = deleteVertexFromRings(initialParts[part], ref);
|
|
442
|
+
if (!rings)
|
|
443
|
+
return null;
|
|
444
|
+
const parts = initialParts.slice();
|
|
445
|
+
parts[part] = rings;
|
|
446
|
+
return parts;
|
|
447
|
+
}
|
|
448
|
+
return copyTopLevelCoordinates(feature.coordinates);
|
|
449
|
+
}
|
|
450
|
+
/**
|
|
451
|
+
* Starts the vertex movement operation
|
|
452
|
+
*
|
|
453
|
+
* @internal
|
|
454
|
+
*/
|
|
455
|
+
export function startVertexMove(feature, vertexIndices, startLngLat) {
|
|
456
|
+
if (vertexIndices.length === 0)
|
|
457
|
+
return null;
|
|
458
|
+
// Check the validity of the vertex references
|
|
459
|
+
if (feature.type === 'Point') {
|
|
460
|
+
if (vertexIndices.length !== 1)
|
|
461
|
+
return null;
|
|
462
|
+
const ref = vertexIndices[0];
|
|
463
|
+
if (getVertexPart(ref) !== 0 || ref.ring !== 0 || ref.index !== 0)
|
|
464
|
+
return null;
|
|
465
|
+
}
|
|
466
|
+
else if (feature.type === 'LineString') {
|
|
467
|
+
const coords = feature.coordinates;
|
|
468
|
+
const isValid = vertexIndices.every((r) => getVertexPart(r) === 0 && r.ring === 0 && r.index >= 0 && r.index < coords.length);
|
|
469
|
+
if (!isValid)
|
|
470
|
+
return null;
|
|
471
|
+
}
|
|
472
|
+
else if (feature.type === 'Polygon') {
|
|
473
|
+
const rings = feature.coordinates;
|
|
474
|
+
if (rings.length === 0)
|
|
475
|
+
return null;
|
|
476
|
+
const isValid = vertexIndices.every((r) => getVertexPart(r) === 0 &&
|
|
477
|
+
r.ring >= 0 &&
|
|
478
|
+
r.ring < rings.length &&
|
|
479
|
+
r.index >= 0 &&
|
|
480
|
+
r.index < rings[r.ring].length);
|
|
481
|
+
if (!isValid)
|
|
482
|
+
return null;
|
|
483
|
+
}
|
|
484
|
+
else if (feature.type === 'MultiPoint') {
|
|
485
|
+
const points = feature.coordinates;
|
|
486
|
+
if (points.length === 0)
|
|
487
|
+
return null;
|
|
488
|
+
const isValid = vertexIndices.every((r) => {
|
|
489
|
+
const part = getVertexPart(r);
|
|
490
|
+
return part >= 0 && part < points.length && r.ring === 0 && r.index === 0;
|
|
491
|
+
});
|
|
492
|
+
if (!isValid)
|
|
493
|
+
return null;
|
|
494
|
+
}
|
|
495
|
+
else if (feature.type === 'MultiLineString') {
|
|
496
|
+
const parts = feature.coordinates;
|
|
497
|
+
if (parts.length === 0)
|
|
498
|
+
return null;
|
|
499
|
+
const isValid = vertexIndices.every((r) => {
|
|
500
|
+
const part = getVertexPart(r);
|
|
501
|
+
if (part < 0 || part >= parts.length)
|
|
502
|
+
return false;
|
|
503
|
+
return r.ring === 0 && r.index >= 0 && r.index < parts[part].length;
|
|
504
|
+
});
|
|
505
|
+
if (!isValid)
|
|
506
|
+
return null;
|
|
507
|
+
}
|
|
508
|
+
else if (feature.type === 'MultiPolygon') {
|
|
509
|
+
const parts = feature.coordinates;
|
|
510
|
+
if (parts.length === 0)
|
|
511
|
+
return null;
|
|
512
|
+
const isValid = vertexIndices.every((r) => {
|
|
513
|
+
const part = getVertexPart(r);
|
|
514
|
+
if (part < 0 || part >= parts.length)
|
|
515
|
+
return false;
|
|
516
|
+
const rings = parts[part];
|
|
517
|
+
if (r.ring < 0 || r.ring >= rings.length)
|
|
518
|
+
return false;
|
|
519
|
+
return r.index >= 0 && r.index < rings[r.ring].length;
|
|
520
|
+
});
|
|
521
|
+
if (!isValid)
|
|
522
|
+
return null;
|
|
523
|
+
}
|
|
524
|
+
else {
|
|
525
|
+
return null;
|
|
526
|
+
}
|
|
527
|
+
return {
|
|
528
|
+
featureId: feature.id,
|
|
529
|
+
vertexIndices: vertexIndices.map((r) => ({ ...r })),
|
|
530
|
+
startLngLat,
|
|
531
|
+
// Coordinates follow the convention of immutable updates (an update is always a
|
|
532
|
+
// replacement with a new array), and during a drag computeVertexMove also builds a
|
|
533
|
+
// new array every time and swaps it in.
|
|
534
|
+
// So holding a reference from the start is enough: the contents do not change
|
|
535
|
+
// afterwards and no copy is needed
|
|
536
|
+
initialCoordinates: feature.coordinates,
|
|
537
|
+
};
|
|
538
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Plugin System
|
|
3
|
+
*
|
|
4
|
+
* Public API of the plugin system.
|
|
5
|
+
*
|
|
6
|
+
* Only the symbols that src/index.ts publishes are listed here (see "The public
|
|
7
|
+
* surface" in CONTRIBUTING.md). Internal code imports from the defining file.
|
|
8
|
+
*/
|
|
9
|
+
export type { DragEndData, DragStartData, Hooks, HoverEvent, MouseLeaveEvent, MutationContext, Plugin, PluginContext, } from './plugin.js';
|
|
10
|
+
export type { HookName, PluginManager } from './plugin-manager.js';
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mutation hooks
|
|
3
|
+
*
|
|
4
|
+
* Fires the after-mutation hooks of the plugins (feature / group / layer create, update and
|
|
5
|
+
* delete, and the selection change) from the change notification of the Store. Every write
|
|
6
|
+
* reaches the Store, so a hook sees every mutation whatever made it: the public API, a
|
|
7
|
+
* drawing mode, a drag, the Delete key, import, a plugin, or a change applied from outside to
|
|
8
|
+
* a replaced Store.
|
|
9
|
+
*
|
|
10
|
+
* The hooks run after the Store has changed, once per notification (one transaction), and
|
|
11
|
+
* the hooks of one notification share its batchId and its source. The intermediate updates
|
|
12
|
+
* of an edit in progress (isIntermediate) are not reported; the committing update that
|
|
13
|
+
* follows them is.
|
|
14
|
+
*/
|
|
15
|
+
import type { Store } from '../store/store.js';
|
|
16
|
+
import type { StateChanges } from '../store/types.js';
|
|
17
|
+
import type { MutationContext } from './plugin.js';
|
|
18
|
+
import type { PluginManager } from './plugin-manager.js';
|
|
19
|
+
/**
|
|
20
|
+
* Subscribes to the Store and fires the mutation hooks of the plugins
|
|
21
|
+
*
|
|
22
|
+
* @returns the function that stops it
|
|
23
|
+
*/
|
|
24
|
+
export declare function subscribeMutationHooks(store: Store, pluginManager: PluginManager): () => void;
|
|
25
|
+
/**
|
|
26
|
+
* Fires the mutation hooks for one change notification of the Store
|
|
27
|
+
*/
|
|
28
|
+
export declare function runMutationHooks(pluginManager: PluginManager, changes: StateChanges, ctx: MutationContext): void;
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
// SPDX-FileCopyrightText: 2026 SAKAIDA Atsushi
|
|
2
|
+
// SPDX-License-Identifier: AGPL-3.0-only
|
|
3
|
+
/**
|
|
4
|
+
* Subscribes to the Store and fires the mutation hooks of the plugins
|
|
5
|
+
*
|
|
6
|
+
* @returns the function that stops it
|
|
7
|
+
*/
|
|
8
|
+
export function subscribeMutationHooks(store, pluginManager) {
|
|
9
|
+
let notification = 0;
|
|
10
|
+
return store.subscribe((changes) => {
|
|
11
|
+
runMutationHooks(pluginManager, changes, {
|
|
12
|
+
source: changes.source ?? 'local',
|
|
13
|
+
batchId: `change_${++notification}`,
|
|
14
|
+
});
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Fires the mutation hooks for one change notification of the Store
|
|
19
|
+
*/
|
|
20
|
+
export function runMutationHooks(pluginManager, changes, ctx) {
|
|
21
|
+
const { features, groups, layers, selection } = changes;
|
|
22
|
+
if (features) {
|
|
23
|
+
if (features.created && features.created.length > 0) {
|
|
24
|
+
pluginManager.runHook('feature:afterCreate', [...features.created], ctx);
|
|
25
|
+
}
|
|
26
|
+
const committed = foldCommittedUpdates(features.updated);
|
|
27
|
+
if (committed.updated.length > 0) {
|
|
28
|
+
pluginManager.runHook('feature:afterUpdate', committed.updated, committed.original, ctx);
|
|
29
|
+
}
|
|
30
|
+
if (features.deleted && features.deleted.length > 0) {
|
|
31
|
+
pluginManager.runHook('feature:afterDelete', [...features.deleted], ctx);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
if (groups) {
|
|
35
|
+
for (const group of groups.created ?? []) {
|
|
36
|
+
pluginManager.runHook('group:afterCreate', group, ctx);
|
|
37
|
+
}
|
|
38
|
+
for (const entry of groups.updated ?? []) {
|
|
39
|
+
pluginManager.runHook('group:afterUpdate', entry.group, entry.previous, ctx);
|
|
40
|
+
}
|
|
41
|
+
for (const group of groups.deleted ?? []) {
|
|
42
|
+
pluginManager.runHook('group:afterDelete', group, ctx);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
if (layers) {
|
|
46
|
+
for (const layer of layers.created ?? []) {
|
|
47
|
+
pluginManager.runHook('layer:afterCreate', layer, ctx);
|
|
48
|
+
}
|
|
49
|
+
for (const entry of layers.updated ?? []) {
|
|
50
|
+
pluginManager.runHook('layer:afterUpdate', entry.layer, entry.previous, ctx);
|
|
51
|
+
}
|
|
52
|
+
for (const layer of layers.deleted ?? []) {
|
|
53
|
+
pluginManager.runHook('layer:afterDelete', layer, ctx);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
if (selection) {
|
|
57
|
+
pluginManager.runHook('selection:afterChange', [...selection.ids], [...selection.previousIds], ctx);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Folds the committed updates of one notification into one entry per feature (the last
|
|
62
|
+
* state, and the state before the first update), in the order of their first update
|
|
63
|
+
*/
|
|
64
|
+
function foldCommittedUpdates(updates) {
|
|
65
|
+
const byId = new Map();
|
|
66
|
+
for (const entry of updates ?? []) {
|
|
67
|
+
if (entry.isIntermediate)
|
|
68
|
+
continue;
|
|
69
|
+
const existing = byId.get(entry.id);
|
|
70
|
+
if (existing) {
|
|
71
|
+
existing.feature = entry.feature;
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
byId.set(entry.id, { feature: entry.feature, previous: entry.previous });
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
const updated = [];
|
|
78
|
+
const original = [];
|
|
79
|
+
for (const { feature, previous } of byId.values()) {
|
|
80
|
+
updated.push(feature);
|
|
81
|
+
original.push(previous);
|
|
82
|
+
}
|
|
83
|
+
return { updated, original };
|
|
84
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|