@ethlete/query 2.9.2 → 3.0.1
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/esm2020/index.mjs +2 -1
- package/esm2020/lib/auth/auth-provider.types.mjs +1 -1
- package/esm2020/lib/auth/auth-provider.utils.mjs +1 -1
- package/esm2020/lib/auth/bearer-auth-provider.mjs +2 -2
- package/esm2020/lib/directives/infinity-query-trigger.directive.mjs +4 -4
- package/esm2020/lib/directives/infinity-query.directive.mjs +18 -24
- package/esm2020/lib/directives/query.directive.mjs +9 -11
- package/esm2020/lib/entity/entity-store.mjs +73 -119
- package/esm2020/lib/entity/entity.types.mjs +1 -1
- package/esm2020/lib/entity/entity.utils.mjs +5 -0
- package/esm2020/lib/entity/index.mjs +2 -1
- package/esm2020/lib/infinite-query/infinity-query.mjs +47 -71
- package/esm2020/lib/infinite-query/infinity-query.types.mjs +1 -1
- package/esm2020/lib/infinite-query/infinity-query.utils.mjs +1 -1
- package/esm2020/lib/query/query.mjs +118 -211
- package/esm2020/lib/query/query.types.mjs +1 -1
- package/esm2020/lib/query/query.utils.mjs +1 -1
- package/esm2020/lib/query-client/query-client.mjs +3 -31
- package/esm2020/lib/query-client/query-client.types.mjs +1 -1
- package/esm2020/lib/query-creator/index.mjs +3 -0
- package/esm2020/lib/query-creator/query-creator.mjs +35 -0
- package/esm2020/lib/query-creator/query-creator.types.mjs +2 -0
- package/esm2020/lib/request/request.types.mjs +1 -1
- package/esm2020/lib/request/request.util.mjs +1 -7
- package/fesm2015/ethlete-query.mjs +314 -473
- package/fesm2015/ethlete-query.mjs.map +1 -1
- package/fesm2020/ethlete-query.mjs +308 -476
- package/fesm2020/ethlete-query.mjs.map +1 -1
- package/index.d.ts +1 -0
- package/lib/auth/auth-provider.types.d.ts +3 -4
- package/lib/auth/auth-provider.utils.d.ts +2 -2
- package/lib/auth/bearer-auth-provider.d.ts +1 -1
- package/lib/directives/infinity-query-trigger.directive.d.ts +1 -1
- package/lib/directives/infinity-query.directive.d.ts +6 -11
- package/lib/directives/query.directive.d.ts +7 -7
- package/lib/entity/entity-store.d.ts +13 -27
- package/lib/entity/entity.types.d.ts +0 -5
- package/lib/entity/entity.utils.d.ts +2 -0
- package/lib/entity/index.d.ts +1 -0
- package/lib/infinite-query/infinity-query.d.ts +10 -19
- package/lib/infinite-query/infinity-query.types.d.ts +4 -4
- package/lib/infinite-query/infinity-query.utils.d.ts +2 -3
- package/lib/query/query.d.ts +19 -12
- package/lib/query/query.types.d.ts +86 -51
- package/lib/query/query.utils.d.ts +16 -14
- package/lib/query-client/query-client.d.ts +12 -10
- package/lib/query-client/query-client.types.d.ts +2 -22
- package/lib/query-creator/index.d.ts +2 -0
- package/lib/query-creator/query-creator.d.ts +14 -0
- package/lib/query-creator/query-creator.types.d.ts +13 -0
- package/lib/request/request.types.d.ts +1 -1
- package/lib/request/request.util.d.ts +0 -1
- package/package.json +1 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as i1 from '@ethlete/core';
|
|
2
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,
|
|
3
|
+
import { Observable, filter, takeWhile, switchMap, of, BehaviorSubject, shareReplay, Subject, takeUntil, tap, interval, skip, map, timer, combineLatest, withLatestFrom, fromEvent, startWith, take, concat, debounceTime, distinctUntilChanged } from 'rxjs';
|
|
4
4
|
import * as i0 from '@angular/core';
|
|
5
5
|
import { Directive, Input, InjectionToken, inject, ChangeDetectorRef, ViewContainerRef, TemplateRef, ErrorHandler, ElementRef } from '@angular/core';
|
|
6
6
|
import { FormGroup } from '@angular/forms';
|
|
@@ -113,12 +113,6 @@ const buildQueryObjectString = (key, object) => {
|
|
|
113
113
|
})
|
|
114
114
|
.join('&');
|
|
115
115
|
};
|
|
116
|
-
const isFetchResponse = (response) => typeof response === 'object' &&
|
|
117
|
-
response !== null &&
|
|
118
|
-
'status' in response &&
|
|
119
|
-
'statusText' in response &&
|
|
120
|
-
'json' in response &&
|
|
121
|
-
typeof response['json'] === 'function';
|
|
122
116
|
const filterInvalidParams = (params) => {
|
|
123
117
|
const filteredParams = Object.entries(params)
|
|
124
118
|
.map(([key, value]) => {
|
|
@@ -706,16 +700,22 @@ class Query {
|
|
|
706
700
|
return ++this._currentId;
|
|
707
701
|
}
|
|
708
702
|
get state$() {
|
|
709
|
-
return this._state$.
|
|
703
|
+
return this._state$.pipe(switchMap((s) => this._transformState(s)), shareReplay({ bufferSize: 1, refCount: true }));
|
|
710
704
|
}
|
|
711
|
-
|
|
705
|
+
/**
|
|
706
|
+
* The current state of the query.
|
|
707
|
+
*
|
|
708
|
+
* **Warning!** This differs from the `state$` observable in that it does not use the query store. Thus, the response data might be outdated.
|
|
709
|
+
* Use `state$` (or `firstValueFrom(state$)`) the most up-to-date data.
|
|
710
|
+
*/
|
|
711
|
+
get rawState() {
|
|
712
712
|
return this._state$.value;
|
|
713
713
|
}
|
|
714
714
|
get isExpired() {
|
|
715
|
-
if (!isQueryStateSuccess(this.
|
|
715
|
+
if (!isQueryStateSuccess(this._state$.value)) {
|
|
716
716
|
return false;
|
|
717
717
|
}
|
|
718
|
-
const ts = this.
|
|
718
|
+
const ts = this._state$.value.meta.expiresAt;
|
|
719
719
|
if (!ts) {
|
|
720
720
|
return true;
|
|
721
721
|
}
|
|
@@ -751,7 +751,7 @@ class Query {
|
|
|
751
751
|
this._args = _args;
|
|
752
752
|
this._currentId = 0;
|
|
753
753
|
this._pollingSubscription = null;
|
|
754
|
-
this.
|
|
754
|
+
this._requestSubscription = null;
|
|
755
755
|
this._onAbort$ = new Subject();
|
|
756
756
|
this._currentPollConfig = null;
|
|
757
757
|
/**
|
|
@@ -762,193 +762,39 @@ class Query {
|
|
|
762
762
|
type: "PREPARED" /* QueryStateType.Prepared */,
|
|
763
763
|
meta: { id: this._currentId, triggeredVia: 'program' },
|
|
764
764
|
});
|
|
765
|
-
if (this._queryConfig.entity?.store) {
|
|
766
|
-
this._entitySubscription = this._queryConfig.entity.store.events$.subscribe((event) => {
|
|
767
|
-
if (event.type !== 'update' && event.type !== 'set') {
|
|
768
|
-
return;
|
|
769
|
-
}
|
|
770
|
-
if (!isQueryStateSuccess(this.state)) {
|
|
771
|
-
return;
|
|
772
|
-
}
|
|
773
|
-
const response = this.state.response;
|
|
774
|
-
const rawResponse = this.state.rawResponse;
|
|
775
|
-
const key = this._queryConfig.entity?.store.config.idKey;
|
|
776
|
-
if (!key) {
|
|
777
|
-
return;
|
|
778
|
-
}
|
|
779
|
-
const newData = this._queryConfig.entity?.store.getOne(event.key);
|
|
780
|
-
if (!newData) {
|
|
781
|
-
return;
|
|
782
|
-
}
|
|
783
|
-
const newResponse = this._queryConfig.entity?.valueUpdater
|
|
784
|
-
? this._queryConfig.entity?.valueUpdater({
|
|
785
|
-
args: this._args,
|
|
786
|
-
entity: newData,
|
|
787
|
-
rawResponse,
|
|
788
|
-
response,
|
|
789
|
-
})
|
|
790
|
-
: response[key] === newData[key]
|
|
791
|
-
? {
|
|
792
|
-
response: newData,
|
|
793
|
-
rawResponse: newData,
|
|
794
|
-
}
|
|
795
|
-
: null;
|
|
796
|
-
if (!newResponse) {
|
|
797
|
-
return;
|
|
798
|
-
}
|
|
799
|
-
this._state$.next({
|
|
800
|
-
...this.state,
|
|
801
|
-
response: newResponse.response,
|
|
802
|
-
rawResponse: newResponse.rawResponse,
|
|
803
|
-
meta: {
|
|
804
|
-
...this.state.meta,
|
|
805
|
-
triggeredVia: 'auto',
|
|
806
|
-
},
|
|
807
|
-
});
|
|
808
|
-
});
|
|
809
|
-
}
|
|
810
|
-
}
|
|
811
|
-
clone() {
|
|
812
|
-
return this._client.fetch(this._queryConfig);
|
|
813
765
|
}
|
|
814
|
-
execute(options) {
|
|
815
|
-
const
|
|
816
|
-
|
|
766
|
+
execute(options = {}) {
|
|
767
|
+
const { skipCache = false, _triggeredVia: triggeredVia = 'program' } = options;
|
|
768
|
+
const { authProvider } = this._client;
|
|
769
|
+
const queryConfig = this._queryConfig;
|
|
770
|
+
if (!this.isExpired && !skipCache && isQueryStateSuccess(this.rawState)) {
|
|
817
771
|
return this;
|
|
818
772
|
}
|
|
819
|
-
if (
|
|
773
|
+
if (queryConfig.secure && !authProvider) {
|
|
820
774
|
throw new Error('Cannot execute secure query without auth provider');
|
|
821
775
|
}
|
|
822
776
|
const id = this._nextId;
|
|
823
|
-
|
|
777
|
+
const meta = { id, triggeredVia };
|
|
778
|
+
if (isQueryStateLoading(this.rawState)) {
|
|
824
779
|
this.abort();
|
|
825
780
|
}
|
|
826
|
-
|
|
827
|
-
this.
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
this._updateUseResultInDependencies();
|
|
832
|
-
const method = computeQueryMethod({ config: this._queryConfig, client: this._client });
|
|
833
|
-
const body = computeQueryBody({
|
|
834
|
-
config: this._queryConfig,
|
|
835
|
-
client: this._client,
|
|
836
|
-
args: this._args,
|
|
837
|
-
method,
|
|
838
|
-
});
|
|
839
|
-
const headers = computeQueryHeaders({ client: this._client, config: this._queryConfig, args: this._args });
|
|
840
|
-
request({
|
|
781
|
+
this._state$.next({ type: "LOADING" /* QueryStateType.Loading */, meta });
|
|
782
|
+
const method = computeQueryMethod({ config: queryConfig, client: this._client });
|
|
783
|
+
const body = computeQueryBody({ config: queryConfig, client: this._client, args: this._args, method });
|
|
784
|
+
const headers = computeQueryHeaders({ client: this._client, config: queryConfig, args: this._args });
|
|
785
|
+
this._requestSubscription = request({
|
|
841
786
|
urlWithParams: this._routeWithParams,
|
|
842
787
|
method,
|
|
843
788
|
body,
|
|
844
789
|
headers,
|
|
845
|
-
reportProgress:
|
|
846
|
-
responseType:
|
|
847
|
-
withCredentials:
|
|
790
|
+
reportProgress: queryConfig.reportProgress,
|
|
791
|
+
responseType: queryConfig.responseType,
|
|
792
|
+
withCredentials: queryConfig.withCredentials,
|
|
848
793
|
cacheAdapter: this._client.config.request?.cacheAdapter,
|
|
849
794
|
retryFn: this._client.config.request?.retryFn,
|
|
850
795
|
})
|
|
851
|
-
.pipe(takeUntil(this._onAbort$))
|
|
852
|
-
.subscribe(
|
|
853
|
-
next: (state) => {
|
|
854
|
-
if (state.type === 'start' || state.type === 'delay-retry') {
|
|
855
|
-
const newMeta = {
|
|
856
|
-
...meta,
|
|
857
|
-
isWaitingForRetry: state.type === 'delay-retry',
|
|
858
|
-
retryDelay: state.retryDelay,
|
|
859
|
-
retryNumber: state.retryNumber,
|
|
860
|
-
};
|
|
861
|
-
this._state$.next({
|
|
862
|
-
type: "LOADING" /* QueryStateType.Loading */,
|
|
863
|
-
meta: newMeta,
|
|
864
|
-
});
|
|
865
|
-
}
|
|
866
|
-
else if (state.type === 'download-progress') {
|
|
867
|
-
this._state$.next({
|
|
868
|
-
type: "LOADING" /* QueryStateType.Loading */,
|
|
869
|
-
progress: state.progress,
|
|
870
|
-
partialText: state.partialText,
|
|
871
|
-
meta,
|
|
872
|
-
});
|
|
873
|
-
}
|
|
874
|
-
else if (state.type === 'upload-progress') {
|
|
875
|
-
this._state$.next({
|
|
876
|
-
type: "LOADING" /* QueryStateType.Loading */,
|
|
877
|
-
progress: state.progress,
|
|
878
|
-
meta,
|
|
879
|
-
});
|
|
880
|
-
}
|
|
881
|
-
else if (state.type === 'success') {
|
|
882
|
-
const isResponseObject = typeof state.response === 'object';
|
|
883
|
-
const isGql = isGqlQueryConfig(this._queryConfig);
|
|
884
|
-
let responseData = null;
|
|
885
|
-
if (isGql &&
|
|
886
|
-
isResponseObject &&
|
|
887
|
-
!!state.response &&
|
|
888
|
-
typeof state.response === 'object' &&
|
|
889
|
-
'data' in state.response) {
|
|
890
|
-
responseData = state.response['data'];
|
|
891
|
-
}
|
|
892
|
-
else {
|
|
893
|
-
responseData = state.response;
|
|
894
|
-
}
|
|
895
|
-
const transformedResponse = this._queryConfig.responseTransformer
|
|
896
|
-
? this._queryConfig.responseTransformer(responseData)
|
|
897
|
-
: responseData;
|
|
898
|
-
this._queryConfig.entity?.successAction?.({
|
|
899
|
-
args: this._args,
|
|
900
|
-
rawResponse: state.response,
|
|
901
|
-
response: transformedResponse,
|
|
902
|
-
store: this._queryConfig.entity.store,
|
|
903
|
-
});
|
|
904
|
-
this._state$.next({
|
|
905
|
-
type: "SUCCESS" /* QueryStateType.Success */,
|
|
906
|
-
rawResponse: state.response,
|
|
907
|
-
response: transformedResponse,
|
|
908
|
-
meta: { ...meta, expiresAt: state.expiresInTimestamp },
|
|
909
|
-
});
|
|
910
|
-
}
|
|
911
|
-
else if (state.type === 'failure') {
|
|
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
|
-
}
|
|
940
|
-
else {
|
|
941
|
-
failure();
|
|
942
|
-
}
|
|
943
|
-
}
|
|
944
|
-
else if (state.type === 'cancel') {
|
|
945
|
-
this._state$.next({
|
|
946
|
-
type: "CANCELLED" /* QueryStateType.Cancelled */,
|
|
947
|
-
meta,
|
|
948
|
-
});
|
|
949
|
-
}
|
|
950
|
-
},
|
|
951
|
-
});
|
|
796
|
+
.pipe(takeUntil(this._onAbort$), tap((state) => this._updateEntityState(state, meta, options)))
|
|
797
|
+
.subscribe();
|
|
952
798
|
return this;
|
|
953
799
|
}
|
|
954
800
|
abort() {
|
|
@@ -960,16 +806,11 @@ class Query {
|
|
|
960
806
|
return this;
|
|
961
807
|
}
|
|
962
808
|
this._currentPollConfig = config;
|
|
963
|
-
const
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
.subscribe(() => {
|
|
969
|
-
if (this.state.type === "LOADING" /* QueryStateType.Loading */) {
|
|
970
|
-
return;
|
|
971
|
-
}
|
|
972
|
-
this.execute({ skipCache: true, _triggeredVia: 'poll' });
|
|
809
|
+
const interval$ = interval(config.interval);
|
|
810
|
+
const poll$ = interval$.pipe(skip(config.triggerImmediately ? 0 : 1), takeUntil(config.takeUntil), takeWhile(() => !this._isPollingPaused), filter(() => !isQueryStateLoading(this._state$.value)));
|
|
811
|
+
this._pollingSubscription = poll$.subscribe({
|
|
812
|
+
next: () => this.execute({ skipCache: true, _triggeredVia: 'poll' }),
|
|
813
|
+
complete: () => this.stopPolling(),
|
|
973
814
|
});
|
|
974
815
|
return this;
|
|
975
816
|
}
|
|
@@ -992,26 +833,6 @@ class Query {
|
|
|
992
833
|
this._isPollingPaused = false;
|
|
993
834
|
return this.poll({ ...this._currentPollConfig, triggerImmediately: true });
|
|
994
835
|
}
|
|
995
|
-
_updateUseResultInDependencies() {
|
|
996
|
-
if (!this._args?.useResultIn?.length) {
|
|
997
|
-
return;
|
|
998
|
-
}
|
|
999
|
-
this.state$
|
|
1000
|
-
.pipe(filterSuccess(), takeUntil(this._onAbort$), takeUntilResponse(), tap((state) => {
|
|
1001
|
-
if (!this._args?.useResultIn) {
|
|
1002
|
-
return;
|
|
1003
|
-
}
|
|
1004
|
-
for (const query of this._args.useResultIn) {
|
|
1005
|
-
query._state$.next({
|
|
1006
|
-
type: "SUCCESS" /* QueryStateType.Success */,
|
|
1007
|
-
meta: { ...state.meta, id: query._nextId },
|
|
1008
|
-
rawResponse: state.rawResponse,
|
|
1009
|
-
response: state.response,
|
|
1010
|
-
});
|
|
1011
|
-
}
|
|
1012
|
-
}))
|
|
1013
|
-
.subscribe();
|
|
1014
|
-
}
|
|
1015
836
|
/**
|
|
1016
837
|
* @internal
|
|
1017
838
|
*/
|
|
@@ -1019,7 +840,7 @@ class Query {
|
|
|
1019
840
|
this._state$.complete();
|
|
1020
841
|
this._onAbort$.complete();
|
|
1021
842
|
this._pollingSubscription?.unsubscribe();
|
|
1022
|
-
this.
|
|
843
|
+
this._requestSubscription?.unsubscribe();
|
|
1023
844
|
}
|
|
1024
845
|
_getBearerAuthProvider() {
|
|
1025
846
|
const authProvider = this._client.authProvider;
|
|
@@ -1028,6 +849,86 @@ class Query {
|
|
|
1028
849
|
}
|
|
1029
850
|
return null;
|
|
1030
851
|
}
|
|
852
|
+
_updateEntityState(requestEvent, meta, options) {
|
|
853
|
+
switch (requestEvent.type) {
|
|
854
|
+
case 'start':
|
|
855
|
+
case 'delay-retry': {
|
|
856
|
+
const { type, retryDelay, retryNumber } = requestEvent;
|
|
857
|
+
const newMeta = { ...meta, isWaitingForRetry: type === 'delay-retry', retryDelay, retryNumber };
|
|
858
|
+
this._state$.next({
|
|
859
|
+
type: "LOADING" /* QueryStateType.Loading */,
|
|
860
|
+
meta: newMeta,
|
|
861
|
+
});
|
|
862
|
+
break;
|
|
863
|
+
}
|
|
864
|
+
case 'upload-progress':
|
|
865
|
+
case 'download-progress': {
|
|
866
|
+
this._state$.next({
|
|
867
|
+
type: "LOADING" /* QueryStateType.Loading */,
|
|
868
|
+
progress: requestEvent.progress,
|
|
869
|
+
partialText: 'partialText' in requestEvent ? requestEvent.partialText : undefined,
|
|
870
|
+
meta,
|
|
871
|
+
});
|
|
872
|
+
break;
|
|
873
|
+
}
|
|
874
|
+
case 'success': {
|
|
875
|
+
const { response, expiresInTimestamp } = requestEvent;
|
|
876
|
+
const isGql = isGqlQueryConfig(this._queryConfig);
|
|
877
|
+
const responseData = isGql && typeof response === 'object' && !!response && 'data' in response
|
|
878
|
+
? response['data']
|
|
879
|
+
: response;
|
|
880
|
+
this._state$.next({
|
|
881
|
+
type: "SUCCESS" /* QueryStateType.Success */,
|
|
882
|
+
response: responseData,
|
|
883
|
+
meta: { ...meta, expiresAt: expiresInTimestamp },
|
|
884
|
+
});
|
|
885
|
+
if (this._queryConfig.entity && this._queryConfig.entity.set) {
|
|
886
|
+
const id = this._queryConfig.entity?.id({ args: this._args, response: responseData });
|
|
887
|
+
this._queryConfig.entity?.set({
|
|
888
|
+
args: this._args,
|
|
889
|
+
response: responseData,
|
|
890
|
+
id,
|
|
891
|
+
store: this._queryConfig.entity.store,
|
|
892
|
+
});
|
|
893
|
+
}
|
|
894
|
+
break;
|
|
895
|
+
}
|
|
896
|
+
case 'failure': {
|
|
897
|
+
const { error } = requestEvent;
|
|
898
|
+
const failure = () => this._state$.next({ type: "FAILURE" /* QueryStateType.Failure */, error, meta });
|
|
899
|
+
const bearerAuthProvider = this._getBearerAuthProvider();
|
|
900
|
+
if (!bearerAuthProvider ||
|
|
901
|
+
options?._isUnauthorizedRetry ||
|
|
902
|
+
error.status !== 401 /* HttpStatusCode.Unauthorized */ ||
|
|
903
|
+
!bearerAuthProvider.shouldRefreshOnUnauthorizedResponse) {
|
|
904
|
+
return failure();
|
|
905
|
+
}
|
|
906
|
+
const query = bearerAuthProvider._refreshQuery();
|
|
907
|
+
if (!query)
|
|
908
|
+
return failure();
|
|
909
|
+
query.state$
|
|
910
|
+
.pipe(takeUntilResponse(), takeUntil(this._onAbort$), tap((state) => isQueryStateSuccess(state) ? this.execute({ ...options, _isUnauthorizedRetry: true }) : failure()))
|
|
911
|
+
.subscribe();
|
|
912
|
+
break;
|
|
913
|
+
}
|
|
914
|
+
case 'cancel': {
|
|
915
|
+
this._state$.next({
|
|
916
|
+
type: "CANCELLED" /* QueryStateType.Cancelled */,
|
|
917
|
+
meta,
|
|
918
|
+
});
|
|
919
|
+
break;
|
|
920
|
+
}
|
|
921
|
+
}
|
|
922
|
+
}
|
|
923
|
+
_transformState(s) {
|
|
924
|
+
if (!isQueryStateSuccess(s) || !this._queryConfig.entity?.get) {
|
|
925
|
+
return of(s);
|
|
926
|
+
}
|
|
927
|
+
const id = this._queryConfig.entity.id({ args: this._args, response: s.response });
|
|
928
|
+
return this._queryConfig.entity
|
|
929
|
+
.get({ args: this._args, id, response: s.response, store: this._queryConfig.entity.store })
|
|
930
|
+
.pipe(map((v) => ({ ...s, response: v })));
|
|
931
|
+
}
|
|
1031
932
|
}
|
|
1032
933
|
|
|
1033
934
|
const isBasicAuthProvider = (authProvider) => authProvider instanceof BasicAuthProvider;
|
|
@@ -1154,7 +1055,7 @@ class BearerAuthProvider {
|
|
|
1154
1055
|
* @internal
|
|
1155
1056
|
*/
|
|
1156
1057
|
_refreshQuery() {
|
|
1157
|
-
if (isQueryStateLoading(this._currentRefreshQuery$.getValue()?.
|
|
1058
|
+
if (isQueryStateLoading(this._currentRefreshQuery$.getValue()?.rawState)) {
|
|
1158
1059
|
return;
|
|
1159
1060
|
}
|
|
1160
1061
|
const currentRefreshToken = this.tokens.refreshToken;
|
|
@@ -1223,8 +1124,7 @@ class QueryDirective {
|
|
|
1223
1124
|
this._subscription = null;
|
|
1224
1125
|
this._viewContext = {
|
|
1225
1126
|
$implicit: null,
|
|
1226
|
-
|
|
1227
|
-
raw: null,
|
|
1127
|
+
etQuery: null,
|
|
1228
1128
|
loading: false,
|
|
1229
1129
|
error: null,
|
|
1230
1130
|
progress: null,
|
|
@@ -1260,14 +1160,12 @@ class QueryDirective {
|
|
|
1260
1160
|
this._viewContext.progress = null;
|
|
1261
1161
|
}
|
|
1262
1162
|
if (isQueryStateSuccess(state)) {
|
|
1263
|
-
this._viewContext.
|
|
1163
|
+
this._viewContext.etQuery = state.response;
|
|
1264
1164
|
this._viewContext.$implicit = state.response;
|
|
1265
|
-
this._viewContext.raw = state.rawResponse;
|
|
1266
1165
|
}
|
|
1267
1166
|
else if (!this.cache) {
|
|
1268
|
-
this._viewContext.
|
|
1167
|
+
this._viewContext.etQuery = null;
|
|
1269
1168
|
this._viewContext.$implicit = null;
|
|
1270
|
-
this._viewContext.raw = null;
|
|
1271
1169
|
}
|
|
1272
1170
|
if (isQueryStateFailure(state)) {
|
|
1273
1171
|
this._viewContext.error = state.error;
|
|
@@ -1286,22 +1184,22 @@ class QueryDirective {
|
|
|
1286
1184
|
}
|
|
1287
1185
|
}
|
|
1288
1186
|
QueryDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.5", ngImport: i0, type: QueryDirective, deps: [{ token: i0.TemplateRef }, { token: i0.ViewContainerRef }, { token: i0.ErrorHandler }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Directive });
|
|
1289
|
-
QueryDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.2.5", type: QueryDirective, isStandalone: true, selector: "[
|
|
1187
|
+
QueryDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.2.5", type: QueryDirective, isStandalone: true, selector: "[etQuery]", inputs: { query: ["etQuery", "query"], cache: ["etQueryCache", "cache"] }, ngImport: i0 });
|
|
1290
1188
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.5", ngImport: i0, type: QueryDirective, decorators: [{
|
|
1291
1189
|
type: Directive,
|
|
1292
1190
|
args: [{
|
|
1293
1191
|
// eslint-disable-next-line @angular-eslint/directive-selector
|
|
1294
|
-
selector: '[
|
|
1192
|
+
selector: '[etQuery]',
|
|
1295
1193
|
standalone: true,
|
|
1296
1194
|
}]
|
|
1297
1195
|
}], ctorParameters: function () { return [{ type: i0.TemplateRef }, { type: i0.ViewContainerRef }, { type: i0.ErrorHandler }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { query: [{
|
|
1298
|
-
type: Input
|
|
1196
|
+
type: Input,
|
|
1197
|
+
args: ['etQuery']
|
|
1299
1198
|
}], cache: [{
|
|
1300
1199
|
type: Input,
|
|
1301
|
-
args: ['
|
|
1200
|
+
args: ['etQueryCache']
|
|
1302
1201
|
}] } });
|
|
1303
1202
|
|
|
1304
|
-
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
1305
1203
|
class InfinityQuery {
|
|
1306
1204
|
get currentPage$() {
|
|
1307
1205
|
return this._currentPage$.asObservable();
|
|
@@ -1327,28 +1225,57 @@ class InfinityQuery {
|
|
|
1327
1225
|
get itemsPerPage() {
|
|
1328
1226
|
return this._itemsPerPage$.getValue();
|
|
1329
1227
|
}
|
|
1330
|
-
get currentQuery$() {
|
|
1331
|
-
return this._currentQuery$.asObservable();
|
|
1332
|
-
}
|
|
1333
|
-
get currentQuery() {
|
|
1334
|
-
return this._currentQuery$.getValue();
|
|
1335
|
-
}
|
|
1336
1228
|
get data$() {
|
|
1337
|
-
return this._data
|
|
1229
|
+
return this._data$;
|
|
1338
1230
|
}
|
|
1339
|
-
get
|
|
1340
|
-
return this.
|
|
1231
|
+
get currentQuery$() {
|
|
1232
|
+
return this._lastQuery$;
|
|
1341
1233
|
}
|
|
1342
1234
|
constructor(_config) {
|
|
1343
1235
|
this._config = _config;
|
|
1236
|
+
this._queries$ = new BehaviorSubject([]);
|
|
1344
1237
|
this._currentPage$ = new BehaviorSubject(null);
|
|
1345
1238
|
this._currentCalculatedPage$ = new BehaviorSubject(null);
|
|
1346
1239
|
this._totalPages$ = new BehaviorSubject(null);
|
|
1347
1240
|
this._itemsPerPage$ = new BehaviorSubject(this._config.limitParam?.value ?? 10);
|
|
1348
|
-
this.
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1241
|
+
this._data$ = this._queries$.pipe(switchMap((queries) => {
|
|
1242
|
+
if (!queries.length) {
|
|
1243
|
+
return of([]);
|
|
1244
|
+
}
|
|
1245
|
+
return combineLatest(queries.map((query) => query.state$));
|
|
1246
|
+
}), tap((states) => {
|
|
1247
|
+
const lastState = states[states.length - 1];
|
|
1248
|
+
if (!isQueryStateSuccess(lastState)) {
|
|
1249
|
+
return;
|
|
1250
|
+
}
|
|
1251
|
+
const totalPages = this._config.response.totalPagesExtractor?.({
|
|
1252
|
+
response: lastState.response,
|
|
1253
|
+
itemsPerPage: this.itemsPerPage,
|
|
1254
|
+
}) ??
|
|
1255
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1256
|
+
lastState.response?.totalPages ??
|
|
1257
|
+
null;
|
|
1258
|
+
this._totalPages$.next(totalPages);
|
|
1259
|
+
}), map((states) => {
|
|
1260
|
+
const fullData = states.reduce((acc, state) => {
|
|
1261
|
+
if (isQueryStateSuccess(state)) {
|
|
1262
|
+
let data = this._config?.response.valueExtractor(state.response);
|
|
1263
|
+
if (this._config.response.reverse) {
|
|
1264
|
+
data = [...data].reverse();
|
|
1265
|
+
}
|
|
1266
|
+
if (this._config.response.appendItemsTo === 'start') {
|
|
1267
|
+
acc.unshift(...data);
|
|
1268
|
+
}
|
|
1269
|
+
else {
|
|
1270
|
+
acc.push(...data);
|
|
1271
|
+
}
|
|
1272
|
+
}
|
|
1273
|
+
return acc;
|
|
1274
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1275
|
+
}, []);
|
|
1276
|
+
return fullData;
|
|
1277
|
+
}), shareReplay({ bufferSize: 1, refCount: true }));
|
|
1278
|
+
this._lastQuery$ = this._queries$.pipe(map((queries) => queries[queries.length - 1] ?? null), shareReplay({ bufferSize: 1, refCount: true }));
|
|
1352
1279
|
}
|
|
1353
1280
|
nextPage() {
|
|
1354
1281
|
const newPage = (this._currentPage$.value ?? 0) + 1;
|
|
@@ -1361,73 +1288,21 @@ class InfinityQuery {
|
|
|
1361
1288
|
console.error('Cannot load more pages, already at the end. Make sure to not render the infinity query trigger using *ngIf canLoadMore');
|
|
1362
1289
|
return;
|
|
1363
1290
|
}
|
|
1364
|
-
this._clearSubscriptions();
|
|
1365
1291
|
const args = this._prepareArgs(this._config, calculatedPage);
|
|
1366
1292
|
const query = this._config.queryCreator.prepare(args).execute();
|
|
1367
|
-
this.
|
|
1293
|
+
this._queries$.next([...this._queries$.value, query]);
|
|
1368
1294
|
this._currentPage$.next(newPage);
|
|
1369
1295
|
this._currentCalculatedPage$.next(calculatedPage);
|
|
1370
|
-
this._currentQuery$.next(query);
|
|
1371
1296
|
}
|
|
1372
1297
|
reset(newConfig) {
|
|
1373
|
-
this._clearSubscriptions();
|
|
1374
1298
|
this._config = { ...this._config, ...(newConfig ?? {}) };
|
|
1375
1299
|
this._currentPage$.next(null);
|
|
1376
1300
|
this._currentCalculatedPage$.next(null);
|
|
1377
1301
|
this._totalPages$.next(null);
|
|
1378
1302
|
this._itemsPerPage$.next(this._config.limitParam?.value ?? 10);
|
|
1379
|
-
this.
|
|
1380
|
-
this._data$.next([]);
|
|
1303
|
+
this._queries$.next([]);
|
|
1381
1304
|
this.nextPage();
|
|
1382
1305
|
}
|
|
1383
|
-
/**
|
|
1384
|
-
* @internal
|
|
1385
|
-
*/
|
|
1386
|
-
_clearSubscriptions() {
|
|
1387
|
-
this._subscriptions.forEach((sub) => sub.unsubscribe());
|
|
1388
|
-
this._subscriptions = [];
|
|
1389
|
-
this._responsiveDataSubscription?.unsubscribe();
|
|
1390
|
-
}
|
|
1391
|
-
_handleNewQuery(query) {
|
|
1392
|
-
const stateChangesSub = query.state$.pipe(takeUntilResponse(), filterSuccess()).subscribe({
|
|
1393
|
-
next: (state) => {
|
|
1394
|
-
let newData = this._config?.response.valueExtractor(state.response);
|
|
1395
|
-
if (this._config.response.reverse) {
|
|
1396
|
-
newData = [...newData].reverse();
|
|
1397
|
-
}
|
|
1398
|
-
if (this._config.response.appendItemsTo === 'start') {
|
|
1399
|
-
newData = [...newData, ...this.data];
|
|
1400
|
-
}
|
|
1401
|
-
else {
|
|
1402
|
-
newData = [...this.data, ...newData];
|
|
1403
|
-
}
|
|
1404
|
-
if (query.store) {
|
|
1405
|
-
this._responsiveDataSubscription?.unsubscribe();
|
|
1406
|
-
const key = query.store.idKey;
|
|
1407
|
-
const responsiveData = query.store.entities$.pipe(map((entities) => newData.map((item) => {
|
|
1408
|
-
// TODO(TRB): This is kind of unsafe. The entity array keys might not be the same as the response keys
|
|
1409
|
-
const index = entities.values.findIndex((entity) => entity[key] === item[key]);
|
|
1410
|
-
return index > -1 ? entities.values[index] : item;
|
|
1411
|
-
})));
|
|
1412
|
-
this._responsiveDataSubscription = responsiveData.subscribe((data) => this._data$.next(data));
|
|
1413
|
-
}
|
|
1414
|
-
else {
|
|
1415
|
-
this._data$.next(newData);
|
|
1416
|
-
}
|
|
1417
|
-
const totalPages = this._config.response.totalPagesExtractor?.({
|
|
1418
|
-
response: state.response,
|
|
1419
|
-
itemsPerPage: this.itemsPerPage,
|
|
1420
|
-
}) ??
|
|
1421
|
-
state.response?.totalPages ??
|
|
1422
|
-
null;
|
|
1423
|
-
this._totalPages$.next(totalPages);
|
|
1424
|
-
},
|
|
1425
|
-
complete: () => {
|
|
1426
|
-
this._subscriptions = this._subscriptions.filter((sub) => sub !== stateChangesSub);
|
|
1427
|
-
},
|
|
1428
|
-
});
|
|
1429
|
-
this._subscriptions.push(stateChangesSub);
|
|
1430
|
-
}
|
|
1431
1306
|
_prepareArgs(config, page) {
|
|
1432
1307
|
const pageParamLocation = this._getPageParamLocation(config?.pageParam?.location);
|
|
1433
1308
|
const pageArgs = {
|
|
@@ -1493,7 +1368,7 @@ class InfinityQueryDirective {
|
|
|
1493
1368
|
this._queryConfigChanged$ = new Subject();
|
|
1494
1369
|
this._viewContext = {
|
|
1495
1370
|
$implicit: null,
|
|
1496
|
-
|
|
1371
|
+
etInfinityQuery: null,
|
|
1497
1372
|
loading: false,
|
|
1498
1373
|
error: null,
|
|
1499
1374
|
isFirstLoad: false,
|
|
@@ -1502,6 +1377,7 @@ class InfinityQueryDirective {
|
|
|
1502
1377
|
currentCalculatedPage: null,
|
|
1503
1378
|
totalPages: null,
|
|
1504
1379
|
itemsPerPage: null,
|
|
1380
|
+
currentQuery: null,
|
|
1505
1381
|
};
|
|
1506
1382
|
this._infinityQueryInstance = null;
|
|
1507
1383
|
this._destroy$ = inject(DestroyService, { host: true }).destroy$;
|
|
@@ -1541,27 +1417,25 @@ class InfinityQueryDirective {
|
|
|
1541
1417
|
ngOnInit() {
|
|
1542
1418
|
this._renderMainView();
|
|
1543
1419
|
}
|
|
1544
|
-
ngOnDestroy() {
|
|
1545
|
-
this.instance?._clearSubscriptions();
|
|
1546
|
-
}
|
|
1547
1420
|
_setupInfinityQuery(config) {
|
|
1548
1421
|
const instance = new InfinityQuery(config);
|
|
1549
1422
|
combineLatest([
|
|
1550
|
-
instance.currentQuery$.pipe(switchQueryState()),
|
|
1423
|
+
instance.currentQuery$.pipe(switchQueryState(), withLatestFrom(instance.currentQuery$)),
|
|
1551
1424
|
this._delayable.isDelayed$,
|
|
1552
1425
|
this._didReceiveFirstData$,
|
|
1553
1426
|
])
|
|
1554
|
-
.pipe(tap(([state, isDelayed, didReceiveFirstData]) => {
|
|
1427
|
+
.pipe(tap(([[state, currentQuery], isDelayed, didReceiveFirstData]) => {
|
|
1555
1428
|
this._viewContext.currentPage = instance.currentPage;
|
|
1556
1429
|
this._viewContext.totalPages = instance.totalPages;
|
|
1557
1430
|
this._viewContext.itemsPerPage = instance.itemsPerPage;
|
|
1558
1431
|
this._viewContext.canLoadMore =
|
|
1559
1432
|
(instance.totalPages && instance.currentPage && instance.totalPages > instance.currentPage) || false;
|
|
1560
1433
|
this._viewContext.currentCalculatedPage = instance.currentCalculatedPage;
|
|
1434
|
+
this._viewContext.currentQuery = currentQuery;
|
|
1561
1435
|
if (isQueryStateLoading(state) || isDelayed || (!didReceiveFirstData && isQueryStateSuccess(state))) {
|
|
1562
1436
|
this._viewContext.loading = true;
|
|
1563
1437
|
this._viewContext.error = null;
|
|
1564
|
-
this._viewContext.isFirstLoad = this.context.
|
|
1438
|
+
this._viewContext.isFirstLoad = this.context.etInfinityQuery === null;
|
|
1565
1439
|
}
|
|
1566
1440
|
else if (isQueryStateFailure(state)) {
|
|
1567
1441
|
this._viewContext.loading = false;
|
|
@@ -1577,13 +1451,14 @@ class InfinityQueryDirective {
|
|
|
1577
1451
|
else {
|
|
1578
1452
|
this._viewContext.loading = false;
|
|
1579
1453
|
this._viewContext.error = null;
|
|
1580
|
-
this._viewContext.
|
|
1454
|
+
this._viewContext.etInfinityQuery = null;
|
|
1581
1455
|
this._viewContext.$implicit = null;
|
|
1582
1456
|
this._viewContext.isFirstLoad = false;
|
|
1583
1457
|
this._viewContext.canLoadMore = false;
|
|
1584
1458
|
this._viewContext.currentPage = null;
|
|
1585
1459
|
this._viewContext.itemsPerPage = null;
|
|
1586
1460
|
this._viewContext.totalPages = null;
|
|
1461
|
+
this._viewContext.currentQuery = null;
|
|
1587
1462
|
this._data$.next([]);
|
|
1588
1463
|
}
|
|
1589
1464
|
this._cdr.markForCheck();
|
|
@@ -1591,7 +1466,7 @@ class InfinityQueryDirective {
|
|
|
1591
1466
|
.subscribe();
|
|
1592
1467
|
instance.data$
|
|
1593
1468
|
.pipe(skip(1), tap((data) => {
|
|
1594
|
-
this._viewContext.
|
|
1469
|
+
this._viewContext.etInfinityQuery = this._viewContext.$implicit = data;
|
|
1595
1470
|
this._data$.next(data);
|
|
1596
1471
|
if (!this._didReceiveFirstData$.getValue()) {
|
|
1597
1472
|
this._didReceiveFirstData$.next(true);
|
|
@@ -1601,13 +1476,6 @@ class InfinityQueryDirective {
|
|
|
1601
1476
|
.subscribe();
|
|
1602
1477
|
return instance;
|
|
1603
1478
|
}
|
|
1604
|
-
/**
|
|
1605
|
-
* @deprecated Use `loadNextPage` instead
|
|
1606
|
-
* @breaking 3.0.0
|
|
1607
|
-
*/
|
|
1608
|
-
_loadNextPage() {
|
|
1609
|
-
this.loadNextPage();
|
|
1610
|
-
}
|
|
1611
1479
|
loadNextPage() {
|
|
1612
1480
|
if (!this._infinityQueryInstance) {
|
|
1613
1481
|
return;
|
|
@@ -1631,33 +1499,34 @@ class InfinityQueryDirective {
|
|
|
1631
1499
|
}
|
|
1632
1500
|
_cleanup() {
|
|
1633
1501
|
this._queryConfigChanged$.next(true);
|
|
1634
|
-
this.instance?._clearSubscriptions();
|
|
1635
1502
|
this._viewContext.loading = false;
|
|
1636
1503
|
this._viewContext.error = null;
|
|
1637
|
-
this._viewContext.
|
|
1504
|
+
this._viewContext.etInfinityQuery = null;
|
|
1638
1505
|
this._viewContext.$implicit = null;
|
|
1639
1506
|
this._viewContext.isFirstLoad = false;
|
|
1640
1507
|
this._viewContext.canLoadMore = false;
|
|
1641
1508
|
this._viewContext.currentPage = null;
|
|
1642
1509
|
this._viewContext.itemsPerPage = null;
|
|
1643
1510
|
this._viewContext.totalPages = null;
|
|
1511
|
+
this._viewContext.currentQuery = null;
|
|
1644
1512
|
this._data$.next([]);
|
|
1645
1513
|
}
|
|
1646
1514
|
}
|
|
1647
1515
|
InfinityQueryDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.5", ngImport: i0, type: InfinityQueryDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
1648
|
-
InfinityQueryDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.2.5", type: InfinityQueryDirective, isStandalone: true, selector: "[
|
|
1516
|
+
InfinityQueryDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.2.5", type: InfinityQueryDirective, isStandalone: true, selector: "[etInfinityQuery]", inputs: { infinityQuery: ["etInfinityQuery", "infinityQuery"] }, providers: [{ provide: INFINITY_QUERY_TOKEN, useExisting: InfinityQueryDirective }, DestroyService], exportAs: ["etInfinityQuery"], hostDirectives: [{ directive: i1.DelayableDirective }], ngImport: i0 });
|
|
1649
1517
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.5", ngImport: i0, type: InfinityQueryDirective, decorators: [{
|
|
1650
1518
|
type: Directive,
|
|
1651
1519
|
args: [{
|
|
1652
1520
|
// eslint-disable-next-line @angular-eslint/directive-selector
|
|
1653
|
-
selector: '[
|
|
1654
|
-
exportAs: '
|
|
1521
|
+
selector: '[etInfinityQuery]',
|
|
1522
|
+
exportAs: 'etInfinityQuery',
|
|
1655
1523
|
standalone: true,
|
|
1656
1524
|
providers: [{ provide: INFINITY_QUERY_TOKEN, useExisting: InfinityQueryDirective }, DestroyService],
|
|
1657
1525
|
hostDirectives: [DelayableDirective],
|
|
1658
1526
|
}]
|
|
1659
1527
|
}], propDecorators: { infinityQuery: [{
|
|
1660
|
-
type: Input
|
|
1528
|
+
type: Input,
|
|
1529
|
+
args: ['etInfinityQuery']
|
|
1661
1530
|
}] } });
|
|
1662
1531
|
|
|
1663
1532
|
class InfinityQueryTriggerDirective {
|
|
@@ -1670,7 +1539,7 @@ class InfinityQueryTriggerDirective {
|
|
|
1670
1539
|
this.scrollContainerSelector = null;
|
|
1671
1540
|
}
|
|
1672
1541
|
ngOnInit() {
|
|
1673
|
-
const isInteractive = this._elementRef.nativeElement.hasAttribute('
|
|
1542
|
+
const isInteractive = this._elementRef.nativeElement.hasAttribute('etInfinityQueryTrigger');
|
|
1674
1543
|
if (isInteractive) {
|
|
1675
1544
|
this.click$.pipe(takeUntil(this._destroy)).subscribe(() => this._infinityQuery.loadNextPage());
|
|
1676
1545
|
}
|
|
@@ -1698,155 +1567,144 @@ class InfinityQueryTriggerDirective {
|
|
|
1698
1567
|
}
|
|
1699
1568
|
}
|
|
1700
1569
|
InfinityQueryTriggerDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.5", ngImport: i0, type: InfinityQueryTriggerDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
1701
|
-
InfinityQueryTriggerDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.2.5", type: InfinityQueryTriggerDirective, isStandalone: true, selector: "[
|
|
1570
|
+
InfinityQueryTriggerDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.2.5", type: InfinityQueryTriggerDirective, isStandalone: true, selector: "[etInfinityQueryTrigger], et-infinity-query-trigger", inputs: { scrollContainerSelector: "scrollContainerSelector" }, ngImport: i0 });
|
|
1702
1571
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.5", ngImport: i0, type: InfinityQueryTriggerDirective, decorators: [{
|
|
1703
1572
|
type: Directive,
|
|
1704
1573
|
args: [{
|
|
1705
1574
|
// eslint-disable-next-line @angular-eslint/directive-selector
|
|
1706
|
-
selector: '[
|
|
1575
|
+
selector: '[etInfinityQueryTrigger], et-infinity-query-trigger',
|
|
1707
1576
|
standalone: true,
|
|
1708
1577
|
}]
|
|
1709
1578
|
}], propDecorators: { scrollContainerSelector: [{
|
|
1710
1579
|
type: Input
|
|
1711
1580
|
}] } });
|
|
1712
1581
|
|
|
1713
|
-
class
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
return [...this._keys];
|
|
1719
|
-
}
|
|
1720
|
-
get values() {
|
|
1721
|
-
return [...this._dictionary.values()];
|
|
1722
|
-
}
|
|
1723
|
-
get size() {
|
|
1724
|
-
return this._keys.size;
|
|
1725
|
-
}
|
|
1726
|
-
get isEmpty() {
|
|
1727
|
-
return this.size === 0;
|
|
1728
|
-
}
|
|
1729
|
-
get config() {
|
|
1730
|
-
return this._config;
|
|
1731
|
-
}
|
|
1732
|
-
get idKey() {
|
|
1733
|
-
return this._config.idKey || 'id';
|
|
1582
|
+
class EntityStoreError extends Error {
|
|
1583
|
+
constructor(message, detail) {
|
|
1584
|
+
super(message);
|
|
1585
|
+
this.detail = detail;
|
|
1586
|
+
this.name = 'EntityStoreError';
|
|
1734
1587
|
}
|
|
1588
|
+
}
|
|
1589
|
+
class EntityStore {
|
|
1735
1590
|
constructor(_config) {
|
|
1736
1591
|
this._config = _config;
|
|
1737
1592
|
this._dictionary = new Map();
|
|
1738
|
-
this.
|
|
1739
|
-
this._events$ = new Subject();
|
|
1740
|
-
this.entities$ = this.events$.pipe(startWith(null), debounceTime(0), map(() => ({
|
|
1741
|
-
keys: this.keys,
|
|
1742
|
-
values: this.values,
|
|
1743
|
-
})));
|
|
1744
|
-
}
|
|
1745
|
-
getOne(key) {
|
|
1746
|
-
const value = this._dictionary.get(key);
|
|
1747
|
-
if (!value) {
|
|
1748
|
-
console.error(`EntityStore: ${this._config.name || 'unknown'}: missing key "${key}" for get`);
|
|
1749
|
-
return null;
|
|
1750
|
-
}
|
|
1751
|
-
if (this._config.logActions) {
|
|
1752
|
-
console.log(`EntityStore: ${this._config.name || 'unknown'}: get "${key}"`);
|
|
1753
|
-
}
|
|
1754
|
-
return value;
|
|
1593
|
+
this._change$ = new Subject();
|
|
1755
1594
|
}
|
|
1756
|
-
|
|
1757
|
-
|
|
1595
|
+
select(keyOrKeys) {
|
|
1596
|
+
if (Array.isArray(keyOrKeys)) {
|
|
1597
|
+
return this._selectMany(keyOrKeys);
|
|
1598
|
+
}
|
|
1599
|
+
return this._select(keyOrKeys);
|
|
1758
1600
|
}
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
|
|
1601
|
+
set(keyOrKeys, valueOrValues) {
|
|
1602
|
+
if (Array.isArray(keyOrKeys)) {
|
|
1603
|
+
if (!Array.isArray(valueOrValues)) {
|
|
1604
|
+
throw new EntityStoreError('When setting multiple keys, values must be an array', {
|
|
1605
|
+
keyOrValues: keyOrKeys,
|
|
1606
|
+
valueOrValues,
|
|
1607
|
+
});
|
|
1608
|
+
}
|
|
1609
|
+
for (let i = 0; i < keyOrKeys.length; i++) {
|
|
1610
|
+
this._set(keyOrKeys[i], valueOrValues[i]);
|
|
1611
|
+
}
|
|
1764
1612
|
}
|
|
1765
|
-
|
|
1766
|
-
|
|
1767
|
-
const event = { type: 'add', key };
|
|
1768
|
-
this._events$.next(event);
|
|
1769
|
-
if (this._config.logActions) {
|
|
1770
|
-
console.log(`EntityStore: ${this._config.name || 'unknown'}: add "${key}"`);
|
|
1613
|
+
else {
|
|
1614
|
+
this._set(keyOrKeys, valueOrValues);
|
|
1771
1615
|
}
|
|
1772
|
-
|
|
1773
|
-
}
|
|
1774
|
-
addMany(values) {
|
|
1775
|
-
const events = values.map((value) => this.addOne(value));
|
|
1776
|
-
return events;
|
|
1616
|
+
this._change$.next(keyOrKeys);
|
|
1777
1617
|
}
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
return null;
|
|
1618
|
+
remove(keyOrKeys) {
|
|
1619
|
+
if (Array.isArray(keyOrKeys)) {
|
|
1620
|
+
for (const key of keyOrKeys) {
|
|
1621
|
+
this._remove(key);
|
|
1622
|
+
}
|
|
1784
1623
|
}
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
this._events$.next(event);
|
|
1788
|
-
if (this._config.logActions) {
|
|
1789
|
-
console.log(`EntityStore: ${this._config.name || 'unknown'}: update "${key}"`);
|
|
1624
|
+
else {
|
|
1625
|
+
this._remove(keyOrKeys);
|
|
1790
1626
|
}
|
|
1791
|
-
|
|
1627
|
+
this._change$.next(keyOrKeys);
|
|
1792
1628
|
}
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
|
|
1629
|
+
logState() {
|
|
1630
|
+
console.log('EntityStore:', this._config.name, {
|
|
1631
|
+
dictionary: this._dictionary,
|
|
1632
|
+
});
|
|
1796
1633
|
}
|
|
1797
|
-
|
|
1798
|
-
const key = this.getKey(value);
|
|
1799
|
-
this._dictionary.set(key, value);
|
|
1800
|
-
this._keys.add(key);
|
|
1801
|
-
const event = { type: 'set', key };
|
|
1802
|
-
this._events$.next(event);
|
|
1634
|
+
_select(key) {
|
|
1803
1635
|
if (this._config.logActions) {
|
|
1804
|
-
console.log(
|
|
1636
|
+
console.log('EntityStore: select', this._config.name, key);
|
|
1805
1637
|
}
|
|
1806
|
-
return
|
|
1807
|
-
|
|
1808
|
-
|
|
1809
|
-
|
|
1810
|
-
|
|
1638
|
+
return this._change$.pipe(startWith(null), filter((v) => {
|
|
1639
|
+
if (v === null) {
|
|
1640
|
+
return true;
|
|
1641
|
+
}
|
|
1642
|
+
if (Array.isArray(v)) {
|
|
1643
|
+
return v.includes(key);
|
|
1644
|
+
}
|
|
1645
|
+
return v === key;
|
|
1646
|
+
}), map(() => this._dictionary.get(key) ?? null));
|
|
1811
1647
|
}
|
|
1812
|
-
|
|
1813
|
-
if (!this._dictionary.has(key)) {
|
|
1814
|
-
console.error(`EntityStore: ${this._config.name || 'unknown'}: missing key "${key}" for remove`);
|
|
1815
|
-
return null;
|
|
1816
|
-
}
|
|
1817
|
-
this._dictionary.delete(key);
|
|
1818
|
-
this._keys.delete(key);
|
|
1819
|
-
const event = { type: 'remove', key };
|
|
1820
|
-
this._events$.next(event);
|
|
1648
|
+
_selectMany(keys) {
|
|
1821
1649
|
if (this._config.logActions) {
|
|
1822
|
-
console.log(
|
|
1650
|
+
console.log('EntityStore: selectMany', this._config.name, keys);
|
|
1823
1651
|
}
|
|
1824
|
-
return
|
|
1825
|
-
|
|
1826
|
-
|
|
1827
|
-
|
|
1828
|
-
|
|
1829
|
-
|
|
1830
|
-
|
|
1831
|
-
|
|
1652
|
+
return this._change$.pipe(startWith(null), filter((v) => {
|
|
1653
|
+
if (v === null) {
|
|
1654
|
+
return true;
|
|
1655
|
+
}
|
|
1656
|
+
if (Array.isArray(v)) {
|
|
1657
|
+
return keys.some((key) => v.includes(key));
|
|
1658
|
+
}
|
|
1659
|
+
return keys.includes(v);
|
|
1660
|
+
}), map(() => keys.map((key) => this._dictionary.get(key)).filter((value) => value !== undefined)));
|
|
1832
1661
|
}
|
|
1833
|
-
|
|
1834
|
-
this.
|
|
1835
|
-
|
|
1662
|
+
_set(key, value) {
|
|
1663
|
+
if (this._config.logActions) {
|
|
1664
|
+
console.log('EntityStore: set', this._config.name, key, value);
|
|
1665
|
+
}
|
|
1666
|
+
this._dictionary.set(key, value);
|
|
1836
1667
|
}
|
|
1837
|
-
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
if (key === undefined) {
|
|
1841
|
-
throw new Error(`EntityStore: ${this._config.name || 'unknown'}: missing key`);
|
|
1668
|
+
_remove(key) {
|
|
1669
|
+
if (this._config.logActions) {
|
|
1670
|
+
console.log('EntityStore: remove', this._config.name, key);
|
|
1842
1671
|
}
|
|
1843
|
-
|
|
1672
|
+
this._dictionary.delete(key);
|
|
1844
1673
|
}
|
|
1845
|
-
|
|
1846
|
-
|
|
1847
|
-
|
|
1848
|
-
|
|
1849
|
-
|
|
1674
|
+
}
|
|
1675
|
+
|
|
1676
|
+
function mapToPaginated(response) {
|
|
1677
|
+
return map((items) => ({ ...response, items }));
|
|
1678
|
+
}
|
|
1679
|
+
|
|
1680
|
+
class QueryCreator {
|
|
1681
|
+
constructor(_queryConfig, _client, _store) {
|
|
1682
|
+
this._queryConfig = _queryConfig;
|
|
1683
|
+
this._client = _client;
|
|
1684
|
+
this._store = _store;
|
|
1685
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
1686
|
+
// @ts-ignore
|
|
1687
|
+
this.prepare = (args) => {
|
|
1688
|
+
const route = buildRoute({
|
|
1689
|
+
base: this._client.config.baseRoute,
|
|
1690
|
+
route: this._queryConfig.route,
|
|
1691
|
+
pathParams: args?.pathParams,
|
|
1692
|
+
queryParams: computeQueryQueryParams({ config: this._queryConfig, client: this._client, args }),
|
|
1693
|
+
});
|
|
1694
|
+
const cacheKey = isGqlQueryConfig(this._queryConfig) ? buildGqlCacheKey(this._queryConfig, args) : route;
|
|
1695
|
+
if (shouldCacheQuery(this._queryConfig.method)) {
|
|
1696
|
+
const existingQuery = this._store.get(cacheKey);
|
|
1697
|
+
if (existingQuery) {
|
|
1698
|
+
return existingQuery;
|
|
1699
|
+
}
|
|
1700
|
+
}
|
|
1701
|
+
const query = new Query(this._client, this._queryConfig, route, args ?? {});
|
|
1702
|
+
if (shouldCacheQuery(this._queryConfig.method)) {
|
|
1703
|
+
this._store.add(cacheKey, query);
|
|
1704
|
+
}
|
|
1705
|
+
return query;
|
|
1706
|
+
};
|
|
1707
|
+
this.behaviorSubject = (initialValue) => new BehaviorSubject(initialValue ?? null);
|
|
1850
1708
|
}
|
|
1851
1709
|
}
|
|
1852
1710
|
|
|
@@ -1979,20 +1837,6 @@ class QueryStore {
|
|
|
1979
1837
|
}
|
|
1980
1838
|
}
|
|
1981
1839
|
|
|
1982
|
-
const shouldCacheQuery = (method) => {
|
|
1983
|
-
return method === 'GET' || method === 'OPTIONS' || method === 'HEAD' || method === 'GQL_QUERY';
|
|
1984
|
-
};
|
|
1985
|
-
const buildGqlCacheKey = (config, args) => {
|
|
1986
|
-
const { query } = config;
|
|
1987
|
-
const variables = args?.variables || {};
|
|
1988
|
-
const queryWithoutNewLinesAndWhitespace = query.replace(/\s/g, '');
|
|
1989
|
-
const queryFirst50Chars = queryWithoutNewLinesAndWhitespace.slice(0, 50);
|
|
1990
|
-
const queryMiddle25Chars = queryWithoutNewLinesAndWhitespace.slice(queryWithoutNewLinesAndWhitespace.length / 2 - 25, queryWithoutNewLinesAndWhitespace.length / 2 + 25);
|
|
1991
|
-
const queryLast50Chars = queryWithoutNewLinesAndWhitespace.slice(-50);
|
|
1992
|
-
const vars = JSON.stringify(variables);
|
|
1993
|
-
return `${queryFirst50Chars}...${queryMiddle25Chars}...${queryLast50Chars}...${vars}`;
|
|
1994
|
-
};
|
|
1995
|
-
|
|
1996
1840
|
class QueryClient {
|
|
1997
1841
|
get config() {
|
|
1998
1842
|
return this._clientConfig;
|
|
@@ -2034,33 +1878,7 @@ class QueryClient {
|
|
|
2034
1878
|
...queryConfig,
|
|
2035
1879
|
method: 'GQL_MUTATE',
|
|
2036
1880
|
});
|
|
2037
|
-
this.fetch = (queryConfig) =>
|
|
2038
|
-
const prepare = (args) => {
|
|
2039
|
-
const route = buildRoute({
|
|
2040
|
-
base: this._clientConfig.baseRoute,
|
|
2041
|
-
route: queryConfig.route,
|
|
2042
|
-
pathParams: args?.pathParams,
|
|
2043
|
-
queryParams: computeQueryQueryParams({ config: queryConfig, client: this, args }),
|
|
2044
|
-
});
|
|
2045
|
-
const cacheKey = isGqlQueryConfig(queryConfig) ? buildGqlCacheKey(queryConfig, args) : route;
|
|
2046
|
-
if (shouldCacheQuery(queryConfig.method)) {
|
|
2047
|
-
const existingQuery = this._store.get(cacheKey);
|
|
2048
|
-
if (existingQuery) {
|
|
2049
|
-
return existingQuery;
|
|
2050
|
-
}
|
|
2051
|
-
}
|
|
2052
|
-
const query = new Query(this, queryConfig, route, args ?? {});
|
|
2053
|
-
if (shouldCacheQuery(queryConfig.method)) {
|
|
2054
|
-
this._store.add(cacheKey, query);
|
|
2055
|
-
}
|
|
2056
|
-
return query;
|
|
2057
|
-
};
|
|
2058
|
-
const behaviorSubject = (initialValue = null) => new BehaviorSubject(initialValue);
|
|
2059
|
-
return {
|
|
2060
|
-
prepare,
|
|
2061
|
-
behaviorSubject,
|
|
2062
|
-
};
|
|
2063
|
-
};
|
|
1881
|
+
this.fetch = (queryConfig) => new QueryCreator(queryConfig, this, this._store);
|
|
2064
1882
|
this.setAuthProvider = (authProvider) => {
|
|
2065
1883
|
if (this.authProvider) {
|
|
2066
1884
|
throw new Error('The auth provider is already set. Please call clearAuthProvider() first.');
|
|
@@ -2093,6 +1911,20 @@ class QueryClient {
|
|
|
2093
1911
|
}
|
|
2094
1912
|
}
|
|
2095
1913
|
|
|
1914
|
+
const shouldCacheQuery = (method) => {
|
|
1915
|
+
return method === 'GET' || method === 'OPTIONS' || method === 'HEAD' || method === 'GQL_QUERY';
|
|
1916
|
+
};
|
|
1917
|
+
const buildGqlCacheKey = (config, args) => {
|
|
1918
|
+
const { query } = config;
|
|
1919
|
+
const variables = args?.variables || {};
|
|
1920
|
+
const queryWithoutNewLinesAndWhitespace = query.replace(/\s/g, '');
|
|
1921
|
+
const queryFirst50Chars = queryWithoutNewLinesAndWhitespace.slice(0, 50);
|
|
1922
|
+
const queryMiddle25Chars = queryWithoutNewLinesAndWhitespace.slice(queryWithoutNewLinesAndWhitespace.length / 2 - 25, queryWithoutNewLinesAndWhitespace.length / 2 + 25);
|
|
1923
|
+
const queryLast50Chars = queryWithoutNewLinesAndWhitespace.slice(-50);
|
|
1924
|
+
const vars = JSON.stringify(variables);
|
|
1925
|
+
return `${queryFirst50Chars}...${queryMiddle25Chars}...${queryLast50Chars}...${vars}`;
|
|
1926
|
+
};
|
|
1927
|
+
|
|
2096
1928
|
class QueryField {
|
|
2097
1929
|
get control() {
|
|
2098
1930
|
return this.data.control;
|
|
@@ -2336,5 +2168,5 @@ const def = () => null;
|
|
|
2336
2168
|
* Generated bundle index. Do not edit.
|
|
2337
2169
|
*/
|
|
2338
2170
|
|
|
2339
|
-
export { BasicAuthProvider, BearerAuthProvider, CustomHeaderAuthProvider, EntityStore, INFINITY_QUERY_TOKEN, InfinityQuery, InfinityQueryDirective, InfinityQueryTriggerDirective, Query, QueryClient, QueryDirective, QueryError, QueryField, QueryForm, QueryStore, buildErrorMessage, buildGqlCacheKey, buildQueryArrayString, buildQueryObjectString, buildQueryString, buildRoute, buildTimestampFromSeconds, castQueryCreatorTypes, computeQueryAuthHeader, computeQueryBody, computeQueryHeaders, computeQueryMethod, computeQueryQueryParams, createInfinityQueryConfig, createQueryCollection, decryptBearer, deepFreeze, def, detectContentTypeHeader, extractExpiresInSeconds, extractQuery, filterFailure, filterInvalidParams, filterNull, filterQueryStates, filterSuccess, forEachHeader, getDefaultHeaders, getResponseUrl, gql, hasHeader, ignoreAutoRefresh, invalidBaseRouteError, invalidBodyError, invalidRouteError, isAutoRefresh, isBasicAuthProvider, isBearerAuthProvider, isCustomHeaderAuthProvider,
|
|
2171
|
+
export { BasicAuthProvider, BearerAuthProvider, CustomHeaderAuthProvider, EntityStore, INFINITY_QUERY_TOKEN, InfinityQuery, InfinityQueryDirective, InfinityQueryTriggerDirective, Query, QueryClient, QueryCreator, QueryDirective, QueryError, QueryField, QueryForm, QueryStore, buildErrorMessage, buildGqlCacheKey, buildQueryArrayString, buildQueryObjectString, buildQueryString, buildRoute, buildTimestampFromSeconds, castQueryCreatorTypes, computeQueryAuthHeader, computeQueryBody, computeQueryHeaders, computeQueryMethod, computeQueryQueryParams, createInfinityQueryConfig, createQueryCollection, decryptBearer, deepFreeze, def, detectContentTypeHeader, extractExpiresInSeconds, extractQuery, filterFailure, filterInvalidParams, filterNull, filterQueryStates, filterSuccess, forEachHeader, getDefaultHeaders, getResponseUrl, gql, hasHeader, ignoreAutoRefresh, invalidBaseRouteError, invalidBodyError, invalidRouteError, isAutoRefresh, isBasicAuthProvider, isBearerAuthProvider, isCustomHeaderAuthProvider, isGqlQueryConfig, isParamValid, isQuery, isQueryStateCancelled, isQueryStateFailure, isQueryStateLoading, isQueryStatePrepared, isQueryStateSuccess, isRequestError, mapToPaginated, mergeHeaders, paginatedEntityValueUpdater, parseAllXhrResponseHeaders, pathParamsMissingInRouteFunctionError, queryStateAlreadyHasKeyError, queryStateCannotTransformError, queryStateDoesNotContainKeyError, request, serializeBody, shouldCacheQuery, shouldRetryRequest, skipPaginationPageParamCalculator, switchQueryCollectionState, switchQueryState, takeUntilResponse, transformGql, transformMethod, transformToBoolean, transformToBooleanArray, transformToDate, transformToDateArray, transformToNumber, transformToNumberArray, transformToSort, transformToSortQueryParam, transformToString, transformToStringArray };
|
|
2340
2172
|
//# sourceMappingURL=ethlete-query.mjs.map
|