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