@nextgis/leaflet-map-adapter 4.0.1 → 4.1.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.
@@ -1,4 +1,4 @@
1
- /** Bundle of @nextgis/leaflet-map-adapter; version: 4.0.1; author: NextGIS */
1
+ /** Bundle of @nextgis/leaflet-map-adapter; version: 4.1.0; author: NextGIS */
2
2
  function getElement(el) {
3
3
  if (typeof el === "string") {
4
4
  let el_ = document.getElementById(el);
@@ -15368,8 +15368,14 @@ function isObject(val) {
15368
15368
  }
15369
15369
 
15370
15370
  function updateUrlParams(urlStr, params) {
15371
- const url = new URL(urlStr);
15372
- const searchParams = new URLSearchParams(url.search);
15371
+ const hashIndex = urlStr.indexOf("#");
15372
+ const hash = hashIndex === -1 ? "" : urlStr.slice(hashIndex);
15373
+ const url = hashIndex === -1 ? urlStr : urlStr.slice(0, hashIndex);
15374
+ const queryIndex = url.indexOf("?");
15375
+ const baseUrl = queryIndex === -1 ? url : url.slice(0, queryIndex);
15376
+ const searchParams = new URLSearchParams(
15377
+ queryIndex === -1 ? "" : url.slice(queryIndex + 1)
15378
+ );
15373
15379
  Object.entries(params).forEach(([key, value]) => {
15374
15380
  if (value === void 0) {
15375
15381
  searchParams.delete(key);
@@ -15379,7 +15385,7 @@ function updateUrlParams(urlStr, params) {
15379
15385
  });
15380
15386
  searchParams.set("timestamp", String((/* @__PURE__ */ new Date()).getTime()));
15381
15387
  const newSearch = [...searchParams.entries()].map(([key, value]) => `${key}=${value}`).join("&");
15382
- return `${url.origin}${url.pathname}?${newSearch}`;
15388
+ return `${baseUrl}?${newSearch}${hash}`;
15383
15389
  }
15384
15390
 
15385
15391
  function boundsToArray(bounds) {
@@ -16488,15 +16494,31 @@ class Queue {
16488
16494
  /**
16489
16495
  * @param {PromiseQueueOptions} options - Configuration options for the queue.
16490
16496
  */
16491
- constructor({ concurrency = 1, delay = 0 } = {}) {
16497
+ constructor({
16498
+ delay = 0,
16499
+ limit,
16500
+ timeout,
16501
+ debounce,
16502
+ concurrency = 1
16503
+ } = {}) {
16492
16504
  __publicField$4(this, "queue", []);
16505
+ __publicField$4(this, "activeRequests", []);
16493
16506
  __publicField$4(this, "concurrency");
16494
- __publicField$4(this, "activeCount", 0);
16495
16507
  __publicField$4(this, "timeoutId");
16508
+ __publicField$4(this, "resumeTimer");
16496
16509
  __publicField$4(this, "delay");
16497
- __publicField$4(this, "toAbort", []);
16498
- this.concurrency = concurrency;
16499
- this.delay = delay;
16510
+ __publicField$4(this, "timeout");
16511
+ __publicField$4(this, "paused", false);
16512
+ __publicField$4(this, "idleResolvers", []);
16513
+ __publicField$4(this, "debounce");
16514
+ this.concurrency = limit != null ? limit : concurrency;
16515
+ this.delay = debounce != null ? debounce : delay;
16516
+ this.debounce = this.delay;
16517
+ this.timeout = timeout;
16518
+ }
16519
+ setLimit(limit) {
16520
+ this.concurrency = limit;
16521
+ this._next();
16500
16522
  }
16501
16523
  /**
16502
16524
  * Adds a task to the queue, which can be either a simple asynchronous function or an array containing a function and its abort handler.
@@ -16515,7 +16537,18 @@ class Queue {
16515
16537
  * ```
16516
16538
  */
16517
16539
  add(promise, abort) {
16518
- this.queue.push({ promise, abort });
16540
+ var _a, _b;
16541
+ const options = typeof abort === "function" ? { abort } : abort;
16542
+ if ((options == null ? void 0 : options.id) !== void 0) {
16543
+ this.removeById(options.id);
16544
+ }
16545
+ this.queue.push({
16546
+ id: (_a = options == null ? void 0 : options.id) != null ? _a : Math.random().toString(36).slice(2),
16547
+ promise,
16548
+ abort: options == null ? void 0 : options.abort,
16549
+ abortController: new AbortController(),
16550
+ timeout: (_b = options == null ? void 0 : options.timeout) != null ? _b : this.timeout
16551
+ });
16519
16552
  this.debouncedNext();
16520
16553
  }
16521
16554
  /**
@@ -16525,60 +16558,167 @@ class Queue {
16525
16558
  * queue.abort(); // Aborts all abortable tasks in the queue.
16526
16559
  */
16527
16560
  abort() {
16528
- for (const abort of this.toAbort) {
16529
- abort();
16561
+ for (const item of [...this.queue, ...this.activeRequests]) {
16562
+ this.abortRequest(item);
16563
+ this.clearRequestTimeout(item);
16564
+ item.completed = true;
16530
16565
  }
16531
- this.toAbort = [];
16532
- this.queue = [];
16566
+ this.queue.length = 0;
16567
+ this.activeRequests.length = 0;
16533
16568
  this._clearTimeout();
16569
+ this.checkIdle();
16570
+ }
16571
+ remove(id) {
16572
+ this.removeById(id);
16573
+ }
16574
+ clearQueue() {
16575
+ for (const item of this.queue) {
16576
+ this.abortRequest(item);
16577
+ item.completed = true;
16578
+ }
16579
+ this.queue.length = 0;
16580
+ this._clearTimeout();
16581
+ this.checkIdle();
16582
+ }
16583
+ waitAll() {
16584
+ return new Promise((resolve) => {
16585
+ if (this.isIdle()) {
16586
+ resolve();
16587
+ } else {
16588
+ this.idleResolvers.push(resolve);
16589
+ }
16590
+ });
16591
+ }
16592
+ pause(pauseDuration) {
16593
+ this.paused = true;
16594
+ this._clearTimeout();
16595
+ this._clearResumeTimer();
16596
+ if (pauseDuration) {
16597
+ this.resumeTimer = setTimeout(() => this.resume(), pauseDuration);
16598
+ }
16599
+ }
16600
+ resume() {
16601
+ if (!this.paused) return;
16602
+ this.paused = false;
16603
+ this._clearResumeTimer();
16604
+ this._next();
16534
16605
  }
16535
16606
  debouncedNext() {
16607
+ if (this.paused) return;
16608
+ if (this.activeRequests.length) {
16609
+ this._next();
16610
+ return;
16611
+ }
16536
16612
  this._clearTimeout();
16537
16613
  this.timeoutId = setTimeout(() => this._next(), this.delay);
16538
16614
  }
16539
16615
  _clearTimeout() {
16540
16616
  if (this.timeoutId) {
16541
16617
  clearTimeout(this.timeoutId);
16618
+ this.timeoutId = void 0;
16619
+ }
16620
+ }
16621
+ _clearResumeTimer() {
16622
+ if (this.resumeTimer) {
16623
+ clearTimeout(this.resumeTimer);
16624
+ this.resumeTimer = void 0;
16542
16625
  }
16543
16626
  }
16544
16627
  _next() {
16545
- while (this.activeCount < this.concurrency && this.queue.length > 0) {
16546
- const { promise, abort } = this.queue.shift();
16547
- this.activeCount++;
16548
- let toAbort = abort;
16549
- let request;
16550
- const execute = promise();
16551
- if (Array.isArray(execute)) {
16552
- request = execute[0];
16553
- toAbort = execute[1];
16554
- } else {
16555
- request = execute;
16556
- }
16557
- if (toAbort) {
16558
- this.toAbort.push(toAbort);
16628
+ if (this.paused) return;
16629
+ while (this.activeRequests.length < this.concurrency && this.queue.length) {
16630
+ const item = this.queue.shift();
16631
+ if (item.abortController.signal.aborted) continue;
16632
+ this.activeRequests.push(item);
16633
+ if (item.timeout && item.timeout > 0) {
16634
+ item.timeoutId = setTimeout(() => {
16635
+ this.abortRequest(
16636
+ item,
16637
+ new DOMException("Request timed out", "TimeoutError")
16638
+ );
16639
+ this.finishRequest(item);
16640
+ }, item.timeout);
16559
16641
  }
16560
- request.finally(() => {
16561
- this.activeCount--;
16562
- if (toAbort) {
16563
- this.toAbort = this.toAbort.filter((a) => a !== toAbort);
16642
+ try {
16643
+ const execute = item.promise({ signal: item.abortController.signal });
16644
+ const request = Array.isArray(execute) ? execute[0] : execute;
16645
+ if (Array.isArray(execute)) {
16646
+ const abort = item.abort;
16647
+ item.abort = abort ? () => {
16648
+ abort();
16649
+ execute[1]();
16650
+ } : execute[1];
16564
16651
  }
16565
- this.debouncedNext();
16566
- });
16652
+ Promise.resolve(request).then(
16653
+ () => this.finishRequest(item),
16654
+ () => this.finishRequest(item)
16655
+ );
16656
+ } catch (error) {
16657
+ this.finishRequest(item);
16658
+ console.error(error);
16659
+ }
16660
+ }
16661
+ this.checkIdle();
16662
+ }
16663
+ removeById(id) {
16664
+ this.queue = this.queue.filter((item) => {
16665
+ if (item.id !== id) return true;
16666
+ this.abortRequest(item);
16667
+ item.completed = true;
16668
+ return false;
16669
+ });
16670
+ for (const item of [...this.activeRequests]) {
16671
+ if (item.id === id) {
16672
+ this.abortRequest(item);
16673
+ this.finishRequest(item);
16674
+ }
16675
+ }
16676
+ this.checkIdle();
16677
+ }
16678
+ abortRequest(item, reason) {
16679
+ var _a;
16680
+ if (!item.abortController.signal.aborted) {
16681
+ item.abortController.abort(reason);
16682
+ }
16683
+ (_a = item.abort) == null ? void 0 : _a.call(item);
16684
+ }
16685
+ clearRequestTimeout(item) {
16686
+ if (item.timeoutId) {
16687
+ clearTimeout(item.timeoutId);
16688
+ item.timeoutId = void 0;
16689
+ }
16690
+ }
16691
+ finishRequest(item) {
16692
+ if (item.completed) return;
16693
+ item.completed = true;
16694
+ this.clearRequestTimeout(item);
16695
+ this.activeRequests = this.activeRequests.filter((x) => x !== item);
16696
+ this.checkIdle();
16697
+ this._next();
16698
+ }
16699
+ isIdle() {
16700
+ return this.queue.length === 0 && this.activeRequests.length === 0;
16701
+ }
16702
+ checkIdle() {
16703
+ if (this.isIdle()) {
16704
+ this.idleResolvers.splice(0).forEach((resolve) => resolve());
16567
16705
  }
16568
16706
  }
16569
16707
  }
16570
16708
 
16571
- const imageQueue = new Queue({ concurrency: 6, delay: 200 });
16709
+ const imageQueue = new Queue({ limit: 6, debounce: 150 });
16572
16710
 
16573
16711
  var __defProp$6 = Object.defineProperty;
16574
16712
  var __defNormalProp$6 = (obj, key, value) => key in obj ? __defProp$6(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
16575
16713
  var __publicField$3 = (obj, key, value) => __defNormalProp$6(obj, key + "" , value);
16714
+ const transparentImage = "data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEAAAAALAAAAAABAAEAAAIBAAA=";
16576
16715
  class ImageOverlay extends leafletSrcExports.ImageOverlay {
16577
16716
  constructor(imageUrl, bounds, options) {
16578
16717
  super(imageUrl, bounds, options);
16579
16718
  __publicField$3(this, "_aborter");
16580
16719
  }
16581
16720
  cancelLoad() {
16721
+ imageQueue.remove(leafletSrcExports.Util.stamp(this));
16582
16722
  if (this._aborter) {
16583
16723
  this._aborter();
16584
16724
  this._aborter = void 0;
@@ -16590,19 +16730,27 @@ class ImageOverlay extends leafletSrcExports.ImageOverlay {
16590
16730
  const img = this._image;
16591
16731
  const src = img.src;
16592
16732
  img.src = "";
16593
- imageQueue.add(() => {
16594
- const [promise, abortFunc] = callAjax({
16595
- src,
16596
- headers,
16597
- request,
16598
- withCredentials
16599
- });
16600
- promise.then((imgUrl) => {
16601
- img.src = imgUrl;
16602
- });
16603
- this._aborter = abortFunc;
16604
- return promise;
16605
- });
16733
+ imageQueue.add(
16734
+ ({ signal }) => {
16735
+ const [promise, abortFunc] = callAjax({
16736
+ src,
16737
+ headers,
16738
+ request,
16739
+ withCredentials
16740
+ });
16741
+ void promise.then((imgUrl) => {
16742
+ if (!signal.aborted) img.src = imgUrl || transparentImage;
16743
+ }).catch((error) => {
16744
+ if (!signal.aborted) {
16745
+ console.error(error);
16746
+ img.src = transparentImage;
16747
+ }
16748
+ });
16749
+ this._aborter = abortFunc;
16750
+ return [promise, abortFunc];
16751
+ },
16752
+ { id: leafletSrcExports.Util.stamp(this) }
16753
+ );
16606
16754
  }
16607
16755
  }
16608
16756
 
@@ -16672,6 +16820,12 @@ class ImageLayer extends leafletSrcExports.Layer {
16672
16820
  map.removeLayer(this._currentOverlay);
16673
16821
  delete this._currentOverlay;
16674
16822
  }
16823
+ if (this._loadedOverlay) {
16824
+ this._loadedOverlay.cancelLoad();
16825
+ this._loadedOverlay.off("load");
16826
+ map.removeLayer(this._loadedOverlay);
16827
+ this._loadedOverlay = void 0;
16828
+ }
16675
16829
  if (this._currentUrl) {
16676
16830
  delete this._currentUrl;
16677
16831
  }
@@ -16697,6 +16851,7 @@ class ImageLayer extends leafletSrcExports.Layer {
16697
16851
  if (this._loadedOverlay) {
16698
16852
  this._loadedOverlay.cancelLoad();
16699
16853
  this._loadedOverlay.off("load");
16854
+ this._map.removeLayer(this._loadedOverlay);
16700
16855
  this._loadedOverlay = void 0;
16701
16856
  }
16702
16857
  const overlay = new ImageOverlay(url, bounds, {
@@ -16747,6 +16902,7 @@ class ImageLayer extends leafletSrcExports.Layer {
16747
16902
  if (this._currentOverlay) {
16748
16903
  this._currentOverlay.setOpacity(opacity);
16749
16904
  }
16905
+ this.fire("opacitychange", { opacity });
16750
16906
  }
16751
16907
  bringToBack() {
16752
16908
  this.options.isBack = true;