@nextgis/ngw-connector 1.18.21 → 1.19.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.
@@ -1,4 +1,4 @@
1
- /** Bundle of @nextgis/ngw-connector; version: 1.18.21; author: NextGIS */
1
+ /** Bundle of @nextgis/ngw-connector; version: 1.19.6; author: NextGIS */
2
2
  var events = {exports: {}};
3
3
 
4
4
  var R = typeof Reflect === 'object' ? Reflect : null;
@@ -475,628 +475,671 @@ function eventTargetAgnosticAddListener(emitter, name, listener, flags) {
475
475
  }
476
476
  }
477
477
 
478
- class CancelError extends Error {
479
- constructor() {
480
- super();
481
- this.name = 'CancelError';
482
- Object.setPrototypeOf(this, CancelError.prototype);
483
- }
478
+ /**
479
+ * from https://github.com/CesiumGS/cesium/blob/master/Source/Core/defined.js
480
+ *
481
+ * @param val - The object.
482
+ * @returns Returns true if the object is defined, returns false otherwise.
483
+ *
484
+ * @example
485
+ * ```javascript
486
+ * if (defined(positions)) {
487
+ * doSomething();
488
+ * } else {
489
+ * doSomethingElse();
490
+ * }
491
+ * ```
492
+ */
493
+ function defined(val) {
494
+ return val !== undefined && val !== null;
495
+ }
496
+ /**
497
+ * from https://github.com/CesiumGS/cesium/blob/master/Source/Core/defined.js
498
+ *
499
+ * @param val - The object.
500
+ * @returns Returns true if the object is defined and not empty string, returns false otherwise.
501
+ *
502
+ * @example
503
+ * ```javascript
504
+ * full('foo') // true
505
+ * full('') // false
506
+ * full(undefined) // false
507
+ * full(0) // true
508
+ * ```
509
+ */
510
+ function full(val) {
511
+ return typeof val === 'string' ? !!val : defined(val);
484
512
  }
485
513
 
486
- class PromiseControl {
487
- constructor(options = {}) {
488
- this.options = options;
489
- this._promises = new Map();
490
- }
491
- get isLoaded() {
492
- return this._promises.size > 0;
514
+ function isEqual(a, b, o, p) {
515
+ if (a instanceof Array) {
516
+ if (!(b instanceof Array))
517
+ return false;
518
+ //if (compareObjects(oVal, pVal === false) return false
519
+ //would work, too, and perhaps is a better fit, still, this is easy, too
520
+ return b.sort().join('') === a.sort().join('');
493
521
  }
494
- remove(promise) {
495
- if (this._promises.has(promise)) {
496
- this._promises.delete(promise);
497
- this._onStop();
498
- }
522
+ else if (a instanceof Date) {
523
+ if (!(b instanceof Date))
524
+ return false;
525
+ return '' + a === '' + b;
499
526
  }
500
- get(promise) {
501
- return this._promises.get(promise);
527
+ else if (a instanceof Function) {
528
+ if (!(b instanceof Function))
529
+ return false;
530
+ //ignore functions, or check them regardless?
502
531
  }
503
- add(promise, name) {
504
- const key = name ? name : promise;
505
- const exist = this._promises.get(key);
506
- if (this.options.onStart && !this.isLoaded) {
507
- this.options.onStart();
532
+ else if (a instanceof Object) {
533
+ if (!(b instanceof Object))
534
+ return false;
535
+ if (a === o) {
536
+ return b === p;
508
537
  }
509
- if (exist) {
510
- return exist;
538
+ else {
539
+ return objectDeepEqual(a, b);
511
540
  }
512
- this._promises.set(key, promise);
513
- promise.finally(() => {
514
- this.remove(key);
515
- });
516
- return promise;
517
541
  }
518
- abort() {
519
- if (this.isLoaded) {
520
- this._promises.forEach((x) => {
521
- if (x.cancel) {
522
- x.cancel();
523
- }
524
- });
525
- this._promises.clear();
526
- this._onStop();
542
+ return a === b;
543
+ }
544
+ // based on https://stackoverflow.com/a/13143059
545
+ function objectDeepEqual(o, p) {
546
+ const keysO = Object.keys(o).sort();
547
+ const keysP = Object.keys(p).sort();
548
+ if (keysO.length !== keysP.length)
549
+ return false;
550
+ if (keysO.join('') !== keysP.join(''))
551
+ return false;
552
+ for (let i = 0; i < keysO.length; i++) {
553
+ const oVal = o[keysO[i]];
554
+ const pVal = p[keysP[i]];
555
+ if (!isEqual(oVal, pVal, o, p)) {
556
+ return false;
527
557
  }
528
558
  }
529
- waitFunc(func, name = '') {
530
- name = name || func.name;
531
- const exist = this.get(name);
532
- if (exist) {
533
- return exist;
559
+ return true;
560
+ }
561
+
562
+ function objectRemoveEmpty(obj) {
563
+ const newObj = {};
564
+ Object.keys(obj).forEach((key) => {
565
+ if (!(obj[key] instanceof Array) && obj[key] === Object(obj[key])) {
566
+ newObj[key] = objectRemoveEmpty(obj[key]);
534
567
  }
535
- return this.add(func(), name);
536
- }
537
- WaitForMe(name = '') {
538
- const get = this.get.bind(this);
539
- const add = this.add.bind(this);
540
- return function (target, key, descriptor) {
541
- const originalMethod = descriptor.value;
542
- name = name || key;
543
- descriptor.value = function (...args) {
544
- const exist = get(name);
545
- if (exist) {
546
- return exist;
547
- }
548
- const result = add(originalMethod.apply(this, args), name);
549
- return result;
550
- };
551
- return descriptor;
552
- };
553
- }
554
- /** @deprecated use {@link PromiseControl.WaitForMe } instead */
555
- GetOrCreateDecorator(name = '') {
556
- return this.WaitForMe(name);
557
- }
558
- _onStop() {
559
- if (this.options.onStop && !this.isLoaded) {
560
- this.options.onStop();
568
+ else if (obj[key] !== undefined) {
569
+ newObj[key] = obj[key];
561
570
  }
562
- }
571
+ });
572
+ return newObj;
563
573
  }
564
574
 
565
- class TimeoutError extends Error {
566
- constructor() {
567
- super();
568
- this.name = 'TimeoutError';
569
- Object.setPrototypeOf(this, TimeoutError.prototype);
570
- }
575
+ function fixUrlStr(url) {
576
+ // remove double slash
577
+ return url.replace(/([^:]\/)\/+/g, '$1');
571
578
  }
572
579
 
573
- const handleCallback = (resolve, reject, callback, r) => {
574
- try {
575
- resolve(callback(r));
576
- }
577
- catch (e) {
578
- reject(e);
579
- }
580
- };
581
- let ID$1 = 0;
582
580
  /**
583
- * Promise that can be canceled
584
- *
585
581
  * @example
586
- * Catch `CancelError`
587
582
  * ```javascript
588
- * import CancelablePromise from "@nextgis/cancelable-promise";
583
+ * const cache1 = new Cache();
584
+ * cache1.add('foo', 'value');
589
585
  *
590
- * const promise = new CancelablePromise((resolve, reject) => {
591
- * setTimeout(() => resolve(), 100);
592
- * }).catch((er) => {
593
- * if (er.name === "CancelError") {
594
- * // handle cancel error
595
- * }
596
- * throw er;
597
- * });
586
+ * const cache2 = new Cache();
587
+ * cache2.match('foo'); // value
598
588
  *
599
- * promise.cancel();
589
+ * const cache3 = new Cache({ namespace: 'foo' });
590
+ * cache3.match('foo'); // undefined
600
591
  * ```
592
+ *
601
593
  * @example
602
- * Handle `onCancel` callback
603
594
  * ```javascript
604
- * import CancelablePromise from "@nextgis/cancelable-promise";
605
- *
606
- * const promise = new CancelablePromise((resolve, reject, onCancel) => {
607
- * const xhr = new XMLHttpRequest();
608
- * xhr.open("GET", url, true);
609
- * xhr.onload = () => {
610
- * resolve(xhr.responseText);
611
- * };
612
- * xhr.onerror = (er) => {
613
- * reject(er);
614
- * };
615
- *
616
- * onCancel(() => {
617
- * xhr.abort();
618
- * });
619
- *
620
- * xhr.send();
595
+ * let COUNTER = 0;
596
+ * const createPromise = () => new Promise((res) => {
597
+ * COUNTER++
598
+ * setTimeout(() => res('Ok'), 300)
621
599
  * });
622
600
  *
623
- * promise.cancel();
601
+ * const cache = new Cache();
602
+ * for (let i = 0; i < 10; i++) {
603
+ * cache.add('foo', createPromise).then((data) => {
604
+ * console.log(data); // 'Ok'
605
+ * });
606
+ * }
607
+ * console.log(COUNTER); // 1
624
608
  * ```
625
609
  */
626
- class CancelablePromise$1 {
627
- constructor(executor, timeout) {
628
- this.id = ID$1++;
629
- this._isCanceled = false;
630
- this._isPending = true;
631
- this._cancelHandlers = [];
632
- this._children = [];
633
- this._cancelPromise = new Promise((resolve_, reject_) => {
634
- this._setCanceledCallback = (er) => resolve_(er || new CancelError());
635
- });
636
- const promises = [
637
- this._cancelPromise,
638
- new Promise((resolve, reject) => {
639
- const onResolve = (value) => {
640
- if (value instanceof CancelablePromise$1) {
641
- this.attach(value);
642
- }
643
- else {
644
- this._isPending = false;
645
- }
646
- // TODO: fix types, `undefined` not allowed since 19.12.2020
647
- resolve(value);
648
- };
649
- const onReject = (error) => {
650
- this._isPending = false;
651
- reject(error);
652
- };
653
- const onCancel = (handler) => {
654
- if (!this._isPending) {
655
- throw new Error('The `onCancel` handler was attached after the promise settled.');
656
- }
657
- this._cancelHandlers.push(handler);
658
- };
659
- return executor(onResolve, onReject, onCancel);
660
- }),
661
- ];
662
- if (timeout) {
663
- promises.push(new Promise((resolve, reject) => {
664
- setTimeout(() => {
665
- if (this._isPending) {
666
- try {
667
- this.cancel();
668
- }
669
- finally {
670
- reject(new TimeoutError());
671
- }
672
- }
673
- }, timeout);
674
- }));
610
+ class Cache$1 {
611
+ constructor(options = {}) {
612
+ var _a;
613
+ this.cache = [];
614
+ const namespace = (_a = options.namespace) !== null && _a !== void 0 ? _a : 'default';
615
+ if (Cache$1.instance[namespace]) {
616
+ return Cache$1.instance[namespace];
675
617
  }
676
- this._promise = Promise.race(promises);
618
+ Cache$1.instance[namespace] = this;
619
+ return this;
677
620
  }
678
- static createControl(opt) {
679
- return new PromiseControl(opt);
621
+ clean() {
622
+ this.cache.length = 0;
680
623
  }
681
- static resolve(value) {
682
- return new CancelablePromise$1((resolve) => resolve(value));
624
+ all() {
625
+ return this.cache;
683
626
  }
684
- static reject(value) {
685
- return new CancelablePromise$1((resolve, reject) => reject(value));
627
+ /**
628
+ * Caching only a non-empty value.
629
+ *
630
+ * Useful for get or create strategy
631
+ * @example
632
+ * ```javascript
633
+ * const cache = new Cache();
634
+ * const getItemFunc = () => fetch(url).then((data) => {
635
+ * return data.json(); // undefined
636
+ * });
637
+ * const item = await cache.addFull('foo', getItemFunc);
638
+ * if (!item) {
639
+ * await createItem(); // 'New item'
640
+ * }
641
+ *
642
+ * // somewhere else in the code
643
+ * const item = await cache.addFull('foo', getItemFunc).then((resp) => {
644
+ * console.log(resp); // 'New item'
645
+ * })
646
+ *
647
+ * ```
648
+ */
649
+ addFull(key, valueToSet, props) {
650
+ return this.add(key, valueToSet, props, true);
686
651
  }
687
- static all(values) {
688
- return new CancelablePromise$1((resolve, reject) => {
689
- Promise.all(values).then(resolve).catch(reject);
690
- }).catch((er) => {
691
- if (er instanceof this.CancelError) {
692
- for (const v of values) {
693
- const v_ = v;
694
- if ('cancel' in v_) {
695
- v_.cancel();
696
- }
652
+ add(key, valueToSet, props, onlyFull) {
653
+ const exist = this._find(key, props);
654
+ if (!exist) {
655
+ let value;
656
+ if (valueToSet instanceof Function) {
657
+ value = valueToSet();
658
+ }
659
+ else {
660
+ value = valueToSet;
661
+ }
662
+ const props_ = props && JSON.parse(JSON.stringify(objectRemoveEmpty(props)));
663
+ const cacheItem = {
664
+ key,
665
+ value,
666
+ props: props_,
667
+ // TODO: remove backward compatibility use only props
668
+ options: props_,
669
+ };
670
+ if (onlyFull && !full(value)) {
671
+ return value;
672
+ }
673
+ this.cache.push(cacheItem);
674
+ if (value instanceof Promise) {
675
+ value.catch((er) => {
676
+ this.delete(key, props);
677
+ throw er;
678
+ });
679
+ if (onlyFull) {
680
+ value.then((x) => {
681
+ if (!full(x)) {
682
+ this.delete(key, props);
683
+ }
684
+ return x;
685
+ });
697
686
  }
687
+ return value;
698
688
  }
699
- throw er;
700
- });
701
- }
702
- attach(p) {
703
- if (this._isCanceled) {
704
- p.cancel();
689
+ return value;
705
690
  }
706
691
  else {
707
- this._children.push(p);
692
+ return exist.value;
708
693
  }
709
694
  }
710
- then(onfulfilled, onrejected) {
711
- const p = new CancelablePromise$1((resolve, reject) => {
712
- if (this._promise) {
713
- const reject_ = (r) => {
714
- if (onrejected) {
715
- handleCallback(resolve, reject, onrejected, r);
716
- }
717
- else {
718
- reject(r);
719
- }
720
- };
721
- this._promise.then((r) => {
722
- if (this._isCanceled) {
723
- reject_(r);
724
- }
725
- else {
726
- if (onfulfilled) {
727
- handleCallback(resolve, reject, onfulfilled, r);
728
- }
729
- else {
730
- resolve(r);
731
- }
732
- }
733
- }, reject_);
734
- }
735
- });
736
- p._parentPromise = this;
737
- this._children.push(p);
738
- return p;
739
- }
740
- catch(onrejected) {
741
- if (this._isCanceled && onrejected) {
742
- onrejected(new CancelError());
695
+ match(key, props) {
696
+ const cacheRecord = this._find(key, props);
697
+ if (cacheRecord) {
698
+ return cacheRecord.value;
743
699
  }
744
- return this.then(undefined, onrejected);
745
700
  }
746
- finally(onfinally) {
747
- if (this._promise) {
748
- return this._promise.finally(onfinally);
749
- }
750
- if (this._isCanceled) {
751
- return Promise.reject(new CancelError());
701
+ matchAll(key, props) {
702
+ if (key) {
703
+ return this.cache
704
+ .filter((x) => this._filter(x, key, props))
705
+ .map((x) => x.value);
752
706
  }
753
- return Promise.reject(onfinally);
707
+ return this.cache.map((x) => x.value);
754
708
  }
755
- cancel() {
756
- // No reason to run cancel action if promise is already complete
757
- if (this._isCanceled || !this._isPending) {
758
- return this;
759
- }
760
- this._isCanceled = true;
761
- const parent = this._getTopParent();
762
- if (parent) {
763
- parent.cancel();
709
+ delete(keyOrItem, props) {
710
+ let exist = [];
711
+ if (typeof keyOrItem === 'string') {
712
+ exist = this.cache.filter((x) => this._filter(x, keyOrItem, props));
764
713
  }
765
- if (this._children) {
766
- this._children.forEach((x) => x.cancel());
714
+ else {
715
+ exist.push(keyOrItem);
767
716
  }
768
- if (this._isPending) {
769
- if (this._cancelHandlers.length) {
770
- try {
771
- for (const handler of this._cancelHandlers) {
772
- handler();
773
- }
774
- }
775
- catch (error) {
776
- // this._setCanceledCallback(error);
777
- }
778
- }
779
- if (this._setCanceledCallback) {
780
- this._setCanceledCallback();
781
- }
717
+ for (const e of exist) {
718
+ const index = this.cache.indexOf(e);
719
+ this.cache.splice(index, 1);
782
720
  }
783
- this._destroy();
784
- return this;
785
721
  }
786
- _getTopParent() {
787
- let parent = this._parentPromise;
788
- let hasParent = !!parent;
789
- while (hasParent) {
790
- if (parent && parent._parentPromise) {
791
- parent = parent._parentPromise;
792
- hasParent = !!parent;
793
- }
794
- else {
795
- hasParent = false;
722
+ _find(key, props) {
723
+ return this.cache.find((x) => this._filter(x, key, props));
724
+ }
725
+ _filter(item, key, props) {
726
+ if (item.key === key) {
727
+ if (props) {
728
+ // TODO: remove backward compatibility
729
+ const itemProps = item.props || item.options;
730
+ return objectDeepEqual(itemProps || {}, objectRemoveEmpty(props));
796
731
  }
732
+ return true;
797
733
  }
798
- return parent;
799
- }
800
- _destroy() {
801
- this._setCanceledCallback = undefined;
802
- this._cancelPromise = undefined;
803
- this._promise = undefined;
734
+ return false;
804
735
  }
805
736
  }
806
- CancelablePromise$1.CancelError = CancelError;
807
- CancelablePromise$1.TimeoutError = TimeoutError;
808
- CancelablePromise$1.PromiseControl = PromiseControl;
809
- Object.setPrototypeOf(CancelablePromise$1.prototype, Promise.prototype);
737
+ Cache$1.instance = {};
810
738
 
811
739
  /**
812
- * A promise you can stop
740
+ * Caching for asynchronous functions
813
741
  *
814
742
  * @packageDocumentation
815
- * @module cancelable-promise
743
+ * @module cache
816
744
  */
817
- var CancelablePromise = CancelablePromise$1;
745
+ var Cache = Cache$1;
818
746
 
819
- /**
820
- * from https://github.com/CesiumGS/cesium/blob/master/Source/Core/defined.js
821
- *
822
- * @param val - The object.
823
- * @returns Returns true if the object is defined, returns false otherwise.
824
- *
825
- * @example
826
- * ```javascript
827
- * if (defined(positions)) {
828
- * doSomething();
829
- * } else {
830
- * doSomethingElse();
831
- * }
832
- * ```
833
- */
834
- function defined(val) {
835
- return val !== undefined && val !== null;
836
- }
837
- /**
838
- * from https://github.com/CesiumGS/cesium/blob/master/Source/Core/defined.js
839
- *
840
- * @param val - The object.
841
- * @returns Returns true if the object is defined and not empty string, returns false otherwise.
842
- *
843
- * @example
844
- * ```javascript
845
- * full('foo') // true
846
- * full('') // false
847
- * full(undefined) // false
848
- * full(0) // true
849
- * ```
850
- */
851
- function full(val) {
852
- return typeof val === 'string' ? !!val : defined(val);
747
+ class CancelError extends Error {
748
+ constructor() {
749
+ super();
750
+ this.name = 'CancelError';
751
+ Object.setPrototypeOf(this, CancelError.prototype);
752
+ }
853
753
  }
854
754
 
855
- function isEqual(a, b, o, p) {
856
- if (a instanceof Array) {
857
- if (!(b instanceof Array))
858
- return false;
859
- //if (compareObjects(oVal, pVal === false) return false
860
- //would work, too, and perhaps is a better fit, still, this is easy, too
861
- return b.sort().join('') === a.sort().join('');
755
+ class PromiseControl {
756
+ constructor(options = {}) {
757
+ this.options = options;
758
+ this._promises = new Map();
862
759
  }
863
- else if (a instanceof Date) {
864
- if (!(b instanceof Date))
865
- return false;
866
- return '' + a === '' + b;
760
+ get isLoaded() {
761
+ return this._promises.size > 0;
867
762
  }
868
- else if (a instanceof Function) {
869
- if (!(b instanceof Function))
870
- return false;
871
- //ignore functions, or check them regardless?
763
+ remove(promise) {
764
+ if (this._promises.has(promise)) {
765
+ this._promises.delete(promise);
766
+ this._onStop();
767
+ }
872
768
  }
873
- else if (a instanceof Object) {
874
- if (!(b instanceof Object))
875
- return false;
876
- if (a === o) {
877
- return b === p;
769
+ get(promise) {
770
+ return this._promises.get(promise);
771
+ }
772
+ add(promise, name) {
773
+ const key = name ? name : promise;
774
+ const exist = this._promises.get(key);
775
+ if (this.options.onStart && !this.isLoaded) {
776
+ this.options.onStart();
878
777
  }
879
- else {
880
- return objectDeepEqual(a, b);
778
+ if (exist) {
779
+ return exist;
881
780
  }
781
+ this._promises.set(key, promise);
782
+ promise.finally(() => {
783
+ this.remove(key);
784
+ });
785
+ return promise;
882
786
  }
883
- return a === b;
884
- }
885
- // based on https://stackoverflow.com/a/13143059
886
- function objectDeepEqual(o, p) {
887
- const keysO = Object.keys(o).sort();
888
- const keysP = Object.keys(p).sort();
889
- if (keysO.length !== keysP.length)
890
- return false;
891
- if (keysO.join('') !== keysP.join(''))
892
- return false;
893
- for (let i = 0; i < keysO.length; i++) {
894
- const oVal = o[keysO[i]];
895
- const pVal = p[keysP[i]];
896
- if (!isEqual(oVal, pVal, o, p)) {
897
- return false;
787
+ abort() {
788
+ if (this.isLoaded) {
789
+ this._promises.forEach((x) => {
790
+ if (x.cancel) {
791
+ x.cancel();
792
+ }
793
+ });
794
+ this._promises.clear();
795
+ this._onStop();
898
796
  }
899
797
  }
900
- return true;
901
- }
902
-
903
- function objectRemoveEmpty(obj) {
904
- const newObj = {};
905
- Object.keys(obj).forEach((key) => {
906
- if (!(obj[key] instanceof Array) && obj[key] === Object(obj[key])) {
907
- newObj[key] = objectRemoveEmpty(obj[key]);
798
+ waitFunc(func, name = '') {
799
+ name = name || func.name;
800
+ const exist = this.get(name);
801
+ if (exist) {
802
+ return exist;
908
803
  }
909
- else if (obj[key] !== undefined) {
910
- newObj[key] = obj[key];
804
+ return this.add(func(), name);
805
+ }
806
+ WaitForMe(name = '') {
807
+ const get = this.get.bind(this);
808
+ const add = this.add.bind(this);
809
+ return function (target, key, descriptor) {
810
+ const originalMethod = descriptor.value;
811
+ name = name || key;
812
+ descriptor.value = function (...args) {
813
+ const exist = get(name);
814
+ if (exist) {
815
+ return exist;
816
+ }
817
+ const result = add(originalMethod.apply(this, args), name);
818
+ return result;
819
+ };
820
+ return descriptor;
821
+ };
822
+ }
823
+ /** @deprecated use {@link PromiseControl.WaitForMe } instead */
824
+ GetOrCreateDecorator(name = '') {
825
+ return this.WaitForMe(name);
826
+ }
827
+ _onStop() {
828
+ if (this.options.onStop && !this.isLoaded) {
829
+ this.options.onStop();
911
830
  }
912
- });
913
- return newObj;
831
+ }
914
832
  }
915
833
 
916
- function fixUrlStr(url) {
917
- // remove double slash
918
- return url.replace(/([^:]\/)\/+/g, '$1');
834
+ class TimeoutError extends Error {
835
+ constructor() {
836
+ super();
837
+ this.name = 'TimeoutError';
838
+ Object.setPrototypeOf(this, TimeoutError.prototype);
839
+ }
919
840
  }
920
841
 
842
+ const handleCallback = (resolve, reject, callback, r) => {
843
+ try {
844
+ resolve(callback(r));
845
+ }
846
+ catch (e) {
847
+ reject(e);
848
+ }
849
+ };
850
+ let ID$1 = 0;
921
851
  /**
852
+ * Promise that can be canceled
853
+ *
922
854
  * @example
855
+ * Catch `CancelError`
923
856
  * ```javascript
924
- * const cache1 = new Cache();
925
- * cache1.add('foo', 'value');
857
+ * import CancelablePromise from "@nextgis/cancelable-promise";
926
858
  *
927
- * const cache2 = new Cache();
928
- * cache2.match('foo'); // value
859
+ * const promise = new CancelablePromise((resolve, reject) => {
860
+ * setTimeout(() => resolve(), 100);
861
+ * }).catch((er) => {
862
+ * if (er.name === "CancelError") {
863
+ * // handle cancel error
864
+ * }
865
+ * throw er;
866
+ * });
929
867
  *
930
- * const cache3 = new Cache({ namespace: 'foo' });
931
- * cache3.match('foo'); // undefined
868
+ * promise.cancel();
932
869
  * ```
933
- *
934
870
  * @example
871
+ * Handle `onCancel` callback
935
872
  * ```javascript
936
- * let COUNTER = 0;
937
- * const createPromise = () => new Promise((res) => {
938
- * COUNTER++
939
- * setTimeout(() => res('Ok'), 300)
940
- * });
873
+ * import CancelablePromise from "@nextgis/cancelable-promise";
941
874
  *
942
- * const cache = new Cache();
943
- * for (let i = 0; i < 10; i++) {
944
- * cache.add('foo', createPromise).then((data) => {
945
- * console.log(data); // 'Ok'
875
+ * const promise = new CancelablePromise((resolve, reject, onCancel) => {
876
+ * const xhr = new XMLHttpRequest();
877
+ * xhr.open("GET", url, true);
878
+ * xhr.onload = () => {
879
+ * resolve(xhr.responseText);
880
+ * };
881
+ * xhr.onerror = (er) => {
882
+ * reject(er);
883
+ * };
884
+ *
885
+ * onCancel(() => {
886
+ * xhr.abort();
946
887
  * });
947
- * }
948
- * console.log(COUNTER); // 1
888
+ *
889
+ * xhr.send();
890
+ * });
891
+ *
892
+ * promise.cancel();
949
893
  * ```
950
894
  */
951
- class Cache$1 {
952
- constructor(options = {}) {
953
- var _a;
954
- this.cache = [];
955
- const namespace = (_a = options.namespace) !== null && _a !== void 0 ? _a : 'default';
956
- if (Cache$1.instance[namespace]) {
957
- return Cache$1.instance[namespace];
958
- }
959
- Cache$1.instance[namespace] = this;
960
- return this;
961
- }
962
- clean() {
963
- this.cache.length = 0;
964
- }
965
- all() {
966
- return this.cache;
967
- }
968
- /**
969
- * Caching only a non-empty value.
970
- *
971
- * Useful for get or create strategy
972
- * @example
973
- * ```javascript
974
- * const cache = new Cache();
975
- * const getItemFunc = () => fetch(url).then((data) => {
976
- * return data.json(); // undefined
977
- * });
978
- * const item = await cache.addFull('foo', getItemFunc);
979
- * if (!item) {
980
- * await createItem(); // 'New item'
981
- * }
982
- *
983
- * // somewhere else in the code
984
- * const item = await cache.addFull('foo', getItemFunc).then((resp) => {
985
- * console.log(resp); // 'New item'
986
- * })
987
- *
988
- * ```
989
- */
990
- addFull(key, valueToSet, props) {
991
- return this.add(key, valueToSet, props, true);
992
- }
993
- add(key, valueToSet, props, onlyFull) {
994
- const exist = this._find(key, props);
995
- if (!exist) {
996
- let value;
997
- if (valueToSet instanceof Function) {
998
- value = valueToSet();
999
- }
1000
- else {
1001
- value = valueToSet;
1002
- }
1003
- const props_ = props && JSON.parse(JSON.stringify(objectRemoveEmpty(props)));
1004
- const cacheItem = {
1005
- key,
1006
- value,
1007
- props: props_,
1008
- // TODO: remove backward compatibility use only props
1009
- options: props_,
1010
- };
1011
- if (onlyFull && !full(value)) {
1012
- return value;
1013
- }
1014
- this.cache.push(cacheItem);
1015
- if (value instanceof Promise) {
1016
- value.catch((er) => {
1017
- this.delete(key, props);
1018
- throw er;
1019
- });
1020
- if (onlyFull) {
1021
- value.then((x) => {
1022
- if (!full(x)) {
1023
- this.delete(key, props);
895
+ class CancelablePromise$1 {
896
+ constructor(executor, timeout) {
897
+ this.id = ID$1++;
898
+ this._isCanceled = false;
899
+ this._isPending = true;
900
+ this._cancelHandlers = [];
901
+ this._children = [];
902
+ this._cancelPromise = new Promise((resolve_, reject_) => {
903
+ this._setCanceledCallback = (er) => resolve_(er || new CancelError());
904
+ });
905
+ const promises = [
906
+ this._cancelPromise,
907
+ new Promise((resolve, reject) => {
908
+ const onResolve = (value) => {
909
+ if (value instanceof CancelablePromise$1) {
910
+ this.attach(value);
911
+ }
912
+ else {
913
+ this._isPending = false;
914
+ }
915
+ // TODO: fix types, `undefined` not allowed since 19.12.2020
916
+ resolve(value);
917
+ };
918
+ const onReject = (error) => {
919
+ this._isPending = false;
920
+ reject(error);
921
+ };
922
+ const onCancel = (handler) => {
923
+ if (!this._isPending) {
924
+ throw new Error('The `onCancel` handler was attached after the promise settled.');
925
+ }
926
+ this._cancelHandlers.push(handler);
927
+ };
928
+ return executor(onResolve, onReject, onCancel);
929
+ }),
930
+ ];
931
+ if (timeout) {
932
+ promises.push(new Promise((resolve, reject) => {
933
+ setTimeout(() => {
934
+ if (this._isPending) {
935
+ try {
936
+ this.cancel();
1024
937
  }
1025
- return x;
1026
- });
938
+ finally {
939
+ reject(new TimeoutError());
940
+ }
941
+ }
942
+ }, timeout);
943
+ }));
944
+ }
945
+ this._promise = Promise.race(promises);
946
+ }
947
+ static createControl(opt) {
948
+ return new PromiseControl(opt);
949
+ }
950
+ static resolve(value) {
951
+ return new CancelablePromise$1((resolve) => resolve(value));
952
+ }
953
+ static reject(value) {
954
+ return new CancelablePromise$1((resolve, reject) => reject(value));
955
+ }
956
+ static all(values) {
957
+ return new CancelablePromise$1((resolve, reject) => {
958
+ Promise.all(values).then(resolve).catch(reject);
959
+ }).catch((er) => {
960
+ if (er instanceof this.CancelError) {
961
+ for (const v of values) {
962
+ const v_ = v;
963
+ if ('cancel' in v_) {
964
+ v_.cancel();
965
+ }
1027
966
  }
1028
- return value;
1029
967
  }
1030
- return value;
968
+ throw er;
969
+ });
970
+ }
971
+ attach(p) {
972
+ if (this._isCanceled) {
973
+ p.cancel();
1031
974
  }
1032
975
  else {
1033
- return exist.value;
976
+ this._children.push(p);
1034
977
  }
1035
978
  }
1036
- match(key, props) {
1037
- const cacheRecord = this._find(key, props);
1038
- if (cacheRecord) {
1039
- return cacheRecord.value;
979
+ then(onfulfilled, onrejected) {
980
+ const p = new CancelablePromise$1((resolve, reject) => {
981
+ if (this._promise) {
982
+ const reject_ = (r) => {
983
+ if (onrejected) {
984
+ handleCallback(resolve, reject, onrejected, r);
985
+ }
986
+ else {
987
+ reject(r);
988
+ }
989
+ };
990
+ this._promise.then((r) => {
991
+ if (this._isCanceled) {
992
+ reject_(r);
993
+ }
994
+ else {
995
+ if (onfulfilled) {
996
+ handleCallback(resolve, reject, onfulfilled, r);
997
+ }
998
+ else {
999
+ resolve(r);
1000
+ }
1001
+ }
1002
+ }, reject_);
1003
+ }
1004
+ });
1005
+ p._parentPromise = this;
1006
+ this._children.push(p);
1007
+ return p;
1008
+ }
1009
+ catch(onrejected) {
1010
+ if (this._isCanceled && onrejected) {
1011
+ onrejected(new CancelError());
1040
1012
  }
1013
+ return this.then(undefined, onrejected);
1041
1014
  }
1042
- matchAll(key, props) {
1043
- if (key) {
1044
- return this.cache
1045
- .filter((x) => this._filter(x, key, props))
1046
- .map((x) => x.value);
1015
+ finally(onfinally) {
1016
+ if (this._promise) {
1017
+ return this._promise.finally(onfinally);
1047
1018
  }
1048
- return this.cache.map((x) => x.value);
1019
+ if (this._isCanceled) {
1020
+ return Promise.reject(new CancelError());
1021
+ }
1022
+ return Promise.reject(onfinally);
1049
1023
  }
1050
- delete(keyOrItem, props) {
1051
- let exist = [];
1052
- if (typeof keyOrItem === 'string') {
1053
- exist = this.cache.filter((x) => this._filter(x, keyOrItem, props));
1024
+ cancel() {
1025
+ // No reason to run cancel action if promise is already complete
1026
+ if (this._isCanceled || !this._isPending) {
1027
+ return this;
1054
1028
  }
1055
- else {
1056
- exist.push(keyOrItem);
1029
+ this._isCanceled = true;
1030
+ const parent = this._getTopParent();
1031
+ if (parent) {
1032
+ parent.cancel();
1057
1033
  }
1058
- for (const e of exist) {
1059
- const index = this.cache.indexOf(e);
1060
- this.cache.splice(index, 1);
1034
+ if (this._children) {
1035
+ this._children.forEach((x) => x.cancel());
1061
1036
  }
1037
+ if (this._isPending) {
1038
+ if (this._cancelHandlers.length) {
1039
+ try {
1040
+ for (const handler of this._cancelHandlers) {
1041
+ handler();
1042
+ }
1043
+ }
1044
+ catch (error) {
1045
+ // this._setCanceledCallback(error);
1046
+ }
1047
+ }
1048
+ if (this._setCanceledCallback) {
1049
+ this._setCanceledCallback();
1050
+ }
1051
+ }
1052
+ this._destroy();
1053
+ return this;
1062
1054
  }
1063
- _find(key, props) {
1064
- return this.cache.find((x) => this._filter(x, key, props));
1065
- }
1066
- _filter(item, key, props) {
1067
- if (item.key === key) {
1068
- if (props) {
1069
- // TODO: remove backward compatibility
1070
- const itemProps = item.props || item.options;
1071
- return objectDeepEqual(itemProps || {}, objectRemoveEmpty(props));
1055
+ _getTopParent() {
1056
+ let parent = this._parentPromise;
1057
+ let hasParent = !!parent;
1058
+ while (hasParent) {
1059
+ if (parent && parent._parentPromise) {
1060
+ parent = parent._parentPromise;
1061
+ hasParent = !!parent;
1062
+ }
1063
+ else {
1064
+ hasParent = false;
1072
1065
  }
1073
- return true;
1074
1066
  }
1075
- return false;
1067
+ return parent;
1068
+ }
1069
+ _destroy() {
1070
+ this._setCanceledCallback = undefined;
1071
+ this._cancelPromise = undefined;
1072
+ this._promise = undefined;
1076
1073
  }
1077
1074
  }
1078
- Cache$1.instance = {};
1075
+ CancelablePromise$1.CancelError = CancelError;
1076
+ CancelablePromise$1.TimeoutError = TimeoutError;
1077
+ CancelablePromise$1.PromiseControl = PromiseControl;
1078
+ Object.setPrototypeOf(CancelablePromise$1.prototype, Promise.prototype);
1079
1079
 
1080
1080
  /**
1081
- * Caching for asynchronous functions
1081
+ * A promise you can stop
1082
1082
  *
1083
1083
  * @packageDocumentation
1084
- * @module cache
1084
+ * @module cancelable-promise
1085
1085
  */
1086
- var Cache = Cache$1;
1086
+ var CancelablePromise = CancelablePromise$1;
1087
1087
 
1088
- /**
1089
- * Thrown when...
1090
- */
1091
- class NetworkError extends Error {
1092
- constructor(url) {
1093
- super();
1094
- this.name = 'NetworkError';
1095
- Object.setPrototypeOf(this, NetworkError.prototype);
1096
- this.message = `Unable to request ${url}.
1097
- Possibly invalid NGW URL entered or CORS not configured to get request from ${location.origin}`; // /control-panel/cors
1098
- }
1099
- }
1088
+ var pkg = {
1089
+ name: "@nextgis/ngw-connector",
1090
+ version: "1.19.6",
1091
+ _priority: 12,
1092
+ description: "A lightweight HTTP client optimized for use with NextGIS Web API",
1093
+ main: "index.js",
1094
+ module: "lib/ngw-connector.esm-bundler.js",
1095
+ unpkg: "lib/ngw-connector.global.prod.js",
1096
+ jsdelivr: "lib/ngw-connector.global.prod.js",
1097
+ types: "lib/index.d.ts",
1098
+ dependencies: {
1099
+ "@nextgis/cache": "^1.19.0",
1100
+ "@nextgis/cancelable-promise": "^1.19.0",
1101
+ "@nextgis/utils": "^1.19.0",
1102
+ "@types/events": "^3.0.0",
1103
+ events: "^3.3.0",
1104
+ "form-data": "^4.0.0"
1105
+ },
1106
+ devDependencies: {
1107
+ "@nextgis/build-tools": "^1.19.0"
1108
+ },
1109
+ scripts: {
1110
+ clean: "rimraf ./lib",
1111
+ dev: "node ../build-tools/lib/build.js",
1112
+ prod: "npm run dev -- --release",
1113
+ lint: "eslint ./src/**/*.ts --fix --c ../../.eslintrc",
1114
+ watch: "npm run dev -- --watch",
1115
+ "gen:types": "node ./scripts/generator"
1116
+ },
1117
+ buildOptions: {
1118
+ name: "NgwConnector",
1119
+ formats: [
1120
+ "esm-bundler",
1121
+ "esm-browser",
1122
+ "cjs",
1123
+ "global"
1124
+ ]
1125
+ },
1126
+ keywords: [
1127
+ "NextGIS",
1128
+ "MAP"
1129
+ ],
1130
+ author: "NextGIS",
1131
+ files: [
1132
+ "index.js",
1133
+ "lib"
1134
+ ],
1135
+ license: "MIT",
1136
+ homepage: "https://github.com/nextgis/nextgis_frontend/tree/master/packages/ngw-connector#readme",
1137
+ repository: {
1138
+ type: "git",
1139
+ url: "git://github.com/nextgis/nextgis_frontend.git"
1140
+ },
1141
+ gitHead: "edc68033f914f6c95c4125b9738bba6d36e990b4"
1142
+ };
1100
1143
 
1101
1144
  /**
1102
1145
  * Thrown when...
@@ -1109,244 +1152,27 @@ class NgwError extends Error {
1109
1152
  Object.setPrototypeOf(this, NgwError.prototype);
1110
1153
  }
1111
1154
  }
1112
-
1113
- function isObject(val) {
1114
- return Object.prototype.toString.call(val) === '[object Object]';
1115
- }
1116
-
1117
- let loadData;
1118
- // @ts-ignore
1119
- {
1120
- loadData = (url, callback, options = {}, error, onCancel) => {
1121
- options.method = options.method || 'GET';
1122
- const xhr = new XMLHttpRequest();
1123
- xhr.open(options.method || 'GET', url, true); // true for asynchronous
1124
- if (options.responseType === 'blob') {
1125
- xhr.responseType = options.responseType;
1126
- }
1127
- const getResponseText = () => {
1128
- try {
1129
- return JSON.parse(xhr.responseText);
1130
- }
1131
- catch (er) {
1132
- return xhr.responseText;
1133
- }
1134
- };
1135
- const processingResponse = (forError = false) => {
1136
- const cb = forError ? error : callback;
1137
- if (options.responseType === 'blob') {
1138
- cb(xhr.response);
1139
- }
1140
- else {
1141
- if (xhr.responseText) {
1142
- cb(getResponseText());
1143
- }
1144
- else {
1145
- error({ message: '' });
1146
- }
1147
- }
1148
- };
1149
- xhr.onload = () => {
1150
- if ([401, 403, 404, 422, 500].indexOf(xhr.status) !== -1) {
1151
- error(new NgwError(getResponseText()));
1152
- }
1153
- processingResponse();
1154
- };
1155
- // xhr.onreadystatechange = () => {
1156
- // if (
1157
- // (xhr.readyState === 4 && xhr.status === 200) ||
1158
- // (xhr.readyState === 3 && xhr.status === 201)
1159
- // ) {
1160
- // processingResponse();
1161
- // } else if (xhr.readyState === 3 && xhr.status === 400) {
1162
- // processingResponse();
1163
- // } else if (xhr.readyState === 4 && xhr.status === 500) {
1164
- // processingResponse();
1165
- // } else if (xhr.readyState === 4 && xhr.status === 401) {
1166
- // error(xhr.statusText);
1167
- // } else if (xhr.readyState === 4) {
1168
- // error('request error');
1169
- // }
1170
- // };
1171
- xhr.onerror = (er) => {
1172
- if (xhr.status === 0) {
1173
- error(new NetworkError(url));
1174
- }
1175
- else {
1176
- error(er);
1177
- }
1178
- };
1179
- xhr.upload.onprogress = function (e) {
1180
- if (e.lengthComputable) {
1181
- const percentComplete = (e.loaded / e.total) * 100;
1182
- if (options.onProgress) {
1183
- options.onProgress(percentComplete, e);
1184
- }
1185
- // console.log(percentComplete + '% uploaded');
1186
- }
1187
- };
1188
- const headers = options.headers;
1189
- if (headers) {
1190
- for (const h in headers) {
1191
- const header = headers[h];
1192
- if (typeof header === 'string') {
1193
- xhr.setRequestHeader(h, header);
1194
- }
1195
- }
1196
- }
1197
- if (options.withCredentials !== undefined) {
1198
- xhr.withCredentials = options.withCredentials;
1199
- }
1200
- let data;
1201
- if (options.file) {
1202
- data = new FormData();
1203
- data.append('file', options.file);
1204
- if (options.data) {
1205
- for (const d in options.data) {
1206
- data.append(d, data[d]);
1207
- }
1208
- }
1209
- }
1210
- else {
1211
- data = options.data
1212
- ? typeof options.data === 'string'
1213
- ? options.data
1214
- : JSON.stringify(options.data)
1215
- : null;
1216
- }
1217
- if (onCancel) {
1218
- onCancel(() => {
1219
- xhr.abort();
1220
- });
1221
- }
1222
- xhr.send(data);
1223
- };
1224
- }
1225
-
1226
- // https://github.com/Leaflet/Leaflet/blob/b507e21c510b53cd704fb8d3f89bb46ea925c8eb/src/core/Util.js#L165
1227
- const templateRe = /\{ *([\w_-]+) *\}/g;
1228
- function template(str, data) {
1229
- return str.replace(templateRe, (s, key) => {
1230
- let value = data[key];
1231
- if (value === undefined) {
1232
- throw new Error('No value provided for letiable ' + s);
1233
- }
1234
- else if (typeof value === 'function') {
1235
- value = value(data);
1236
- }
1237
- return value;
1238
- });
1239
- }
1240
-
1241
- function apiRequest(opt) {
1242
- const params = opt.params;
1243
- return new CancelablePromise((resolve, reject) => {
1244
- opt.connector
1245
- .connect()
1246
- .then((apiItems) => {
1247
- let apiItem = apiItems && apiItems[opt.name];
1248
- if (apiItem) {
1249
- apiItem = [...apiItem];
1250
- let url = apiItem.shift();
1251
- if (apiItem.length) {
1252
- const replaceParams = {};
1253
- for (let fry = 0; fry < apiItem.length; fry++) {
1254
- const arg = apiItem[fry];
1255
- replaceParams[fry] = '{' + arg + '}';
1256
- if (params[arg] === undefined) {
1257
- throw new Error('`' + arg + '`' + ' url api argument is not specified');
1258
- }
1259
- }
1260
- if (url) {
1261
- url = template(url, replaceParams);
1262
- }
1263
- }
1264
- // Transfer part of the parameters from `params` to the URL string
1265
- if (params) {
1266
- const paramArray = [];
1267
- const paramList = params.paramList;
1268
- if (Array.isArray(paramList)) {
1269
- delete params.paramList;
1270
- paramList.forEach((x) => {
1271
- paramArray.push(`${x[0]}=${x[1]}`);
1272
- });
1273
- }
1274
- for (const p in params) {
1275
- if (apiItem.indexOf(p) === -1) {
1276
- paramArray.push(`${p}=${params[p]}`);
1277
- }
1278
- }
1279
- if (paramArray.length) {
1280
- url = url + '?' + paramArray.join('&');
1281
- }
1282
- }
1283
- if (url) {
1284
- resolve(opt.connector.makeQuery(url, params, opt.requestOptions));
1285
- }
1286
- else {
1287
- reject(new Error('request url is not set'));
1288
- }
1289
- }
1290
- else {
1291
- resolve(undefined);
1292
- }
1293
- })
1294
- .catch((er) => {
1295
- reject(er);
1296
- });
1297
- });
1298
- }
1299
-
1300
- /**
1301
- * Thrown when ...
1302
- */
1303
- class ResourceNotFoundError extends NgwError {
1304
- constructor(obj) {
1305
- super(obj);
1306
- this.name = 'ResourceNotFoundError';
1307
- this.exception = 'nextgisweb.resource.exception.ResourceNotFound';
1308
- Object.setPrototypeOf(this, ResourceNotFoundError.prototype);
1309
- }
1310
- }
1311
-
1312
- /**
1313
- * Thrown when ...
1314
- */
1315
- class InsufficientPermissionsError extends NgwError {
1316
- constructor(obj) {
1317
- super(obj);
1318
- this.name = 'InsufficientPermissionsError';
1319
- this.exception = 'nextgisweb.core.exception.InsufficientPermissions';
1320
- Object.setPrototypeOf(this, InsufficientPermissionsError.prototype);
1321
- }
1322
- }
1323
-
1324
- const CONNECTORS = [];
1325
- function addConnector(connector) {
1326
- CONNECTORS.push(connector);
1327
- }
1328
- function findConnector(options) {
1329
- return CONNECTORS.find((x) => {
1330
- if (x.options.baseUrl === options.baseUrl) {
1331
- if (options.auth) {
1332
- if (x.options.auth) {
1333
- return objectDeepEqual(x.options.auth, options.auth);
1334
- }
1335
- }
1336
- else {
1337
- // if auth not in find options; use first connector with same url
1338
- return true;
1339
- }
1340
- }
1341
- });
1342
- }
1343
- function removeConnector(connector) {
1344
- const index = CONNECTORS.indexOf(connector);
1345
- if (index !== -1) {
1346
- CONNECTORS.splice(index, 1);
1155
+
1156
+ /**
1157
+ * Thrown when ...
1158
+ */
1159
+ class ResourceNotFoundError extends NgwError {
1160
+ constructor(obj) {
1161
+ super(obj);
1162
+ this.name = 'ResourceNotFoundError';
1163
+ this.exception = 'nextgisweb.resource.exception.ResourceNotFound';
1164
+ Object.setPrototypeOf(this, ResourceNotFoundError.prototype);
1347
1165
  }
1348
1166
  }
1349
1167
 
1168
+ function isObject(val) {
1169
+ return Object.prototype.toString.call(val) === '[object Object]';
1170
+ }
1171
+
1172
+ function resourceCompare(res1, res2) {
1173
+ return objectDeepEqual(res1, res2);
1174
+ }
1175
+
1350
1176
  const exclude = ['description'];
1351
1177
  /**
1352
1178
  * @remarks
@@ -1380,10 +1206,6 @@ function resourceToQuery(resource, prefix = '') {
1380
1206
  return query;
1381
1207
  }
1382
1208
 
1383
- function resourceCompare(res1, res2) {
1384
- return objectDeepEqual(res1, res2);
1385
- }
1386
-
1387
1209
  class ResourcesControl {
1388
1210
  constructor(connector) {
1389
1211
  this.connector = connector;
@@ -1624,12 +1446,247 @@ class ResourcesControl {
1624
1446
  }
1625
1447
  }
1626
1448
 
1449
+ const CONNECTORS = [];
1450
+ function addConnector(connector) {
1451
+ CONNECTORS.push(connector);
1452
+ }
1453
+ function findConnector(options) {
1454
+ return CONNECTORS.find((x) => {
1455
+ if (x.options.baseUrl === options.baseUrl) {
1456
+ if (options.auth) {
1457
+ if (x.options.auth) {
1458
+ return objectDeepEqual(x.options.auth, options.auth);
1459
+ }
1460
+ }
1461
+ else {
1462
+ // if auth not in find options; use first connector with same url
1463
+ return true;
1464
+ }
1465
+ }
1466
+ });
1467
+ }
1468
+ function removeConnector(connector) {
1469
+ const index = CONNECTORS.indexOf(connector);
1470
+ if (index !== -1) {
1471
+ CONNECTORS.splice(index, 1);
1472
+ }
1473
+ }
1474
+
1475
+ /**
1476
+ * Thrown when ...
1477
+ */
1478
+ class InsufficientPermissionsError extends NgwError {
1479
+ constructor(obj) {
1480
+ super(obj);
1481
+ this.name = 'InsufficientPermissionsError';
1482
+ this.exception = 'nextgisweb.core.exception.InsufficientPermissions';
1483
+ Object.setPrototypeOf(this, InsufficientPermissionsError.prototype);
1484
+ }
1485
+ }
1486
+
1487
+ // https://github.com/Leaflet/Leaflet/blob/b507e21c510b53cd704fb8d3f89bb46ea925c8eb/src/core/Util.js#L165
1488
+ const templateRe = /\{ *([\w_-]+) *\}/g;
1489
+ function template(str, data) {
1490
+ return str.replace(templateRe, (s, key) => {
1491
+ let value = data[key];
1492
+ if (value === undefined) {
1493
+ throw new Error('No value provided for letiable ' + s);
1494
+ }
1495
+ else if (typeof value === 'function') {
1496
+ value = value(data);
1497
+ }
1498
+ return value;
1499
+ });
1500
+ }
1501
+
1502
+ function apiRequest(opt) {
1503
+ const params = opt.params;
1504
+ return new CancelablePromise((resolve, reject) => {
1505
+ opt.connector
1506
+ .connect()
1507
+ .then((apiItems) => {
1508
+ let apiItem = apiItems && apiItems[opt.name];
1509
+ if (apiItem) {
1510
+ apiItem = [...apiItem];
1511
+ let url = apiItem.shift();
1512
+ if (apiItem.length) {
1513
+ const replaceParams = {};
1514
+ for (let fry = 0; fry < apiItem.length; fry++) {
1515
+ const arg = apiItem[fry];
1516
+ replaceParams[fry] = '{' + arg + '}';
1517
+ if (params[arg] === undefined) {
1518
+ throw new Error('`' + arg + '`' + ' url api argument is not specified');
1519
+ }
1520
+ }
1521
+ if (url) {
1522
+ url = template(url, replaceParams);
1523
+ }
1524
+ }
1525
+ // Transfer part of the parameters from `params` to the URL string
1526
+ if (params) {
1527
+ const paramArray = [];
1528
+ const paramList = params.paramList;
1529
+ if (Array.isArray(paramList)) {
1530
+ delete params.paramList;
1531
+ paramList.forEach((x) => {
1532
+ paramArray.push(`${x[0]}=${x[1]}`);
1533
+ });
1534
+ }
1535
+ for (const p in params) {
1536
+ if (apiItem.indexOf(p) === -1) {
1537
+ paramArray.push(`${p}=${params[p]}`);
1538
+ }
1539
+ }
1540
+ if (paramArray.length) {
1541
+ url = url + '?' + paramArray.join('&');
1542
+ }
1543
+ }
1544
+ if (url) {
1545
+ resolve(opt.connector.makeQuery(url, params, opt.requestOptions));
1546
+ }
1547
+ else {
1548
+ reject(new Error('request url is not set'));
1549
+ }
1550
+ }
1551
+ else {
1552
+ resolve(undefined);
1553
+ }
1554
+ })
1555
+ .catch((er) => {
1556
+ reject(er);
1557
+ });
1558
+ });
1559
+ }
1560
+
1561
+ /**
1562
+ * Thrown when...
1563
+ */
1564
+ class NetworkError extends Error {
1565
+ constructor(url) {
1566
+ super();
1567
+ this.name = 'NetworkError';
1568
+ Object.setPrototypeOf(this, NetworkError.prototype);
1569
+ this.message = `Unable to request ${url}.
1570
+ Possibly invalid NGW URL entered or CORS not configured to get request from ${location.origin}`; // /control-panel/cors
1571
+ }
1572
+ }
1573
+
1574
+ let loadData;
1575
+ // @ts-ignore
1576
+ {
1577
+ loadData = (url, callback, options = {}, error, onCancel) => {
1578
+ options.method = options.method || 'GET';
1579
+ const xhr = new XMLHttpRequest();
1580
+ xhr.open(options.method || 'GET', url, true); // true for asynchronous
1581
+ if (options.responseType === 'blob') {
1582
+ xhr.responseType = options.responseType;
1583
+ }
1584
+ const getResponseText = () => {
1585
+ try {
1586
+ return JSON.parse(xhr.responseText);
1587
+ }
1588
+ catch (er) {
1589
+ return xhr.responseText;
1590
+ }
1591
+ };
1592
+ const processingResponse = (forError = false) => {
1593
+ const cb = forError ? error : callback;
1594
+ if (options.responseType === 'blob') {
1595
+ cb(xhr.response);
1596
+ }
1597
+ else {
1598
+ if (xhr.responseText) {
1599
+ cb(getResponseText());
1600
+ }
1601
+ else {
1602
+ error({ message: '' });
1603
+ }
1604
+ }
1605
+ };
1606
+ xhr.onload = () => {
1607
+ if ([401, 403, 404, 422, 500].indexOf(xhr.status) !== -1) {
1608
+ error(new NgwError(getResponseText()));
1609
+ }
1610
+ processingResponse();
1611
+ };
1612
+ // xhr.onreadystatechange = () => {
1613
+ // if (
1614
+ // (xhr.readyState === 4 && xhr.status === 200) ||
1615
+ // (xhr.readyState === 3 && xhr.status === 201)
1616
+ // ) {
1617
+ // processingResponse();
1618
+ // } else if (xhr.readyState === 3 && xhr.status === 400) {
1619
+ // processingResponse();
1620
+ // } else if (xhr.readyState === 4 && xhr.status === 500) {
1621
+ // processingResponse();
1622
+ // } else if (xhr.readyState === 4 && xhr.status === 401) {
1623
+ // error(xhr.statusText);
1624
+ // } else if (xhr.readyState === 4) {
1625
+ // error('request error');
1626
+ // }
1627
+ // };
1628
+ xhr.onerror = (er) => {
1629
+ if (xhr.status === 0) {
1630
+ error(new NetworkError(url));
1631
+ }
1632
+ else {
1633
+ error(er);
1634
+ }
1635
+ };
1636
+ xhr.upload.onprogress = function (e) {
1637
+ if (e.lengthComputable) {
1638
+ const percentComplete = (e.loaded / e.total) * 100;
1639
+ if (options.onProgress) {
1640
+ options.onProgress(percentComplete, e);
1641
+ }
1642
+ // console.log(percentComplete + '% uploaded');
1643
+ }
1644
+ };
1645
+ const headers = options.headers;
1646
+ if (headers) {
1647
+ for (const h in headers) {
1648
+ const header = headers[h];
1649
+ if (typeof header === 'string') {
1650
+ xhr.setRequestHeader(h, header);
1651
+ }
1652
+ }
1653
+ }
1654
+ if (options.withCredentials !== undefined) {
1655
+ xhr.withCredentials = options.withCredentials;
1656
+ }
1657
+ let data;
1658
+ if (options.file) {
1659
+ data = new FormData();
1660
+ data.append('file', options.file);
1661
+ if (options.data) {
1662
+ for (const d in options.data) {
1663
+ data.append(d, data[d]);
1664
+ }
1665
+ }
1666
+ }
1667
+ else {
1668
+ data = options.data
1669
+ ? typeof options.data === 'string'
1670
+ ? options.data
1671
+ : JSON.stringify(options.data)
1672
+ : null;
1673
+ }
1674
+ if (onCancel) {
1675
+ onCancel(() => {
1676
+ xhr.abort();
1677
+ });
1678
+ }
1679
+ xhr.send(data);
1680
+ };
1681
+ }
1682
+
1627
1683
  let ID = 0;
1628
1684
  class NgwConnector$1 {
1629
1685
  constructor(options) {
1630
1686
  this.options = options;
1631
1687
  this.id = ID++;
1632
1688
  this.emitter = new events.exports.EventEmitter();
1689
+ this.client = `NextGIS-NGW-Connector/${pkg.version}`;
1633
1690
  this.routeStr = '/api/component/pyramid/route';
1634
1691
  this.activeRequests = [];
1635
1692
  const exist = findConnector(options);
@@ -1681,7 +1738,8 @@ class NgwConnector$1 {
1681
1738
  const auth = this.options.auth;
1682
1739
  const makeConnect = () => new CancelablePromise((resolve, reject) => {
1683
1740
  const makeQuery = () => {
1684
- return this.makeQuery(this.routeStr, {}, {})
1741
+ const routeUrl = `${this.routeStr}?client=${this.client}`;
1742
+ return this.makeQuery(routeUrl.toString(), {}, {})
1685
1743
  .then((route) => {
1686
1744
  resolve(route);
1687
1745
  })