@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.
Files changed (53) hide show
  1. package/esm2020/index.mjs +2 -1
  2. package/esm2020/lib/auth/auth-provider.types.mjs +1 -1
  3. package/esm2020/lib/auth/auth-provider.utils.mjs +1 -1
  4. package/esm2020/lib/auth/bearer-auth-provider.mjs +2 -2
  5. package/esm2020/lib/directives/infinity-query-trigger.directive.mjs +4 -4
  6. package/esm2020/lib/directives/infinity-query.directive.mjs +18 -24
  7. package/esm2020/lib/directives/query.directive.mjs +9 -11
  8. package/esm2020/lib/entity/entity-store.mjs +73 -119
  9. package/esm2020/lib/entity/entity.types.mjs +1 -1
  10. package/esm2020/lib/entity/entity.utils.mjs +5 -0
  11. package/esm2020/lib/entity/index.mjs +2 -1
  12. package/esm2020/lib/infinite-query/infinity-query.mjs +47 -71
  13. package/esm2020/lib/infinite-query/infinity-query.types.mjs +1 -1
  14. package/esm2020/lib/infinite-query/infinity-query.utils.mjs +1 -1
  15. package/esm2020/lib/query/query.mjs +118 -211
  16. package/esm2020/lib/query/query.types.mjs +1 -1
  17. package/esm2020/lib/query/query.utils.mjs +1 -1
  18. package/esm2020/lib/query-client/query-client.mjs +3 -31
  19. package/esm2020/lib/query-client/query-client.types.mjs +1 -1
  20. package/esm2020/lib/query-creator/index.mjs +3 -0
  21. package/esm2020/lib/query-creator/query-creator.mjs +35 -0
  22. package/esm2020/lib/query-creator/query-creator.types.mjs +2 -0
  23. package/esm2020/lib/request/request.types.mjs +1 -1
  24. package/esm2020/lib/request/request.util.mjs +1 -7
  25. package/fesm2015/ethlete-query.mjs +314 -473
  26. package/fesm2015/ethlete-query.mjs.map +1 -1
  27. package/fesm2020/ethlete-query.mjs +308 -476
  28. package/fesm2020/ethlete-query.mjs.map +1 -1
  29. package/index.d.ts +1 -0
  30. package/lib/auth/auth-provider.types.d.ts +3 -4
  31. package/lib/auth/auth-provider.utils.d.ts +2 -2
  32. package/lib/auth/bearer-auth-provider.d.ts +1 -1
  33. package/lib/directives/infinity-query-trigger.directive.d.ts +1 -1
  34. package/lib/directives/infinity-query.directive.d.ts +6 -11
  35. package/lib/directives/query.directive.d.ts +7 -7
  36. package/lib/entity/entity-store.d.ts +13 -27
  37. package/lib/entity/entity.types.d.ts +0 -5
  38. package/lib/entity/entity.utils.d.ts +2 -0
  39. package/lib/entity/index.d.ts +1 -0
  40. package/lib/infinite-query/infinity-query.d.ts +10 -19
  41. package/lib/infinite-query/infinity-query.types.d.ts +4 -4
  42. package/lib/infinite-query/infinity-query.utils.d.ts +2 -3
  43. package/lib/query/query.d.ts +19 -12
  44. package/lib/query/query.types.d.ts +86 -51
  45. package/lib/query/query.utils.d.ts +16 -14
  46. package/lib/query-client/query-client.d.ts +12 -10
  47. package/lib/query-client/query-client.types.d.ts +2 -22
  48. package/lib/query-creator/index.d.ts +2 -0
  49. package/lib/query-creator/query-creator.d.ts +14 -0
  50. package/lib/query-creator/query-creator.types.d.ts +13 -0
  51. package/lib/request/request.types.d.ts +1 -1
  52. package/lib/request/request.util.d.ts +0 -1
  53. 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, startWith, finalize, timer, map, combineLatest, skip, fromEvent, debounceTime, take, concat, distinctUntilChanged } from 'rxjs';
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';
@@ -114,12 +114,6 @@ const buildQueryObjectString = (key, object) => {
114
114
  })
115
115
  .join('&');
116
116
  };
117
- const isFetchResponse = (response) => typeof response === 'object' &&
118
- response !== null &&
119
- 'status' in response &&
120
- 'statusText' in response &&
121
- 'json' in response &&
122
- typeof response['json'] === 'function';
123
117
  const filterInvalidParams = (params) => {
124
118
  const filteredParams = Object.entries(params)
125
119
  .map(([key, value]) => {
@@ -706,16 +700,22 @@ class Query {
706
700
  return ++this._currentId;
707
701
  }
708
702
  get state$() {
709
- return this._state$.asObservable();
703
+ return this._state$.pipe(switchMap((s) => this._transformState(s)), shareReplay({ bufferSize: 1, refCount: true }));
710
704
  }
711
- get state() {
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.state)) {
715
+ if (!isQueryStateSuccess(this._state$.value)) {
716
716
  return false;
717
717
  }
718
- const ts = this.state.meta.expiresAt;
718
+ const ts = this._state$.value.meta.expiresAt;
719
719
  if (!ts) {
720
720
  return true;
721
721
  }
@@ -748,14 +748,13 @@ class Query {
748
748
  return (_b = (_a = this._queryConfig.entity) === null || _a === void 0 ? void 0 : _a.store) !== null && _b !== void 0 ? _b : null;
749
749
  }
750
750
  constructor(_client, _queryConfig, _routeWithParams, _args) {
751
- var _a;
752
751
  this._client = _client;
753
752
  this._queryConfig = _queryConfig;
754
753
  this._routeWithParams = _routeWithParams;
755
754
  this._args = _args;
756
755
  this._currentId = 0;
757
756
  this._pollingSubscription = null;
758
- this._entitySubscription = null;
757
+ this._requestSubscription = null;
759
758
  this._onAbort$ = new Subject();
760
759
  this._currentPollConfig = null;
761
760
  /**
@@ -766,183 +765,40 @@ class Query {
766
765
  type: "PREPARED" /* QueryStateType.Prepared */,
767
766
  meta: { id: this._currentId, triggeredVia: 'program' },
768
767
  });
769
- if ((_a = this._queryConfig.entity) === null || _a === void 0 ? void 0 : _a.store) {
770
- this._entitySubscription = this._queryConfig.entity.store.events$.subscribe((event) => {
771
- var _a, _b, _c, _d;
772
- if (event.type !== 'update' && event.type !== 'set') {
773
- return;
774
- }
775
- if (!isQueryStateSuccess(this.state)) {
776
- return;
777
- }
778
- const response = this.state.response;
779
- const rawResponse = this.state.rawResponse;
780
- const key = (_a = this._queryConfig.entity) === null || _a === void 0 ? void 0 : _a.store.config.idKey;
781
- if (!key) {
782
- return;
783
- }
784
- const newData = (_b = this._queryConfig.entity) === null || _b === void 0 ? void 0 : _b.store.getOne(event.key);
785
- if (!newData) {
786
- return;
787
- }
788
- const newResponse = ((_c = this._queryConfig.entity) === null || _c === void 0 ? void 0 : _c.valueUpdater)
789
- ? (_d = this._queryConfig.entity) === null || _d === void 0 ? void 0 : _d.valueUpdater({
790
- args: this._args,
791
- entity: newData,
792
- rawResponse,
793
- response,
794
- })
795
- : response[key] === newData[key]
796
- ? {
797
- response: newData,
798
- rawResponse: newData,
799
- }
800
- : null;
801
- if (!newResponse) {
802
- return;
803
- }
804
- this._state$.next(Object.assign(Object.assign({}, this.state), { response: newResponse.response, rawResponse: newResponse.rawResponse, meta: Object.assign(Object.assign({}, this.state.meta), { triggeredVia: 'auto' }) }));
805
- });
806
- }
807
768
  }
808
- clone() {
809
- return this._client.fetch(this._queryConfig);
810
- }
811
- execute(options) {
812
- var _a, _b, _c;
813
- const triggeredVia = (_a = options === null || options === void 0 ? void 0 : options._triggeredVia) !== null && _a !== void 0 ? _a : 'program';
814
- if (!this.isExpired && !(options === null || options === void 0 ? void 0 : options.skipCache) && isQueryStateSuccess(this.state)) {
769
+ execute(options = {}) {
770
+ var _a, _b;
771
+ const { skipCache = false, _triggeredVia: triggeredVia = 'program' } = options;
772
+ const { authProvider } = this._client;
773
+ const queryConfig = this._queryConfig;
774
+ if (!this.isExpired && !skipCache && isQueryStateSuccess(this.rawState)) {
815
775
  return this;
816
776
  }
817
- if (this._queryConfig.secure && !this._client.authProvider) {
777
+ if (queryConfig.secure && !authProvider) {
818
778
  throw new Error('Cannot execute secure query without auth provider');
819
779
  }
820
780
  const id = this._nextId;
821
- if (isQueryStateLoading(this._state$.value)) {
781
+ const meta = { id, triggeredVia };
782
+ if (isQueryStateLoading(this.rawState)) {
822
783
  this.abort();
823
784
  }
824
- const meta = { id, triggeredVia };
825
- this._state$.next({
826
- type: "LOADING" /* QueryStateType.Loading */,
827
- meta,
828
- });
829
- this._updateUseResultInDependencies();
830
- const method = computeQueryMethod({ config: this._queryConfig, client: this._client });
831
- const body = computeQueryBody({
832
- config: this._queryConfig,
833
- client: this._client,
834
- args: this._args,
835
- method,
836
- });
837
- const headers = computeQueryHeaders({ client: this._client, config: this._queryConfig, args: this._args });
838
- request({
785
+ this._state$.next({ type: "LOADING" /* QueryStateType.Loading */, meta });
786
+ const method = computeQueryMethod({ config: queryConfig, client: this._client });
787
+ const body = computeQueryBody({ config: queryConfig, client: this._client, args: this._args, method });
788
+ const headers = computeQueryHeaders({ client: this._client, config: queryConfig, args: this._args });
789
+ this._requestSubscription = request({
839
790
  urlWithParams: this._routeWithParams,
840
791
  method,
841
792
  body,
842
793
  headers,
843
- reportProgress: this._queryConfig.reportProgress,
844
- responseType: this._queryConfig.responseType,
845
- withCredentials: this._queryConfig.withCredentials,
846
- cacheAdapter: (_b = this._client.config.request) === null || _b === void 0 ? void 0 : _b.cacheAdapter,
847
- retryFn: (_c = this._client.config.request) === null || _c === void 0 ? void 0 : _c.retryFn,
794
+ reportProgress: queryConfig.reportProgress,
795
+ responseType: queryConfig.responseType,
796
+ withCredentials: queryConfig.withCredentials,
797
+ cacheAdapter: (_a = this._client.config.request) === null || _a === void 0 ? void 0 : _a.cacheAdapter,
798
+ retryFn: (_b = this._client.config.request) === null || _b === void 0 ? void 0 : _b.retryFn,
848
799
  })
849
- .pipe(takeUntil(this._onAbort$))
850
- .subscribe({
851
- next: (state) => {
852
- var _a, _b;
853
- if (state.type === 'start' || state.type === 'delay-retry') {
854
- const newMeta = Object.assign(Object.assign({}, meta), { isWaitingForRetry: state.type === 'delay-retry', retryDelay: state.retryDelay, retryNumber: state.retryNumber });
855
- this._state$.next({
856
- type: "LOADING" /* QueryStateType.Loading */,
857
- meta: newMeta,
858
- });
859
- }
860
- else if (state.type === 'download-progress') {
861
- this._state$.next({
862
- type: "LOADING" /* QueryStateType.Loading */,
863
- progress: state.progress,
864
- partialText: state.partialText,
865
- meta,
866
- });
867
- }
868
- else if (state.type === 'upload-progress') {
869
- this._state$.next({
870
- type: "LOADING" /* QueryStateType.Loading */,
871
- progress: state.progress,
872
- meta,
873
- });
874
- }
875
- else if (state.type === 'success') {
876
- const isResponseObject = typeof state.response === 'object';
877
- const isGql = isGqlQueryConfig(this._queryConfig);
878
- let responseData = null;
879
- if (isGql &&
880
- isResponseObject &&
881
- !!state.response &&
882
- typeof state.response === 'object' &&
883
- 'data' in state.response) {
884
- responseData = state.response['data'];
885
- }
886
- else {
887
- responseData = state.response;
888
- }
889
- const transformedResponse = this._queryConfig.responseTransformer
890
- ? this._queryConfig.responseTransformer(responseData)
891
- : responseData;
892
- (_b = (_a = this._queryConfig.entity) === null || _a === void 0 ? void 0 : _a.successAction) === null || _b === void 0 ? void 0 : _b.call(_a, {
893
- args: this._args,
894
- rawResponse: state.response,
895
- response: transformedResponse,
896
- store: this._queryConfig.entity.store,
897
- });
898
- this._state$.next({
899
- type: "SUCCESS" /* QueryStateType.Success */,
900
- rawResponse: state.response,
901
- response: transformedResponse,
902
- meta: Object.assign(Object.assign({}, meta), { expiresAt: state.expiresInTimestamp }),
903
- });
904
- }
905
- else if (state.type === 'failure') {
906
- const failure = () => {
907
- this._state$.next({
908
- type: "FAILURE" /* QueryStateType.Failure */,
909
- error: state.error,
910
- meta,
911
- });
912
- };
913
- const bearerAuthProvider = this._getBearerAuthProvider();
914
- if (!bearerAuthProvider || (options === null || options === void 0 ? void 0 : options._isUnauthorizedRetry)) {
915
- return failure();
916
- }
917
- else if (state.error.status === 401 /* HttpStatusCode.Unauthorized */ &&
918
- bearerAuthProvider.shouldRefreshOnUnauthorizedResponse) {
919
- const query = bearerAuthProvider._refreshQuery();
920
- if (!query) {
921
- return failure();
922
- }
923
- query.state$
924
- .pipe(takeUntilResponse(), takeUntil(this._onAbort$), tap((state) => {
925
- if (isQueryStateSuccess(state)) {
926
- this.execute(Object.assign(Object.assign({}, options), { _isUnauthorizedRetry: true }));
927
- }
928
- else if (isQueryStateFailure(state)) {
929
- failure();
930
- }
931
- }))
932
- .subscribe();
933
- }
934
- else {
935
- failure();
936
- }
937
- }
938
- else if (state.type === 'cancel') {
939
- this._state$.next({
940
- type: "CANCELLED" /* QueryStateType.Cancelled */,
941
- meta,
942
- });
943
- }
944
- },
945
- });
800
+ .pipe(takeUntil(this._onAbort$), tap((state) => this._updateEntityState(state, meta, options)))
801
+ .subscribe();
946
802
  return this;
947
803
  }
948
804
  abort() {
@@ -954,16 +810,11 @@ class Query {
954
810
  return this;
955
811
  }
956
812
  this._currentPollConfig = config;
957
- const _interval = config.triggerImmediately
958
- ? interval(config.interval).pipe(startWith(-1))
959
- : interval(config.interval);
960
- this._pollingSubscription = _interval
961
- .pipe(takeUntil(config.takeUntil), finalize(() => this.stopPolling()))
962
- .subscribe(() => {
963
- if (this.state.type === "LOADING" /* QueryStateType.Loading */) {
964
- return;
965
- }
966
- this.execute({ skipCache: true, _triggeredVia: 'poll' });
813
+ const interval$ = interval(config.interval);
814
+ const poll$ = interval$.pipe(skip(config.triggerImmediately ? 0 : 1), takeUntil(config.takeUntil), takeWhile(() => !this._isPollingPaused), filter(() => !isQueryStateLoading(this._state$.value)));
815
+ this._pollingSubscription = poll$.subscribe({
816
+ next: () => this.execute({ skipCache: true, _triggeredVia: 'poll' }),
817
+ complete: () => this.stopPolling(),
967
818
  });
968
819
  return this;
969
820
  }
@@ -988,28 +839,6 @@ class Query {
988
839
  this._isPollingPaused = false;
989
840
  return this.poll(Object.assign(Object.assign({}, this._currentPollConfig), { triggerImmediately: true }));
990
841
  }
991
- _updateUseResultInDependencies() {
992
- var _a, _b;
993
- if (!((_b = (_a = this._args) === null || _a === void 0 ? void 0 : _a.useResultIn) === null || _b === void 0 ? void 0 : _b.length)) {
994
- return;
995
- }
996
- this.state$
997
- .pipe(filterSuccess(), takeUntil(this._onAbort$), takeUntilResponse(), tap((state) => {
998
- var _a;
999
- if (!((_a = this._args) === null || _a === void 0 ? void 0 : _a.useResultIn)) {
1000
- return;
1001
- }
1002
- for (const query of this._args.useResultIn) {
1003
- query._state$.next({
1004
- type: "SUCCESS" /* QueryStateType.Success */,
1005
- meta: Object.assign(Object.assign({}, state.meta), { id: query._nextId }),
1006
- rawResponse: state.rawResponse,
1007
- response: state.response,
1008
- });
1009
- }
1010
- }))
1011
- .subscribe();
1012
- }
1013
842
  /**
1014
843
  * @internal
1015
844
  */
@@ -1018,7 +847,7 @@ class Query {
1018
847
  this._state$.complete();
1019
848
  this._onAbort$.complete();
1020
849
  (_a = this._pollingSubscription) === null || _a === void 0 ? void 0 : _a.unsubscribe();
1021
- (_b = this._entitySubscription) === null || _b === void 0 ? void 0 : _b.unsubscribe();
850
+ (_b = this._requestSubscription) === null || _b === void 0 ? void 0 : _b.unsubscribe();
1022
851
  }
1023
852
  _getBearerAuthProvider() {
1024
853
  const authProvider = this._client.authProvider;
@@ -1027,6 +856,88 @@ class Query {
1027
856
  }
1028
857
  return null;
1029
858
  }
859
+ _updateEntityState(requestEvent, meta, options) {
860
+ var _a, _b;
861
+ switch (requestEvent.type) {
862
+ case 'start':
863
+ case 'delay-retry': {
864
+ const { type, retryDelay, retryNumber } = requestEvent;
865
+ const newMeta = Object.assign(Object.assign({}, meta), { isWaitingForRetry: type === 'delay-retry', retryDelay, retryNumber });
866
+ this._state$.next({
867
+ type: "LOADING" /* QueryStateType.Loading */,
868
+ meta: newMeta,
869
+ });
870
+ break;
871
+ }
872
+ case 'upload-progress':
873
+ case 'download-progress': {
874
+ this._state$.next({
875
+ type: "LOADING" /* QueryStateType.Loading */,
876
+ progress: requestEvent.progress,
877
+ partialText: 'partialText' in requestEvent ? requestEvent.partialText : undefined,
878
+ meta,
879
+ });
880
+ break;
881
+ }
882
+ case 'success': {
883
+ const { response, expiresInTimestamp } = requestEvent;
884
+ const isGql = isGqlQueryConfig(this._queryConfig);
885
+ const responseData = isGql && typeof response === 'object' && !!response && 'data' in response
886
+ ? response['data']
887
+ : response;
888
+ this._state$.next({
889
+ type: "SUCCESS" /* QueryStateType.Success */,
890
+ response: responseData,
891
+ meta: Object.assign(Object.assign({}, meta), { expiresAt: expiresInTimestamp }),
892
+ });
893
+ if (this._queryConfig.entity && this._queryConfig.entity.set) {
894
+ const id = (_a = this._queryConfig.entity) === null || _a === void 0 ? void 0 : _a.id({ args: this._args, response: responseData });
895
+ (_b = this._queryConfig.entity) === null || _b === void 0 ? void 0 : _b.set({
896
+ args: this._args,
897
+ response: responseData,
898
+ id,
899
+ store: this._queryConfig.entity.store,
900
+ });
901
+ }
902
+ break;
903
+ }
904
+ case 'failure': {
905
+ const { error } = requestEvent;
906
+ const failure = () => this._state$.next({ type: "FAILURE" /* QueryStateType.Failure */, error, meta });
907
+ const bearerAuthProvider = this._getBearerAuthProvider();
908
+ if (!bearerAuthProvider ||
909
+ (options === null || options === void 0 ? void 0 : options._isUnauthorizedRetry) ||
910
+ error.status !== 401 /* HttpStatusCode.Unauthorized */ ||
911
+ !bearerAuthProvider.shouldRefreshOnUnauthorizedResponse) {
912
+ return failure();
913
+ }
914
+ const query = bearerAuthProvider._refreshQuery();
915
+ if (!query)
916
+ return failure();
917
+ query.state$
918
+ .pipe(takeUntilResponse(), takeUntil(this._onAbort$), tap((state) => isQueryStateSuccess(state) ? this.execute(Object.assign(Object.assign({}, options), { _isUnauthorizedRetry: true })) : failure()))
919
+ .subscribe();
920
+ break;
921
+ }
922
+ case 'cancel': {
923
+ this._state$.next({
924
+ type: "CANCELLED" /* QueryStateType.Cancelled */,
925
+ meta,
926
+ });
927
+ break;
928
+ }
929
+ }
930
+ }
931
+ _transformState(s) {
932
+ var _a;
933
+ if (!isQueryStateSuccess(s) || !((_a = this._queryConfig.entity) === null || _a === void 0 ? void 0 : _a.get)) {
934
+ return of(s);
935
+ }
936
+ const id = this._queryConfig.entity.id({ args: this._args, response: s.response });
937
+ return this._queryConfig.entity
938
+ .get({ args: this._args, id, response: s.response, store: this._queryConfig.entity.store })
939
+ .pipe(map((v) => (Object.assign(Object.assign({}, s), { response: v }))));
940
+ }
1030
941
  }
1031
942
 
1032
943
  const isBasicAuthProvider = (authProvider) => authProvider instanceof BasicAuthProvider;
@@ -1159,7 +1070,7 @@ class BearerAuthProvider {
1159
1070
  */
1160
1071
  _refreshQuery() {
1161
1072
  var _a, _b, _c, _d;
1162
- if (isQueryStateLoading((_a = this._currentRefreshQuery$.getValue()) === null || _a === void 0 ? void 0 : _a.state)) {
1073
+ if (isQueryStateLoading((_a = this._currentRefreshQuery$.getValue()) === null || _a === void 0 ? void 0 : _a.rawState)) {
1163
1074
  return;
1164
1075
  }
1165
1076
  const currentRefreshToken = this.tokens.refreshToken;
@@ -1229,8 +1140,7 @@ class QueryDirective {
1229
1140
  this._subscription = null;
1230
1141
  this._viewContext = {
1231
1142
  $implicit: null,
1232
- query: null,
1233
- raw: null,
1143
+ etQuery: null,
1234
1144
  loading: false,
1235
1145
  error: null,
1236
1146
  progress: null,
@@ -1269,14 +1179,12 @@ class QueryDirective {
1269
1179
  this._viewContext.progress = null;
1270
1180
  }
1271
1181
  if (isQueryStateSuccess(state)) {
1272
- this._viewContext.query = state.response;
1182
+ this._viewContext.etQuery = state.response;
1273
1183
  this._viewContext.$implicit = state.response;
1274
- this._viewContext.raw = state.rawResponse;
1275
1184
  }
1276
1185
  else if (!this.cache) {
1277
- this._viewContext.query = null;
1186
+ this._viewContext.etQuery = null;
1278
1187
  this._viewContext.$implicit = null;
1279
- this._viewContext.raw = null;
1280
1188
  }
1281
1189
  if (isQueryStateFailure(state)) {
1282
1190
  this._viewContext.error = state.error;
@@ -1295,22 +1203,22 @@ class QueryDirective {
1295
1203
  }
1296
1204
  }
1297
1205
  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 });
1298
- QueryDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.2.5", type: QueryDirective, isStandalone: true, selector: "[query]", inputs: { query: "query", cache: ["queryCache", "cache"] }, ngImport: i0 });
1206
+ 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 });
1299
1207
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.5", ngImport: i0, type: QueryDirective, decorators: [{
1300
1208
  type: Directive,
1301
1209
  args: [{
1302
1210
  // eslint-disable-next-line @angular-eslint/directive-selector
1303
- selector: '[query]',
1211
+ selector: '[etQuery]',
1304
1212
  standalone: true,
1305
1213
  }]
1306
1214
  }], ctorParameters: function () { return [{ type: i0.TemplateRef }, { type: i0.ViewContainerRef }, { type: i0.ErrorHandler }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { query: [{
1307
- type: Input
1215
+ type: Input,
1216
+ args: ['etQuery']
1308
1217
  }], cache: [{
1309
1218
  type: Input,
1310
- args: ['queryCache']
1219
+ args: ['etQueryCache']
1311
1220
  }] } });
1312
1221
 
1313
- /* eslint-disable @typescript-eslint/no-explicit-any */
1314
1222
  class InfinityQuery {
1315
1223
  get currentPage$() {
1316
1224
  return this._currentPage$.asObservable();
@@ -1336,29 +1244,59 @@ class InfinityQuery {
1336
1244
  get itemsPerPage() {
1337
1245
  return this._itemsPerPage$.getValue();
1338
1246
  }
1339
- get currentQuery$() {
1340
- return this._currentQuery$.asObservable();
1341
- }
1342
- get currentQuery() {
1343
- return this._currentQuery$.getValue();
1344
- }
1345
1247
  get data$() {
1346
- return this._data$.asObservable();
1248
+ return this._data$;
1347
1249
  }
1348
- get data() {
1349
- return this._data$.getValue();
1250
+ get currentQuery$() {
1251
+ return this._lastQuery$;
1350
1252
  }
1351
1253
  constructor(_config) {
1352
1254
  var _a, _b;
1353
1255
  this._config = _config;
1256
+ this._queries$ = new BehaviorSubject([]);
1354
1257
  this._currentPage$ = new BehaviorSubject(null);
1355
1258
  this._currentCalculatedPage$ = new BehaviorSubject(null);
1356
1259
  this._totalPages$ = new BehaviorSubject(null);
1357
1260
  this._itemsPerPage$ = new BehaviorSubject((_b = (_a = this._config.limitParam) === null || _a === void 0 ? void 0 : _a.value) !== null && _b !== void 0 ? _b : 10);
1358
- this._currentQuery$ = new BehaviorSubject(null);
1359
- this._data$ = new BehaviorSubject([]);
1360
- this._subscriptions = [];
1361
- this._responsiveDataSubscription = null;
1261
+ this._data$ = this._queries$.pipe(switchMap((queries) => {
1262
+ if (!queries.length) {
1263
+ return of([]);
1264
+ }
1265
+ return combineLatest(queries.map((query) => query.state$));
1266
+ }), tap((states) => {
1267
+ var _a, _b, _c, _d, _e;
1268
+ const lastState = states[states.length - 1];
1269
+ if (!isQueryStateSuccess(lastState)) {
1270
+ return;
1271
+ }
1272
+ const totalPages = (_e = (_c = (_b = (_a = this._config.response).totalPagesExtractor) === null || _b === void 0 ? void 0 : _b.call(_a, {
1273
+ response: lastState.response,
1274
+ itemsPerPage: this.itemsPerPage,
1275
+ })) !== null && _c !== void 0 ? _c :
1276
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
1277
+ (_d = lastState.response) === null || _d === void 0 ? void 0 : _d.totalPages) !== null && _e !== void 0 ? _e : null;
1278
+ this._totalPages$.next(totalPages);
1279
+ }), map((states) => {
1280
+ const fullData = states.reduce((acc, state) => {
1281
+ var _a;
1282
+ if (isQueryStateSuccess(state)) {
1283
+ let data = (_a = this._config) === null || _a === void 0 ? void 0 : _a.response.valueExtractor(state.response);
1284
+ if (this._config.response.reverse) {
1285
+ data = [...data].reverse();
1286
+ }
1287
+ if (this._config.response.appendItemsTo === 'start') {
1288
+ acc.unshift(...data);
1289
+ }
1290
+ else {
1291
+ acc.push(...data);
1292
+ }
1293
+ }
1294
+ return acc;
1295
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
1296
+ }, []);
1297
+ return fullData;
1298
+ }), shareReplay({ bufferSize: 1, refCount: true }));
1299
+ this._lastQuery$ = this._queries$.pipe(map((queries) => { var _a; return (_a = queries[queries.length - 1]) !== null && _a !== void 0 ? _a : null; }), shareReplay({ bufferSize: 1, refCount: true }));
1362
1300
  }
1363
1301
  nextPage() {
1364
1302
  var _a, _b, _c, _d, _e;
@@ -1372,74 +1310,22 @@ class InfinityQuery {
1372
1310
  console.error('Cannot load more pages, already at the end. Make sure to not render the infinity query trigger using *ngIf canLoadMore');
1373
1311
  return;
1374
1312
  }
1375
- this._clearSubscriptions();
1376
1313
  const args = this._prepareArgs(this._config, calculatedPage);
1377
1314
  const query = this._config.queryCreator.prepare(args).execute();
1378
- this._handleNewQuery(query);
1315
+ this._queries$.next([...this._queries$.value, query]);
1379
1316
  this._currentPage$.next(newPage);
1380
1317
  this._currentCalculatedPage$.next(calculatedPage);
1381
- this._currentQuery$.next(query);
1382
1318
  }
1383
1319
  reset(newConfig) {
1384
1320
  var _a, _b;
1385
- this._clearSubscriptions();
1386
1321
  this._config = Object.assign(Object.assign({}, this._config), (newConfig !== null && newConfig !== void 0 ? newConfig : {}));
1387
1322
  this._currentPage$.next(null);
1388
1323
  this._currentCalculatedPage$.next(null);
1389
1324
  this._totalPages$.next(null);
1390
1325
  this._itemsPerPage$.next((_b = (_a = this._config.limitParam) === null || _a === void 0 ? void 0 : _a.value) !== null && _b !== void 0 ? _b : 10);
1391
- this._currentQuery$.next(null);
1392
- this._data$.next([]);
1326
+ this._queries$.next([]);
1393
1327
  this.nextPage();
1394
1328
  }
1395
- /**
1396
- * @internal
1397
- */
1398
- _clearSubscriptions() {
1399
- var _a;
1400
- this._subscriptions.forEach((sub) => sub.unsubscribe());
1401
- this._subscriptions = [];
1402
- (_a = this._responsiveDataSubscription) === null || _a === void 0 ? void 0 : _a.unsubscribe();
1403
- }
1404
- _handleNewQuery(query) {
1405
- const stateChangesSub = query.state$.pipe(takeUntilResponse(), filterSuccess()).subscribe({
1406
- next: (state) => {
1407
- var _a, _b, _c, _d, _e, _f, _g;
1408
- let newData = (_a = this._config) === null || _a === void 0 ? void 0 : _a.response.valueExtractor(state.response);
1409
- if (this._config.response.reverse) {
1410
- newData = [...newData].reverse();
1411
- }
1412
- if (this._config.response.appendItemsTo === 'start') {
1413
- newData = [...newData, ...this.data];
1414
- }
1415
- else {
1416
- newData = [...this.data, ...newData];
1417
- }
1418
- if (query.store) {
1419
- (_b = this._responsiveDataSubscription) === null || _b === void 0 ? void 0 : _b.unsubscribe();
1420
- const key = query.store.idKey;
1421
- const responsiveData = query.store.entities$.pipe(map((entities) => newData.map((item) => {
1422
- // TODO(TRB): This is kind of unsafe. The entity array keys might not be the same as the response keys
1423
- const index = entities.values.findIndex((entity) => entity[key] === item[key]);
1424
- return index > -1 ? entities.values[index] : item;
1425
- })));
1426
- this._responsiveDataSubscription = responsiveData.subscribe((data) => this._data$.next(data));
1427
- }
1428
- else {
1429
- this._data$.next(newData);
1430
- }
1431
- const totalPages = (_g = (_e = (_d = (_c = this._config.response).totalPagesExtractor) === null || _d === void 0 ? void 0 : _d.call(_c, {
1432
- response: state.response,
1433
- itemsPerPage: this.itemsPerPage,
1434
- })) !== null && _e !== void 0 ? _e : (_f = state.response) === null || _f === void 0 ? void 0 : _f.totalPages) !== null && _g !== void 0 ? _g : null;
1435
- this._totalPages$.next(totalPages);
1436
- },
1437
- complete: () => {
1438
- this._subscriptions = this._subscriptions.filter((sub) => sub !== stateChangesSub);
1439
- },
1440
- });
1441
- this._subscriptions.push(stateChangesSub);
1442
- }
1443
1329
  _prepareArgs(config, page) {
1444
1330
  var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q;
1445
1331
  const pageParamLocation = this._getPageParamLocation((_a = config === null || config === void 0 ? void 0 : config.pageParam) === null || _a === void 0 ? void 0 : _a.location);
@@ -1488,7 +1374,7 @@ class InfinityQueryDirective {
1488
1374
  this._queryConfigChanged$ = new Subject();
1489
1375
  this._viewContext = {
1490
1376
  $implicit: null,
1491
- infinityQuery: null,
1377
+ etInfinityQuery: null,
1492
1378
  loading: false,
1493
1379
  error: null,
1494
1380
  isFirstLoad: false,
@@ -1497,6 +1383,7 @@ class InfinityQueryDirective {
1497
1383
  currentCalculatedPage: null,
1498
1384
  totalPages: null,
1499
1385
  itemsPerPage: null,
1386
+ currentQuery: null,
1500
1387
  };
1501
1388
  this._infinityQueryInstance = null;
1502
1389
  this._destroy$ = inject(DestroyService, { host: true }).destroy$;
@@ -1536,28 +1423,25 @@ class InfinityQueryDirective {
1536
1423
  ngOnInit() {
1537
1424
  this._renderMainView();
1538
1425
  }
1539
- ngOnDestroy() {
1540
- var _a;
1541
- (_a = this.instance) === null || _a === void 0 ? void 0 : _a._clearSubscriptions();
1542
- }
1543
1426
  _setupInfinityQuery(config) {
1544
1427
  const instance = new InfinityQuery(config);
1545
1428
  combineLatest([
1546
- instance.currentQuery$.pipe(switchQueryState()),
1429
+ instance.currentQuery$.pipe(switchQueryState(), withLatestFrom(instance.currentQuery$)),
1547
1430
  this._delayable.isDelayed$,
1548
1431
  this._didReceiveFirstData$,
1549
1432
  ])
1550
- .pipe(tap(([state, isDelayed, didReceiveFirstData]) => {
1433
+ .pipe(tap(([[state, currentQuery], isDelayed, didReceiveFirstData]) => {
1551
1434
  this._viewContext.currentPage = instance.currentPage;
1552
1435
  this._viewContext.totalPages = instance.totalPages;
1553
1436
  this._viewContext.itemsPerPage = instance.itemsPerPage;
1554
1437
  this._viewContext.canLoadMore =
1555
1438
  (instance.totalPages && instance.currentPage && instance.totalPages > instance.currentPage) || false;
1556
1439
  this._viewContext.currentCalculatedPage = instance.currentCalculatedPage;
1440
+ this._viewContext.currentQuery = currentQuery;
1557
1441
  if (isQueryStateLoading(state) || isDelayed || (!didReceiveFirstData && isQueryStateSuccess(state))) {
1558
1442
  this._viewContext.loading = true;
1559
1443
  this._viewContext.error = null;
1560
- this._viewContext.isFirstLoad = this.context.infinityQuery === null;
1444
+ this._viewContext.isFirstLoad = this.context.etInfinityQuery === null;
1561
1445
  }
1562
1446
  else if (isQueryStateFailure(state)) {
1563
1447
  this._viewContext.loading = false;
@@ -1573,13 +1457,14 @@ class InfinityQueryDirective {
1573
1457
  else {
1574
1458
  this._viewContext.loading = false;
1575
1459
  this._viewContext.error = null;
1576
- this._viewContext.infinityQuery = null;
1460
+ this._viewContext.etInfinityQuery = null;
1577
1461
  this._viewContext.$implicit = null;
1578
1462
  this._viewContext.isFirstLoad = false;
1579
1463
  this._viewContext.canLoadMore = false;
1580
1464
  this._viewContext.currentPage = null;
1581
1465
  this._viewContext.itemsPerPage = null;
1582
1466
  this._viewContext.totalPages = null;
1467
+ this._viewContext.currentQuery = null;
1583
1468
  this._data$.next([]);
1584
1469
  }
1585
1470
  this._cdr.markForCheck();
@@ -1587,7 +1472,7 @@ class InfinityQueryDirective {
1587
1472
  .subscribe();
1588
1473
  instance.data$
1589
1474
  .pipe(skip(1), tap((data) => {
1590
- this._viewContext.infinityQuery = this._viewContext.$implicit = data;
1475
+ this._viewContext.etInfinityQuery = this._viewContext.$implicit = data;
1591
1476
  this._data$.next(data);
1592
1477
  if (!this._didReceiveFirstData$.getValue()) {
1593
1478
  this._didReceiveFirstData$.next(true);
@@ -1597,13 +1482,6 @@ class InfinityQueryDirective {
1597
1482
  .subscribe();
1598
1483
  return instance;
1599
1484
  }
1600
- /**
1601
- * @deprecated Use `loadNextPage` instead
1602
- * @breaking 3.0.0
1603
- */
1604
- _loadNextPage() {
1605
- this.loadNextPage();
1606
- }
1607
1485
  loadNextPage() {
1608
1486
  if (!this._infinityQueryInstance) {
1609
1487
  return;
@@ -1626,35 +1504,35 @@ class InfinityQueryDirective {
1626
1504
  }
1627
1505
  }
1628
1506
  _cleanup() {
1629
- var _a;
1630
1507
  this._queryConfigChanged$.next(true);
1631
- (_a = this.instance) === null || _a === void 0 ? void 0 : _a._clearSubscriptions();
1632
1508
  this._viewContext.loading = false;
1633
1509
  this._viewContext.error = null;
1634
- this._viewContext.infinityQuery = null;
1510
+ this._viewContext.etInfinityQuery = null;
1635
1511
  this._viewContext.$implicit = null;
1636
1512
  this._viewContext.isFirstLoad = false;
1637
1513
  this._viewContext.canLoadMore = false;
1638
1514
  this._viewContext.currentPage = null;
1639
1515
  this._viewContext.itemsPerPage = null;
1640
1516
  this._viewContext.totalPages = null;
1517
+ this._viewContext.currentQuery = null;
1641
1518
  this._data$.next([]);
1642
1519
  }
1643
1520
  }
1644
1521
  InfinityQueryDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.5", ngImport: i0, type: InfinityQueryDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
1645
- 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 });
1522
+ 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 });
1646
1523
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.5", ngImport: i0, type: InfinityQueryDirective, decorators: [{
1647
1524
  type: Directive,
1648
1525
  args: [{
1649
1526
  // eslint-disable-next-line @angular-eslint/directive-selector
1650
- selector: '[infinityQuery]',
1651
- exportAs: 'infinityQuery',
1527
+ selector: '[etInfinityQuery]',
1528
+ exportAs: 'etInfinityQuery',
1652
1529
  standalone: true,
1653
1530
  providers: [{ provide: INFINITY_QUERY_TOKEN, useExisting: InfinityQueryDirective }, DestroyService],
1654
1531
  hostDirectives: [DelayableDirective],
1655
1532
  }]
1656
1533
  }], propDecorators: { infinityQuery: [{
1657
- type: Input
1534
+ type: Input,
1535
+ args: ['etInfinityQuery']
1658
1536
  }] } });
1659
1537
 
1660
1538
  class InfinityQueryTriggerDirective {
@@ -1667,7 +1545,7 @@ class InfinityQueryTriggerDirective {
1667
1545
  this.scrollContainerSelector = null;
1668
1546
  }
1669
1547
  ngOnInit() {
1670
- const isInteractive = this._elementRef.nativeElement.hasAttribute('infinityQueryTrigger');
1548
+ const isInteractive = this._elementRef.nativeElement.hasAttribute('etInfinityQueryTrigger');
1671
1549
  if (isInteractive) {
1672
1550
  this.click$.pipe(takeUntil(this._destroy)).subscribe(() => this._infinityQuery.loadNextPage());
1673
1551
  }
@@ -1696,155 +1574,144 @@ class InfinityQueryTriggerDirective {
1696
1574
  }
1697
1575
  }
1698
1576
  InfinityQueryTriggerDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.5", ngImport: i0, type: InfinityQueryTriggerDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
1699
- InfinityQueryTriggerDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.2.5", type: InfinityQueryTriggerDirective, isStandalone: true, selector: "[infinityQueryTrigger], infinity-query-trigger", inputs: { scrollContainerSelector: "scrollContainerSelector" }, ngImport: i0 });
1577
+ 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 });
1700
1578
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.5", ngImport: i0, type: InfinityQueryTriggerDirective, decorators: [{
1701
1579
  type: Directive,
1702
1580
  args: [{
1703
1581
  // eslint-disable-next-line @angular-eslint/directive-selector
1704
- selector: '[infinityQueryTrigger], infinity-query-trigger',
1582
+ selector: '[etInfinityQueryTrigger], et-infinity-query-trigger',
1705
1583
  standalone: true,
1706
1584
  }]
1707
1585
  }], propDecorators: { scrollContainerSelector: [{
1708
1586
  type: Input
1709
1587
  }] } });
1710
1588
 
1711
- class EntityStore {
1712
- get events$() {
1713
- return this._events$.asObservable();
1714
- }
1715
- get keys() {
1716
- return [...this._keys];
1717
- }
1718
- get values() {
1719
- return [...this._dictionary.values()];
1720
- }
1721
- get size() {
1722
- return this._keys.size;
1723
- }
1724
- get isEmpty() {
1725
- return this.size === 0;
1726
- }
1727
- get config() {
1728
- return this._config;
1729
- }
1730
- get idKey() {
1731
- return this._config.idKey || 'id';
1589
+ class EntityStoreError extends Error {
1590
+ constructor(message, detail) {
1591
+ super(message);
1592
+ this.detail = detail;
1593
+ this.name = 'EntityStoreError';
1732
1594
  }
1595
+ }
1596
+ class EntityStore {
1733
1597
  constructor(_config) {
1734
1598
  this._config = _config;
1735
1599
  this._dictionary = new Map();
1736
- this._keys = new Set();
1737
- this._events$ = new Subject();
1738
- this.entities$ = this.events$.pipe(startWith(null), debounceTime(0), map(() => ({
1739
- keys: this.keys,
1740
- values: this.values,
1741
- })));
1742
- }
1743
- getOne(key) {
1744
- const value = this._dictionary.get(key);
1745
- if (!value) {
1746
- console.error(`EntityStore: ${this._config.name || 'unknown'}: missing key "${key}" for get`);
1747
- return null;
1748
- }
1749
- if (this._config.logActions) {
1750
- console.log(`EntityStore: ${this._config.name || 'unknown'}: get "${key}"`);
1751
- }
1752
- return value;
1600
+ this._change$ = new Subject();
1753
1601
  }
1754
- getMany(keys) {
1755
- return keys.map((key) => this.getOne(key));
1602
+ select(keyOrKeys) {
1603
+ if (Array.isArray(keyOrKeys)) {
1604
+ return this._selectMany(keyOrKeys);
1605
+ }
1606
+ return this._select(keyOrKeys);
1756
1607
  }
1757
- addOne(value) {
1758
- const key = this.getKey(value);
1759
- if (this._dictionary.has(key)) {
1760
- console.error(`EntityStore: ${this._config.name || 'unknown'}: duplicate key "${key}" for add`);
1761
- return null;
1608
+ set(keyOrKeys, valueOrValues) {
1609
+ if (Array.isArray(keyOrKeys)) {
1610
+ if (!Array.isArray(valueOrValues)) {
1611
+ throw new EntityStoreError('When setting multiple keys, values must be an array', {
1612
+ keyOrValues: keyOrKeys,
1613
+ valueOrValues,
1614
+ });
1615
+ }
1616
+ for (let i = 0; i < keyOrKeys.length; i++) {
1617
+ this._set(keyOrKeys[i], valueOrValues[i]);
1618
+ }
1762
1619
  }
1763
- this._dictionary.set(key, value);
1764
- this._keys.add(key);
1765
- const event = { type: 'add', key };
1766
- this._events$.next(event);
1767
- if (this._config.logActions) {
1768
- console.log(`EntityStore: ${this._config.name || 'unknown'}: add "${key}"`);
1620
+ else {
1621
+ this._set(keyOrKeys, valueOrValues);
1769
1622
  }
1770
- return event;
1623
+ this._change$.next(keyOrKeys);
1771
1624
  }
1772
- addMany(values) {
1773
- const events = values.map((value) => this.addOne(value));
1774
- return events;
1775
- }
1776
- updateOne(value) {
1777
- const key = this.getKey(value);
1778
- const existing = this._dictionary.get(key);
1779
- if (!existing) {
1780
- console.error(`EntityStore: ${this._config.name || 'unknown'}: missing key "${key}" for update`);
1781
- return null;
1625
+ remove(keyOrKeys) {
1626
+ if (Array.isArray(keyOrKeys)) {
1627
+ for (const key of keyOrKeys) {
1628
+ this._remove(key);
1629
+ }
1782
1630
  }
1783
- this._dictionary.set(key, value);
1784
- const event = { type: 'update', key };
1785
- this._events$.next(event);
1786
- if (this._config.logActions) {
1787
- console.log(`EntityStore: ${this._config.name || 'unknown'}: update "${key}"`);
1631
+ else {
1632
+ this._remove(keyOrKeys);
1788
1633
  }
1789
- return event;
1634
+ this._change$.next(keyOrKeys);
1790
1635
  }
1791
- updateMany(values) {
1792
- const events = values.map((value) => this.updateOne(value));
1793
- return events;
1636
+ logState() {
1637
+ console.log('EntityStore:', this._config.name, {
1638
+ dictionary: this._dictionary,
1639
+ });
1794
1640
  }
1795
- setOne(value) {
1796
- const key = this.getKey(value);
1797
- this._dictionary.set(key, value);
1798
- this._keys.add(key);
1799
- const event = { type: 'set', key };
1800
- this._events$.next(event);
1641
+ _select(key) {
1801
1642
  if (this._config.logActions) {
1802
- console.log(`EntityStore: ${this._config.name || 'unknown'}: set "${key}"`);
1643
+ console.log('EntityStore: select', this._config.name, key);
1803
1644
  }
1804
- return event;
1805
- }
1806
- setMany(values) {
1807
- const events = values.map((value) => this.setOne(value));
1808
- return events;
1645
+ return this._change$.pipe(startWith(null), filter((v) => {
1646
+ if (v === null) {
1647
+ return true;
1648
+ }
1649
+ if (Array.isArray(v)) {
1650
+ return v.includes(key);
1651
+ }
1652
+ return v === key;
1653
+ }), map(() => { var _a; return (_a = this._dictionary.get(key)) !== null && _a !== void 0 ? _a : null; }));
1809
1654
  }
1810
- removeOne(key) {
1811
- if (!this._dictionary.has(key)) {
1812
- console.error(`EntityStore: ${this._config.name || 'unknown'}: missing key "${key}" for remove`);
1813
- return null;
1814
- }
1815
- this._dictionary.delete(key);
1816
- this._keys.delete(key);
1817
- const event = { type: 'remove', key };
1818
- this._events$.next(event);
1655
+ _selectMany(keys) {
1819
1656
  if (this._config.logActions) {
1820
- console.log(`EntityStore: ${this._config.name || 'unknown'}: remove "${key}"`);
1657
+ console.log('EntityStore: selectMany', this._config.name, keys);
1821
1658
  }
1822
- return event;
1823
- }
1824
- removeMany(keys) {
1825
- const events = keys.map((key) => this.removeOne(key));
1826
- return events;
1827
- }
1828
- has(key) {
1829
- return this._dictionary.has(key);
1659
+ return this._change$.pipe(startWith(null), filter((v) => {
1660
+ if (v === null) {
1661
+ return true;
1662
+ }
1663
+ if (Array.isArray(v)) {
1664
+ return keys.some((key) => v.includes(key));
1665
+ }
1666
+ return keys.includes(v);
1667
+ }), map(() => keys.map((key) => this._dictionary.get(key)).filter((value) => value !== undefined)));
1830
1668
  }
1831
- clear() {
1832
- this._dictionary.clear();
1833
- this._keys.clear();
1669
+ _set(key, value) {
1670
+ if (this._config.logActions) {
1671
+ console.log('EntityStore: set', this._config.name, key, value);
1672
+ }
1673
+ this._dictionary.set(key, value);
1834
1674
  }
1835
- getKey(value) {
1836
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
1837
- const key = value[this._config.idKey || 'id'];
1838
- if (key === undefined) {
1839
- throw new Error(`EntityStore: ${this._config.name || 'unknown'}: missing key`);
1675
+ _remove(key) {
1676
+ if (this._config.logActions) {
1677
+ console.log('EntityStore: remove', this._config.name, key);
1840
1678
  }
1841
- return key;
1679
+ this._dictionary.delete(key);
1842
1680
  }
1843
- logState() {
1844
- console.log('EntityStore:', this._config.name, {
1845
- dictionary: this._dictionary,
1846
- keys: this._keys,
1847
- });
1681
+ }
1682
+
1683
+ function mapToPaginated(response) {
1684
+ return map((items) => (Object.assign(Object.assign({}, response), { items })));
1685
+ }
1686
+
1687
+ class QueryCreator {
1688
+ constructor(_queryConfig, _client, _store) {
1689
+ this._queryConfig = _queryConfig;
1690
+ this._client = _client;
1691
+ this._store = _store;
1692
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
1693
+ // @ts-ignore
1694
+ this.prepare = (args) => {
1695
+ const route = buildRoute({
1696
+ base: this._client.config.baseRoute,
1697
+ route: this._queryConfig.route,
1698
+ pathParams: args === null || args === void 0 ? void 0 : args.pathParams,
1699
+ queryParams: computeQueryQueryParams({ config: this._queryConfig, client: this._client, args }),
1700
+ });
1701
+ const cacheKey = isGqlQueryConfig(this._queryConfig) ? buildGqlCacheKey(this._queryConfig, args) : route;
1702
+ if (shouldCacheQuery(this._queryConfig.method)) {
1703
+ const existingQuery = this._store.get(cacheKey);
1704
+ if (existingQuery) {
1705
+ return existingQuery;
1706
+ }
1707
+ }
1708
+ const query = new Query(this._client, this._queryConfig, route, args !== null && args !== void 0 ? args : {});
1709
+ if (shouldCacheQuery(this._queryConfig.method)) {
1710
+ this._store.add(cacheKey, query);
1711
+ }
1712
+ return query;
1713
+ };
1714
+ this.behaviorSubject = (initialValue) => new BehaviorSubject(initialValue !== null && initialValue !== void 0 ? initialValue : null);
1848
1715
  }
1849
1716
  }
1850
1717
 
@@ -1984,20 +1851,6 @@ class QueryStore {
1984
1851
  }
1985
1852
  }
1986
1853
 
1987
- const shouldCacheQuery = (method) => {
1988
- return method === 'GET' || method === 'OPTIONS' || method === 'HEAD' || method === 'GQL_QUERY';
1989
- };
1990
- const buildGqlCacheKey = (config, args) => {
1991
- const { query } = config;
1992
- const variables = (args === null || args === void 0 ? void 0 : args.variables) || {};
1993
- const queryWithoutNewLinesAndWhitespace = query.replace(/\s/g, '');
1994
- const queryFirst50Chars = queryWithoutNewLinesAndWhitespace.slice(0, 50);
1995
- const queryMiddle25Chars = queryWithoutNewLinesAndWhitespace.slice(queryWithoutNewLinesAndWhitespace.length / 2 - 25, queryWithoutNewLinesAndWhitespace.length / 2 + 25);
1996
- const queryLast50Chars = queryWithoutNewLinesAndWhitespace.slice(-50);
1997
- const vars = JSON.stringify(variables);
1998
- return `${queryFirst50Chars}...${queryMiddle25Chars}...${queryLast50Chars}...${vars}`;
1999
- };
2000
-
2001
1854
  class QueryClient {
2002
1855
  get config() {
2003
1856
  return this._clientConfig;
@@ -2021,33 +1874,7 @@ class QueryClient {
2021
1874
  this.delete = (queryConfig) => this.fetch(Object.assign(Object.assign({}, queryConfig), { method: 'DELETE' }));
2022
1875
  this.gqlQuery = (queryConfig) => this.fetch(Object.assign(Object.assign({}, queryConfig), { method: 'GQL_QUERY' }));
2023
1876
  this.gqlMutate = (queryConfig) => this.fetch(Object.assign(Object.assign({}, queryConfig), { method: 'GQL_MUTATE' }));
2024
- this.fetch = (queryConfig) => {
2025
- const prepare = (args) => {
2026
- const route = buildRoute({
2027
- base: this._clientConfig.baseRoute,
2028
- route: queryConfig.route,
2029
- pathParams: args === null || args === void 0 ? void 0 : args.pathParams,
2030
- queryParams: computeQueryQueryParams({ config: queryConfig, client: this, args }),
2031
- });
2032
- const cacheKey = isGqlQueryConfig(queryConfig) ? buildGqlCacheKey(queryConfig, args) : route;
2033
- if (shouldCacheQuery(queryConfig.method)) {
2034
- const existingQuery = this._store.get(cacheKey);
2035
- if (existingQuery) {
2036
- return existingQuery;
2037
- }
2038
- }
2039
- const query = new Query(this, queryConfig, route, args !== null && args !== void 0 ? args : {});
2040
- if (shouldCacheQuery(queryConfig.method)) {
2041
- this._store.add(cacheKey, query);
2042
- }
2043
- return query;
2044
- };
2045
- const behaviorSubject = (initialValue = null) => new BehaviorSubject(initialValue);
2046
- return {
2047
- prepare,
2048
- behaviorSubject,
2049
- };
2050
- };
1877
+ this.fetch = (queryConfig) => new QueryCreator(queryConfig, this, this._store);
2051
1878
  this.setAuthProvider = (authProvider) => {
2052
1879
  if (this.authProvider) {
2053
1880
  throw new Error('The auth provider is already set. Please call clearAuthProvider() first.');
@@ -2082,6 +1909,20 @@ class QueryClient {
2082
1909
  }
2083
1910
  }
2084
1911
 
1912
+ const shouldCacheQuery = (method) => {
1913
+ return method === 'GET' || method === 'OPTIONS' || method === 'HEAD' || method === 'GQL_QUERY';
1914
+ };
1915
+ const buildGqlCacheKey = (config, args) => {
1916
+ const { query } = config;
1917
+ const variables = (args === null || args === void 0 ? void 0 : args.variables) || {};
1918
+ const queryWithoutNewLinesAndWhitespace = query.replace(/\s/g, '');
1919
+ const queryFirst50Chars = queryWithoutNewLinesAndWhitespace.slice(0, 50);
1920
+ const queryMiddle25Chars = queryWithoutNewLinesAndWhitespace.slice(queryWithoutNewLinesAndWhitespace.length / 2 - 25, queryWithoutNewLinesAndWhitespace.length / 2 + 25);
1921
+ const queryLast50Chars = queryWithoutNewLinesAndWhitespace.slice(-50);
1922
+ const vars = JSON.stringify(variables);
1923
+ return `${queryFirst50Chars}...${queryMiddle25Chars}...${queryLast50Chars}...${vars}`;
1924
+ };
1925
+
2085
1926
  class QueryField {
2086
1927
  get control() {
2087
1928
  return this.data.control;
@@ -2328,5 +2169,5 @@ const def = () => null;
2328
2169
  * Generated bundle index. Do not edit.
2329
2170
  */
2330
2171
 
2331
- 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, isFetchResponse, isGqlQueryConfig, isParamValid, isQuery, isQueryStateCancelled, isQueryStateFailure, isQueryStateLoading, isQueryStatePrepared, isQueryStateSuccess, isRequestError, 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 };
2172
+ 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 };
2332
2173
  //# sourceMappingURL=ethlete-query.mjs.map