@tileflow/interactions 0.1.0-alpha.4 → 0.1.0-alpha.6

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.
@@ -195,6 +195,11 @@ type TileflowMapLibrePoiPointerEvent = Readonly<{
195
195
  point: unknown;
196
196
  }>;
197
197
  type TileflowMapLibrePoiMap = Readonly<{
198
+ /** A style layer's source; lets the controller keep its manifest while the style only restyles. */
199
+ getLayer?: (id: string) => Readonly<{
200
+ source?: unknown;
201
+ sourceLayer?: unknown;
202
+ }> | undefined;
198
203
  getStyle: () => unknown;
199
204
  off?: (event: string, listener: (event: unknown) => void) => unknown;
200
205
  on: (event: string, listener: (event: unknown) => void) => Readonly<{
@@ -1662,7 +1662,7 @@ var tileflowInteractionActionSchema = z.discriminatedUnion("type", [
1662
1662
 
1663
1663
  // src/maplibre-poi.ts
1664
1664
  var interactionManifestMetadataKey = "tileflow:interaction-manifest";
1665
- var interactionManifestVersion = 2;
1665
+ var interactionManifestVersion = 3;
1666
1666
  var missingSourceLayerNamespace = "tileflow-no-source-layer";
1667
1667
  function createTileflowMapLibrePoiController(options) {
1668
1668
  let bindings = semanticPoiBindings(options.bindings ?? [], options.onDiagnostic);
@@ -1726,9 +1726,20 @@ function createTileflowMapLibrePoiController(options) {
1726
1726
  );
1727
1727
  continue;
1728
1728
  }
1729
+ const properties = normalizePoiProperties(feature.properties, manifest.fields);
1730
+ const category = properties.category;
1731
+ if (category === void 0) {
1732
+ manifestMismatch = true;
1733
+ diagnostic(
1734
+ options.onDiagnostic,
1735
+ "SEMANTIC_MANIFEST_MISMATCH",
1736
+ "A rendered POI feature has no supported category."
1737
+ );
1738
+ continue;
1739
+ }
1729
1740
  const binding = bindings.find((candidate) => {
1730
1741
  const target = candidate.target;
1731
- return target.kind === "semantic-feature" && target.domain === "poi" && (!target.categories || target.categories.includes(layer.category));
1742
+ return target.kind === "semantic-feature" && target.domain === "poi" && (!target.categories || target.categories.includes(category));
1732
1743
  });
1733
1744
  if (!binding) continue;
1734
1745
  const featureId = normalizeFeatureId(feature.id);
@@ -1742,9 +1753,9 @@ function createTileflowMapLibrePoiController(options) {
1742
1753
  coordinate: [event.lngLat.lng, event.lngLat.lat],
1743
1754
  domain: "poi",
1744
1755
  feature: {
1745
- category: layer.category,
1756
+ category,
1746
1757
  ...featureId === void 0 ? {} : { id: featureId },
1747
- properties: normalizePoiProperties(feature.properties, manifest.fields)
1758
+ properties
1748
1759
  },
1749
1760
  kind: "semantic-feature"
1750
1761
  }
@@ -1793,6 +1804,11 @@ function createTileflowMapLibrePoiController(options) {
1793
1804
  }
1794
1805
  options.onActivate?.(match, modality);
1795
1806
  };
1807
+ let loaded;
1808
+ const sourcesOf = (layers) => options.map.getLayer ? layers.map(({ layerId }) => {
1809
+ const layer = options.map.getLayer(layerId);
1810
+ return layer ? `${String(layer.source)}/${String(layer.sourceLayer)}` : "";
1811
+ }).join("\n") : void 0;
1796
1812
  const refreshManifest = () => {
1797
1813
  if (disposed) return;
1798
1814
  setHovered(null, "programmatic");
@@ -1801,6 +1817,12 @@ function createTileflowMapLibrePoiController(options) {
1801
1817
  options.onManifestChange?.(true);
1802
1818
  return;
1803
1819
  }
1820
+ if (loaded && sourcesOf(loaded.manifest.layers) === loaded.sources) {
1821
+ manifest = loaded.manifest;
1822
+ options.onManifestChange?.(true);
1823
+ return;
1824
+ }
1825
+ loaded = void 0;
1804
1826
  const style = options.map.getStyle();
1805
1827
  if (style === void 0) {
1806
1828
  manifest = null;
@@ -1808,6 +1830,8 @@ function createTileflowMapLibrePoiController(options) {
1808
1830
  return;
1809
1831
  }
1810
1832
  manifest = parsePoiManifest(style, options.onDiagnostic);
1833
+ const sources = manifest ? sourcesOf(manifest.layers) : void 0;
1834
+ if (manifest && sources !== void 0) loaded = { manifest, sources };
1811
1835
  options.onManifestChange?.(manifest !== null);
1812
1836
  };
1813
1837
  let manifestRefreshScheduled = false;
@@ -1822,6 +1846,7 @@ function createTileflowMapLibrePoiController(options) {
1822
1846
  };
1823
1847
  const handleStyleLoad = () => {
1824
1848
  manifestRefreshScheduled = false;
1849
+ loaded = void 0;
1825
1850
  refreshManifest();
1826
1851
  };
1827
1852
  try {
@@ -1974,7 +1999,7 @@ function parsePoiManifest(styleInput, onDiagnostic) {
1974
1999
  for (const input of layerInputs) {
1975
2000
  const layer = asRecord(input);
1976
2001
  const sourceLayer = layer?.sourceLayer;
1977
- if (!layer || !isTileflowPoiCategory(layer.category) || !isSafeManifestName(layer.layerId) || !isSafeManifestName(layer.source) || sourceLayer !== void 0 && !isSafeManifestName(sourceLayer) || layer.anchor !== "pointer-coordinate" || !isPoiRepresentation(layer.representation) || !Number.isSafeInteger(layer.priority) || layer.priority < 0 || layer.priority > 1e5 || ids.has(layer.layerId)) {
2002
+ if (!layer || !isSafeManifestName(layer.layerId) || !isSafeManifestName(layer.source) || sourceLayer !== void 0 && !isSafeManifestName(sourceLayer) || layer.anchor !== "pointer-coordinate" || !isPoiRepresentation(layer.representation) || !Number.isSafeInteger(layer.priority) || layer.priority < 0 || layer.priority > 1e5 || ids.has(layer.layerId)) {
1978
2003
  diagnostic(onDiagnostic, "SEMANTIC_MANIFEST_MISMATCH", "Invalid semantic POI layer lookup.");
1979
2004
  return null;
1980
2005
  }
@@ -2002,7 +2027,6 @@ function parsePoiManifest(styleInput, onDiagnostic) {
2002
2027
  identityNamespace = namespace;
2003
2028
  ids.add(layer.layerId);
2004
2029
  layers.push({
2005
- category: layer.category,
2006
2030
  layerId: layer.layerId,
2007
2031
  priority: layer.priority,
2008
2032
  representation: layer.representation,
@@ -2072,11 +2096,7 @@ function sourceLayerNamespace(sourceLayer) {
2072
2096
  return sourceLayer ?? missingSourceLayerNamespace;
2073
2097
  }
2074
2098
  function relevantLayerIds(manifest, bindings) {
2075
- return manifest.layers.filter(
2076
- (layer) => bindings.some(
2077
- (binding) => binding.target.kind === "semantic-feature" && (!binding.target.categories || binding.target.categories.includes(layer.category))
2078
- )
2079
- ).map((layer) => layer.layerId);
2099
+ return bindings.some((binding) => binding.target.kind === "semantic-feature") ? manifest.layers.map((layer) => layer.layerId) : [];
2080
2100
  }
2081
2101
  function normalizePoiProperties(properties, fields) {
2082
2102
  const source = properties ?? {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tileflow/interactions",
3
- "version": "0.1.0-alpha.4",
3
+ "version": "0.1.0-alpha.6",
4
4
  "license": "Apache-2.0",
5
5
  "description": "Portable annotation and interaction contracts for Tileflow maps.",
6
6
  "type": "module",