@orbat-mapper/tactical-draw-adapter-maplibre 0.2.0-alpha.22 → 0.2.0-alpha.23

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/dist/index.d.mts CHANGED
@@ -17,6 +17,10 @@ interface MapLibreGroupBundle {
17
17
  readonly sourceId: string;
18
18
  readonly layerIds: Map<PaintChannel, string>;
19
19
  features: readonly Feature[];
20
+ /** Features most recently submitted to the native source, after MapLibre-specific promotion. */
21
+ sourceFeatures: readonly Feature[];
22
+ /** Whether the native source has received its first complete dataset. */
23
+ sourceInitialized: boolean;
20
24
  /** Unset while the stored value describes older features than `features` holds. */
21
25
  featureSignature: string | undefined;
22
26
  /**
package/dist/index.mjs CHANGED
@@ -28,6 +28,49 @@ function sameOrder(a, b) {
28
28
  return true;
29
29
  }
30
30
  /**
31
+ * Replace the contents of shared-id features while adding/removing ids that
32
+ * entered or left a stable group bundle. Remove stale keys explicitly instead
33
+ * of combining `removeAllProperties` with `addOrUpdateProperties`: MapLibre's
34
+ * tile-index diff treats the former as exclusive and otherwise drops the
35
+ * replacement properties, including the promoted feature id.
36
+ */
37
+ function buildGeoJSONSourceDiff(previousFeatures, nextFeatures) {
38
+ const previousById = new Map(previousFeatures.map((feature) => [feature.id, feature]));
39
+ const nextById = new Map(nextFeatures.map((feature) => [feature.id, feature]));
40
+ const remove = previousFeatures.filter((feature) => !nextById.has(feature.id)).map((feature) => feature.id);
41
+ const add = [];
42
+ const update = [];
43
+ for (const feature of nextFeatures) {
44
+ const previous = previousById.get(feature.id);
45
+ if (!previous) {
46
+ add.push(feature);
47
+ continue;
48
+ }
49
+ if (feature.geometry === null) {
50
+ remove.push(feature.id);
51
+ add.push(feature);
52
+ continue;
53
+ }
54
+ const previousProperties = previous.properties ?? {};
55
+ const nextProperties = feature.properties ?? {};
56
+ const removeProperties = Object.keys(previousProperties).filter((key) => !Object.hasOwn(nextProperties, key));
57
+ update.push({
58
+ id: feature.id,
59
+ newGeometry: feature.geometry,
60
+ ...removeProperties.length > 0 ? { removeProperties } : {},
61
+ addOrUpdateProperties: Object.entries(nextProperties).map(([key, value]) => ({
62
+ key,
63
+ value
64
+ }))
65
+ });
66
+ }
67
+ return {
68
+ ...remove.length > 0 ? { remove } : {},
69
+ ...add.length > 0 ? { add } : {},
70
+ ...update.length > 0 ? { update } : {}
71
+ };
72
+ }
73
+ /**
31
74
  * Find the largest subset of bundles whose relative order already matches the
32
75
  * desired stack. Reorders then move only the remaining bundles.
33
76
  */
@@ -831,6 +874,8 @@ var MapLibreAdapter = class extends BaseMapAdapter {
831
874
  sourceId,
832
875
  layerIds: /* @__PURE__ */ new Map(),
833
876
  features: [],
877
+ sourceFeatures: [],
878
+ sourceInitialized: false,
834
879
  featureSignature: "[]",
835
880
  requiredIconIds: /* @__PURE__ */ new Set()
836
881
  };
@@ -924,10 +969,12 @@ var MapLibreAdapter = class extends BaseMapAdapter {
924
969
  const source = this.map.getSource(bundle.sourceId);
925
970
  if (!source) return;
926
971
  const features = [...bundle.requiredIconIds].every((id) => this.map.hasImage(id)) ? bundle.features.map((feature) => this.promoteFeature(feature)) : [];
927
- const result = source.setData({
972
+ const result = bundle.sourceInitialized && typeof source.updateData === "function" ? source.updateData(buildGeoJSONSourceDiff(bundle.sourceFeatures, features), true) : source.setData({
928
973
  type: "FeatureCollection",
929
974
  features
930
975
  }, true);
976
+ bundle.sourceFeatures = features;
977
+ bundle.sourceInitialized = true;
931
978
  if (isPromiseLike(result)) Promise.resolve(result).catch(() => {});
932
979
  }
933
980
  orderGroupBundles(handle, previousGroupIds, desiredGroupIds, forcedGroupIds) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@orbat-mapper/tactical-draw-adapter-maplibre",
3
- "version": "0.2.0-alpha.22",
3
+ "version": "0.2.0-alpha.23",
4
4
  "description": "MapLibre GL JS engine adapter for @orbat-mapper/tactical-draw. Draw and edit tactical control measures (MIL-STD-2525 / APP-6) on a MapLibre map.",
5
5
  "license": "MIT",
6
6
  "author": "Orbat Mapper",
@@ -37,8 +37,8 @@
37
37
  "access": "public"
38
38
  },
39
39
  "dependencies": {
40
- "@orbat-mapper/control-measures": "^0.2.0-alpha.26",
41
- "@orbat-mapper/tactical-draw": "^0.2.0-alpha.38"
40
+ "@orbat-mapper/tactical-draw": "^0.2.0-alpha.38",
41
+ "@orbat-mapper/control-measures": "^0.2.0-alpha.26"
42
42
  },
43
43
  "peerDependencies": {
44
44
  "maplibre-gl": ">=5.8.0 <6.0.0"