@ethlete/query 2.7.3 → 2.9.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,5 +1,6 @@
1
- import { BehaviorSubjectWithSubscriberCount, getCookie, setCookie, deleteCookie, DestroyService, equal, clone } from '@ethlete/core';
2
- import { Observable, filter, takeWhile, switchMap, of, BehaviorSubject, Subject, takeUntil, interval, startWith, finalize, tap, timer, map, fromEvent, debounceTime, take, concat, combineLatest, distinctUntilChanged } from 'rxjs';
1
+ import * as i1 from '@ethlete/core';
2
+ import { BehaviorSubjectWithSubscriberCount, getCookie, setCookie, deleteCookie, DestroyService, DelayableDirective, equal, clone } from '@ethlete/core';
3
+ import { Observable, filter, takeWhile, switchMap, of, BehaviorSubject, Subject, takeUntil, tap, interval, startWith, finalize, timer, map, combineLatest, fromEvent, debounceTime, take, concat, distinctUntilChanged } from 'rxjs';
3
4
  import * as i0 from '@angular/core';
4
5
  import { Directive, Input, InjectionToken, inject, ChangeDetectorRef, ViewContainerRef, TemplateRef, ErrorHandler, ElementRef } from '@angular/core';
5
6
  import { FormGroup } from '@angular/forms';
@@ -908,11 +909,34 @@ class Query {
908
909
  });
909
910
  }
910
911
  else if (state.type === 'failure') {
911
- this._state$.next({
912
- type: "FAILURE" /* QueryStateType.Failure */,
913
- error: state.error,
914
- meta,
915
- });
912
+ const failure = () => {
913
+ this._state$.next({
914
+ type: "FAILURE" /* QueryStateType.Failure */,
915
+ error: state.error,
916
+ meta,
917
+ });
918
+ };
919
+ const bearerAuthProvider = this._getBearerAuthProvider();
920
+ if (!bearerAuthProvider || options?._isUnauthorizedRetry) {
921
+ return failure();
922
+ }
923
+ else if (state.error.status === 401 /* HttpStatusCode.Unauthorized */ &&
924
+ bearerAuthProvider.shouldRefreshOnUnauthorizedResponse) {
925
+ const query = bearerAuthProvider._refreshQuery();
926
+ if (!query) {
927
+ return failure();
928
+ }
929
+ query.state$
930
+ .pipe(takeUntilResponse(), takeUntil(this._onAbort$), tap((state) => {
931
+ if (isQueryStateSuccess(state)) {
932
+ this.execute({ ...options, _isUnauthorizedRetry: true });
933
+ }
934
+ else if (isQueryStateFailure(state)) {
935
+ failure();
936
+ }
937
+ }))
938
+ .subscribe();
939
+ }
916
940
  }
917
941
  else if (state.type === 'cancel') {
918
942
  this._state$.next({
@@ -994,6 +1018,13 @@ class Query {
994
1018
  this._pollingSubscription?.unsubscribe();
995
1019
  this._entitySubscription?.unsubscribe();
996
1020
  }
1021
+ _getBearerAuthProvider() {
1022
+ const authProvider = this._client.authProvider;
1023
+ if (authProvider && isBearerAuthProvider(authProvider)) {
1024
+ return authProvider;
1025
+ }
1026
+ return null;
1027
+ }
997
1028
  }
998
1029
 
999
1030
  const isBasicAuthProvider = (authProvider) => authProvider instanceof BasicAuthProvider;
@@ -1031,6 +1062,11 @@ class BearerAuthProvider {
1031
1062
  get currentRefreshQuery() {
1032
1063
  return this._currentRefreshQuery$.getValue();
1033
1064
  }
1065
+ get shouldRefreshOnUnauthorizedResponse() {
1066
+ return (!!this._config.refreshConfig &&
1067
+ (this._config.refreshConfig.refreshOnUnauthorizedResponse === undefined ||
1068
+ this._config.refreshConfig.refreshOnUnauthorizedResponse));
1069
+ }
1034
1070
  constructor(_config) {
1035
1071
  this._config = _config;
1036
1072
  this._destroy$ = new Subject();
@@ -1111,7 +1147,13 @@ class BearerAuthProvider {
1111
1147
  break;
1112
1148
  }
1113
1149
  }
1150
+ /**
1151
+ * @internal
1152
+ */
1114
1153
  _refreshQuery() {
1154
+ if (isQueryStateLoading(this._currentRefreshQuery$.getValue()?.state)) {
1155
+ return;
1156
+ }
1115
1157
  const currentRefreshToken = this.tokens.refreshToken;
1116
1158
  if (!currentRefreshToken || !this._config.refreshConfig) {
1117
1159
  return;
@@ -1151,6 +1193,7 @@ class BearerAuthProvider {
1151
1193
  }
1152
1194
  }), takeUntilResponse(), takeUntil(this._destroy$))
1153
1195
  .subscribe();
1196
+ return query;
1154
1197
  }
1155
1198
  }
1156
1199
 
@@ -1463,6 +1506,7 @@ class InfinityQueryDirective {
1463
1506
  this._viewContainerRef = inject(ViewContainerRef);
1464
1507
  this._mainTemplateRef = inject((TemplateRef));
1465
1508
  this._errorHandler = inject(ErrorHandler);
1509
+ this._delayable = inject(DelayableDirective, { host: true });
1466
1510
  this._data$ = new BehaviorSubject([]);
1467
1511
  this._isMainViewCreated = false;
1468
1512
  }
@@ -1498,15 +1542,15 @@ class InfinityQueryDirective {
1498
1542
  }
1499
1543
  _setupInfinityQuery(config) {
1500
1544
  const instance = new InfinityQuery(config);
1501
- instance.currentQuery$
1502
- .pipe(switchMap((q) => q?.state$ ?? of(null)), tap((state) => {
1545
+ combineLatest([instance.currentQuery$.pipe(switchQueryState()), this._delayable.isDelayed$])
1546
+ .pipe(tap(([state, isDelayed]) => {
1503
1547
  this._viewContext.currentPage = instance.currentPage;
1504
1548
  this._viewContext.totalPages = instance.totalPages;
1505
1549
  this._viewContext.itemsPerPage = instance.itemsPerPage;
1506
1550
  this._viewContext.canLoadMore =
1507
1551
  (instance.totalPages && instance.currentPage && instance.totalPages > instance.currentPage) || false;
1508
1552
  this._viewContext.currentCalculatedPage = instance.currentCalculatedPage;
1509
- if (isQueryStateLoading(state)) {
1553
+ if (isQueryStateLoading(state) || isDelayed) {
1510
1554
  this._viewContext.loading = true;
1511
1555
  this._viewContext.error = null;
1512
1556
  this._viewContext.isFirstLoad = this.context.infinityQuery === null;
@@ -1557,6 +1601,9 @@ class InfinityQueryDirective {
1557
1601
  if (!this._infinityQueryInstance) {
1558
1602
  return;
1559
1603
  }
1604
+ if (this._viewContext.loading) {
1605
+ return;
1606
+ }
1560
1607
  this._infinityQueryInstance.nextPage();
1561
1608
  }
1562
1609
  reset(newConfig) {
@@ -1587,7 +1634,7 @@ class InfinityQueryDirective {
1587
1634
  }
1588
1635
  }
1589
1636
  InfinityQueryDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.5", ngImport: i0, type: InfinityQueryDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
1590
- InfinityQueryDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.2.5", type: InfinityQueryDirective, isStandalone: true, selector: "[infinityQuery]", inputs: { infinityQuery: "infinityQuery" }, providers: [{ provide: INFINITY_QUERY_TOKEN, useExisting: InfinityQueryDirective }, DestroyService], exportAs: ["infinityQuery"], ngImport: i0 });
1637
+ InfinityQueryDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.2.5", type: InfinityQueryDirective, isStandalone: true, selector: "[infinityQuery]", inputs: { infinityQuery: "infinityQuery" }, providers: [{ provide: INFINITY_QUERY_TOKEN, useExisting: InfinityQueryDirective }, DestroyService], exportAs: ["infinityQuery"], hostDirectives: [{ directive: i1.DelayableDirective }], ngImport: i0 });
1591
1638
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.5", ngImport: i0, type: InfinityQueryDirective, decorators: [{
1592
1639
  type: Directive,
1593
1640
  args: [{
@@ -1596,6 +1643,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.5", ngImpor
1596
1643
  exportAs: 'infinityQuery',
1597
1644
  standalone: true,
1598
1645
  providers: [{ provide: INFINITY_QUERY_TOKEN, useExisting: InfinityQueryDirective }, DestroyService],
1646
+ hostDirectives: [DelayableDirective],
1599
1647
  }]
1600
1648
  }], propDecorators: { infinityQuery: [{
1601
1649
  type: Input