@fxi/zartigl 0.9.0 → 0.9.2

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/zartigl.d.ts CHANGED
@@ -1572,11 +1572,14 @@ export declare class Zartigl {
1572
1572
  private updateQueue;
1573
1573
  private suspended;
1574
1574
  private attachQueued;
1575
+ /**
1576
+ * Place of the detached render layer, for the next one : the layer above
1577
+ * it, `undefined` at the top, `null` when none was attached.
1578
+ */
1579
+ private anchor;
1575
1580
  private querySources;
1576
1581
  private listeners;
1577
- private readonly onMapLoad;
1578
- private readonly onStyleData;
1579
- private readonly onMapIdle;
1582
+ private readonly onMapReady;
1580
1583
  constructor(options: ZartiglOptions);
1581
1584
  init(): Promise<void>;
1582
1585
  update(input: ZartiglUpdate): Promise<void>;
@@ -1740,7 +1743,11 @@ export declare class Zartigl {
1740
1743
  private resolveSource;
1741
1744
  private querySource;
1742
1745
  private isMapReady;
1746
+ /** A new render layer takes the place of the detached one, else `before`. */
1743
1747
  private getBeforeLayerId;
1748
+ private isAttached;
1749
+ /** First layer above the render layer that is not its own WMTS raster. */
1750
+ private layerAbove;
1744
1751
  private requireLayer;
1745
1752
  private assertAlive;
1746
1753
  private emit;
@@ -1797,6 +1804,8 @@ declare type ZartiglEventMap = {
1797
1804
  id: string;
1798
1805
  type: CatalogSource["type"];
1799
1806
  }) => void;
1807
+ /** The render layer was added to the map, e.g. for the host to order it. */
1808
+ layerAttach: (id: string) => void;
1800
1809
  };
1801
1810
 
1802
1811
  export declare class ZartiglFrameUnavailableError extends Error {
package/dist/zartigl.js CHANGED
@@ -5731,12 +5731,8 @@ class _E {
5731
5731
  source: this.rasterSourceId,
5732
5732
  metadata: this.metadata ? { ...this.metadata } : void 0,
5733
5733
  paint: { "raster-opacity": this.opacity }
5734
- }, C = this.getBeforeLayerId();
5735
- if (C) {
5736
- this.map.addLayer(g, C);
5737
- return;
5738
- }
5739
- this.map.addLayer(g);
5734
+ };
5735
+ this.map.addLayer(g, this.getBeforeLayerId());
5740
5736
  }
5741
5737
  removeWmts() {
5742
5738
  this.map && (this.map.getLayer(this.rasterLayerId) && this.map.removeLayer(this.rasterLayerId), this.map.getSource(this.rasterSourceId) && this.map.removeSource(this.rasterSourceId));
@@ -5757,10 +5753,13 @@ class _E {
5757
5753
  for (const C of g)
5758
5754
  C(...I);
5759
5755
  }
5756
+ /** The WMTS raster takes the place of this custom layer, right above it. */
5760
5757
  getBeforeLayerId() {
5761
- const A = this.options.before;
5762
- if (!(!A || !this.map?.getLayer(A)))
5763
- return A;
5758
+ const A = this.map?.getLayersOrder?.() ?? [], I = A.indexOf(this.options.id);
5759
+ if (I > -1)
5760
+ return A[I + 1];
5761
+ const g = this.options.before;
5762
+ return g && this.map?.getLayer(g) ? g : void 0;
5764
5763
  }
5765
5764
  }
5766
5765
  function mI(B, A) {
@@ -6125,7 +6124,9 @@ function yB(B, A, I) {
6125
6124
  }
6126
6125
  class ki {
6127
6126
  constructor(A) {
6128
- if (this.fullTimeMeta = null, this.autoplayPending = !0, this.playing = !1, this.catalogLayer = null, this.catalogSource = null, this.layer = null, this.time = 0, this.pendingTime = null, this.requestedTime = null, this.playbackIntent = 0, this.requestSeq = 0, this.playSeq = 0, this.depth = 0, this.depthRequest = null, this.failedGeoVideo = /* @__PURE__ */ new Set(), this.lastMeta = null, this.timeMeta = null, this.resolvedTimeRange = null, this.verticalMeta = null, this.variableUnit = "", this.geoVideoManifest = null, this.wmtsMetadata = null, this.fieldSources = /* @__PURE__ */ new Map(), this.archiveChunks = /* @__PURE__ */ new Map(), this.nextChunkManifest = null, this.activeFieldSource = null, this.switchGeneration = 0, this.destroyed = !1, this.initialized = !1, this.initStarted = !1, this.updateQueue = Promise.resolve(), this.suspended = !1, this.attachQueued = !1, this.querySources = /* @__PURE__ */ new Map(), this.listeners = /* @__PURE__ */ new Map(), this.onMapLoad = () => this.attachWhenReady(), this.onStyleData = () => this.attachWhenReady(), this.onMapIdle = () => this.attachWhenReady(), !A.layer)
6127
+ if (this.fullTimeMeta = null, this.autoplayPending = !0, this.playing = !1, this.catalogLayer = null, this.catalogSource = null, this.layer = null, this.time = 0, this.pendingTime = null, this.requestedTime = null, this.playbackIntent = 0, this.requestSeq = 0, this.playSeq = 0, this.depth = 0, this.depthRequest = null, this.failedGeoVideo = /* @__PURE__ */ new Set(), this.lastMeta = null, this.timeMeta = null, this.resolvedTimeRange = null, this.verticalMeta = null, this.variableUnit = "", this.geoVideoManifest = null, this.wmtsMetadata = null, this.fieldSources = /* @__PURE__ */ new Map(), this.archiveChunks = /* @__PURE__ */ new Map(), this.nextChunkManifest = null, this.activeFieldSource = null, this.switchGeneration = 0, this.destroyed = !1, this.initialized = !1, this.initStarted = !1, this.updateQueue = Promise.resolve(), this.suspended = !1, this.attachQueued = !1, this.anchor = null, this.querySources = /* @__PURE__ */ new Map(), this.listeners = /* @__PURE__ */ new Map(), this.onMapReady = () => {
6128
+ this.attachQueued && this.attachWhenReady();
6129
+ }, !A.layer)
6129
6130
  throw new Error("Zartigl requires a layer UUID");
6130
6131
  if (A.time != null && gA(A.time, "time"), A.depth != null && !Number.isFinite(A.depth))
6131
6132
  throw new Error("Depth must be finite");
@@ -6133,7 +6134,7 @@ class ki {
6133
6134
  const I = TI(A.settings);
6134
6135
  rB(I.legacyKeys), this.style = vA(I.style, A.style), yB(this.style, A.catalog, A.layer), this.settings = { ...I.settings, ...oI(this.style) }, this.settings.colorDomain !== void 0 && (this.settings.colorDomain = fA(
6135
6136
  this.settings.colorDomain
6136
- )), this.colorDomainOverridden = this.settings.colorDomain !== void 0, this.paletteOverridden = this.settings.palette !== void 0, this.map.on("load", this.onMapLoad), this.map.on("styledata", this.onStyleData), this.map.on("idle", this.onMapIdle);
6137
+ )), this.colorDomainOverridden = this.settings.colorDomain !== void 0, this.paletteOverridden = this.settings.palette !== void 0, this.map.on("load", this.onMapReady), this.map.on("styledata", this.onMapReady), this.map.on("idle", this.onMapReady);
6137
6138
  }
6138
6139
  async init() {
6139
6140
  if (this.assertAlive(), this.initStarted)
@@ -6406,7 +6407,7 @@ class ki {
6406
6407
  }
6407
6408
  }
6408
6409
  destroy() {
6409
- this.destroyed || (this.switchGeneration++, this.detach(), this.querySources.forEach((A) => A.cancelAll()), this.fieldSources.forEach((A) => A.cancelAll()), this.querySources.clear(), this.fieldSources.clear(), this.map.off("load", this.onMapLoad), this.map.off("styledata", this.onStyleData), this.map.off("idle", this.onMapIdle), this.destroyed = !0);
6410
+ this.destroyed || (this.switchGeneration++, this.detach(), this.querySources.forEach((A) => A.cancelAll()), this.fieldSources.forEach((A) => A.cancelAll()), this.querySources.clear(), this.fieldSources.clear(), this.map.off("load", this.onMapReady), this.map.off("styledata", this.onMapReady), this.map.off("idle", this.onMapReady), this.destroyed = !0);
6410
6411
  }
6411
6412
  applyTime(A) {
6412
6413
  this.assertAlive();
@@ -6760,9 +6761,15 @@ class ki {
6760
6761
  this.attachQueued = !0;
6761
6762
  return;
6762
6763
  }
6763
- if (this.layer && this.map.getLayer(this.layer.id))
6764
+ if (this.layer && this.isAttached(this.layer))
6764
6765
  return;
6765
- this.attachQueued = !1;
6766
+ if (this.attachQueued = !1, this.map.getLayer(this.id)) {
6767
+ this.emit(
6768
+ "error",
6769
+ new Error(`Map layer id '${this.id}' is already used by another layer`)
6770
+ );
6771
+ return;
6772
+ }
6766
6773
  const A = new _E({
6767
6774
  id: this.id,
6768
6775
  entry: this.catalogLayer,
@@ -6792,23 +6799,17 @@ class ki {
6792
6799
  metadata: this.metadata ? { ...this.metadata } : void 0,
6793
6800
  before: this.before
6794
6801
  });
6795
- this.pendingTime = null, this.autoplayPending = !1, A.on("loading", () => this.emit("loading")), A.on("loaded", (g) => {
6796
- this.lastMeta = g, this.emit("loaded", g);
6797
- }), A.on("error", (g) => {
6798
- this.emit("error", g), this.fallBackFromGeoVideo(A, g);
6799
- }), A.on("status", (g) => this.emit("status", g)), A.on("frameBuffered", (g) => this.emit("frameBuffered", g)), A.on("cacheInvalidated", () => this.emit("cacheInvalidated")), A.on("timeChange", (g) => {
6800
- A === this.layer && (this.time = IA(this.timeMeta?.values ?? [], g), this.playing && (this.requestedTime = null), this.emit("timeChange", this.time));
6801
- }), A.on("playbackChange", (g) => {
6802
- A === this.layer && (g && this.preloadNextArchiveChunk(A), g !== this.playing && (this.playing = g, this.emit("playbackChange", g)));
6802
+ this.pendingTime = null, this.autoplayPending = !1, A.on("loading", () => this.emit("loading")), A.on("loaded", (I) => {
6803
+ this.lastMeta = I, this.emit("loaded", I);
6804
+ }), A.on("error", (I) => {
6805
+ this.emit("error", I), this.fallBackFromGeoVideo(A, I);
6806
+ }), A.on("status", (I) => this.emit("status", I)), A.on("frameBuffered", (I) => this.emit("frameBuffered", I)), A.on("cacheInvalidated", () => this.emit("cacheInvalidated")), A.on("timeChange", (I) => {
6807
+ A === this.layer && (this.time = IA(this.timeMeta?.values ?? [], I), this.playing && (this.requestedTime = null), this.emit("timeChange", this.time));
6808
+ }), A.on("playbackChange", (I) => {
6809
+ A === this.layer && (I && this.preloadNextArchiveChunk(A), I !== this.playing && (this.playing = I, this.emit("playbackChange", I)));
6803
6810
  }), A.on("playbackEnd", () => {
6804
6811
  this.continueArchivePlayback();
6805
- }), this.layer = A;
6806
- const I = this.getBeforeLayerId();
6807
- if (I) {
6808
- this.map.addLayer(A, I);
6809
- return;
6810
- }
6811
- this.map.addLayer(A);
6812
+ }), this.layer = A, this.map.addLayer(A, this.getBeforeLayerId()), this.emit("layerAttach", A.id);
6812
6813
  }
6813
6814
  /** GeoVideo playback options shared by a new layer and an in-place swap. */
6814
6815
  geoVideoPlayback() {
@@ -6826,7 +6827,7 @@ class ki {
6826
6827
  */
6827
6828
  replaceGeoVideoInPlace(A) {
6828
6829
  const I = this.layer;
6829
- if (!I || !this.geoVideoManifest || !this.map.getLayer(I.id) || I.getBackend() !== "scalar-geovideo")
6830
+ if (!I || !this.geoVideoManifest || !this.isAttached(I) || I.getBackend() !== "scalar-geovideo")
6830
6831
  return !1;
6831
6832
  const g = this.geoVideoPlayback();
6832
6833
  return I.replaceGeoVideoManifest(this.geoVideoManifest, {
@@ -6837,8 +6838,8 @@ class ki {
6837
6838
  }) ? (I.setColorDomain(this.settings.colorDomain ?? null), this.settings.palette && this.settings.palette !== A && I.setColorRamp(this.settings.palette), !0) : !1;
6838
6839
  }
6839
6840
  detach() {
6840
- const A = this.layer?.id ?? this.id, I = `${A}-wmts`, g = `${A}-wmts-source`;
6841
- this.map.getLayer(A) && this.map.removeLayer(A), this.map.getLayer(I) && this.map.removeLayer(I), this.map.getSource(g) && this.map.removeSource(g), this.layer = null, this.playing && (this.playing = !1, this.emit("playbackChange", !1));
6841
+ const A = this.layer;
6842
+ this.layer = null, A && this.isAttached(A) && (this.anchor = this.layerAbove(A.id), this.map.removeLayer(A.id)), this.playing && (this.playing = !1, this.emit("playbackChange", !1));
6842
6843
  }
6843
6844
  /**
6844
6845
  * In "auto", a GeoVideo that fails while it renders (media, mask) yields
@@ -7062,9 +7063,22 @@ class ki {
7062
7063
  const A = this.map;
7063
7064
  return A.isStyleLoaded?.() ?? A.loaded?.() ?? !0;
7064
7065
  }
7066
+ /** A new render layer takes the place of the detached one, else `before`. */
7065
7067
  getBeforeLayerId() {
7066
- if (!(!this.before || !this.map.getLayer(this.before)))
7067
- return this.before;
7068
+ if (this.anchor !== void 0) {
7069
+ for (const A of [this.anchor, this.before])
7070
+ if (A && this.map.getLayer(A))
7071
+ return A;
7072
+ }
7073
+ }
7074
+ isAttached(A) {
7075
+ const I = this.map.getLayer(A.id);
7076
+ return I === A || I?.implementation === A;
7077
+ }
7078
+ /** First layer above the render layer that is not its own WMTS raster. */
7079
+ layerAbove(A) {
7080
+ const I = this.map.getLayersOrder?.() ?? [], g = I.indexOf(A);
7081
+ return g < 0 ? void 0 : I.slice(g + 1).find((C) => C !== `${A}-wmts`);
7068
7082
  }
7069
7083
  requireLayer() {
7070
7084
  if (!this.catalogLayer)
@@ -7106,7 +7120,7 @@ function Ji(B, A, I) {
7106
7120
  (C, Q) => Math.abs(Q - g) < Math.abs(C - g) ? Q : C
7107
7121
  );
7108
7122
  }
7109
- const yi = "0.9.0", ni = { "maplibre-gl": "^5.17.0" }, zB = {
7123
+ const yi = "0.9.2", ni = { "maplibre-gl": "^5.17.0" }, zB = {
7110
7124
  version: yi,
7111
7125
  devDependencies: ni
7112
7126
  }, jB = zB.devDependencies["maplibre-gl"].replace(
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fxi/zartigl",
3
- "version": "0.9.0",
3
+ "version": "0.9.2",
4
4
  "description": "MapLibre GL JS visualization for catalog-backed Zarr, WMTS, and GeoVideo data",
5
5
  "repository": {
6
6
  "type": "git",