@ethlete/query 5.22.0 → 5.24.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +16 -0
- package/fesm2022/ethlete-query.mjs +1090 -680
- package/fesm2022/ethlete-query.mjs.map +1 -1
- package/lib/experimental/{bearer-auth-provider-config.d.ts → auth/bearer-auth-provider-config.d.ts} +1 -3
- package/lib/experimental/{bearer-auth-provider.d.ts → auth/bearer-auth-provider.d.ts} +1 -1
- package/lib/experimental/auth/index.d.ts +2 -0
- package/lib/experimental/gql/gql-query-creator-templates.d.ts +11 -0
- package/lib/experimental/gql/gql-query-creator.d.ts +14 -0
- package/lib/experimental/gql/gql-query-execute.d.ts +11 -0
- package/lib/experimental/gql/gql-query.d.ts +12 -0
- package/lib/experimental/gql/index.d.ts +4 -0
- package/lib/experimental/{http-request.d.ts → http/http-request.d.ts} +1 -1
- package/lib/experimental/http/index.d.ts +20 -0
- package/lib/experimental/http/paged-query-stack.d.ts +149 -0
- package/lib/experimental/http/query-client-config.d.ts +45 -0
- package/lib/experimental/{query-creator-templates.d.ts → http/query-creator-templates.d.ts} +11 -1
- package/lib/experimental/http/query-creator.d.ts +73 -0
- package/lib/experimental/{query-dependencies.d.ts → http/query-dependencies.d.ts} +5 -0
- package/lib/experimental/http/query-errors.d.ts +50 -0
- package/lib/experimental/{query-execute-utils.d.ts → http/query-execute-utils.d.ts} +16 -3
- package/lib/experimental/{query-execute.d.ts → http/query-execute.d.ts} +5 -3
- package/lib/experimental/http/query-features.d.ts +85 -0
- package/lib/experimental/{query-repository.d.ts → http/query-repository.d.ts} +3 -1
- package/lib/experimental/{query-snapshot.d.ts → http/query-snapshot.d.ts} +2 -2
- package/lib/experimental/http/query-stack.d.ts +101 -0
- package/lib/experimental/http/query-utils.d.ts +59 -0
- package/lib/experimental/{query.d.ts → http/query.d.ts} +24 -2
- package/lib/experimental/{secure-query-creator.d.ts → http/secure-query-creator.d.ts} +1 -1
- package/lib/experimental/{secure-query-execute.d.ts → http/secure-query-execute.d.ts} +2 -2
- package/lib/experimental/index.d.ts +4 -22
- package/lib/experimental/ws/index.d.ts +2 -0
- package/lib/experimental/ws/web-socket-client-config.d.ts +12 -0
- package/lib/experimental/ws/web-socket-client.d.ts +20 -0
- package/lib/experimental/ws/web-socket-errors.d.ts +9 -0
- package/lib/gql/gql.d.ts +3 -2
- package/lib/utils/data.utils.d.ts +5 -2
- package/package.json +8 -7
- package/lib/experimental/paged-query.d.ts +0 -35
- package/lib/experimental/query-client-config.d.ts +0 -18
- package/lib/experimental/query-creator.d.ts +0 -39
- package/lib/experimental/query-errors.d.ts +0 -49
- package/lib/experimental/query-features.d.ts +0 -48
- package/lib/experimental/query-stack.d.ts +0 -48
- package/lib/experimental/query-utils.d.ts +0 -49
- /package/lib/experimental/{query-client.d.ts → http/query-client.d.ts} +0 -0
- /package/lib/experimental/{query-state.d.ts → http/query-state.d.ts} +0 -0
- /package/lib/experimental/{secure-query.d.ts → http/secure-query.d.ts} +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as i1 from '@ethlete/core';
|
|
2
|
-
import { createDestroy, computedTillTruthy, getCookie, setCookie, deleteCookie, DelayableDirective, nextFrame, RuntimeError, isObject, getDomain,
|
|
3
|
-
import { Observable, takeUntil, startWith, pairwise, tap, switchMap, of, BehaviorSubject, Subject, fromEvent, timer, take, filter, takeWhile, map,
|
|
2
|
+
import { createDestroy, computedTillTruthy, syncSignal, getCookie, setCookie, deleteCookie, DelayableDirective, nextFrame, RuntimeError, isObject, getDomain, previousSignalValue, injectQueryParamChanges, injectQueryParams, clone, equal, ET_PROPERTY_REMOVED } from '@ethlete/core';
|
|
3
|
+
import { Observable, takeUntil, startWith, pairwise, tap, switchMap, of, BehaviorSubject, Subject, fromEvent, timer, take, filter, takeWhile, map, ReplaySubject, shareReplay, combineLatest, interval, skip, withLatestFrom, debounceTime, Subscription, retry, throwError, catchError, merge } from 'rxjs';
|
|
4
4
|
import * as i0 from '@angular/core';
|
|
5
5
|
import { assertInInjectionContext, inject, Injector, computed, signal, isDevMode, untracked, TemplateRef, ViewContainerRef, ErrorHandler, ChangeDetectorRef, Directive, Input, InjectionToken, ElementRef, Pipe, effect, Component, ChangeDetectionStrategy, ViewEncapsulation, runInInjectionContext, EnvironmentInjector, createEnvironmentInjector, DestroyRef, NgZone } from '@angular/core';
|
|
6
6
|
import { toSignal, toObservable, takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
|
@@ -8,9 +8,12 @@ import { AsyncPipe, JsonPipe, NgClass } from '@angular/common';
|
|
|
8
8
|
import * as i1$1 from '@angular/forms';
|
|
9
9
|
import { FormControl, ReactiveFormsModule, FormGroup } from '@angular/forms';
|
|
10
10
|
import { HttpErrorResponse, HttpStatusCode, HttpEventType, HttpClient, HttpHeaders } from '@angular/common/http';
|
|
11
|
+
import { getActiveConsumer, setActiveConsumer } from '@angular/core/primitives/signals';
|
|
12
|
+
import { io } from 'socket.io-client';
|
|
11
13
|
import { Router, ActivatedRoute } from '@angular/router';
|
|
12
14
|
|
|
13
15
|
class CustomHeaderAuthProvider {
|
|
16
|
+
_config;
|
|
14
17
|
get header() {
|
|
15
18
|
return { [this._config.name]: this._config.value };
|
|
16
19
|
}
|
|
@@ -23,6 +26,7 @@ class CustomHeaderAuthProvider {
|
|
|
23
26
|
}
|
|
24
27
|
|
|
25
28
|
class BasicAuthProvider {
|
|
29
|
+
_config;
|
|
26
30
|
get header() {
|
|
27
31
|
return { Authorization: `Basic ${this._basicAuthString}` };
|
|
28
32
|
}
|
|
@@ -39,6 +43,7 @@ class BasicAuthProvider {
|
|
|
39
43
|
|
|
40
44
|
const buildErrorMessage = (code, message) => `[@ethlete\\query:${code}] ${message}`;
|
|
41
45
|
class QueryError extends Error {
|
|
46
|
+
data;
|
|
42
47
|
constructor(code, message, data) {
|
|
43
48
|
super(buildErrorMessage(code, message));
|
|
44
49
|
this.name = 'QueryError';
|
|
@@ -630,7 +635,7 @@ function toQuerySubject(source, options) {
|
|
|
630
635
|
}
|
|
631
636
|
function queryStateSignal(source, options) {
|
|
632
637
|
const { cacheResponse } = options ?? {};
|
|
633
|
-
|
|
638
|
+
const roSignal = toSignal(toObservable(source).pipe(switchMap((q) => extractQuery(q)?.state$ ?? of(null)), switchMap((state) => {
|
|
634
639
|
if (cacheResponse) {
|
|
635
640
|
return of(state).pipe(filterQueryStates(["SUCCESS" /* QueryStateType.Success */, "FAILURE" /* QueryStateType.Failure */]));
|
|
636
641
|
}
|
|
@@ -638,13 +643,20 @@ function queryStateSignal(source, options) {
|
|
|
638
643
|
})), {
|
|
639
644
|
initialValue: null,
|
|
640
645
|
});
|
|
646
|
+
const rwSignal = signal(roSignal());
|
|
647
|
+
syncSignal(roSignal, rwSignal);
|
|
648
|
+
return rwSignal;
|
|
641
649
|
}
|
|
642
650
|
function queryStateResponseSignal(source, options) {
|
|
643
651
|
const s = queryStateSignal(source, options);
|
|
644
|
-
|
|
652
|
+
const dataSignal = computed(() => {
|
|
645
653
|
const state = s();
|
|
646
654
|
return isQueryStateSuccess(state) ? state.response : null;
|
|
647
655
|
});
|
|
656
|
+
dataSignal['reset'] = () => {
|
|
657
|
+
s.set(null);
|
|
658
|
+
};
|
|
659
|
+
return dataSignal;
|
|
648
660
|
}
|
|
649
661
|
function queryStateErrorSignal(source) {
|
|
650
662
|
const s = queryStateSignal(source);
|
|
@@ -687,67 +699,71 @@ const deepFreeze = (object) => {
|
|
|
687
699
|
const def = () => null;
|
|
688
700
|
|
|
689
701
|
class QueryCreator {
|
|
702
|
+
_queryConfig;
|
|
703
|
+
_client;
|
|
704
|
+
_store;
|
|
690
705
|
constructor(_queryConfig, _client, _store) {
|
|
691
706
|
this._queryConfig = _queryConfig;
|
|
692
707
|
this._client = _client;
|
|
693
708
|
this._store = _store;
|
|
694
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
695
|
-
// @ts-ignore
|
|
696
|
-
this.prepare = (args) => {
|
|
697
|
-
const route = buildRoute({
|
|
698
|
-
base: this._client.config.baseRoute,
|
|
699
|
-
route: this._queryConfig.route,
|
|
700
|
-
pathParams: args?.pathParams,
|
|
701
|
-
queryParams: computeQueryQueryParams({ config: this._queryConfig, client: this._client, args }),
|
|
702
|
-
queryParamConfig: this._client.config.request?.queryParams,
|
|
703
|
-
});
|
|
704
|
-
const cacheKey = (args?.config?.queryStoreCacheKey ?? '') + buildQueryCacheKey(route, args);
|
|
705
|
-
if (shouldCacheQuery(this._queryConfig.method) && !args?.config?.skipQueryStore) {
|
|
706
|
-
const existingQuery = this._store.get(cacheKey);
|
|
707
|
-
if (existingQuery) {
|
|
708
|
-
return existingQuery;
|
|
709
|
-
}
|
|
710
|
-
}
|
|
711
|
-
const query = new Query(this._client, this._queryConfig, route, args ?? {}, cacheKey);
|
|
712
|
-
if (shouldCacheQuery(this._queryConfig.method) && !args?.config?.skipQueryStore) {
|
|
713
|
-
this._store.add(cacheKey, query);
|
|
714
|
-
}
|
|
715
|
-
this._store._dispatchQueryCreated(query);
|
|
716
|
-
return query;
|
|
717
|
-
};
|
|
718
|
-
this.createSubject = (initialValue, config) => {
|
|
719
|
-
assertInInjectionContext(this.createSubject);
|
|
720
|
-
const subject = new BehaviorSubject(initialValue ?? null);
|
|
721
|
-
addQueryContainerHandling(subject, () => subject.getValue(), config);
|
|
722
|
-
return subject;
|
|
723
|
-
};
|
|
724
|
-
this.createSignal = (initialValue, config) => {
|
|
725
|
-
assertInInjectionContext(this.createSignal);
|
|
726
|
-
const _signal = signal(initialValue ?? null);
|
|
727
|
-
addQueryContainerHandling(toObservable(_signal), () => _signal(), config);
|
|
728
|
-
return _signal;
|
|
729
|
-
};
|
|
730
|
-
/**
|
|
731
|
-
* @deprecated Use `myQuery.createSubject()` or `myQuery.createSignal()` instead. Will be removed in v6.
|
|
732
|
-
*/
|
|
733
|
-
this.behaviorSubject = (initialValue) => new BehaviorSubject(initialValue ?? null);
|
|
734
709
|
}
|
|
710
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
711
|
+
// @ts-ignore
|
|
712
|
+
prepare = (args) => {
|
|
713
|
+
const route = buildRoute({
|
|
714
|
+
base: this._client.config.baseRoute,
|
|
715
|
+
route: this._queryConfig.route,
|
|
716
|
+
pathParams: args?.pathParams,
|
|
717
|
+
queryParams: computeQueryQueryParams({ config: this._queryConfig, client: this._client, args }),
|
|
718
|
+
queryParamConfig: this._client.config.request?.queryParams,
|
|
719
|
+
});
|
|
720
|
+
const cacheKey = (args?.config?.queryStoreCacheKey ?? '') + buildQueryCacheKey$1(route, args);
|
|
721
|
+
if (shouldCacheQuery$1(this._queryConfig.method) && !args?.config?.skipQueryStore) {
|
|
722
|
+
const existingQuery = this._store.get(cacheKey);
|
|
723
|
+
if (existingQuery) {
|
|
724
|
+
return existingQuery;
|
|
725
|
+
}
|
|
726
|
+
}
|
|
727
|
+
const query = new Query(this._client, this._queryConfig, route, args ?? {}, cacheKey);
|
|
728
|
+
if (shouldCacheQuery$1(this._queryConfig.method) && !args?.config?.skipQueryStore) {
|
|
729
|
+
this._store.add(cacheKey, query);
|
|
730
|
+
}
|
|
731
|
+
this._store._dispatchQueryCreated(query);
|
|
732
|
+
return query;
|
|
733
|
+
};
|
|
734
|
+
createSubject = (initialValue, config) => {
|
|
735
|
+
assertInInjectionContext(this.createSubject);
|
|
736
|
+
const subject = new BehaviorSubject(initialValue ?? null);
|
|
737
|
+
addQueryContainerHandling(subject, () => subject.getValue(), config);
|
|
738
|
+
return subject;
|
|
739
|
+
};
|
|
740
|
+
createSignal = (initialValue, config) => {
|
|
741
|
+
assertInInjectionContext(this.createSignal);
|
|
742
|
+
const _signal = signal(initialValue ?? null);
|
|
743
|
+
addQueryContainerHandling(toObservable(_signal), () => _signal(), config);
|
|
744
|
+
return _signal;
|
|
745
|
+
};
|
|
746
|
+
/**
|
|
747
|
+
* @deprecated Use `myQuery.createSubject()` or `myQuery.createSignal()` instead. Will be removed in v6.
|
|
748
|
+
*/
|
|
749
|
+
behaviorSubject = (initialValue) => new BehaviorSubject(initialValue ?? null);
|
|
735
750
|
}
|
|
736
751
|
|
|
737
752
|
class QueryStore {
|
|
753
|
+
_config;
|
|
754
|
+
/**
|
|
755
|
+
* @internal
|
|
756
|
+
*/
|
|
757
|
+
_store = new Map();
|
|
758
|
+
_garbageCollector = null;
|
|
759
|
+
_isInLowResourceMode = false;
|
|
760
|
+
_lastBlurTimestamp = Date.now();
|
|
761
|
+
_storeChange$ = new Subject();
|
|
762
|
+
_queryCreated$ = new Subject();
|
|
763
|
+
storeChange$ = this._storeChange$.asObservable();
|
|
764
|
+
queryCreated$ = this._queryCreated$.asObservable();
|
|
738
765
|
constructor(_config) {
|
|
739
766
|
this._config = _config;
|
|
740
|
-
/**
|
|
741
|
-
* @internal
|
|
742
|
-
*/
|
|
743
|
-
this._store = new Map();
|
|
744
|
-
this._garbageCollector = null;
|
|
745
|
-
this._isInLowResourceMode = false;
|
|
746
|
-
this._lastBlurTimestamp = Date.now();
|
|
747
|
-
this._storeChange$ = new Subject();
|
|
748
|
-
this._queryCreated$ = new Subject();
|
|
749
|
-
this.storeChange$ = this._storeChange$.asObservable();
|
|
750
|
-
this.queryCreated$ = this._queryCreated$.asObservable();
|
|
751
767
|
this._initSmartQueryHandling();
|
|
752
768
|
}
|
|
753
769
|
add(id, query) {
|
|
@@ -878,6 +894,11 @@ class QueryStore {
|
|
|
878
894
|
}
|
|
879
895
|
|
|
880
896
|
class QueryClient {
|
|
897
|
+
_clientConfig;
|
|
898
|
+
/**
|
|
899
|
+
* @internal
|
|
900
|
+
*/
|
|
901
|
+
_store;
|
|
881
902
|
get config() {
|
|
882
903
|
return this._clientConfig;
|
|
883
904
|
}
|
|
@@ -887,64 +908,9 @@ class QueryClient {
|
|
|
887
908
|
get authProvider$() {
|
|
888
909
|
return this._authProvider$.asObservable() ?? this._clientConfig.parent?._authProvider$.asObservable() ?? null;
|
|
889
910
|
}
|
|
911
|
+
_authProvider$ = new BehaviorSubject(null);
|
|
890
912
|
constructor(_clientConfig) {
|
|
891
913
|
this._clientConfig = _clientConfig;
|
|
892
|
-
this._authProvider$ = new BehaviorSubject(null);
|
|
893
|
-
this.get = (queryConfig) => this.fetch({
|
|
894
|
-
...queryConfig,
|
|
895
|
-
method: 'GET',
|
|
896
|
-
});
|
|
897
|
-
this.post = (queryConfig) => this.fetch({
|
|
898
|
-
...queryConfig,
|
|
899
|
-
method: 'POST',
|
|
900
|
-
});
|
|
901
|
-
this.put = (queryConfig) => this.fetch({
|
|
902
|
-
...queryConfig,
|
|
903
|
-
method: 'PUT',
|
|
904
|
-
});
|
|
905
|
-
this.patch = (queryConfig) => this.fetch({
|
|
906
|
-
...queryConfig,
|
|
907
|
-
method: 'PATCH',
|
|
908
|
-
});
|
|
909
|
-
this.delete = (queryConfig) => this.fetch({
|
|
910
|
-
...queryConfig,
|
|
911
|
-
method: 'DELETE',
|
|
912
|
-
});
|
|
913
|
-
this.gqlQuery = (queryConfig) => this.fetch({
|
|
914
|
-
...queryConfig,
|
|
915
|
-
method: 'GQL_QUERY',
|
|
916
|
-
});
|
|
917
|
-
this.gqlMutate = (queryConfig) => this.fetch({
|
|
918
|
-
...queryConfig,
|
|
919
|
-
method: 'GQL_MUTATE',
|
|
920
|
-
});
|
|
921
|
-
this.fetch = (queryConfig) => new QueryCreator(queryConfig, this, this._store);
|
|
922
|
-
this.setAuthProvider = (authProvider) => {
|
|
923
|
-
if (this.authProvider) {
|
|
924
|
-
this.authProvider?.cleanUp();
|
|
925
|
-
}
|
|
926
|
-
this._authProvider$.next(authProvider);
|
|
927
|
-
};
|
|
928
|
-
this.setDefaultHeaders = (config) => {
|
|
929
|
-
if (!this._clientConfig.request) {
|
|
930
|
-
this._clientConfig.request = {
|
|
931
|
-
headers: config.headers ?? undefined,
|
|
932
|
-
};
|
|
933
|
-
}
|
|
934
|
-
else {
|
|
935
|
-
this._clientConfig.request.headers = config.headers ?? undefined;
|
|
936
|
-
}
|
|
937
|
-
if (config.refreshQueriesInUse) {
|
|
938
|
-
this._store.refreshQueriesInUse({ purgeUnused: true, ignoreCacheValidity: true });
|
|
939
|
-
}
|
|
940
|
-
};
|
|
941
|
-
this.clearAuthProvider = () => {
|
|
942
|
-
this.authProvider?.cleanUp();
|
|
943
|
-
this._authProvider$.next(null);
|
|
944
|
-
};
|
|
945
|
-
this._updateBaseRoute = (route) => {
|
|
946
|
-
this._clientConfig.baseRoute = route;
|
|
947
|
-
};
|
|
948
914
|
this._store = new QueryStore({
|
|
949
915
|
enableChangeLogging: _clientConfig.logging?.queryStateChanges,
|
|
950
916
|
enableGarbageCollectorLogging: _clientConfig.logging?.queryStateGarbageCollector,
|
|
@@ -952,12 +918,67 @@ class QueryClient {
|
|
|
952
918
|
enableSmartPolling: _clientConfig.request?.enableSmartPolling ?? true,
|
|
953
919
|
});
|
|
954
920
|
}
|
|
921
|
+
get = (queryConfig) => this.fetch({
|
|
922
|
+
...queryConfig,
|
|
923
|
+
method: 'GET',
|
|
924
|
+
});
|
|
925
|
+
post = (queryConfig) => this.fetch({
|
|
926
|
+
...queryConfig,
|
|
927
|
+
method: 'POST',
|
|
928
|
+
});
|
|
929
|
+
put = (queryConfig) => this.fetch({
|
|
930
|
+
...queryConfig,
|
|
931
|
+
method: 'PUT',
|
|
932
|
+
});
|
|
933
|
+
patch = (queryConfig) => this.fetch({
|
|
934
|
+
...queryConfig,
|
|
935
|
+
method: 'PATCH',
|
|
936
|
+
});
|
|
937
|
+
delete = (queryConfig) => this.fetch({
|
|
938
|
+
...queryConfig,
|
|
939
|
+
method: 'DELETE',
|
|
940
|
+
});
|
|
941
|
+
gqlQuery = (queryConfig) => this.fetch({
|
|
942
|
+
...queryConfig,
|
|
943
|
+
method: 'GQL_QUERY',
|
|
944
|
+
});
|
|
945
|
+
gqlMutate = (queryConfig) => this.fetch({
|
|
946
|
+
...queryConfig,
|
|
947
|
+
method: 'GQL_MUTATE',
|
|
948
|
+
});
|
|
949
|
+
fetch = (queryConfig) => new QueryCreator(queryConfig, this, this._store);
|
|
950
|
+
setAuthProvider = (authProvider) => {
|
|
951
|
+
if (this.authProvider) {
|
|
952
|
+
this.authProvider?.cleanUp();
|
|
953
|
+
}
|
|
954
|
+
this._authProvider$.next(authProvider);
|
|
955
|
+
};
|
|
956
|
+
setDefaultHeaders = (config) => {
|
|
957
|
+
if (!this._clientConfig.request) {
|
|
958
|
+
this._clientConfig.request = {
|
|
959
|
+
headers: config.headers ?? undefined,
|
|
960
|
+
};
|
|
961
|
+
}
|
|
962
|
+
else {
|
|
963
|
+
this._clientConfig.request.headers = config.headers ?? undefined;
|
|
964
|
+
}
|
|
965
|
+
if (config.refreshQueriesInUse) {
|
|
966
|
+
this._store.refreshQueriesInUse({ purgeUnused: true, ignoreCacheValidity: true });
|
|
967
|
+
}
|
|
968
|
+
};
|
|
969
|
+
clearAuthProvider = () => {
|
|
970
|
+
this.authProvider?.cleanUp();
|
|
971
|
+
this._authProvider$.next(null);
|
|
972
|
+
};
|
|
973
|
+
_updateBaseRoute = (route) => {
|
|
974
|
+
this._clientConfig.baseRoute = route;
|
|
975
|
+
};
|
|
955
976
|
}
|
|
956
977
|
|
|
957
|
-
const shouldCacheQuery = (method) => {
|
|
978
|
+
const shouldCacheQuery$1 = (method) => {
|
|
958
979
|
return method === 'GET' || method === 'OPTIONS' || method === 'HEAD' || method === 'GQL_QUERY';
|
|
959
980
|
};
|
|
960
|
-
const buildQueryCacheKey = (route, args) => {
|
|
981
|
+
const buildQueryCacheKey$1 = (route, args) => {
|
|
961
982
|
const variables = JSON.stringify(args?.variables || {})
|
|
962
983
|
// replace all curly braces with empty string
|
|
963
984
|
.replace(/{|}/g, '')
|
|
@@ -981,12 +1002,14 @@ const transformGql = (str) => {
|
|
|
981
1002
|
return function (variables) {
|
|
982
1003
|
const data = { query: str };
|
|
983
1004
|
if (variables)
|
|
984
|
-
data['variables'] =
|
|
1005
|
+
data['variables'] = variables;
|
|
985
1006
|
if (name && name.length) {
|
|
986
1007
|
const operationName = name[2];
|
|
987
1008
|
if (operationName)
|
|
988
1009
|
data['operationName'] = name[2];
|
|
989
1010
|
}
|
|
1011
|
+
// minify the query
|
|
1012
|
+
data.query = data.query.replace(/\s+/g, ' ').trim();
|
|
990
1013
|
return data;
|
|
991
1014
|
};
|
|
992
1015
|
};
|
|
@@ -1241,6 +1264,36 @@ const paginatedEntityValueUpdater = (findFn) => ({ response, rawResponse, entity
|
|
|
1241
1264
|
|
|
1242
1265
|
let _nextQueryId = 0;
|
|
1243
1266
|
class Query {
|
|
1267
|
+
_client;
|
|
1268
|
+
_queryConfig;
|
|
1269
|
+
_routeWithParams;
|
|
1270
|
+
_arguments;
|
|
1271
|
+
_queryStoreKey;
|
|
1272
|
+
_id = _nextQueryId++;
|
|
1273
|
+
_currentLocalId = 0;
|
|
1274
|
+
_pollingSubscription = null;
|
|
1275
|
+
_onAbort$ = new Subject();
|
|
1276
|
+
_currentPollConfig = null;
|
|
1277
|
+
/**
|
|
1278
|
+
* @internal
|
|
1279
|
+
* Used to track which components depend on this query.
|
|
1280
|
+
* The key is the component's _tNode index.
|
|
1281
|
+
* The value is the number of times the component has subscribed to this query.
|
|
1282
|
+
* The value might increase since we cant distinguish between a component and a host directive applied to it.
|
|
1283
|
+
*/
|
|
1284
|
+
_dependents = {};
|
|
1285
|
+
/**
|
|
1286
|
+
* @internal
|
|
1287
|
+
*/
|
|
1288
|
+
_dependentsChanged$ = new ReplaySubject();
|
|
1289
|
+
/**
|
|
1290
|
+
* @internal
|
|
1291
|
+
*/
|
|
1292
|
+
_isPollingPaused = false;
|
|
1293
|
+
_state$ = new BehaviorSubject({
|
|
1294
|
+
type: "PREPARED" /* QueryStateType.Prepared */,
|
|
1295
|
+
meta: { id: this._currentLocalId, triggeredVia: 'program' },
|
|
1296
|
+
});
|
|
1244
1297
|
get _nextId() {
|
|
1245
1298
|
return ++this._currentLocalId;
|
|
1246
1299
|
}
|
|
@@ -1307,7 +1360,7 @@ class Query {
|
|
|
1307
1360
|
return this._queryConfig.entity?.store ?? null;
|
|
1308
1361
|
}
|
|
1309
1362
|
get canBeCached() {
|
|
1310
|
-
return shouldCacheQuery(this._queryConfig.method);
|
|
1363
|
+
return shouldCacheQuery$1(this._queryConfig.method);
|
|
1311
1364
|
}
|
|
1312
1365
|
get _isInMockMode() {
|
|
1313
1366
|
return !!this._arguments?.mock;
|
|
@@ -1334,31 +1387,6 @@ class Query {
|
|
|
1334
1387
|
this._routeWithParams = _routeWithParams;
|
|
1335
1388
|
this._arguments = _arguments;
|
|
1336
1389
|
this._queryStoreKey = _queryStoreKey;
|
|
1337
|
-
this._id = _nextQueryId++;
|
|
1338
|
-
this._currentLocalId = 0;
|
|
1339
|
-
this._pollingSubscription = null;
|
|
1340
|
-
this._onAbort$ = new Subject();
|
|
1341
|
-
this._currentPollConfig = null;
|
|
1342
|
-
/**
|
|
1343
|
-
* @internal
|
|
1344
|
-
* Used to track which components depend on this query.
|
|
1345
|
-
* The key is the component's _tNode index.
|
|
1346
|
-
* The value is the number of times the component has subscribed to this query.
|
|
1347
|
-
* The value might increase since we cant distinguish between a component and a host directive applied to it.
|
|
1348
|
-
*/
|
|
1349
|
-
this._dependents = {};
|
|
1350
|
-
/**
|
|
1351
|
-
* @internal
|
|
1352
|
-
*/
|
|
1353
|
-
this._dependentsChanged$ = new ReplaySubject();
|
|
1354
|
-
/**
|
|
1355
|
-
* @internal
|
|
1356
|
-
*/
|
|
1357
|
-
this._isPollingPaused = false;
|
|
1358
|
-
this._state$ = new BehaviorSubject({
|
|
1359
|
-
type: "PREPARED" /* QueryStateType.Prepared */,
|
|
1360
|
-
meta: { id: this._currentLocalId, triggeredVia: 'program' },
|
|
1361
|
-
});
|
|
1362
1390
|
}
|
|
1363
1391
|
execute(options = {}) {
|
|
1364
1392
|
const { skipCache = false, _triggeredVia: triggeredVia = 'program', cancelPrevious = false } = options;
|
|
@@ -1687,6 +1715,13 @@ const decryptBearer = (token) => {
|
|
|
1687
1715
|
};
|
|
1688
1716
|
|
|
1689
1717
|
class BearerAuthProvider {
|
|
1718
|
+
_config;
|
|
1719
|
+
_destroy$ = new Subject();
|
|
1720
|
+
_currentRefreshQuery$ = new BehaviorSubject(null);
|
|
1721
|
+
_tokens$ = new BehaviorSubject({
|
|
1722
|
+
token: null,
|
|
1723
|
+
refreshToken: null,
|
|
1724
|
+
});
|
|
1690
1725
|
get header() {
|
|
1691
1726
|
return { Authorization: `Bearer ${this._tokens$.getValue().token}` };
|
|
1692
1727
|
}
|
|
@@ -1709,12 +1744,6 @@ class BearerAuthProvider {
|
|
|
1709
1744
|
}
|
|
1710
1745
|
constructor(_config) {
|
|
1711
1746
|
this._config = _config;
|
|
1712
|
-
this._destroy$ = new Subject();
|
|
1713
|
-
this._currentRefreshQuery$ = new BehaviorSubject(null);
|
|
1714
|
-
this._tokens$ = new BehaviorSubject({
|
|
1715
|
-
token: null,
|
|
1716
|
-
refreshToken: null,
|
|
1717
|
-
});
|
|
1718
1747
|
const cookieEnabled = _config.refreshConfig?.cookieEnabled ?? true;
|
|
1719
1748
|
const cookieToken = _config.refreshConfig?.cookieName && cookieEnabled ? (getCookie(_config.refreshConfig.cookieName) ?? null) : null;
|
|
1720
1749
|
this._tokens$.next({
|
|
@@ -1855,25 +1884,22 @@ const isClassValidatorError = (error) => {
|
|
|
1855
1884
|
};
|
|
1856
1885
|
|
|
1857
1886
|
class QueryDirective {
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
|
|
1864
|
-
|
|
1865
|
-
|
|
1866
|
-
|
|
1867
|
-
|
|
1868
|
-
|
|
1869
|
-
|
|
1870
|
-
|
|
1871
|
-
|
|
1872
|
-
|
|
1873
|
-
|
|
1874
|
-
};
|
|
1875
|
-
this._cache = false;
|
|
1876
|
-
}
|
|
1887
|
+
_mainTemplateRef = inject(TemplateRef);
|
|
1888
|
+
_viewContainerRef = inject(ViewContainerRef);
|
|
1889
|
+
_errorHandler = inject(ErrorHandler);
|
|
1890
|
+
_cdr = inject(ChangeDetectorRef);
|
|
1891
|
+
_isMainViewCreated = false;
|
|
1892
|
+
_subscription = null;
|
|
1893
|
+
_viewContext = {
|
|
1894
|
+
$implicit: null,
|
|
1895
|
+
etQuery: null,
|
|
1896
|
+
loading: false,
|
|
1897
|
+
refreshing: false,
|
|
1898
|
+
error: null,
|
|
1899
|
+
progress: null,
|
|
1900
|
+
scope: null,
|
|
1901
|
+
query: null,
|
|
1902
|
+
};
|
|
1877
1903
|
get query() {
|
|
1878
1904
|
return this._query;
|
|
1879
1905
|
}
|
|
@@ -1881,12 +1907,14 @@ class QueryDirective {
|
|
|
1881
1907
|
this._query = v;
|
|
1882
1908
|
this._subscribeToQuery();
|
|
1883
1909
|
}
|
|
1910
|
+
_query;
|
|
1884
1911
|
get cache() {
|
|
1885
1912
|
return this._cache;
|
|
1886
1913
|
}
|
|
1887
1914
|
set cache(v) {
|
|
1888
1915
|
this._cache = v;
|
|
1889
1916
|
}
|
|
1917
|
+
_cache = false;
|
|
1890
1918
|
static ngTemplateContextGuard(dir, ctx) {
|
|
1891
1919
|
return true;
|
|
1892
1920
|
}
|
|
@@ -1955,10 +1983,10 @@ class QueryDirective {
|
|
|
1955
1983
|
this._viewContainerRef.createEmbeddedView(this._mainTemplateRef, this._viewContext);
|
|
1956
1984
|
}
|
|
1957
1985
|
}
|
|
1958
|
-
static
|
|
1959
|
-
static
|
|
1986
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.4", ngImport: i0, type: QueryDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
1987
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.1.4", type: QueryDirective, isStandalone: true, selector: "[etQuery]", inputs: { query: ["etQuery", "query"], cache: ["etQueryCache", "cache"] }, ngImport: i0 });
|
|
1960
1988
|
}
|
|
1961
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.
|
|
1989
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.4", ngImport: i0, type: QueryDirective, decorators: [{
|
|
1962
1990
|
type: Directive,
|
|
1963
1991
|
args: [{
|
|
1964
1992
|
selector: '[etQuery]',
|
|
@@ -1973,6 +2001,58 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.3", ngImpor
|
|
|
1973
2001
|
}] } });
|
|
1974
2002
|
|
|
1975
2003
|
class InfinityQuery {
|
|
2004
|
+
_config;
|
|
2005
|
+
_destroy$;
|
|
2006
|
+
_queries$ = new BehaviorSubject([]);
|
|
2007
|
+
_currentPage$ = new BehaviorSubject(null);
|
|
2008
|
+
_currentCalculatedPage$ = new BehaviorSubject(null);
|
|
2009
|
+
_totalPages$ = new BehaviorSubject(null);
|
|
2010
|
+
_itemsPerPage$ = new BehaviorSubject(10);
|
|
2011
|
+
_data$ = this._queries$.pipe(switchMap((queries) => {
|
|
2012
|
+
if (!queries.length) {
|
|
2013
|
+
return of([]);
|
|
2014
|
+
}
|
|
2015
|
+
return combineLatest(queries.map((query) => query.state$.pipe(filterSuccess(), map((state) => ({ state, query })))));
|
|
2016
|
+
}), tap((stateMaps) => {
|
|
2017
|
+
const lastState = stateMaps[stateMaps.length - 1]?.state;
|
|
2018
|
+
const lastQuery = stateMaps[stateMaps.length - 1]?.query;
|
|
2019
|
+
if (!lastState || !lastQuery) {
|
|
2020
|
+
return;
|
|
2021
|
+
}
|
|
2022
|
+
const totalPages = this._config.response.totalPagesExtractor?.({
|
|
2023
|
+
response: lastState.response,
|
|
2024
|
+
itemsPerPage: this.itemsPerPage,
|
|
2025
|
+
args: lastQuery._arguments,
|
|
2026
|
+
}) ??
|
|
2027
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
2028
|
+
lastState.response?.totalPages ??
|
|
2029
|
+
null;
|
|
2030
|
+
this._totalPages$.next(totalPages);
|
|
2031
|
+
}), map((stateMaps) => {
|
|
2032
|
+
if (!stateMaps.length) {
|
|
2033
|
+
return null;
|
|
2034
|
+
}
|
|
2035
|
+
const fullData = stateMaps.reduce((acc, stateMap) => {
|
|
2036
|
+
const valExtractFn = this._config?.response?.valueExtractor;
|
|
2037
|
+
let data = valExtractFn
|
|
2038
|
+
? valExtractFn?.(stateMap.state.response)
|
|
2039
|
+
: stateMap.state.response;
|
|
2040
|
+
if (this._config.response.reverse) {
|
|
2041
|
+
data = [...data].reverse();
|
|
2042
|
+
}
|
|
2043
|
+
if (this._config.response.appendItemsTo === 'start') {
|
|
2044
|
+
acc.unshift(...data);
|
|
2045
|
+
}
|
|
2046
|
+
else {
|
|
2047
|
+
acc.push(...data);
|
|
2048
|
+
}
|
|
2049
|
+
return acc;
|
|
2050
|
+
},
|
|
2051
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
2052
|
+
[]);
|
|
2053
|
+
return fullData;
|
|
2054
|
+
}), shareReplay({ bufferSize: 1, refCount: true }));
|
|
2055
|
+
_lastQuery$ = this._queries$.pipe(map((queries) => queries[queries.length - 1] ?? null), shareReplay({ bufferSize: 1, refCount: true }));
|
|
1976
2056
|
get currentPage$() {
|
|
1977
2057
|
return this._currentPage$.asObservable();
|
|
1978
2058
|
}
|
|
@@ -2006,56 +2086,7 @@ class InfinityQuery {
|
|
|
2006
2086
|
constructor(_config, _destroy$) {
|
|
2007
2087
|
this._config = _config;
|
|
2008
2088
|
this._destroy$ = _destroy$;
|
|
2009
|
-
this.
|
|
2010
|
-
this._currentPage$ = new BehaviorSubject(null);
|
|
2011
|
-
this._currentCalculatedPage$ = new BehaviorSubject(null);
|
|
2012
|
-
this._totalPages$ = new BehaviorSubject(null);
|
|
2013
|
-
this._itemsPerPage$ = new BehaviorSubject(this._config.limitParam?.value ?? 10);
|
|
2014
|
-
this._data$ = this._queries$.pipe(switchMap((queries) => {
|
|
2015
|
-
if (!queries.length) {
|
|
2016
|
-
return of([]);
|
|
2017
|
-
}
|
|
2018
|
-
return combineLatest(queries.map((query) => query.state$.pipe(filterSuccess(), map((state) => ({ state, query })))));
|
|
2019
|
-
}), tap((stateMaps) => {
|
|
2020
|
-
const lastState = stateMaps[stateMaps.length - 1]?.state;
|
|
2021
|
-
const lastQuery = stateMaps[stateMaps.length - 1]?.query;
|
|
2022
|
-
if (!lastState || !lastQuery) {
|
|
2023
|
-
return;
|
|
2024
|
-
}
|
|
2025
|
-
const totalPages = this._config.response.totalPagesExtractor?.({
|
|
2026
|
-
response: lastState.response,
|
|
2027
|
-
itemsPerPage: this.itemsPerPage,
|
|
2028
|
-
args: lastQuery._arguments,
|
|
2029
|
-
}) ??
|
|
2030
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
2031
|
-
lastState.response?.totalPages ??
|
|
2032
|
-
null;
|
|
2033
|
-
this._totalPages$.next(totalPages);
|
|
2034
|
-
}), map((stateMaps) => {
|
|
2035
|
-
if (!stateMaps.length) {
|
|
2036
|
-
return null;
|
|
2037
|
-
}
|
|
2038
|
-
const fullData = stateMaps.reduce((acc, stateMap) => {
|
|
2039
|
-
const valExtractFn = this._config?.response?.valueExtractor;
|
|
2040
|
-
let data = valExtractFn
|
|
2041
|
-
? valExtractFn?.(stateMap.state.response)
|
|
2042
|
-
: stateMap.state.response;
|
|
2043
|
-
if (this._config.response.reverse) {
|
|
2044
|
-
data = [...data].reverse();
|
|
2045
|
-
}
|
|
2046
|
-
if (this._config.response.appendItemsTo === 'start') {
|
|
2047
|
-
acc.unshift(...data);
|
|
2048
|
-
}
|
|
2049
|
-
else {
|
|
2050
|
-
acc.push(...data);
|
|
2051
|
-
}
|
|
2052
|
-
return acc;
|
|
2053
|
-
},
|
|
2054
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
2055
|
-
[]);
|
|
2056
|
-
return fullData;
|
|
2057
|
-
}), shareReplay({ bufferSize: 1, refCount: true }));
|
|
2058
|
-
this._lastQuery$ = this._queries$.pipe(map((queries) => queries[queries.length - 1] ?? null), shareReplay({ bufferSize: 1, refCount: true }));
|
|
2089
|
+
this._itemsPerPage$.next(this._config.limitParam?.value ?? 10);
|
|
2059
2090
|
}
|
|
2060
2091
|
nextPage() {
|
|
2061
2092
|
const newPage = (this._currentPage$.value ?? 0) + 1;
|
|
@@ -2147,6 +2178,28 @@ const skipPaginationPageParamCalculator = ({ page, itemsPerPage }) => itemsPerPa
|
|
|
2147
2178
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2148
2179
|
const INFINITY_QUERY_TOKEN = new InjectionToken('INFINITY_QUERY_TOKEN');
|
|
2149
2180
|
class InfinityQueryDirective {
|
|
2181
|
+
_queryConfigChanged$ = new Subject();
|
|
2182
|
+
_viewContext = {
|
|
2183
|
+
$implicit: null,
|
|
2184
|
+
etInfinityQuery: null,
|
|
2185
|
+
loading: false,
|
|
2186
|
+
error: null,
|
|
2187
|
+
isFirstLoad: false,
|
|
2188
|
+
canLoadMore: false,
|
|
2189
|
+
currentPage: null,
|
|
2190
|
+
currentCalculatedPage: null,
|
|
2191
|
+
totalPages: null,
|
|
2192
|
+
itemsPerPage: null,
|
|
2193
|
+
currentQuery: null,
|
|
2194
|
+
};
|
|
2195
|
+
_infinityQueryInstance = null;
|
|
2196
|
+
_destroy$ = createDestroy();
|
|
2197
|
+
_cdr = inject(ChangeDetectorRef);
|
|
2198
|
+
_viewContainerRef = inject(ViewContainerRef);
|
|
2199
|
+
_mainTemplateRef = inject((TemplateRef));
|
|
2200
|
+
_errorHandler = inject(ErrorHandler);
|
|
2201
|
+
_delayable = inject(DelayableDirective, { host: true });
|
|
2202
|
+
_data$ = new BehaviorSubject([]);
|
|
2150
2203
|
get infinityQuery() {
|
|
2151
2204
|
return this._infinityQuery;
|
|
2152
2205
|
}
|
|
@@ -2156,6 +2209,7 @@ class InfinityQueryDirective {
|
|
|
2156
2209
|
this._infinityQueryInstance = this._setupInfinityQuery(v);
|
|
2157
2210
|
this._infinityQueryInstance.nextPage();
|
|
2158
2211
|
}
|
|
2212
|
+
_infinityQuery;
|
|
2159
2213
|
get context() {
|
|
2160
2214
|
return this._viewContext;
|
|
2161
2215
|
}
|
|
@@ -2165,33 +2219,11 @@ class InfinityQueryDirective {
|
|
|
2165
2219
|
get data$() {
|
|
2166
2220
|
return this._data$.asObservable();
|
|
2167
2221
|
}
|
|
2222
|
+
data = toSignal(this._data$, { requireSync: true });
|
|
2168
2223
|
static ngTemplateContextGuard(dir, ctx) {
|
|
2169
2224
|
return true;
|
|
2170
2225
|
}
|
|
2171
2226
|
constructor() {
|
|
2172
|
-
this._queryConfigChanged$ = new Subject();
|
|
2173
|
-
this._viewContext = {
|
|
2174
|
-
$implicit: null,
|
|
2175
|
-
etInfinityQuery: null,
|
|
2176
|
-
loading: false,
|
|
2177
|
-
error: null,
|
|
2178
|
-
isFirstLoad: false,
|
|
2179
|
-
canLoadMore: false,
|
|
2180
|
-
currentPage: null,
|
|
2181
|
-
currentCalculatedPage: null,
|
|
2182
|
-
totalPages: null,
|
|
2183
|
-
itemsPerPage: null,
|
|
2184
|
-
currentQuery: null,
|
|
2185
|
-
};
|
|
2186
|
-
this._infinityQueryInstance = null;
|
|
2187
|
-
this._destroy$ = createDestroy();
|
|
2188
|
-
this._cdr = inject(ChangeDetectorRef);
|
|
2189
|
-
this._viewContainerRef = inject(ViewContainerRef);
|
|
2190
|
-
this._mainTemplateRef = inject((TemplateRef));
|
|
2191
|
-
this._errorHandler = inject(ErrorHandler);
|
|
2192
|
-
this._delayable = inject(DelayableDirective, { host: true });
|
|
2193
|
-
this._data$ = new BehaviorSubject([]);
|
|
2194
|
-
this.data = toSignal(this._data$, { requireSync: true });
|
|
2195
2227
|
this._viewContainerRef.createEmbeddedView(this._mainTemplateRef, this._viewContext);
|
|
2196
2228
|
}
|
|
2197
2229
|
_setupInfinityQuery(config) {
|
|
@@ -2265,10 +2297,10 @@ class InfinityQueryDirective {
|
|
|
2265
2297
|
this._viewContext.currentQuery = null;
|
|
2266
2298
|
this._data$.next([]);
|
|
2267
2299
|
}
|
|
2268
|
-
static
|
|
2269
|
-
static
|
|
2300
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.4", ngImport: i0, type: InfinityQueryDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
2301
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.1.4", type: InfinityQueryDirective, isStandalone: true, selector: "[etInfinityQuery]", inputs: { infinityQuery: ["etInfinityQuery", "infinityQuery"] }, providers: [{ provide: INFINITY_QUERY_TOKEN, useExisting: InfinityQueryDirective }], exportAs: ["etInfinityQuery"], hostDirectives: [{ directive: i1.DelayableDirective }], ngImport: i0 });
|
|
2270
2302
|
}
|
|
2271
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.
|
|
2303
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.4", ngImport: i0, type: InfinityQueryDirective, decorators: [{
|
|
2272
2304
|
type: Directive,
|
|
2273
2305
|
args: [{
|
|
2274
2306
|
selector: '[etInfinityQuery]',
|
|
@@ -2283,14 +2315,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.3", ngImpor
|
|
|
2283
2315
|
}] } });
|
|
2284
2316
|
|
|
2285
2317
|
class InfinityQueryTriggerDirective {
|
|
2286
|
-
|
|
2287
|
-
|
|
2288
|
-
|
|
2289
|
-
|
|
2290
|
-
|
|
2291
|
-
|
|
2292
|
-
this.scrollContainerSelector = null;
|
|
2293
|
-
}
|
|
2318
|
+
_elementRef = inject((ElementRef));
|
|
2319
|
+
_infinityQuery = inject(INFINITY_QUERY_TOKEN);
|
|
2320
|
+
_destroy = new Subject();
|
|
2321
|
+
_observer = null;
|
|
2322
|
+
click$ = fromEvent(this._elementRef.nativeElement, 'click');
|
|
2323
|
+
scrollContainerSelector = null;
|
|
2294
2324
|
ngOnInit() {
|
|
2295
2325
|
const isInteractive = this._elementRef.nativeElement.tagName === 'BUTTON';
|
|
2296
2326
|
if (isInteractive) {
|
|
@@ -2320,10 +2350,10 @@ class InfinityQueryTriggerDirective {
|
|
|
2320
2350
|
});
|
|
2321
2351
|
this._observer.observe(this._elementRef.nativeElement);
|
|
2322
2352
|
}
|
|
2323
|
-
static
|
|
2324
|
-
static
|
|
2353
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.4", ngImport: i0, type: InfinityQueryTriggerDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
2354
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.1.4", type: InfinityQueryTriggerDirective, isStandalone: true, selector: "[etInfinityQueryTrigger], et-infinity-query-trigger", inputs: { scrollContainerSelector: "scrollContainerSelector" }, ngImport: i0 });
|
|
2325
2355
|
}
|
|
2326
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.
|
|
2356
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.4", ngImport: i0, type: InfinityQueryTriggerDirective, decorators: [{
|
|
2327
2357
|
type: Directive,
|
|
2328
2358
|
args: [{
|
|
2329
2359
|
selector: '[etInfinityQueryTrigger], et-infinity-query-trigger',
|
|
@@ -2347,10 +2377,10 @@ class QueryShortNamePipe {
|
|
|
2347
2377
|
}
|
|
2348
2378
|
return route;
|
|
2349
2379
|
}
|
|
2350
|
-
static
|
|
2351
|
-
static
|
|
2380
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.4", ngImport: i0, type: QueryShortNamePipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
|
|
2381
|
+
static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "19.1.4", ngImport: i0, type: QueryShortNamePipe, isStandalone: true, name: "queryShortName" });
|
|
2352
2382
|
}
|
|
2353
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.
|
|
2383
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.4", ngImport: i0, type: QueryShortNamePipe, decorators: [{
|
|
2354
2384
|
type: Pipe,
|
|
2355
2385
|
args: [{ name: 'queryShortName', standalone: true }]
|
|
2356
2386
|
}] });
|
|
@@ -2368,161 +2398,159 @@ const provideQueryClientForDevtools = (queryClient) => {
|
|
|
2368
2398
|
};
|
|
2369
2399
|
|
|
2370
2400
|
class QueryDevtoolsComponent {
|
|
2371
|
-
|
|
2372
|
-
|
|
2373
|
-
|
|
2374
|
-
|
|
2375
|
-
|
|
2376
|
-
|
|
2377
|
-
|
|
2378
|
-
|
|
2379
|
-
|
|
2380
|
-
|
|
2381
|
-
|
|
2382
|
-
|
|
2383
|
-
|
|
2384
|
-
|
|
2385
|
-
|
|
2386
|
-
|
|
2387
|
-
|
|
2388
|
-
this.
|
|
2389
|
-
|
|
2390
|
-
|
|
2391
|
-
|
|
2392
|
-
|
|
2393
|
-
|
|
2394
|
-
|
|
2395
|
-
|
|
2396
|
-
|
|
2397
|
-
|
|
2398
|
-
|
|
2399
|
-
|
|
2400
|
-
|
|
2401
|
-
|
|
2402
|
-
|
|
2403
|
-
|
|
2404
|
-
|
|
2405
|
-
|
|
2406
|
-
|
|
2407
|
-
|
|
2408
|
-
|
|
2409
|
-
|
|
2410
|
-
|
|
2411
|
-
|
|
2412
|
-
|
|
2413
|
-
|
|
2414
|
-
|
|
2415
|
-
|
|
2416
|
-
|
|
2417
|
-
|
|
2418
|
-
|
|
2419
|
-
|
|
2420
|
-
|
|
2421
|
-
|
|
2422
|
-
|
|
2423
|
-
|
|
2424
|
-
|
|
2425
|
-
|
|
2426
|
-
|
|
2427
|
-
|
|
2428
|
-
|
|
2429
|
-
|
|
2430
|
-
|
|
2431
|
-
|
|
2432
|
-
|
|
2433
|
-
|
|
2434
|
-
|
|
2435
|
-
|
|
2436
|
-
|
|
2437
|
-
|
|
2438
|
-
|
|
2439
|
-
|
|
2440
|
-
|
|
2441
|
-
|
|
2442
|
-
|
|
2443
|
-
|
|
2444
|
-
|
|
2445
|
-
|
|
2446
|
-
|
|
2447
|
-
|
|
2448
|
-
|
|
2449
|
-
|
|
2450
|
-
|
|
2451
|
-
if (isGqlQueryConfig(cfg)) {
|
|
2452
|
-
return {
|
|
2453
|
-
...sharedCfg,
|
|
2454
|
-
query: cfg.query,
|
|
2455
|
-
transferVia: cfg.transferVia,
|
|
2456
|
-
};
|
|
2457
|
-
}
|
|
2401
|
+
_cdr = inject(ChangeDetectorRef);
|
|
2402
|
+
_destroy$ = createDestroy();
|
|
2403
|
+
queryClientConfigs = inject(QUERY_CLIENT_DEVTOOLS_TOKEN);
|
|
2404
|
+
isOpen = signal(false);
|
|
2405
|
+
isTranslucent = signal(false);
|
|
2406
|
+
snapLayout = signal('full');
|
|
2407
|
+
queryListMode = signal('live');
|
|
2408
|
+
viewMode = signal('query');
|
|
2409
|
+
showResponse = signal(false);
|
|
2410
|
+
showRawResponse = signal(false);
|
|
2411
|
+
showQueryConfig = signal(false);
|
|
2412
|
+
showEntityStoreValue = signal(false);
|
|
2413
|
+
showArguments = signal(false);
|
|
2414
|
+
selectedClientIdCtrl = new FormControl(0);
|
|
2415
|
+
selectedClientId = toSignal(this.selectedClientIdCtrl.valueChanges.pipe(startWith(this.selectedClientIdCtrl.value)));
|
|
2416
|
+
selectedQueryId = signal(null);
|
|
2417
|
+
selectedClientConfig = computed(() => {
|
|
2418
|
+
if (this.queryClientConfigs.length === 1) {
|
|
2419
|
+
return this.queryClientConfigs[0];
|
|
2420
|
+
}
|
|
2421
|
+
const index = this.selectedClientId() ?? 0;
|
|
2422
|
+
const cfg = this.queryClientConfigs[index];
|
|
2423
|
+
if (!cfg) {
|
|
2424
|
+
return this.queryClientConfigs[0];
|
|
2425
|
+
}
|
|
2426
|
+
return cfg;
|
|
2427
|
+
});
|
|
2428
|
+
queryStore = computed(() => {
|
|
2429
|
+
const config = this.selectedClientConfig();
|
|
2430
|
+
return config.client._store;
|
|
2431
|
+
});
|
|
2432
|
+
queryStore$ = toObservable(this.queryStore);
|
|
2433
|
+
_queries$ = new BehaviorSubject([]);
|
|
2434
|
+
queries = toSignal(this._queries$);
|
|
2435
|
+
selectedQuery = computed(() => {
|
|
2436
|
+
const id = this.selectedQueryId();
|
|
2437
|
+
const mode = this.queryListMode();
|
|
2438
|
+
if (id === null || !mode) {
|
|
2439
|
+
return null;
|
|
2440
|
+
}
|
|
2441
|
+
if (mode === 'live') {
|
|
2442
|
+
return this.queries()?.find((q) => q._id === id) ?? null;
|
|
2443
|
+
}
|
|
2444
|
+
return this.queryHistory$.getValue()?.find((q) => q._id === id) ?? null;
|
|
2445
|
+
});
|
|
2446
|
+
selectedQuery$ = toObservable(this.selectedQuery);
|
|
2447
|
+
selectedQueryEntityStore = computed(() => {
|
|
2448
|
+
const query = this.selectedQuery();
|
|
2449
|
+
if (!query)
|
|
2450
|
+
return null;
|
|
2451
|
+
return query.store;
|
|
2452
|
+
});
|
|
2453
|
+
selectedQueryEntityStore$ = toObservable(this.selectedQueryEntityStore);
|
|
2454
|
+
selectedQueryEntityStoreValue$ = this.selectedQueryEntityStore$.pipe(switchMap((s) => s?._change$.pipe(startWith(''), map(() => {
|
|
2455
|
+
if (!s._dictionary)
|
|
2456
|
+
return null;
|
|
2457
|
+
return Array.from(s._dictionary).reduce((obj, [key, value]) => {
|
|
2458
|
+
obj[key] = value;
|
|
2459
|
+
return obj;
|
|
2460
|
+
}, {});
|
|
2461
|
+
})) ?? of(null)));
|
|
2462
|
+
queryHistory$ = new BehaviorSubject([]);
|
|
2463
|
+
stringifiedQueryConfig = computed(() => {
|
|
2464
|
+
const query = this.selectedQuery();
|
|
2465
|
+
if (!query)
|
|
2466
|
+
return null;
|
|
2467
|
+
const cfg = query._queryConfig;
|
|
2468
|
+
const route = typeof cfg.route === 'string' ? cfg.route : cfg.route ? cfg.route({}).replace(/undefined/g, ':param') : null;
|
|
2469
|
+
const sharedCfg = {
|
|
2470
|
+
method: cfg.method,
|
|
2471
|
+
secure: cfg.secure,
|
|
2472
|
+
route,
|
|
2473
|
+
reportProgress: cfg.reportProgress,
|
|
2474
|
+
responseType: cfg.responseType,
|
|
2475
|
+
withCredentials: cfg.withCredentials,
|
|
2476
|
+
autoRefreshOn: cfg.autoRefreshOn,
|
|
2477
|
+
enableSmartPolling: cfg.enableSmartPolling,
|
|
2478
|
+
hasEntityStore: !!cfg.entity,
|
|
2479
|
+
};
|
|
2480
|
+
if (isGqlQueryConfig(cfg)) {
|
|
2458
2481
|
return {
|
|
2459
2482
|
...sharedCfg,
|
|
2483
|
+
query: cfg.query,
|
|
2484
|
+
transferVia: cfg.transferVia,
|
|
2460
2485
|
};
|
|
2461
|
-
}
|
|
2462
|
-
|
|
2463
|
-
|
|
2464
|
-
|
|
2465
|
-
|
|
2466
|
-
|
|
2467
|
-
|
|
2468
|
-
|
|
2469
|
-
|
|
2470
|
-
|
|
2471
|
-
|
|
2472
|
-
|
|
2473
|
-
|
|
2474
|
-
|
|
2475
|
-
|
|
2476
|
-
|
|
2477
|
-
|
|
2478
|
-
|
|
2479
|
-
|
|
2480
|
-
|
|
2481
|
-
|
|
2482
|
-
|
|
2483
|
-
|
|
2484
|
-
|
|
2485
|
-
|
|
2486
|
-
|
|
2487
|
-
|
|
2488
|
-
|
|
2489
|
-
|
|
2490
|
-
|
|
2491
|
-
|
|
2492
|
-
|
|
2493
|
-
|
|
2494
|
-
|
|
2495
|
-
|
|
2496
|
-
|
|
2497
|
-
|
|
2498
|
-
|
|
2499
|
-
|
|
2500
|
-
|
|
2501
|
-
|
|
2502
|
-
|
|
2503
|
-
|
|
2504
|
-
|
|
2505
|
-
|
|
2506
|
-
|
|
2507
|
-
|
|
2508
|
-
|
|
2509
|
-
|
|
2510
|
-
|
|
2511
|
-
|
|
2486
|
+
}
|
|
2487
|
+
return {
|
|
2488
|
+
...sharedCfg,
|
|
2489
|
+
};
|
|
2490
|
+
});
|
|
2491
|
+
authProvider = toSignal(toObservable(this.selectedClientConfig).pipe(switchMap((c) => c.client.authProvider$)));
|
|
2492
|
+
authProviderDetails = computed(() => {
|
|
2493
|
+
const provider = this.authProvider();
|
|
2494
|
+
if (!provider)
|
|
2495
|
+
return null;
|
|
2496
|
+
if (provider instanceof CustomHeaderAuthProvider) {
|
|
2497
|
+
return {
|
|
2498
|
+
type: 'CustomHeaderAuthProvider',
|
|
2499
|
+
header: () => provider.header,
|
|
2500
|
+
provider: provider,
|
|
2501
|
+
config: {
|
|
2502
|
+
name: provider._config.name,
|
|
2503
|
+
value: provider._config.value,
|
|
2504
|
+
},
|
|
2505
|
+
};
|
|
2506
|
+
}
|
|
2507
|
+
else if (provider instanceof BasicAuthProvider) {
|
|
2508
|
+
return {
|
|
2509
|
+
type: 'BasicAuthProvider',
|
|
2510
|
+
header: () => provider.header,
|
|
2511
|
+
provider: provider,
|
|
2512
|
+
config: {
|
|
2513
|
+
username: provider._config.username,
|
|
2514
|
+
password: provider._config.password,
|
|
2515
|
+
},
|
|
2516
|
+
};
|
|
2517
|
+
}
|
|
2518
|
+
else if (isBearerAuthProvider(provider)) {
|
|
2519
|
+
const refreshCfg = provider._config.refreshConfig;
|
|
2520
|
+
return {
|
|
2521
|
+
type: 'BearerAuthProvider',
|
|
2522
|
+
header: () => provider.header,
|
|
2523
|
+
provider: provider,
|
|
2524
|
+
config: {
|
|
2525
|
+
token: provider._config.token,
|
|
2526
|
+
refreshConfig: {
|
|
2527
|
+
refreshOnUnauthorizedResponse: refreshCfg?.refreshOnUnauthorizedResponse ?? 'true (default)',
|
|
2528
|
+
token: refreshCfg?.token,
|
|
2529
|
+
cookieName: refreshCfg?.cookieName,
|
|
2530
|
+
cookieDomain: refreshCfg?.cookieDomain ?? 'current origin (default)',
|
|
2531
|
+
cookieExpiresInDays: refreshCfg?.cookieExpiresInDays ?? '30 (default)',
|
|
2532
|
+
cookiePath: refreshCfg?.cookiePath ?? '/ (default)',
|
|
2533
|
+
cookieEnabled: refreshCfg?.cookieEnabled ?? 'true (default)',
|
|
2534
|
+
cookieSameSite: refreshCfg?.cookieSameSite ?? 'lax (default)',
|
|
2535
|
+
refreshBuffer: refreshCfg?.refreshBuffer ?? '30000 (default)',
|
|
2536
|
+
expiresInPropertyName: refreshCfg?.expiresInPropertyName ?? 'exp (default)',
|
|
2537
|
+
strategy: refreshCfg?.strategy ?? 'AuthBearerRefreshStrategy.BeforeExpiration (default)',
|
|
2538
|
+
requestArgsAdapter: refreshCfg?.requestArgsAdapter ? 'custom' : 'default',
|
|
2539
|
+
responseAdapter: refreshCfg?.responseAdapter ? 'custom' : 'default',
|
|
2512
2540
|
},
|
|
2513
|
-
}
|
|
2514
|
-
}
|
|
2515
|
-
|
|
2516
|
-
|
|
2517
|
-
|
|
2518
|
-
|
|
2519
|
-
|
|
2520
|
-
|
|
2521
|
-
}
|
|
2522
|
-
}
|
|
2523
|
-
}
|
|
2524
|
-
|
|
2525
|
-
|
|
2541
|
+
},
|
|
2542
|
+
};
|
|
2543
|
+
}
|
|
2544
|
+
else {
|
|
2545
|
+
return {
|
|
2546
|
+
type: 'UnknownAuthProvider',
|
|
2547
|
+
header: () => provider.header,
|
|
2548
|
+
provider: provider,
|
|
2549
|
+
config: {},
|
|
2550
|
+
};
|
|
2551
|
+
}
|
|
2552
|
+
});
|
|
2553
|
+
constructor() {
|
|
2526
2554
|
this.selectedClientIdCtrl.valueChanges
|
|
2527
2555
|
.pipe(tap(() => this.clearQueryHistory()), takeUntil(this._destroy$))
|
|
2528
2556
|
.subscribe();
|
|
@@ -2602,6 +2630,8 @@ class QueryDevtoolsComponent {
|
|
|
2602
2630
|
this.viewMode.set(parsed.viewMode ?? 'query');
|
|
2603
2631
|
}
|
|
2604
2632
|
}
|
|
2633
|
+
trackByClient = (_, { client }) => client.config.baseRoute;
|
|
2634
|
+
trackByQuery = (_, { _id }) => _id;
|
|
2605
2635
|
toggleOpen() {
|
|
2606
2636
|
this.isOpen.set(!this.isOpen());
|
|
2607
2637
|
}
|
|
@@ -2641,10 +2671,10 @@ class QueryDevtoolsComponent {
|
|
|
2641
2671
|
clearQueryHistory() {
|
|
2642
2672
|
this.queryHistory$.next([]);
|
|
2643
2673
|
}
|
|
2644
|
-
static
|
|
2645
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.3", type: QueryDevtoolsComponent, isStandalone: true, selector: "et-query-devtools", host: { classAttribute: "et-query-devtools" }, ngImport: i0, template: "@if (!isOpen()) {\n <button (click)=\"toggleOpen()\" class=\"et-query-devtools-open-btn et-qd-chip\">Query Devtools</button>\n}\n\n@if (isOpen()) {\n <div\n [class.et-query-devtools-container--transparent]=\"isTranslucent()\"\n class=\"et-query-devtools-container et-query-devtools-container--snap-{{ snapLayout() }}\"\n >\n <header class=\"et-qd-header\">\n <h3 class=\"et-qd-header__title\">Query Devtools</h3>\n\n <div class=\"et-qd-header__select\">\n <label for=\"et-query-client-instance\">Client instance</label>\n <select [formControl]=\"selectedClientIdCtrl\" id=\"et-query-client-instance\">\n @for (clientConfig of queryClientConfigs; track trackByClient(i, clientConfig); let i = $index) {\n <option [value]=\"i\">\n {{ clientConfig.displayName ?? clientConfig.client.config.baseRoute }}\n </option>\n }\n </select>\n </div>\n\n <button (click)=\"toggleOpen()\" class=\"et-qd-btn et-qd-btn-secondary\">Close</button>\n </header>\n\n <div class=\"et-qd-sub-header\">\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': !isTranslucent() }\"\n (click)=\"toggleTranslucent()\"\n class=\"et-qd-chip et-qd-translucent-clickable\"\n >\n Translucent\n </button>\n <div class=\"et-qd-sub-header__divider\"></div>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': snapLayout() !== 'full' }\"\n (click)=\"selectSnapLayout('full')\"\n class=\"et-qd-chip\"\n >\n Fullscreen\n </button>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': snapLayout() !== 'top' }\"\n (click)=\"selectSnapLayout('top')\"\n class=\"et-qd-chip\"\n >\n Top\n </button>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': snapLayout() !== 'bottom' }\"\n (click)=\"selectSnapLayout('bottom')\"\n class=\"et-qd-chip\"\n >\n Bottom\n </button>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': snapLayout() !== 'left' }\"\n (click)=\"selectSnapLayout('left')\"\n class=\"et-qd-chip\"\n >\n Left\n </button>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': snapLayout() !== 'right' }\"\n (click)=\"selectSnapLayout('right')\"\n class=\"et-qd-chip\"\n >\n Right\n </button>\n </div>\n\n @if (selectedClientConfig(); as cfg) {\n <div class=\"et-qd-client\">\n <p class=\"et-qd-client__title\">{{ cfg.displayName ?? cfg.client.config.baseRoute }}</p>\n\n <div class=\"et-qd-client__actions\">\n <button (click)=\"cfg.client._store.refreshQueriesInUse()\" class=\"et-qd-chip\">Refresh all</button>\n <button (click)=\"cfg.client._store.refreshQueriesInUse({ ignoreCacheValidity: true })\" class=\"et-qd-chip\">\n Refresh all (ignore caches)\n </button>\n <button\n (click)=\"cfg.client._store.refreshQueriesInUse({ ignoreCacheValidity: true, purgeUnused: true })\"\n class=\"et-qd-chip\"\n >\n Refresh all (ignore caches & purge unused)\n </button>\n </div>\n </div>\n }\n\n @if (selectedClientConfig(); as cfg) {\n <div class=\"et-qd-queries\">\n <p class=\"et-qd-queries__title\">Inspector</p>\n <div class=\"et-qd-queries__actions\">\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': queryListMode() !== 'live' || viewMode() !== 'query' }\"\n (click)=\"selectQueryListMode('live'); selectViewMode('query')\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Live Queries ({{ queries()?.length ?? 0 }})\n </button>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': queryListMode() !== 'history' || viewMode() !== 'query' }\"\n (click)=\"selectQueryListMode('history'); selectViewMode('query')\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Query History ({{ (queryHistory$ | async)?.length ?? 0 }}/50)\n </button>\n @if (queryListMode() === 'history' && viewMode() === 'query') {\n <div class=\"et-qd-queries__divider\"></div>\n <button (click)=\"clearQueryHistory()\" class=\"et-qd-chip et-qd-chip-bordered\">Clear history</button>\n }\n\n <div class=\"et-qd-queries__divider\"></div>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': viewMode() !== 'authProvider' }\"\n (click)=\"selectViewMode('authProvider')\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Auth Provider\n </button>\n </div>\n\n @if (viewMode() === 'query') {\n <div class=\"et-qd-queries__browser\">\n @if (queryListMode() === 'live') {\n <ul class=\"et-qd-queries__browser-list\">\n @for (query of queries(); track trackByQuery($index, query)) {\n <li>\n <button\n [class.et-qd-query--active]=\"selectedQuery()?._id === query._id\"\n (click)=\"selectQuery(query)\"\n >\n <span> {{ query._queryConfig.method }}</span>\n <span> {{ query | queryShortName }}</span>\n </button>\n </li>\n }\n </ul>\n }\n @if (queryListMode() === 'history') {\n <ul class=\"et-qd-queries__browser-list\">\n @for (query of queryHistory$ | async; track trackByQuery($index, query)) {\n <li>\n <button\n [class.et-qd-query--active]=\"selectedQuery()?._id === query._id\"\n (click)=\"selectQuery(query)\"\n >\n <span> {{ query._queryConfig.method }}</span>\n <span> {{ query | queryShortName }}</span>\n </button>\n </li>\n }\n </ul>\n }\n <div class=\"et-qd-queries__browser-detail\">\n @if (selectedQuery(); as query) {\n <p class=\"et-qd-queries__browser-detail__title\">\n {{ query._queryConfig.method }} {{ query._routeWithParams }}\n </p>\n\n <div class=\"et-qd-queries__actions\">\n <button (click)=\"query.execute()\" class=\"et-qd-chip et-qd-chip-bordered\">Execute</button>\n <button (click)=\"query.execute({ skipCache: true })\" class=\"et-qd-chip et-qd-chip-bordered\">\n Execute (ignore cache)\n </button>\n\n <button (click)=\"query.abort()\" class=\"et-qd-chip et-qd-chip-bordered\">Abort</button>\n <div class=\"et-qd-queries__divider\"></div>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': !query.isPolling }\"\n (click)=\"query.poll({ interval: 5000, takeUntil: _destroy$ })\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Poll\n </button>\n\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': query.isPolling }\"\n (click)=\"query.stopPolling()\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Stop polling\n </button>\n @if (query.isPolling || query._isPollingPaused) {\n <button (click)=\"query.pausePolling()\" class=\"et-qd-chip et-qd-chip-secondary et-qd-chip-bordered\">\n Pause polling\n </button>\n <button (click)=\"query.resumePolling()\" class=\"et-qd-chip et-qd-chip-secondary et-qd-chip-bordered\">\n Resume polling\n </button>\n }\n </div>\n\n <div class=\"et-qd-list\">\n <div class=\"et-qd-list-item\">\n <p>State type</p>\n <pre>{{ query.rawState.type }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Dependents</p>\n <pre>{{ query._dependents | json }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Is expired</p>\n <pre>{{ query.isExpired }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Is in use</p>\n <pre>{{ query.isInUse }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Subscriber count</p>\n <pre>{{ query._subscriberCount }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Is polling</p>\n <pre>{{ query.isPolling }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Is polling paused</p>\n <pre>{{ query._isPollingPaused }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Enable smart polling</p>\n <pre>{{ query._enableSmartPolling }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Query store key</p>\n <pre>{{ query._queryStoreKey }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Arguments</p>\n\n <div>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': !showArguments() }\"\n (click)=\"toggleShowArguments()\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Toggle\n </button>\n </div>\n @if (showArguments()) {\n <pre>{{ query._arguments | json }}</pre>\n }\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>State</p>\n <p><i> Warning, this will cause a subscription if shown!</i></p>\n <div>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': !showResponse() }\"\n (click)=\"toggleShowResponse()\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Toggle\n </button>\n </div>\n @if (showResponse()) {\n <pre>{{ query.state$ | async | json }}</pre>\n }\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Raw state</p>\n <p><i> The query state unaffected by entity stores</i></p>\n\n <div>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': !showRawResponse() }\"\n (click)=\"toggleShowRawResponse()\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Toggle\n </button>\n </div>\n @if (showRawResponse()) {\n <pre>{{ query.rawState | json }}</pre>\n }\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Query config</p>\n\n <div>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': !showQueryConfig() }\"\n (click)=\"toggleShowQueryConfig()\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Toggle\n </button>\n </div>\n @if (showQueryConfig()) {\n <pre>{{ stringifiedQueryConfig() | json }}</pre>\n }\n </div>\n\n @if (!!query._queryConfig.entity) {\n <div class=\"et-qd-list-item\">\n <p>Entity store value</p>\n\n <div>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': !showEntityStoreValue() }\"\n (click)=\"toggleShowEntityStoreValue()\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Toggle\n </button>\n </div>\n @if (showEntityStoreValue()) {\n <pre>{{ selectedQueryEntityStoreValue$ | async | json }}</pre>\n }\n </div>\n }\n </div>\n }\n </div>\n </div>\n } @else if (viewMode() === 'authProvider') {\n <div class=\"et-qd-auth-provider__viewer\">\n @if (authProviderDetails(); as details) {\n <div class=\"et-qd-list\">\n <div class=\"et-qd-list-item\">\n <p>Type</p>\n <pre>{{ details.type }}</pre>\n </div>\n <div class=\"et-qd-list-item\">\n <p>Header value</p>\n <pre>{{ details.header() | json }}</pre>\n </div>\n <div class=\"et-qd-list-item\">\n <p>Config</p>\n <pre>{{ details.config | json }}</pre>\n </div>\n\n @if (details.type === 'BearerAuthProvider') {\n <div class=\"et-qd-list-item\">\n <p>Tokens</p>\n <pre>{{ details.provider.tokens$ | async | json }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Should refresh on unauthorized response</p>\n <pre>{{ details.provider.shouldRefreshOnUnauthorizedResponse }}</pre>\n </div>\n\n <ng-container\n *etQuery=\"\n details.provider.currentRefreshQuery$ | async as response;\n loading as loading;\n error as error;\n query as query\n \"\n >\n <div class=\"et-qd-list-item\">\n <p>Refresh query response</p>\n\n <div>\n <button (click)=\"details.provider._refreshQuery()\" class=\"et-qd-chip et-qd-chip-bordered\">\n Refresh\n </button>\n </div>\n <pre>{{ response | json }}</pre>\n </div>\n <div class=\"et-qd-list-item\">\n <p>Refresh query loading</p>\n <pre>{{ loading }}</pre>\n </div>\n <div class=\"et-qd-list-item\">\n <p>Refresh query error</p>\n <pre>{{ error ?? 'null' }}</pre>\n </div>\n <div class=\"et-qd-list-item\">\n <p>State</p>\n <pre>{{ query?.state$ | async | json }}</pre>\n </div>\n </ng-container>\n }\n </div>\n } @else {\n <p>No auth provider set</p>\n }\n </div>\n }\n </div>\n }\n </div>\n}\n", styles: [":host{position:fixed;top:0;z-index:1000000;font-size:14px;color:#fff}.et-query-devtools-container{position:fixed;inset:0;background-color:#25292e;z-index:10000;overflow:auto;font-family:monospace;display:grid;grid-template-rows:auto auto auto minmax(0,1fr)}.et-query-devtools-container.et-query-devtools-container--transparent{opacity:.25;pointer-events:none}.et-query-devtools-container.et-query-devtools-container--transparent .et-query-devtools-translucent-btn{pointer-events:all}.et-query-devtools-container.et-query-devtools-container--snap-left{inset-inline-start:0;inset-block-start:0;inset-block-end:0;width:50%;border-right:1px solid rgb(37,41,46)}.et-query-devtools-container.et-query-devtools-container--snap-right{inset-inline-start:unset;inset-inline-end:0;inset-block-start:0;inset-block-end:0;width:50%;border-left:1px solid rgb(37,41,46)}.et-query-devtools-container.et-query-devtools-container--snap-top{inset-inline-start:0;inset-block-start:0;inset-inline-end:0;height:50%;border-bottom:1px solid rgb(37,41,46)}.et-query-devtools-container.et-query-devtools-container--snap-bottom{inset-inline-start:0;inset-block-start:unset;inset-block-end:0;inset-inline-end:0;height:50%;border-top:1px solid rgb(37,41,46)}button.et-query-devtools-open-btn{position:fixed;inset-inline-end:20px;inset-block-end:0;z-index:9999;font-family:monospace;border-radius:3px 3px 0 0;line-height:14px;font-size:12px}.et-qd-header{background-color:#00ffa1;padding:12px;display:grid;grid-template-columns:1fr auto auto;gap:12px;align-items:center}.et-qd-header__title{color:#25292e;margin:0;font-size:22px}.et-qd-header__select{display:grid;background-color:#25292e;border-radius:10px;overflow:hidden}.et-qd-header__select select{width:250px;color:#fff;padding:3px 10px 2px;border:none;background-color:#25292e;font-family:monospace}.et-qd-header__select label{padding:3px 10px;color:#25292e;font-size:12px;font-weight:700;color:#fff;border-bottom:1px solid gray}.et-qd-sub-header{background-color:#00b371;padding:12px;display:flex;gap:12px;flex-wrap:wrap}.et-qd-sub-header__divider{width:1px;background-color:#25292e}.et-qd-btn{background-color:#00ffa1;color:#25292e;border:none;padding:12px;cursor:pointer;font-size:14px;font-weight:700;text-align:center;text-decoration:none;display:inline-block;width:100%;transition:all .3s ease-in-out;font-family:monospace;border-radius:10px}.et-qd-btn:hover{background-color:#00cc81}.et-qd-btn.et-qd-btn-secondary{background-color:#25292e;color:#00ffa1}.et-qd-btn.et-qd-btn-secondary:hover{background-color:#3c424a}.et-qd-chip{background-color:#00ffa1;color:#25292e;border:none;padding:4px 9px;cursor:pointer;font-size:12px;font-weight:700;text-align:center;text-decoration:none;display:inline-block;transition:all .3s ease-in-out;font-family:monospace;border-radius:10px}.et-qd-chip:hover{background-color:#00cc81}.et-qd-chip.et-qd-chip-secondary{background-color:#25292e;color:#00ffa1}.et-qd-chip.et-qd-chip-secondary:hover{background-color:#3c424a}.et-qd-chip.et-qd-chip-bordered{border:1px solid rgb(0,255,161)}.et-qd-translucent-clickable{pointer-events:all}.et-qd-client{border-bottom:1px solid rgb(59.734939759,66.1927710843,74.265060241);padding:12px}.et-qd-client__title{margin:0;font-size:14px;color:#fff;font-weight:700}.et-qd-client__actions{display:flex;gap:12px;margin-top:12px}.et-qd-queries{padding:12px;display:grid;grid-template-rows:auto auto minmax(0,1fr)}.et-qd-queries__actions{display:flex;gap:12px;margin-top:12px;margin-bottom:16px}.et-qd-queries__title{margin:0;font-size:14px;color:#fff;font-weight:700}.et-qd-queries__divider{width:1px;background-color:#3c424a}.et-qd-queries__browser{display:grid;grid-template-columns:1fr minmax(0,3fr);margin-left:-12px;margin-right:-12px;border-top:1px solid rgb(59.734939759,66.1927710843,74.265060241);margin-bottom:-12px}.et-qd-queries__browser-list{border-right:1px solid rgb(59.734939759,66.1927710843,74.265060241);list-style:none;padding:0;margin:0;display:grid;grid-auto-flow:row;grid-auto-rows:55px;overflow-y:auto;overflow-x:hidden}.et-qd-queries__browser-list li{margin:0}.et-qd-queries__browser-list li button{all:unset;font-family:monospace;box-sizing:border-box;width:100%;border:none;border-bottom:1px solid rgb(59.734939759,66.1927710843,74.265060241);background-color:#25292e;color:#fff;text-align:left;padding:12px;height:100%;transition:all .3s ease-in-out;cursor:pointer;display:grid;grid-template-columns:auto minmax(0,1fr);gap:2px;display:block}.et-qd-queries__browser-list li button span{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.et-qd-queries__browser-list li button span:first-of-type{font-weight:700}.et-qd-queries__browser-list li button:hover,.et-qd-queries__browser-list li button.et-qd-query--active{background-color:#30363c}.et-qd-queries__browser-detail{padding:12px;overflow-y:auto;overflow-x:hidden}.et-qd-queries__browser-detail__title{margin:0;font-size:14px;color:#fff;font-weight:700}.et-qd-auth-provider__viewer{border-top:1px solid rgb(59.734939759,66.1927710843,74.265060241);margin-left:-12px;margin-right:-12px;margin-bottom:-12px;padding:12px;overflow-y:auto;overflow-x:hidden}.et-qd-list{display:grid;gap:12px}.et-qd-list-item{display:grid}.et-qd-list-item p{font-weight:700;margin:0;padding-bottom:8px}.et-qd-list-item p+p{margin-top:-8px}.et-qd-list-item div+pre{margin-top:8px}.et-qd-list-item pre{margin:0;padding:4px;background-color:#0e1012;border-radius:4px;max-height:450px;overflow:auto}\n"], dependencies: [{ kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "pipe", type: JsonPipe, name: "json" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1$1.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1$1.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "pipe", type: QueryShortNamePipe, name: "queryShortName" }, { kind: "directive", type: QueryDirective, selector: "[etQuery]", inputs: ["etQuery", "etQueryCache"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.ShadowDom }); }
|
|
2674
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.4", ngImport: i0, type: QueryDevtoolsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2675
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.1.4", type: QueryDevtoolsComponent, isStandalone: true, selector: "et-query-devtools", host: { classAttribute: "et-query-devtools" }, ngImport: i0, template: "@if (!isOpen()) {\n <button (click)=\"toggleOpen()\" class=\"et-query-devtools-open-btn et-qd-chip\">Query Devtools</button>\n}\n\n@if (isOpen()) {\n <div\n [class.et-query-devtools-container--transparent]=\"isTranslucent()\"\n class=\"et-query-devtools-container et-query-devtools-container--snap-{{ snapLayout() }}\"\n >\n <header class=\"et-qd-header\">\n <h3 class=\"et-qd-header__title\">Query Devtools</h3>\n\n <div class=\"et-qd-header__select\">\n <label for=\"et-query-client-instance\">Client instance</label>\n <select [formControl]=\"selectedClientIdCtrl\" id=\"et-query-client-instance\">\n @for (clientConfig of queryClientConfigs; track trackByClient(i, clientConfig); let i = $index) {\n <option [value]=\"i\">\n {{ clientConfig.displayName ?? clientConfig.client.config.baseRoute }}\n </option>\n }\n </select>\n </div>\n\n <button (click)=\"toggleOpen()\" class=\"et-qd-btn et-qd-btn-secondary\">Close</button>\n </header>\n\n <div class=\"et-qd-sub-header\">\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': !isTranslucent() }\"\n (click)=\"toggleTranslucent()\"\n class=\"et-qd-chip et-qd-translucent-clickable\"\n >\n Translucent\n </button>\n <div class=\"et-qd-sub-header__divider\"></div>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': snapLayout() !== 'full' }\"\n (click)=\"selectSnapLayout('full')\"\n class=\"et-qd-chip\"\n >\n Fullscreen\n </button>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': snapLayout() !== 'top' }\"\n (click)=\"selectSnapLayout('top')\"\n class=\"et-qd-chip\"\n >\n Top\n </button>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': snapLayout() !== 'bottom' }\"\n (click)=\"selectSnapLayout('bottom')\"\n class=\"et-qd-chip\"\n >\n Bottom\n </button>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': snapLayout() !== 'left' }\"\n (click)=\"selectSnapLayout('left')\"\n class=\"et-qd-chip\"\n >\n Left\n </button>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': snapLayout() !== 'right' }\"\n (click)=\"selectSnapLayout('right')\"\n class=\"et-qd-chip\"\n >\n Right\n </button>\n </div>\n\n @if (selectedClientConfig(); as cfg) {\n <div class=\"et-qd-client\">\n <p class=\"et-qd-client__title\">{{ cfg.displayName ?? cfg.client.config.baseRoute }}</p>\n\n <div class=\"et-qd-client__actions\">\n <button (click)=\"cfg.client._store.refreshQueriesInUse()\" class=\"et-qd-chip\">Refresh all</button>\n <button (click)=\"cfg.client._store.refreshQueriesInUse({ ignoreCacheValidity: true })\" class=\"et-qd-chip\">\n Refresh all (ignore caches)\n </button>\n <button\n (click)=\"cfg.client._store.refreshQueriesInUse({ ignoreCacheValidity: true, purgeUnused: true })\"\n class=\"et-qd-chip\"\n >\n Refresh all (ignore caches & purge unused)\n </button>\n </div>\n </div>\n }\n\n @if (selectedClientConfig(); as cfg) {\n <div class=\"et-qd-queries\">\n <p class=\"et-qd-queries__title\">Inspector</p>\n <div class=\"et-qd-queries__actions\">\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': queryListMode() !== 'live' || viewMode() !== 'query' }\"\n (click)=\"selectQueryListMode('live'); selectViewMode('query')\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Live Queries ({{ queries()?.length ?? 0 }})\n </button>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': queryListMode() !== 'history' || viewMode() !== 'query' }\"\n (click)=\"selectQueryListMode('history'); selectViewMode('query')\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Query History ({{ (queryHistory$ | async)?.length ?? 0 }}/50)\n </button>\n @if (queryListMode() === 'history' && viewMode() === 'query') {\n <div class=\"et-qd-queries__divider\"></div>\n <button (click)=\"clearQueryHistory()\" class=\"et-qd-chip et-qd-chip-bordered\">Clear history</button>\n }\n\n <div class=\"et-qd-queries__divider\"></div>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': viewMode() !== 'authProvider' }\"\n (click)=\"selectViewMode('authProvider')\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Auth Provider\n </button>\n </div>\n\n @if (viewMode() === 'query') {\n <div class=\"et-qd-queries__browser\">\n @if (queryListMode() === 'live') {\n <ul class=\"et-qd-queries__browser-list\">\n @for (query of queries(); track trackByQuery($index, query)) {\n <li>\n <button\n [class.et-qd-query--active]=\"selectedQuery()?._id === query._id\"\n (click)=\"selectQuery(query)\"\n >\n <span> {{ query._queryConfig.method }}</span>\n <span> {{ query | queryShortName }}</span>\n </button>\n </li>\n }\n </ul>\n }\n @if (queryListMode() === 'history') {\n <ul class=\"et-qd-queries__browser-list\">\n @for (query of queryHistory$ | async; track trackByQuery($index, query)) {\n <li>\n <button\n [class.et-qd-query--active]=\"selectedQuery()?._id === query._id\"\n (click)=\"selectQuery(query)\"\n >\n <span> {{ query._queryConfig.method }}</span>\n <span> {{ query | queryShortName }}</span>\n </button>\n </li>\n }\n </ul>\n }\n <div class=\"et-qd-queries__browser-detail\">\n @if (selectedQuery(); as query) {\n <p class=\"et-qd-queries__browser-detail__title\">\n {{ query._queryConfig.method }} {{ query._routeWithParams }}\n </p>\n\n <div class=\"et-qd-queries__actions\">\n <button (click)=\"query.execute()\" class=\"et-qd-chip et-qd-chip-bordered\">Execute</button>\n <button (click)=\"query.execute({ skipCache: true })\" class=\"et-qd-chip et-qd-chip-bordered\">\n Execute (ignore cache)\n </button>\n\n <button (click)=\"query.abort()\" class=\"et-qd-chip et-qd-chip-bordered\">Abort</button>\n <div class=\"et-qd-queries__divider\"></div>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': !query.isPolling }\"\n (click)=\"query.poll({ interval: 5000, takeUntil: _destroy$ })\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Poll\n </button>\n\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': query.isPolling }\"\n (click)=\"query.stopPolling()\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Stop polling\n </button>\n @if (query.isPolling || query._isPollingPaused) {\n <button (click)=\"query.pausePolling()\" class=\"et-qd-chip et-qd-chip-secondary et-qd-chip-bordered\">\n Pause polling\n </button>\n <button (click)=\"query.resumePolling()\" class=\"et-qd-chip et-qd-chip-secondary et-qd-chip-bordered\">\n Resume polling\n </button>\n }\n </div>\n\n <div class=\"et-qd-list\">\n <div class=\"et-qd-list-item\">\n <p>State type</p>\n <pre>{{ query.rawState.type }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Dependents</p>\n <pre>{{ query._dependents | json }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Is expired</p>\n <pre>{{ query.isExpired }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Is in use</p>\n <pre>{{ query.isInUse }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Subscriber count</p>\n <pre>{{ query._subscriberCount }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Is polling</p>\n <pre>{{ query.isPolling }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Is polling paused</p>\n <pre>{{ query._isPollingPaused }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Enable smart polling</p>\n <pre>{{ query._enableSmartPolling }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Query store key</p>\n <pre>{{ query._queryStoreKey }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Arguments</p>\n\n <div>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': !showArguments() }\"\n (click)=\"toggleShowArguments()\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Toggle\n </button>\n </div>\n @if (showArguments()) {\n <pre>{{ query._arguments | json }}</pre>\n }\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>State</p>\n <p><i> Warning, this will cause a subscription if shown!</i></p>\n <div>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': !showResponse() }\"\n (click)=\"toggleShowResponse()\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Toggle\n </button>\n </div>\n @if (showResponse()) {\n <pre>{{ query.state$ | async | json }}</pre>\n }\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Raw state</p>\n <p><i> The query state unaffected by entity stores</i></p>\n\n <div>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': !showRawResponse() }\"\n (click)=\"toggleShowRawResponse()\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Toggle\n </button>\n </div>\n @if (showRawResponse()) {\n <pre>{{ query.rawState | json }}</pre>\n }\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Query config</p>\n\n <div>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': !showQueryConfig() }\"\n (click)=\"toggleShowQueryConfig()\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Toggle\n </button>\n </div>\n @if (showQueryConfig()) {\n <pre>{{ stringifiedQueryConfig() | json }}</pre>\n }\n </div>\n\n @if (!!query._queryConfig.entity) {\n <div class=\"et-qd-list-item\">\n <p>Entity store value</p>\n\n <div>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': !showEntityStoreValue() }\"\n (click)=\"toggleShowEntityStoreValue()\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Toggle\n </button>\n </div>\n @if (showEntityStoreValue()) {\n <pre>{{ selectedQueryEntityStoreValue$ | async | json }}</pre>\n }\n </div>\n }\n </div>\n }\n </div>\n </div>\n } @else if (viewMode() === 'authProvider') {\n <div class=\"et-qd-auth-provider__viewer\">\n @if (authProviderDetails(); as details) {\n <div class=\"et-qd-list\">\n <div class=\"et-qd-list-item\">\n <p>Type</p>\n <pre>{{ details.type }}</pre>\n </div>\n <div class=\"et-qd-list-item\">\n <p>Header value</p>\n <pre>{{ details.header() | json }}</pre>\n </div>\n <div class=\"et-qd-list-item\">\n <p>Config</p>\n <pre>{{ details.config | json }}</pre>\n </div>\n\n @if (details.type === 'BearerAuthProvider') {\n <div class=\"et-qd-list-item\">\n <p>Tokens</p>\n <pre>{{ details.provider.tokens$ | async | json }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Should refresh on unauthorized response</p>\n <pre>{{ details.provider.shouldRefreshOnUnauthorizedResponse }}</pre>\n </div>\n\n <ng-container\n *etQuery=\"\n details.provider.currentRefreshQuery$ | async as response;\n loading as loading;\n error as error;\n query as query\n \"\n >\n <div class=\"et-qd-list-item\">\n <p>Refresh query response</p>\n\n <div>\n <button (click)=\"details.provider._refreshQuery()\" class=\"et-qd-chip et-qd-chip-bordered\">\n Refresh\n </button>\n </div>\n <pre>{{ response | json }}</pre>\n </div>\n <div class=\"et-qd-list-item\">\n <p>Refresh query loading</p>\n <pre>{{ loading }}</pre>\n </div>\n <div class=\"et-qd-list-item\">\n <p>Refresh query error</p>\n <pre>{{ error ?? 'null' }}</pre>\n </div>\n <div class=\"et-qd-list-item\">\n <p>State</p>\n <pre>{{ query?.state$ | async | json }}</pre>\n </div>\n </ng-container>\n }\n </div>\n } @else {\n <p>No auth provider set</p>\n }\n </div>\n }\n </div>\n }\n </div>\n}\n", styles: [":host{position:fixed;top:0;z-index:1000000;font-size:14px;color:#fff}.et-query-devtools-container{position:fixed;inset:0;background-color:#25292e;z-index:10000;overflow:auto;font-family:monospace;display:grid;grid-template-rows:auto auto auto minmax(0,1fr)}.et-query-devtools-container.et-query-devtools-container--transparent{opacity:.25;pointer-events:none}.et-query-devtools-container.et-query-devtools-container--transparent .et-query-devtools-translucent-btn{pointer-events:all}.et-query-devtools-container.et-query-devtools-container--snap-left{inset-inline-start:0;inset-block-start:0;inset-block-end:0;width:50%;border-right:1px solid rgb(37,41,46)}.et-query-devtools-container.et-query-devtools-container--snap-right{inset-inline-start:unset;inset-inline-end:0;inset-block-start:0;inset-block-end:0;width:50%;border-left:1px solid rgb(37,41,46)}.et-query-devtools-container.et-query-devtools-container--snap-top{inset-inline-start:0;inset-block-start:0;inset-inline-end:0;height:50%;border-bottom:1px solid rgb(37,41,46)}.et-query-devtools-container.et-query-devtools-container--snap-bottom{inset-inline-start:0;inset-block-start:unset;inset-block-end:0;inset-inline-end:0;height:50%;border-top:1px solid rgb(37,41,46)}button.et-query-devtools-open-btn{position:fixed;inset-inline-end:20px;inset-block-end:0;z-index:9999;font-family:monospace;border-radius:3px 3px 0 0;line-height:14px;font-size:12px}.et-qd-header{background-color:#00ffa1;padding:12px;display:grid;grid-template-columns:1fr auto auto;gap:12px;align-items:center}.et-qd-header__title{color:#25292e;margin:0;font-size:22px}.et-qd-header__select{display:grid;background-color:#25292e;border-radius:10px;overflow:hidden}.et-qd-header__select select{width:250px;color:#fff;padding:3px 10px 2px;border:none;background-color:#25292e;font-family:monospace}.et-qd-header__select label{padding:3px 10px;color:#25292e;font-size:12px;font-weight:700;color:#fff;border-bottom:1px solid gray}.et-qd-sub-header{background-color:#00b371;padding:12px;display:flex;gap:12px;flex-wrap:wrap}.et-qd-sub-header__divider{width:1px;background-color:#25292e}.et-qd-btn{background-color:#00ffa1;color:#25292e;border:none;padding:12px;cursor:pointer;font-size:14px;font-weight:700;text-align:center;text-decoration:none;display:inline-block;width:100%;transition:all .3s ease-in-out;font-family:monospace;border-radius:10px}.et-qd-btn:hover{background-color:#00cc81}.et-qd-btn.et-qd-btn-secondary{background-color:#25292e;color:#00ffa1}.et-qd-btn.et-qd-btn-secondary:hover{background-color:#3c424a}.et-qd-chip{background-color:#00ffa1;color:#25292e;border:none;padding:4px 9px;cursor:pointer;font-size:12px;font-weight:700;text-align:center;text-decoration:none;display:inline-block;transition:all .3s ease-in-out;font-family:monospace;border-radius:10px}.et-qd-chip:hover{background-color:#00cc81}.et-qd-chip.et-qd-chip-secondary{background-color:#25292e;color:#00ffa1}.et-qd-chip.et-qd-chip-secondary:hover{background-color:#3c424a}.et-qd-chip.et-qd-chip-bordered{border:1px solid rgb(0,255,161)}.et-qd-translucent-clickable{pointer-events:all}.et-qd-client{border-bottom:1px solid rgb(59.734939759,66.1927710843,74.265060241);padding:12px}.et-qd-client__title{margin:0;font-size:14px;color:#fff;font-weight:700}.et-qd-client__actions{display:flex;gap:12px;margin-top:12px}.et-qd-queries{padding:12px;display:grid;grid-template-rows:auto auto minmax(0,1fr)}.et-qd-queries__actions{display:flex;gap:12px;margin-top:12px;margin-bottom:16px}.et-qd-queries__title{margin:0;font-size:14px;color:#fff;font-weight:700}.et-qd-queries__divider{width:1px;background-color:#3c424a}.et-qd-queries__browser{display:grid;grid-template-columns:1fr minmax(0,3fr);margin-left:-12px;margin-right:-12px;border-top:1px solid rgb(59.734939759,66.1927710843,74.265060241);margin-bottom:-12px}.et-qd-queries__browser-list{border-right:1px solid rgb(59.734939759,66.1927710843,74.265060241);list-style:none;padding:0;margin:0;display:grid;grid-auto-flow:row;grid-auto-rows:55px;overflow-y:auto;overflow-x:hidden}.et-qd-queries__browser-list li{margin:0}.et-qd-queries__browser-list li button{all:unset;font-family:monospace;box-sizing:border-box;width:100%;border:none;border-bottom:1px solid rgb(59.734939759,66.1927710843,74.265060241);background-color:#25292e;color:#fff;text-align:left;padding:12px;height:100%;transition:all .3s ease-in-out;cursor:pointer;display:grid;grid-template-columns:auto minmax(0,1fr);gap:2px;display:block}.et-qd-queries__browser-list li button span{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.et-qd-queries__browser-list li button span:first-of-type{font-weight:700}.et-qd-queries__browser-list li button:hover,.et-qd-queries__browser-list li button.et-qd-query--active{background-color:#30363c}.et-qd-queries__browser-detail{padding:12px;overflow-y:auto;overflow-x:hidden}.et-qd-queries__browser-detail__title{margin:0;font-size:14px;color:#fff;font-weight:700}.et-qd-auth-provider__viewer{border-top:1px solid rgb(59.734939759,66.1927710843,74.265060241);margin-left:-12px;margin-right:-12px;margin-bottom:-12px;padding:12px;overflow-y:auto;overflow-x:hidden}.et-qd-list{display:grid;gap:12px}.et-qd-list-item{display:grid}.et-qd-list-item p{font-weight:700;margin:0;padding-bottom:8px}.et-qd-list-item p+p{margin-top:-8px}.et-qd-list-item div+pre{margin-top:8px}.et-qd-list-item pre{margin:0;padding:4px;background-color:#0e1012;border-radius:4px;max-height:450px;overflow:auto}\n"], dependencies: [{ kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "pipe", type: JsonPipe, name: "json" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1$1.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1$1.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "pipe", type: QueryShortNamePipe, name: "queryShortName" }, { kind: "directive", type: QueryDirective, selector: "[etQuery]", inputs: ["etQuery", "etQueryCache"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.ShadowDom });
|
|
2646
2676
|
}
|
|
2647
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.
|
|
2677
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.4", ngImport: i0, type: QueryDevtoolsComponent, decorators: [{
|
|
2648
2678
|
type: Component,
|
|
2649
2679
|
args: [{ selector: 'et-query-devtools', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.ShadowDom, host: {
|
|
2650
2680
|
class: 'et-query-devtools',
|
|
@@ -2652,6 +2682,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.3", ngImpor
|
|
|
2652
2682
|
}], ctorParameters: () => [] });
|
|
2653
2683
|
|
|
2654
2684
|
class EntityStoreError extends Error {
|
|
2685
|
+
detail;
|
|
2655
2686
|
constructor(message, detail) {
|
|
2656
2687
|
super(message);
|
|
2657
2688
|
this.detail = detail;
|
|
@@ -2662,16 +2693,17 @@ function flatten(arr) {
|
|
|
2662
2693
|
return arr.reduce((acc, val) => acc.concat(val), []);
|
|
2663
2694
|
}
|
|
2664
2695
|
class EntityStore {
|
|
2696
|
+
_config;
|
|
2697
|
+
/**
|
|
2698
|
+
* @internal
|
|
2699
|
+
*/
|
|
2700
|
+
_dictionary = new Map();
|
|
2701
|
+
/**
|
|
2702
|
+
* @internal
|
|
2703
|
+
*/
|
|
2704
|
+
_change$ = new Subject();
|
|
2665
2705
|
constructor(_config) {
|
|
2666
2706
|
this._config = _config;
|
|
2667
|
-
/**
|
|
2668
|
-
* @internal
|
|
2669
|
-
*/
|
|
2670
|
-
this._dictionary = new Map();
|
|
2671
|
-
/**
|
|
2672
|
-
* @internal
|
|
2673
|
-
*/
|
|
2674
|
-
this._change$ = new Subject();
|
|
2675
2707
|
}
|
|
2676
2708
|
select(keyOrKeys) {
|
|
2677
2709
|
if (Array.isArray(keyOrKeys)) {
|
|
@@ -2806,71 +2838,74 @@ const removeFrom = (store, { where, id }) => {
|
|
|
2806
2838
|
};
|
|
2807
2839
|
|
|
2808
2840
|
const queryFeatureUsedMultipleTimes = (type) => {
|
|
2809
|
-
return new RuntimeError(0 /*
|
|
2841
|
+
return new RuntimeError(0 /* QueryRuntimeErrorCode.QUERY_FEATURE_USED_MULTIPLE_TIMES */, `The query feature "${type}()" was used multiple times.`);
|
|
2810
2842
|
};
|
|
2811
2843
|
const withArgsQueryFeatureMissingButRouteIsFunction = () => {
|
|
2812
|
-
return new RuntimeError(100 /*
|
|
2844
|
+
return new RuntimeError(100 /* QueryRuntimeErrorCode.WITH_ARGS_QUERY_FEATURE_MISSING_BUT_ROUTE_IS_FUNCTION */, `This queries route is a function, but a "withArgs()" feature is missing.`);
|
|
2813
2845
|
};
|
|
2814
2846
|
const withPollingUsedOnUnsupportedHttpMethod = (method) => {
|
|
2815
|
-
return new RuntimeError(101 /*
|
|
2847
|
+
return new RuntimeError(101 /* QueryRuntimeErrorCode.WITH_POLLING_USED_ON_UNSUPPORTED_HTTP_METHOD */, `This is a "${method}" request, "withPolling()" is only supported for GET, HEAD, OPTIONS requests and GQL queries.`);
|
|
2816
2848
|
};
|
|
2817
2849
|
const withAutoRefreshUsedOnUnsupportedHttpMethod = (method) => {
|
|
2818
|
-
return new RuntimeError(102 /*
|
|
2850
|
+
return new RuntimeError(102 /* QueryRuntimeErrorCode.WITH_AUTO_REFRESH_USED_ON_UNSUPPORTED_HTTP_METHOD */, `This is a "${method}" request, "withAutoRefresh()" is only supported for GET, HEAD, OPTIONS requests and GQL queries.`);
|
|
2819
2851
|
};
|
|
2820
2852
|
const withAutoRefreshUsedInManualQuery = () => {
|
|
2821
|
-
return new RuntimeError(103 /*
|
|
2853
|
+
return new RuntimeError(103 /* QueryRuntimeErrorCode.WITH_AUTO_REFRESH_USED_IN_MANUAL_QUERY */, `"withAutoRefresh()" has been used inside a query that has "onlyManualExecution" set to true.` +
|
|
2822
2854
|
` If this is intentional, set "ignoreOnlyManualExecution" to true inside the auto refresh config.`);
|
|
2823
2855
|
};
|
|
2824
2856
|
const cookieLoginTriedButCookieDisabled = () => {
|
|
2825
|
-
return new RuntimeError(200 /*
|
|
2857
|
+
return new RuntimeError(200 /* QueryRuntimeErrorCode.COOKIE_LOGIN_TRIED_BUT_COOKIE_DISABLED */, `Cookie login has been tried, but the cookie is disabled.`);
|
|
2826
2858
|
};
|
|
2827
2859
|
const enableCookieCalledWithoutCookieConfig = () => {
|
|
2828
|
-
return new RuntimeError(201 /*
|
|
2860
|
+
return new RuntimeError(201 /* QueryRuntimeErrorCode.ENABLE_COOKIE_CALLED_WITHOUT_COOKIE_CONFIG */, `enableCookie() has been called but there is no cookie config. Please set it during the auth provider creation.`);
|
|
2829
2861
|
};
|
|
2830
2862
|
const disableCookieCalledWithoutCookieConfig = () => {
|
|
2831
|
-
return new RuntimeError(202 /*
|
|
2863
|
+
return new RuntimeError(202 /* QueryRuntimeErrorCode.DISABLE_COOKIE_CALLED_WITHOUT_COOKIE_CONFIG */, `disableCookie() has been called but there is no cookie config. Please set it during the auth provider creation.`);
|
|
2832
2864
|
};
|
|
2833
2865
|
const loginCalledWithoutConfig = () => {
|
|
2834
|
-
return new RuntimeError(203 /*
|
|
2866
|
+
return new RuntimeError(203 /* QueryRuntimeErrorCode.LOGIN_CALLED_WITHOUT_CONFIG */, `login() has been called without a config. Please set it during the auth provider creation.`);
|
|
2835
2867
|
};
|
|
2836
2868
|
const loginWithTokenCalledWithoutConfig = () => {
|
|
2837
|
-
return new RuntimeError(204 /*
|
|
2869
|
+
return new RuntimeError(204 /* QueryRuntimeErrorCode.LOGIN_WITH_TOKEN_CALLED_WITHOUT_CONFIG */, `loginWithToken() has been called without a config. Please set it during the auth provider creation.`);
|
|
2838
2870
|
};
|
|
2839
2871
|
const refreshTokenCalledWithoutConfig = () => {
|
|
2840
|
-
return new RuntimeError(205 /*
|
|
2872
|
+
return new RuntimeError(205 /* QueryRuntimeErrorCode.REFRESH_TOKEN_CALLED_WITHOUT_CONFIG */, `refreshToken() has been called without a config. Please set it during the auth provider creation.`);
|
|
2841
2873
|
};
|
|
2842
2874
|
const selectRoleCalledWithoutConfig = () => {
|
|
2843
|
-
return new RuntimeError(206 /*
|
|
2875
|
+
return new RuntimeError(206 /* QueryRuntimeErrorCode.SELECT_ROLE_CALLED_WITHOUT_CONFIG */, `selectRole() has been called without a config. Please set it during the auth provider creation.`);
|
|
2844
2876
|
};
|
|
2845
2877
|
const defaultResponseTransformerResponseNotObject = (currentType) => {
|
|
2846
|
-
return new RuntimeError(207 /*
|
|
2878
|
+
return new RuntimeError(207 /* QueryRuntimeErrorCode.DEFAULT_RESPONSE_TRANSFORMER_RESPONSE_NOT_OBJECT */, `The default response transformer expects the response to be an object, but it is a "${currentType}".`);
|
|
2847
2879
|
};
|
|
2848
2880
|
const defaultResponseTransformerResponseNotContainingAccessToken = () => {
|
|
2849
|
-
return new RuntimeError(208 /*
|
|
2881
|
+
return new RuntimeError(208 /* QueryRuntimeErrorCode.DEFAULT_RESPONSE_TRANSFORMER_RESPONSE_NOT_CONTAINING_ACCESS_TOKEN */, `The default response transformer expects the response to contain an "accessToken" property.`);
|
|
2850
2882
|
};
|
|
2851
2883
|
const defaultResponseTransformerResponseNotContainingRefreshToken = () => {
|
|
2852
|
-
return new RuntimeError(209 /*
|
|
2884
|
+
return new RuntimeError(209 /* QueryRuntimeErrorCode.DEFAULT_RESPONSE_TRANSFORMER_RESPONSE_NOT_CONTAINING_REFRESH_TOKEN */, `The default response transformer expects the response to contain a "refreshToken" property.`);
|
|
2853
2885
|
};
|
|
2854
2886
|
const unableToDecryptBearerToken = (token) => {
|
|
2855
|
-
return new RuntimeError(210 /*
|
|
2887
|
+
return new RuntimeError(210 /* QueryRuntimeErrorCode.UNABLE_TO_DECRYPT_BEARER_TOKEN */, `The bearer token could not be decrypted: ${token}`);
|
|
2856
2888
|
};
|
|
2857
2889
|
const bearerExpiresInPropertyNotNumber = (expiresIn) => {
|
|
2858
|
-
return new RuntimeError(211 /*
|
|
2890
|
+
return new RuntimeError(211 /* QueryRuntimeErrorCode.BEARER_EXPIRES_IN_PROPERTY_NOT_NUMBER */, `The expires in property is not a number: ${expiresIn}`);
|
|
2859
2891
|
};
|
|
2860
2892
|
const uncacheableRequestHasCacheKeyParam = (key) => {
|
|
2861
|
-
return new RuntimeError(300 /*
|
|
2893
|
+
return new RuntimeError(300 /* QueryRuntimeErrorCode.UNCACHEABLE_REQUEST_HAS_CACHE_KEY_PARAM */, `This request is uncacheable, but a cache key was provided: ${key}. Please remove it.`);
|
|
2862
2894
|
};
|
|
2863
|
-
const
|
|
2864
|
-
return new RuntimeError(301 /*
|
|
2895
|
+
const uncacheableRequestHasAllowCacheParam = () => {
|
|
2896
|
+
return new RuntimeError(301 /* QueryRuntimeErrorCode.UNCACHEABLE_REQUEST_HAS_ALLOW_CACHE_PARAM */, `This request is uncacheable, but allowCache is set to true. Please remove it.`);
|
|
2865
2897
|
};
|
|
2866
|
-
const
|
|
2867
|
-
return new RuntimeError(400 /*
|
|
2898
|
+
const pagedQueryStackPageBiggerThanTotalPages = (page, totalPages) => {
|
|
2899
|
+
return new RuntimeError(400 /* QueryRuntimeErrorCode.PAGED_QUERY_STACK_PAGE_BIGGER_THAN_TOTAL_PAGES */, `The page "${page}" is bigger than the total pages "${totalPages}".`);
|
|
2868
2900
|
};
|
|
2869
|
-
const
|
|
2870
|
-
return new RuntimeError(401 /*
|
|
2901
|
+
const pagedQueryStackNextPageCalledWithoutPreviousPage = () => {
|
|
2902
|
+
return new RuntimeError(401 /* QueryRuntimeErrorCode.PAGED_QUERY_STACK_NEXT_PAGE_CALLED_WITHOUT_PREVIOUS_PAGE */, `fetchNextPage() has been called but the current page is not yet loaded. Please call it after the previous page has been loaded.`);
|
|
2871
2903
|
};
|
|
2872
|
-
const
|
|
2873
|
-
return new RuntimeError(402 /*
|
|
2904
|
+
const pagedQueryStackPreviousPageCalledButAlreadyAtFirstPage = () => {
|
|
2905
|
+
return new RuntimeError(402 /* QueryRuntimeErrorCode.PAGED_QUERY_STACK_PREVIOUS_PAGE_CALLED_BUT_ALREADY_AT_FIRST_PAGE */, `fetchPreviousPage() has been called but the current page is already the first page.`);
|
|
2906
|
+
};
|
|
2907
|
+
const queryStackWithArgsUsed = () => {
|
|
2908
|
+
return new RuntimeError(500 /* QueryRuntimeErrorCode.QUERY_STACK_WITH_ARGS_USED */, `withArgs() has been used in a query stack or a paged query stack. This is not supported.`);
|
|
2874
2909
|
};
|
|
2875
2910
|
|
|
2876
2911
|
const defaultResponseTransformer = (response) => {
|
|
@@ -3034,10 +3069,10 @@ const createBearerAuthProvider = (options) => {
|
|
|
3034
3069
|
};
|
|
3035
3070
|
const logout = () => {
|
|
3036
3071
|
deleteCookie$1();
|
|
3037
|
-
loginQuery?.query.
|
|
3038
|
-
tokenLoginQuery?.query.
|
|
3039
|
-
tokenRefreshQuery?.query.
|
|
3040
|
-
selectRoleQuery?.query.
|
|
3072
|
+
loginQuery?.query.reset();
|
|
3073
|
+
tokenLoginQuery?.query.reset();
|
|
3074
|
+
tokenRefreshQuery?.query.reset();
|
|
3075
|
+
selectRoleQuery?.query.reset();
|
|
3041
3076
|
latestNonInternalQuery.set(null);
|
|
3042
3077
|
};
|
|
3043
3078
|
const enableCookie = () => {
|
|
@@ -3129,29 +3164,81 @@ const createBearerAuthProviderConfig = (options) => {
|
|
|
3129
3164
|
return bearerAuthProviderConfig;
|
|
3130
3165
|
};
|
|
3131
3166
|
|
|
3167
|
+
const setupQueryState = (options) => {
|
|
3168
|
+
const response = signal(null);
|
|
3169
|
+
const args = signal(null);
|
|
3170
|
+
const latestHttpEvent = signal(null);
|
|
3171
|
+
const error = signal(null);
|
|
3172
|
+
const loading = signal(null);
|
|
3173
|
+
const lastTimeExecutedAt = signal(null);
|
|
3174
|
+
const state = {
|
|
3175
|
+
response,
|
|
3176
|
+
args,
|
|
3177
|
+
latestHttpEvent,
|
|
3178
|
+
loading,
|
|
3179
|
+
error,
|
|
3180
|
+
lastTimeExecutedAt,
|
|
3181
|
+
};
|
|
3182
|
+
return state;
|
|
3183
|
+
};
|
|
3184
|
+
|
|
3185
|
+
const createQuerySnapshotFn = (options) => {
|
|
3186
|
+
const { state, deps } = options;
|
|
3187
|
+
const snapshotFn = () => {
|
|
3188
|
+
const snapshotState = setupQueryState({});
|
|
3189
|
+
const isAlive = signal(true);
|
|
3190
|
+
const killEffectRef = effect(() => {
|
|
3191
|
+
const currentLoading = state.loading();
|
|
3192
|
+
const currentError = state.error();
|
|
3193
|
+
const currentResponse = state.response();
|
|
3194
|
+
const currentArgs = state.args();
|
|
3195
|
+
const currentLatestHttpEvent = state.latestHttpEvent();
|
|
3196
|
+
const currentLastTimeExecutedAt = state.lastTimeExecutedAt();
|
|
3197
|
+
untracked(() => {
|
|
3198
|
+
snapshotState.args.set(currentArgs);
|
|
3199
|
+
snapshotState.error.set(currentError);
|
|
3200
|
+
snapshotState.lastTimeExecutedAt.set(currentLastTimeExecutedAt);
|
|
3201
|
+
snapshotState.latestHttpEvent.set(currentLatestHttpEvent);
|
|
3202
|
+
snapshotState.loading.set(currentLoading);
|
|
3203
|
+
snapshotState.response.set(currentResponse);
|
|
3204
|
+
if (currentLoading)
|
|
3205
|
+
return;
|
|
3206
|
+
if (!currentResponse && !currentError)
|
|
3207
|
+
return;
|
|
3208
|
+
// kill the effect once loading is done and we either have a response or an error
|
|
3209
|
+
killEffectRef.destroy();
|
|
3210
|
+
isAlive.set(false);
|
|
3211
|
+
});
|
|
3212
|
+
}, { injector: deps.injector });
|
|
3213
|
+
const snapshot = {
|
|
3214
|
+
args: snapshotState.args.asReadonly(),
|
|
3215
|
+
response: snapshotState.response.asReadonly(),
|
|
3216
|
+
latestHttpEvent: snapshotState.latestHttpEvent.asReadonly(),
|
|
3217
|
+
loading: snapshotState.loading.asReadonly(),
|
|
3218
|
+
error: snapshotState.error.asReadonly(),
|
|
3219
|
+
lastTimeExecutedAt: snapshotState.lastTimeExecutedAt.asReadonly(),
|
|
3220
|
+
isAlive: isAlive.asReadonly(),
|
|
3221
|
+
id: normalizeQueryRepositoryKey(options.execute.currentRepositoryKey),
|
|
3222
|
+
};
|
|
3223
|
+
return snapshot;
|
|
3224
|
+
};
|
|
3225
|
+
return snapshotFn;
|
|
3226
|
+
};
|
|
3227
|
+
|
|
3132
3228
|
/**
|
|
3133
|
-
* Returning this inside
|
|
3229
|
+
* Returning this inside a withArgs feature will reset the query args to null.
|
|
3134
3230
|
* This will also pause polling and auto refresh until new args are set.
|
|
3135
3231
|
*/
|
|
3136
|
-
const
|
|
3232
|
+
const CLEAR_QUERY_ARGS = Symbol('CLEAR_QUERY_ARGS');
|
|
3137
3233
|
const QUERY_EFFECT_ERROR_MESSAGE = 'Effect triggered too often. This is probably due to a circular dependency inside the query.';
|
|
3138
3234
|
/** A angular effect that will throw an error in dev mode if it is called too often. This indicates a circular dependency inside the effect. */
|
|
3139
3235
|
const queryEffect = (fn, errorMessage, options) => {
|
|
3140
3236
|
let lastTriggerTs = 0;
|
|
3141
3237
|
let illegalWrites = 0;
|
|
3142
|
-
// The first run should be synchronous anf not depend on the angular scheduler
|
|
3143
|
-
if (options?.injector) {
|
|
3144
|
-
runInInjectionContext(options.injector, () => fn());
|
|
3145
|
-
}
|
|
3146
|
-
else {
|
|
3147
|
-
fn();
|
|
3148
|
-
}
|
|
3149
3238
|
let isFirstRun = true;
|
|
3150
|
-
|
|
3151
|
-
|
|
3152
|
-
|
|
3153
|
-
return;
|
|
3154
|
-
}
|
|
3239
|
+
const activeConsumer = getActiveConsumer();
|
|
3240
|
+
setActiveConsumer(null);
|
|
3241
|
+
const eff = effect(() => {
|
|
3155
3242
|
if (isDevMode()) {
|
|
3156
3243
|
const now = performance.now();
|
|
3157
3244
|
if (now - lastTriggerTs < 100) {
|
|
@@ -3162,12 +3249,20 @@ const queryEffect = (fn, errorMessage, options) => {
|
|
|
3162
3249
|
}
|
|
3163
3250
|
lastTriggerTs = now;
|
|
3164
3251
|
}
|
|
3165
|
-
fn();
|
|
3166
|
-
|
|
3252
|
+
fn(isFirstRun);
|
|
3253
|
+
if (isFirstRun) {
|
|
3254
|
+
isFirstRun = false;
|
|
3255
|
+
}
|
|
3256
|
+
}, options);
|
|
3257
|
+
setActiveConsumer(activeConsumer);
|
|
3258
|
+
return eff;
|
|
3167
3259
|
};
|
|
3168
3260
|
const shouldAutoExecuteQuery = (method) => {
|
|
3169
3261
|
return method === 'GET' || method === 'HEAD' || method === 'OPTIONS';
|
|
3170
3262
|
};
|
|
3263
|
+
const shouldAutoExecuteGqlQuery = (method) => {
|
|
3264
|
+
return method === 'QUERY';
|
|
3265
|
+
};
|
|
3171
3266
|
const extractExpiresInSeconds = (headers) => {
|
|
3172
3267
|
const cacheControl = headers.get('cache-control');
|
|
3173
3268
|
const age = headers.get('age');
|
|
@@ -3214,7 +3309,8 @@ const extractExpiresInSeconds = (headers) => {
|
|
|
3214
3309
|
return expiresIn;
|
|
3215
3310
|
};
|
|
3216
3311
|
const shouldRetryRequest = (options) => {
|
|
3217
|
-
const { retryCount, error }
|
|
3312
|
+
const normalizedOptions = options instanceof HttpErrorResponse ? { retryCount: 0, error: options } : options;
|
|
3313
|
+
const { retryCount, error } = normalizedOptions;
|
|
3218
3314
|
const defaultRetryDelay = 1000 + 1000 * retryCount;
|
|
3219
3315
|
if (retryCount > 3) {
|
|
3220
3316
|
return { retry: false };
|
|
@@ -3223,8 +3319,8 @@ const shouldRetryRequest = (options) => {
|
|
|
3223
3319
|
return { retry: false };
|
|
3224
3320
|
}
|
|
3225
3321
|
const { status, error: detail, headers } = error;
|
|
3226
|
-
// Retry on 5xx errors
|
|
3227
|
-
if (status >=
|
|
3322
|
+
// Retry on 5xx errors (except 500 internal server error since those are usually not recoverable)
|
|
3323
|
+
if (status >= 501) {
|
|
3228
3324
|
// Don't retry if a requested page is out of range
|
|
3229
3325
|
if (isSymfonyPagerfantaOutOfRangeError(detail)) {
|
|
3230
3326
|
return { retry: false };
|
|
@@ -3252,9 +3348,11 @@ const shouldRetryRequest = (options) => {
|
|
|
3252
3348
|
return { retry: false };
|
|
3253
3349
|
};
|
|
3254
3350
|
const getQueryFeatureUsage = (options) => {
|
|
3255
|
-
const { creator,
|
|
3351
|
+
const { creator, features, queryConfig } = options;
|
|
3256
3352
|
const hasWithArgsFeature = features.some((f) => f.type == "withArgs" /* QueryFeatureType.WithArgs */);
|
|
3257
|
-
const shouldAutoExecuteMethod =
|
|
3353
|
+
const shouldAutoExecuteMethod = isCreateGqlQueryOptions(options)
|
|
3354
|
+
? shouldAutoExecuteGqlQuery(options.creatorInternals.method)
|
|
3355
|
+
: shouldAutoExecuteQuery(options.creatorInternals.method);
|
|
3258
3356
|
const shouldAutoExecute = shouldAutoExecuteMethod && !queryConfig.onlyManualExecution;
|
|
3259
3357
|
const hasRouteFunction = typeof creator.route === 'function';
|
|
3260
3358
|
if (hasRouteFunction && !hasWithArgsFeature) {
|
|
@@ -3265,12 +3363,16 @@ const getQueryFeatureUsage = (options) => {
|
|
|
3265
3363
|
shouldAutoExecuteMethod,
|
|
3266
3364
|
shouldAutoExecute,
|
|
3267
3365
|
hasRouteFunction,
|
|
3366
|
+
onlyManualExecution: queryConfig.onlyManualExecution,
|
|
3367
|
+
method: isCreateGqlQueryOptions(options)
|
|
3368
|
+
? `GQL ${options.creatorInternals.method}`
|
|
3369
|
+
: options.creatorInternals.method,
|
|
3268
3370
|
};
|
|
3269
3371
|
return featureFnContext;
|
|
3270
3372
|
};
|
|
3271
|
-
const applyQueryFeatures = (
|
|
3373
|
+
const applyQueryFeatures = (features, context) => {
|
|
3272
3374
|
const featureTypes = new Set();
|
|
3273
|
-
for (const feature of
|
|
3375
|
+
for (const feature of features) {
|
|
3274
3376
|
if (featureTypes.has(feature.type)) {
|
|
3275
3377
|
throw queryFeatureUsedMultipleTimes(feature.type);
|
|
3276
3378
|
}
|
|
@@ -3278,13 +3380,16 @@ const applyQueryFeatures = (options, context) => {
|
|
|
3278
3380
|
feature.fn(context);
|
|
3279
3381
|
}
|
|
3280
3382
|
};
|
|
3383
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
3281
3384
|
const maybeExecute = (options) => {
|
|
3282
3385
|
if (options.flags.shouldAutoExecute && !options.flags.hasRouteFunction && !options.flags.hasWithArgsFeature) {
|
|
3283
3386
|
options.execute();
|
|
3284
3387
|
}
|
|
3285
3388
|
};
|
|
3286
3389
|
const createQueryObject = (options) => {
|
|
3287
|
-
const { state, execute,
|
|
3390
|
+
const { state, execute, deps } = options;
|
|
3391
|
+
const destroy = () => deps.injector.destroy();
|
|
3392
|
+
const createSnapshot = createQuerySnapshotFn({ state, deps, execute });
|
|
3288
3393
|
const query = {
|
|
3289
3394
|
execute,
|
|
3290
3395
|
args: state.args.asReadonly(),
|
|
@@ -3293,12 +3398,44 @@ const createQueryObject = (options) => {
|
|
|
3293
3398
|
loading: state.loading.asReadonly(),
|
|
3294
3399
|
error: state.error.asReadonly(),
|
|
3295
3400
|
lastTimeExecutedAt: state.lastTimeExecutedAt.asReadonly(),
|
|
3296
|
-
id: execute.currentRepositoryKey,
|
|
3401
|
+
id: normalizeQueryRepositoryKey(execute.currentRepositoryKey),
|
|
3297
3402
|
createSnapshot,
|
|
3298
|
-
|
|
3403
|
+
reset: execute.reset,
|
|
3404
|
+
subtle: {
|
|
3405
|
+
destroy,
|
|
3406
|
+
},
|
|
3299
3407
|
};
|
|
3300
3408
|
return query;
|
|
3301
3409
|
};
|
|
3410
|
+
const normalizeQueryRepositoryKey = (key) => computed(() => {
|
|
3411
|
+
const k = key();
|
|
3412
|
+
if (k === false) {
|
|
3413
|
+
// false means the query cannot be cached and thus it is not stored in the repository
|
|
3414
|
+
// We generate a random id in this case to avoid confusion
|
|
3415
|
+
return crypto.randomUUID();
|
|
3416
|
+
}
|
|
3417
|
+
return k;
|
|
3418
|
+
});
|
|
3419
|
+
const shouldCacheQuery = (method) => {
|
|
3420
|
+
return method === 'GET' || method === 'OPTIONS' || method === 'HEAD';
|
|
3421
|
+
};
|
|
3422
|
+
const buildQueryCacheKey = (route, args) => {
|
|
3423
|
+
// We need to hash the body in case it's a gql query and the query get's transported in the body
|
|
3424
|
+
const body = JSON.stringify(args?.body || {})
|
|
3425
|
+
// replace all curly braces with empty string
|
|
3426
|
+
.replace(/{|}/g, '')
|
|
3427
|
+
// replace new lines and whitespaces with empty string
|
|
3428
|
+
.replace(/\s/g, '');
|
|
3429
|
+
const seed = `${route}_${body}`;
|
|
3430
|
+
let hash = 0;
|
|
3431
|
+
for (const char of seed) {
|
|
3432
|
+
hash = (Math.imul(31, hash) + char.charCodeAt(0)) << 0;
|
|
3433
|
+
}
|
|
3434
|
+
// Force positive number hash.
|
|
3435
|
+
// 2147483647 = equivalent of Integer.MAX_VALUE.
|
|
3436
|
+
hash += 2147483647 + 1;
|
|
3437
|
+
return hash.toString();
|
|
3438
|
+
};
|
|
3302
3439
|
|
|
3303
3440
|
const SPEED_BUFFER_TIME_IN_MS = 2000;
|
|
3304
3441
|
const createHttpRequest = (options) => {
|
|
@@ -3341,8 +3478,8 @@ const createHttpRequest = (options) => {
|
|
|
3341
3478
|
return throwError(() => e);
|
|
3342
3479
|
}));
|
|
3343
3480
|
const execute = (options) => {
|
|
3344
|
-
if (loading() || (!isStale() &&
|
|
3345
|
-
// Do not execute if there is already a request in progress or
|
|
3481
|
+
if (loading() || (!isStale() && options?.allowCache)) {
|
|
3482
|
+
// Do not execute if there is already a request in progress or caching is allowed
|
|
3346
3483
|
return false;
|
|
3347
3484
|
}
|
|
3348
3485
|
currentStreamSubscription.unsubscribe();
|
|
@@ -3451,6 +3588,15 @@ const createHttpRequest = (options) => {
|
|
|
3451
3588
|
const createQueryFeature = (config) => {
|
|
3452
3589
|
return config;
|
|
3453
3590
|
};
|
|
3591
|
+
/**
|
|
3592
|
+
* A query feature that allows you to set the arguments of the query.
|
|
3593
|
+
* The arguments are read within a computed function, so you can use reactive values.
|
|
3594
|
+
*
|
|
3595
|
+
* To set the arguments to `null`, return the symbol `CLEAR_QUERY_ARGS`.
|
|
3596
|
+
* If you instead return `null`, the arguments won't change.
|
|
3597
|
+
*
|
|
3598
|
+
* Changing arguments will automatically trigger a new execution of the query if it is eligible for auto execution (e.g. a GET request).
|
|
3599
|
+
*/
|
|
3454
3600
|
const withArgs = (args) => {
|
|
3455
3601
|
return createQueryFeature({
|
|
3456
3602
|
type: "withArgs" /* QueryFeatureType.WithArgs */,
|
|
@@ -3461,7 +3607,7 @@ const withArgs = (args) => {
|
|
|
3461
3607
|
if (currArgsNow === null)
|
|
3462
3608
|
return;
|
|
3463
3609
|
untracked(() => {
|
|
3464
|
-
if (currArgsNow ===
|
|
3610
|
+
if (currArgsNow === CLEAR_QUERY_ARGS) {
|
|
3465
3611
|
context.state.args.set(null);
|
|
3466
3612
|
return;
|
|
3467
3613
|
}
|
|
@@ -3473,12 +3619,19 @@ const withArgs = (args) => {
|
|
|
3473
3619
|
},
|
|
3474
3620
|
});
|
|
3475
3621
|
};
|
|
3622
|
+
/**
|
|
3623
|
+
* A query feature that will automatically execute the query at a given interval.
|
|
3624
|
+
* The interval will be cleared when the query is destroyed.
|
|
3625
|
+
* The interval will be reset when the arguments of the query change.
|
|
3626
|
+
*
|
|
3627
|
+
* @throws If the query is not eligible for auto execution (e.g. a POST request)
|
|
3628
|
+
*/
|
|
3476
3629
|
const withPolling = (options) => {
|
|
3477
3630
|
return createQueryFeature({
|
|
3478
3631
|
type: "withPolling" /* QueryFeatureType.WithPolling */,
|
|
3479
3632
|
fn: (context) => {
|
|
3480
3633
|
if (!context.flags.shouldAutoExecuteMethod) {
|
|
3481
|
-
throw withPollingUsedOnUnsupportedHttpMethod(context.
|
|
3634
|
+
throw withPollingUsedOnUnsupportedHttpMethod(context.flags.method);
|
|
3482
3635
|
}
|
|
3483
3636
|
let intervalId = null;
|
|
3484
3637
|
queryEffect(() => {
|
|
@@ -3486,7 +3639,9 @@ const withPolling = (options) => {
|
|
|
3486
3639
|
untracked(() => {
|
|
3487
3640
|
if (intervalId !== null)
|
|
3488
3641
|
clearInterval(intervalId);
|
|
3489
|
-
if
|
|
3642
|
+
// Don't start polling if the query doesn't have args.
|
|
3643
|
+
// It should have args because a withArgs feature is present.
|
|
3644
|
+
if (args === null && context.flags.hasWithArgsFeature)
|
|
3490
3645
|
return;
|
|
3491
3646
|
if (options.executeInitially) {
|
|
3492
3647
|
context.execute({ args });
|
|
@@ -3500,68 +3655,78 @@ const withPolling = (options) => {
|
|
|
3500
3655
|
},
|
|
3501
3656
|
});
|
|
3502
3657
|
};
|
|
3658
|
+
/** A query feature that can be used to log the latest http event */
|
|
3503
3659
|
const withLogging = (options) => {
|
|
3504
3660
|
return createQueryFeature({
|
|
3505
3661
|
type: "withLogging" /* QueryFeatureType.WithLogging */,
|
|
3506
3662
|
fn: (context) => {
|
|
3507
|
-
|
|
3663
|
+
queryEffect(() => {
|
|
3508
3664
|
const event = context.state.latestHttpEvent();
|
|
3509
3665
|
if (event === null)
|
|
3510
3666
|
return;
|
|
3511
3667
|
untracked(() => {
|
|
3512
3668
|
options.logFn(event);
|
|
3513
3669
|
});
|
|
3514
|
-
}, { injector: context.deps.injector });
|
|
3670
|
+
}, QUERY_EFFECT_ERROR_MESSAGE, { injector: context.deps.injector });
|
|
3515
3671
|
},
|
|
3516
3672
|
});
|
|
3517
3673
|
};
|
|
3674
|
+
/** A query feature that can be used to handle errors */
|
|
3518
3675
|
const withErrorHandling = (options) => {
|
|
3519
3676
|
return createQueryFeature({
|
|
3520
3677
|
type: "withErrorHandling" /* QueryFeatureType.WithErrorHandling */,
|
|
3521
3678
|
fn: (context) => {
|
|
3522
|
-
|
|
3679
|
+
queryEffect(() => {
|
|
3523
3680
|
const error = context.state.error();
|
|
3524
3681
|
if (error === null)
|
|
3525
3682
|
return;
|
|
3526
3683
|
untracked(() => {
|
|
3527
3684
|
options.handler(error);
|
|
3528
3685
|
});
|
|
3529
|
-
}, { injector: context.deps.injector });
|
|
3686
|
+
}, QUERY_EFFECT_ERROR_MESSAGE, { injector: context.deps.injector });
|
|
3530
3687
|
},
|
|
3531
3688
|
});
|
|
3532
3689
|
};
|
|
3690
|
+
/** A query feature that can be used to handle successful responses */
|
|
3533
3691
|
const withSuccessHandling = (options) => {
|
|
3534
3692
|
return createQueryFeature({
|
|
3535
3693
|
type: "withSuccessHandling" /* QueryFeatureType.WithSuccessHandling */,
|
|
3536
3694
|
fn: (context) => {
|
|
3537
|
-
|
|
3695
|
+
queryEffect(() => {
|
|
3538
3696
|
const response = context.state.response();
|
|
3539
3697
|
if (response === null)
|
|
3540
3698
|
return;
|
|
3541
3699
|
untracked(() => {
|
|
3542
3700
|
options.handler(response);
|
|
3543
3701
|
});
|
|
3544
|
-
}, { injector: context.deps.injector });
|
|
3702
|
+
}, QUERY_EFFECT_ERROR_MESSAGE, { injector: context.deps.injector });
|
|
3545
3703
|
},
|
|
3546
3704
|
});
|
|
3547
3705
|
};
|
|
3706
|
+
/**
|
|
3707
|
+
* A query feature that will automatically execute the query when any of the provided signals change
|
|
3708
|
+
* @throws If the query is not eligible for auto execution (e.g. a POST request)
|
|
3709
|
+
* @throws If the query has the `onlyManualExecution` query config flag set and `ignoreOnlyManualExecution` is not set
|
|
3710
|
+
*/
|
|
3548
3711
|
const withAutoRefresh = (options) => {
|
|
3549
3712
|
return createQueryFeature({
|
|
3550
3713
|
type: "withAutoRefresh" /* QueryFeatureType.WithAutoRefresh */,
|
|
3551
3714
|
fn: (context) => {
|
|
3552
3715
|
if (!context.flags.shouldAutoExecuteMethod) {
|
|
3553
|
-
throw withAutoRefreshUsedOnUnsupportedHttpMethod(context.
|
|
3716
|
+
throw withAutoRefreshUsedOnUnsupportedHttpMethod(context.flags.method);
|
|
3554
3717
|
}
|
|
3555
|
-
if (context.
|
|
3556
|
-
throw
|
|
3718
|
+
if (context.flags.onlyManualExecution && !options.ignoreOnlyManualExecution) {
|
|
3719
|
+
throw withAutoRefreshUsedInManualQuery();
|
|
3557
3720
|
}
|
|
3558
3721
|
queryEffect(() => {
|
|
3559
|
-
for (const signal of options.
|
|
3722
|
+
for (const signal of options.onSignalChanges) {
|
|
3560
3723
|
signal();
|
|
3561
3724
|
}
|
|
3562
3725
|
untracked(() => {
|
|
3563
3726
|
const args = context.state.args();
|
|
3564
|
-
if
|
|
3727
|
+
// Don't start polling if the query doesn't have args.
|
|
3728
|
+
// It should have args because a withArgs feature is present.
|
|
3729
|
+
if (args === null && context.flags.hasWithArgsFeature)
|
|
3565
3730
|
return;
|
|
3566
3731
|
context.execute({ args });
|
|
3567
3732
|
});
|
|
@@ -3570,10 +3735,12 @@ const withAutoRefresh = (options) => {
|
|
|
3570
3735
|
});
|
|
3571
3736
|
};
|
|
3572
3737
|
|
|
3738
|
+
/** Transforms an array of arrays into a single array and filters out `null` values. */
|
|
3573
3739
|
const transformArrayResponse = (responses) => responses.filter((r) => !!r).flatMap((r) => r);
|
|
3740
|
+
/** Transforms an array of paginated responses into a single array and filters out `null` values. */
|
|
3574
3741
|
const transformPaginatedResponse = (responses) => responses.filter((r) => !!r).flatMap((r) => r.items);
|
|
3575
|
-
const createQueryStack = (
|
|
3576
|
-
const { append =
|
|
3742
|
+
const createQueryStack = (options) => {
|
|
3743
|
+
const { args, queryCreator, dependencies, append, features = [], appendFn = (oldQueries, newQueries) => {
|
|
3577
3744
|
const queries = [...oldQueries, ...newQueries];
|
|
3578
3745
|
const lastQuery = newQueries[newQueries.length - 1] ?? oldQueries[oldQueries.length - 1] ?? null;
|
|
3579
3746
|
return { queries, lastQuery };
|
|
@@ -3581,9 +3748,21 @@ const createQueryStack = (computation, options) => {
|
|
|
3581
3748
|
const injector = inject(Injector);
|
|
3582
3749
|
const queries = signal([]);
|
|
3583
3750
|
const lastQuery = signal(null);
|
|
3751
|
+
const hasWithArgsFeature = features.some((f) => f.type == "withArgs" /* QueryFeatureType.WithArgs */);
|
|
3752
|
+
if (hasWithArgsFeature) {
|
|
3753
|
+
throw queryStackWithArgsUsed();
|
|
3754
|
+
}
|
|
3755
|
+
effect(() => {
|
|
3756
|
+
// Clear the stack if dependencies change
|
|
3757
|
+
dependencies?.();
|
|
3758
|
+
untracked(() => clear());
|
|
3759
|
+
});
|
|
3584
3760
|
effect(() => {
|
|
3585
|
-
const
|
|
3586
|
-
|
|
3761
|
+
const newArgs = args(dependencies?.());
|
|
3762
|
+
if (newArgs === null)
|
|
3763
|
+
return;
|
|
3764
|
+
const newArgsArray = Array.isArray(newArgs) ? newArgs : [newArgs];
|
|
3765
|
+
const newQueries = runInInjectionContext(injector, () => newArgsArray.map((newArgsEntry) => queryCreator(withArgs(() => newArgsEntry), ...features)));
|
|
3587
3766
|
untracked(() => {
|
|
3588
3767
|
const oldQueries = queries();
|
|
3589
3768
|
if (append) {
|
|
@@ -3594,7 +3773,7 @@ const createQueryStack = (computation, options) => {
|
|
|
3594
3773
|
else {
|
|
3595
3774
|
for (const oldQuery of oldQueries) {
|
|
3596
3775
|
if (!newQueries.some((q) => q.id() === oldQuery.id())) {
|
|
3597
|
-
oldQuery.destroy();
|
|
3776
|
+
oldQuery.subtle.destroy();
|
|
3598
3777
|
}
|
|
3599
3778
|
}
|
|
3600
3779
|
queries.set(newQueries);
|
|
@@ -3612,12 +3791,12 @@ const createQueryStack = (computation, options) => {
|
|
|
3612
3791
|
});
|
|
3613
3792
|
const execute = (options) => {
|
|
3614
3793
|
for (const query of queries()) {
|
|
3615
|
-
query.execute({ options: {
|
|
3794
|
+
query.execute({ options: { allowCache: options?.allowCache } });
|
|
3616
3795
|
}
|
|
3617
3796
|
};
|
|
3618
3797
|
const clear = () => {
|
|
3619
3798
|
for (const query of queries()) {
|
|
3620
|
-
query.destroy();
|
|
3799
|
+
query.subtle.destroy();
|
|
3621
3800
|
}
|
|
3622
3801
|
queries.set([]);
|
|
3623
3802
|
lastQuery.set(null);
|
|
@@ -3676,23 +3855,31 @@ const contentfulGqlLikePaginationAdapter = (response) => {
|
|
|
3676
3855
|
};
|
|
3677
3856
|
return pagination;
|
|
3678
3857
|
};
|
|
3679
|
-
const
|
|
3680
|
-
|
|
3858
|
+
const fakePaginationAdapter = (totalHits = 10) => {
|
|
3859
|
+
return (response) => {
|
|
3860
|
+
const pagination = {
|
|
3861
|
+
items: [response],
|
|
3862
|
+
totalPages: totalHits,
|
|
3863
|
+
currentPage: 1,
|
|
3864
|
+
itemsPerPage: 1,
|
|
3865
|
+
totalHits,
|
|
3866
|
+
};
|
|
3867
|
+
return pagination;
|
|
3868
|
+
};
|
|
3869
|
+
};
|
|
3870
|
+
const createPagedQueryStack = (options) => {
|
|
3871
|
+
const { responseNormalizer, queryCreator, features } = options;
|
|
3681
3872
|
const currentPageArgs = signal(null);
|
|
3682
3873
|
const initialPage = signal(options.initialPage ?? 1);
|
|
3683
3874
|
const loadedMinPage = signal(initialPage());
|
|
3684
3875
|
const loadedMaxPage = signal(initialPage());
|
|
3685
3876
|
const lastResetTimestamp = signal(Date.now());
|
|
3686
3877
|
const pageDirection = signal('next');
|
|
3687
|
-
const stack = createQueryStack(
|
|
3688
|
-
|
|
3689
|
-
|
|
3690
|
-
return null;
|
|
3691
|
-
return queryCreator(withArgs(() => {
|
|
3692
|
-
return args;
|
|
3693
|
-
}));
|
|
3694
|
-
}, {
|
|
3878
|
+
const stack = createQueryStack({
|
|
3879
|
+
args: () => currentPageArgs(),
|
|
3880
|
+
queryCreator,
|
|
3695
3881
|
append: true,
|
|
3882
|
+
features,
|
|
3696
3883
|
appendFn: (oldQueries, newQueries) => {
|
|
3697
3884
|
const newQuery = newQueries[0];
|
|
3698
3885
|
const dir = pageDirection();
|
|
@@ -3729,7 +3916,7 @@ const createPagedQuery = (options) => {
|
|
|
3729
3916
|
const page = loadedMinPage() - 1;
|
|
3730
3917
|
if (page < 1) {
|
|
3731
3918
|
if (isDevMode()) {
|
|
3732
|
-
throw
|
|
3919
|
+
throw pagedQueryStackPreviousPageCalledButAlreadyAtFirstPage();
|
|
3733
3920
|
}
|
|
3734
3921
|
return;
|
|
3735
3922
|
}
|
|
@@ -3742,13 +3929,13 @@ const createPagedQuery = (options) => {
|
|
|
3742
3929
|
const currentPagination = pagination();
|
|
3743
3930
|
if (!currentPagination) {
|
|
3744
3931
|
if (isDevMode()) {
|
|
3745
|
-
throw
|
|
3932
|
+
throw pagedQueryStackNextPageCalledWithoutPreviousPage();
|
|
3746
3933
|
}
|
|
3747
3934
|
return;
|
|
3748
3935
|
}
|
|
3749
3936
|
if (page > currentPagination.totalPages) {
|
|
3750
3937
|
if (isDevMode()) {
|
|
3751
|
-
throw
|
|
3938
|
+
throw pagedQueryStackPageBiggerThanTotalPages(page, currentPagination.totalPages);
|
|
3752
3939
|
}
|
|
3753
3940
|
return;
|
|
3754
3941
|
}
|
|
@@ -3762,7 +3949,12 @@ const createPagedQuery = (options) => {
|
|
|
3762
3949
|
pageDirection.set('next');
|
|
3763
3950
|
lastResetTimestamp.set(Date.now());
|
|
3764
3951
|
};
|
|
3765
|
-
const canFetchPreviousPage = computed(() =>
|
|
3952
|
+
const canFetchPreviousPage = computed(() => {
|
|
3953
|
+
const currentPagination = pagination();
|
|
3954
|
+
if (!currentPagination)
|
|
3955
|
+
return false;
|
|
3956
|
+
return loadedMinPage() > 1;
|
|
3957
|
+
});
|
|
3766
3958
|
const canFetchNextPage = computed(() => {
|
|
3767
3959
|
const currentPagination = pagination();
|
|
3768
3960
|
return currentPagination ? loadedMaxPage() < currentPagination.totalPages : false;
|
|
@@ -3777,32 +3969,41 @@ const createPagedQuery = (options) => {
|
|
|
3777
3969
|
return stack.queries().length === 1 && !!stack.lastQuery()?.loading();
|
|
3778
3970
|
});
|
|
3779
3971
|
const execute = (options) => {
|
|
3780
|
-
|
|
3781
|
-
|
|
3972
|
+
const whereFn = options?.where;
|
|
3973
|
+
if (whereFn) {
|
|
3974
|
+
const queriesToExecute = new Set();
|
|
3782
3975
|
for (const [index, query] of stack.queries().entries()) {
|
|
3783
|
-
|
|
3784
|
-
|
|
3785
|
-
|
|
3786
|
-
|
|
3787
|
-
|
|
3788
|
-
|
|
3789
|
-
|
|
3976
|
+
const res = query.response();
|
|
3977
|
+
const err = query.error();
|
|
3978
|
+
const isErroredAndCanBeRetried = err && shouldRetryRequest(err);
|
|
3979
|
+
if (isErroredAndCanBeRetried) {
|
|
3980
|
+
queriesToExecute.add(query);
|
|
3981
|
+
}
|
|
3982
|
+
else if (res) {
|
|
3983
|
+
if (responseNormalizer(res).items.some((item, i, a) => whereFn(item, i, a))) {
|
|
3984
|
+
queriesToExecute.add(query);
|
|
3985
|
+
// Also execute the previous and next query to the one that matched the condition.
|
|
3986
|
+
if (index !== 0) {
|
|
3987
|
+
const prevQuery = stack.queries()[index - 1];
|
|
3988
|
+
if (prevQuery) {
|
|
3989
|
+
queriesToExecute.add(prevQuery);
|
|
3990
|
+
}
|
|
3790
3991
|
}
|
|
3791
|
-
|
|
3792
|
-
|
|
3793
|
-
|
|
3794
|
-
|
|
3795
|
-
|
|
3992
|
+
if (index !== stack.queries().length - 1) {
|
|
3993
|
+
const nextQuery = stack.queries()[index + 1];
|
|
3994
|
+
if (nextQuery) {
|
|
3995
|
+
queriesToExecute.add(nextQuery);
|
|
3996
|
+
}
|
|
3796
3997
|
}
|
|
3797
3998
|
}
|
|
3798
3999
|
}
|
|
3799
4000
|
}
|
|
3800
4001
|
for (const query of queriesToExecute) {
|
|
3801
|
-
query.execute({ options: {
|
|
4002
|
+
query.execute({ options: { allowCache: options.allowCache } });
|
|
3802
4003
|
}
|
|
3803
4004
|
}
|
|
3804
4005
|
else {
|
|
3805
|
-
stack.execute({
|
|
4006
|
+
stack.execute({ allowCache: options?.allowCache });
|
|
3806
4007
|
}
|
|
3807
4008
|
};
|
|
3808
4009
|
const pagedQuery = {
|
|
@@ -3817,7 +4018,7 @@ const createPagedQuery = (options) => {
|
|
|
3817
4018
|
error: stack.error,
|
|
3818
4019
|
lastQuery: stack.lastQuery,
|
|
3819
4020
|
isFirstLoad,
|
|
3820
|
-
queries: stack.queries
|
|
4021
|
+
queries: stack.queries,
|
|
3821
4022
|
reset,
|
|
3822
4023
|
execute,
|
|
3823
4024
|
};
|
|
@@ -3828,12 +4029,32 @@ const setupQueryDependencies = (options) => {
|
|
|
3828
4029
|
const environmentInjector = inject(EnvironmentInjector);
|
|
3829
4030
|
const queryEnvironmentInjector = createEnvironmentInjector([], environmentInjector);
|
|
3830
4031
|
const destroyRef = queryEnvironmentInjector.get(DestroyRef);
|
|
4032
|
+
const scopeDestroyRef = inject(DestroyRef);
|
|
3831
4033
|
const client = inject(options.clientConfig.token);
|
|
3832
4034
|
const dependencies = {
|
|
3833
4035
|
destroyRef,
|
|
4036
|
+
scopeDestroyRef,
|
|
3834
4037
|
client,
|
|
3835
4038
|
injector: queryEnvironmentInjector,
|
|
3836
4039
|
};
|
|
4040
|
+
// cleanup the environment injector when the scope (e.g. the component the query is in) is destroyed
|
|
4041
|
+
const scopeDestroyListener = scopeDestroyRef.onDestroy(() => {
|
|
4042
|
+
try {
|
|
4043
|
+
queryEnvironmentInjector.destroy();
|
|
4044
|
+
}
|
|
4045
|
+
catch {
|
|
4046
|
+
// ignore
|
|
4047
|
+
}
|
|
4048
|
+
});
|
|
4049
|
+
destroyRef.onDestroy(() => {
|
|
4050
|
+
// cleanup the scope destroy listener
|
|
4051
|
+
try {
|
|
4052
|
+
scopeDestroyListener();
|
|
4053
|
+
}
|
|
4054
|
+
catch {
|
|
4055
|
+
// ignore
|
|
4056
|
+
}
|
|
4057
|
+
});
|
|
3837
4058
|
return dependencies;
|
|
3838
4059
|
};
|
|
3839
4060
|
|
|
@@ -3856,7 +4077,7 @@ const setupQueryExecuteState = () => {
|
|
|
3856
4077
|
};
|
|
3857
4078
|
};
|
|
3858
4079
|
const queryExecute = (options) => {
|
|
3859
|
-
const { executeOptions, args, executeState, options: runQueryOptions } = options;
|
|
4080
|
+
const { executeOptions, args, executeState, options: runQueryOptions, internalOptions: internalRunQueryOptions, transformResponse, } = options;
|
|
3860
4081
|
const { deps, state, creator, creatorInternals, queryConfig } = executeOptions;
|
|
3861
4082
|
const { key, request } = deps.client.repository.request({
|
|
3862
4083
|
route: creator.route,
|
|
@@ -3871,11 +4092,13 @@ const queryExecute = (options) => {
|
|
|
3871
4092
|
destroyRef: deps.destroyRef,
|
|
3872
4093
|
key: queryConfig.key,
|
|
3873
4094
|
previousKey: executeState.previousKey(),
|
|
4095
|
+
internalRunQueryOptions,
|
|
3874
4096
|
runQueryOptions,
|
|
3875
4097
|
});
|
|
3876
4098
|
executeState.previousKey.set(key);
|
|
4099
|
+
const responseSignal = transformResponse ? computed(() => transformResponse(request.response())) : request.response;
|
|
3877
4100
|
runInInjectionContext(deps.injector, () => {
|
|
3878
|
-
const responseRef = syncSignal(
|
|
4101
|
+
const responseRef = syncSignal(responseSignal, state.response);
|
|
3879
4102
|
const loadingRef = syncSignal(request.loading, state.loading);
|
|
3880
4103
|
const errorRef = syncSignal(request.error, state.error);
|
|
3881
4104
|
const latestHttpEventRef = syncSignal(request.currentEvent, state.latestHttpEvent);
|
|
@@ -3902,88 +4125,22 @@ const createExecuteFn = (executeOptions) => {
|
|
|
3902
4125
|
return exec;
|
|
3903
4126
|
};
|
|
3904
4127
|
|
|
3905
|
-
const setupQueryState = (options) => {
|
|
3906
|
-
const response = signal(null);
|
|
3907
|
-
const args = signal(null);
|
|
3908
|
-
const latestHttpEvent = signal(null);
|
|
3909
|
-
const error = signal(null);
|
|
3910
|
-
const loading = signal(null);
|
|
3911
|
-
const lastTimeExecutedAt = signal(null);
|
|
3912
|
-
const state = {
|
|
3913
|
-
response,
|
|
3914
|
-
args,
|
|
3915
|
-
latestHttpEvent,
|
|
3916
|
-
loading,
|
|
3917
|
-
error,
|
|
3918
|
-
lastTimeExecutedAt,
|
|
3919
|
-
};
|
|
3920
|
-
return state;
|
|
3921
|
-
};
|
|
3922
|
-
|
|
3923
|
-
const createQuerySnapshotFn = (options) => {
|
|
3924
|
-
const { state, deps } = options;
|
|
3925
|
-
const snapshotFn = () => {
|
|
3926
|
-
const snapshotState = setupQueryState({});
|
|
3927
|
-
const isAlive = signal(true);
|
|
3928
|
-
const killEffectRef = effect(() => {
|
|
3929
|
-
const currentLoading = state.loading();
|
|
3930
|
-
const currentError = state.error();
|
|
3931
|
-
const currentResponse = state.response();
|
|
3932
|
-
const currentArgs = state.args();
|
|
3933
|
-
const currentLatestHttpEvent = state.latestHttpEvent();
|
|
3934
|
-
const currentLastTimeExecutedAt = state.lastTimeExecutedAt();
|
|
3935
|
-
untracked(() => {
|
|
3936
|
-
snapshotState.args.set(currentArgs);
|
|
3937
|
-
snapshotState.error.set(currentError);
|
|
3938
|
-
snapshotState.lastTimeExecutedAt.set(currentLastTimeExecutedAt);
|
|
3939
|
-
snapshotState.latestHttpEvent.set(currentLatestHttpEvent);
|
|
3940
|
-
snapshotState.loading.set(currentLoading);
|
|
3941
|
-
snapshotState.response.set(currentResponse);
|
|
3942
|
-
if (currentLoading)
|
|
3943
|
-
return;
|
|
3944
|
-
if (!currentResponse && !currentError)
|
|
3945
|
-
return;
|
|
3946
|
-
// kill the effect once loading is done and we either have a response or an error
|
|
3947
|
-
killEffectRef.destroy();
|
|
3948
|
-
isAlive.set(false);
|
|
3949
|
-
});
|
|
3950
|
-
}, { injector: deps.injector });
|
|
3951
|
-
const snapshot = {
|
|
3952
|
-
args: snapshotState.args.asReadonly(),
|
|
3953
|
-
response: snapshotState.response.asReadonly(),
|
|
3954
|
-
latestHttpEvent: snapshotState.latestHttpEvent.asReadonly(),
|
|
3955
|
-
loading: snapshotState.loading.asReadonly(),
|
|
3956
|
-
error: snapshotState.error.asReadonly(),
|
|
3957
|
-
lastTimeExecutedAt: snapshotState.lastTimeExecutedAt.asReadonly(),
|
|
3958
|
-
isAlive: isAlive.asReadonly(),
|
|
3959
|
-
id: options.execute.currentRepositoryKey,
|
|
3960
|
-
};
|
|
3961
|
-
return snapshot;
|
|
3962
|
-
};
|
|
3963
|
-
return snapshotFn;
|
|
3964
|
-
};
|
|
3965
|
-
|
|
3966
4128
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
3967
4129
|
const createQuery = (options) => {
|
|
3968
4130
|
const deps = setupQueryDependencies({ clientConfig: options.creatorInternals.client });
|
|
3969
4131
|
const state = setupQueryState({});
|
|
3970
4132
|
const { creator, creatorInternals, queryConfig } = options;
|
|
3971
4133
|
const flags = getQueryFeatureUsage(options);
|
|
3972
|
-
const execute = createExecuteFn({ deps, state, creator, creatorInternals, queryConfig
|
|
3973
|
-
const createSnapshot = createQuerySnapshotFn({ state, deps, execute });
|
|
3974
|
-
const destroy = () => deps.injector.destroy();
|
|
4134
|
+
const execute = createExecuteFn({ deps, state, creator, creatorInternals, queryConfig });
|
|
3975
4135
|
const featureFnContext = {
|
|
3976
4136
|
state,
|
|
3977
|
-
queryConfig,
|
|
3978
|
-
creatorConfig: creator,
|
|
3979
|
-
creatorInternals,
|
|
3980
4137
|
execute,
|
|
3981
4138
|
flags,
|
|
3982
4139
|
deps,
|
|
3983
4140
|
};
|
|
3984
|
-
applyQueryFeatures(options, featureFnContext);
|
|
4141
|
+
applyQueryFeatures(options.features, featureFnContext);
|
|
3985
4142
|
maybeExecute({ execute, flags });
|
|
3986
|
-
return createQueryObject({ state, execute,
|
|
4143
|
+
return createQueryObject({ state, execute, deps });
|
|
3987
4144
|
};
|
|
3988
4145
|
|
|
3989
4146
|
const createQueryRepository = (config) => {
|
|
@@ -3991,11 +4148,13 @@ const createQueryRepository = (config) => {
|
|
|
3991
4148
|
const cache = new Map();
|
|
3992
4149
|
const request = (options) => {
|
|
3993
4150
|
const { args, clientOptions, runQueryOptions } = options;
|
|
3994
|
-
const shouldCache =
|
|
4151
|
+
const shouldCache = options.internalRunQueryOptions?.useQueryRepositoryCache === false
|
|
4152
|
+
? false
|
|
4153
|
+
: shouldCacheQuery(options.method) || options.internalRunQueryOptions?.useQueryRepositoryCache === true;
|
|
3995
4154
|
if (!shouldCache && options.key)
|
|
3996
4155
|
throw uncacheableRequestHasCacheKeyParam(options.key);
|
|
3997
|
-
if (!shouldCache && runQueryOptions?.
|
|
3998
|
-
throw
|
|
4156
|
+
if (!shouldCache && runQueryOptions?.allowCache)
|
|
4157
|
+
throw uncacheableRequestHasAllowCacheParam();
|
|
3999
4158
|
const route = buildRoute({
|
|
4000
4159
|
base: config.baseUrl,
|
|
4001
4160
|
route: options.route,
|
|
@@ -4008,8 +4167,7 @@ const createQueryRepository = (config) => {
|
|
|
4008
4167
|
body: args?.body,
|
|
4009
4168
|
queryParams: args?.queryParams,
|
|
4010
4169
|
pathParams: args?.pathParams,
|
|
4011
|
-
|
|
4012
|
-
// headers: args?.headers,
|
|
4170
|
+
headers: args?.headers,
|
|
4013
4171
|
});
|
|
4014
4172
|
const previousKey = options.previousKey;
|
|
4015
4173
|
if (key !== previousKey && previousKey) {
|
|
@@ -4019,8 +4177,8 @@ const createQueryRepository = (config) => {
|
|
|
4019
4177
|
const cacheEntry = cache.get(key);
|
|
4020
4178
|
if (cacheEntry) {
|
|
4021
4179
|
bind(key, options.destroyRef, cacheEntry.request);
|
|
4022
|
-
if (runQueryOptions?.
|
|
4023
|
-
cacheEntry.request.execute({
|
|
4180
|
+
if (!runQueryOptions?.allowCache || cacheEntry.request.isStale()) {
|
|
4181
|
+
cacheEntry.request.execute({ allowCache: runQueryOptions?.allowCache });
|
|
4024
4182
|
}
|
|
4025
4183
|
return { key, request: cacheEntry.request };
|
|
4026
4184
|
}
|
|
@@ -4091,6 +4249,10 @@ const provideQueryClient = (config) => {
|
|
|
4091
4249
|
};
|
|
4092
4250
|
};
|
|
4093
4251
|
|
|
4252
|
+
/**
|
|
4253
|
+
* This function creates a query client config.
|
|
4254
|
+
* The config is used to create a query client using the `provideQueryClient(myConfig)` function.
|
|
4255
|
+
*/
|
|
4094
4256
|
const createQueryClientConfig = (options) => {
|
|
4095
4257
|
const token = new InjectionToken(`QueryClient_${options.name}`);
|
|
4096
4258
|
const clientConfig = {
|
|
@@ -4098,6 +4260,9 @@ const createQueryClientConfig = (options) => {
|
|
|
4098
4260
|
token,
|
|
4099
4261
|
name: options.name,
|
|
4100
4262
|
queryString: options.queryString,
|
|
4263
|
+
// createHttpRequest will use fallbacks if these are not provided
|
|
4264
|
+
cacheAdapter: options.cacheAdapter,
|
|
4265
|
+
retryFn: options.retryFn,
|
|
4101
4266
|
};
|
|
4102
4267
|
return clientConfig;
|
|
4103
4268
|
};
|
|
@@ -4214,22 +4379,17 @@ const createSecureQuery = (options) => {
|
|
|
4214
4379
|
state,
|
|
4215
4380
|
creator,
|
|
4216
4381
|
creatorInternals,
|
|
4217
|
-
queryConfig
|
|
4382
|
+
queryConfig,
|
|
4218
4383
|
});
|
|
4219
|
-
const createSnapshot = createQuerySnapshotFn({ state, deps, execute });
|
|
4220
|
-
const destroy = () => deps.injector.destroy();
|
|
4221
4384
|
const featureFnContext = {
|
|
4385
|
+
deps,
|
|
4222
4386
|
state,
|
|
4223
|
-
queryConfig,
|
|
4224
|
-
creatorConfig: creator,
|
|
4225
|
-
creatorInternals,
|
|
4226
4387
|
execute,
|
|
4227
4388
|
flags,
|
|
4228
|
-
deps,
|
|
4229
4389
|
};
|
|
4230
|
-
applyQueryFeatures(options, featureFnContext);
|
|
4390
|
+
applyQueryFeatures(options.features, featureFnContext);
|
|
4231
4391
|
maybeExecute({ execute, flags });
|
|
4232
|
-
return createQueryObject({ state, execute,
|
|
4392
|
+
return createQueryObject({ state, execute, deps });
|
|
4233
4393
|
};
|
|
4234
4394
|
|
|
4235
4395
|
const createSecureQueryCreator = (options, internals) => {
|
|
@@ -4245,44 +4405,275 @@ const createSecureQueryCreator = (options, internals) => {
|
|
|
4245
4405
|
return queryCreator;
|
|
4246
4406
|
};
|
|
4247
4407
|
|
|
4408
|
+
/** A query creator that creates a GET query */
|
|
4248
4409
|
const createGetQuery = (client) => {
|
|
4249
4410
|
return (creatorOptions) => createQueryCreator(creatorOptions, { method: 'GET', client });
|
|
4250
4411
|
};
|
|
4412
|
+
/** A query creator that creates a secure GET query (requires authentication) */
|
|
4251
4413
|
const createSecureGetQuery = (client, authProvider) => {
|
|
4252
4414
|
return (creatorOptions) => createSecureQueryCreator(creatorOptions, { method: 'GET', client, authProvider });
|
|
4253
4415
|
};
|
|
4416
|
+
/** A query creator that creates a POST query */
|
|
4254
4417
|
const createPostQuery = (client) => {
|
|
4255
4418
|
return (creatorOptions) => createQueryCreator(creatorOptions, { method: 'POST', client });
|
|
4256
4419
|
};
|
|
4420
|
+
/** A query creator that creates a secure POST query (requires authentication) */
|
|
4257
4421
|
const createSecurePostQuery = (client, authProvider) => {
|
|
4258
4422
|
return (creatorOptions) => createSecureQueryCreator(creatorOptions, { method: 'POST', client, authProvider });
|
|
4259
4423
|
};
|
|
4424
|
+
/** A query creator that creates a PUT query */
|
|
4260
4425
|
const createPutQuery = (client) => {
|
|
4261
4426
|
return (creatorOptions) => createQueryCreator(creatorOptions, { method: 'PUT', client });
|
|
4262
4427
|
};
|
|
4428
|
+
/** A query creator that creates a secure PUT query (requires authentication) */
|
|
4263
4429
|
const createSecurePutQuery = (client, authProvider) => {
|
|
4264
4430
|
return (creatorOptions) => createSecureQueryCreator(creatorOptions, { method: 'PUT', client, authProvider });
|
|
4265
4431
|
};
|
|
4432
|
+
/** A query creator that creates a DELETE query */
|
|
4266
4433
|
const createDeleteQuery = (client) => {
|
|
4267
4434
|
return (creatorOptions) => createQueryCreator(creatorOptions, { method: 'DELETE', client });
|
|
4268
4435
|
};
|
|
4436
|
+
/** A query creator that creates a secure DELETE query (requires authentication) */
|
|
4269
4437
|
const createSecureDeleteQuery = (client, authProvider) => {
|
|
4270
4438
|
return (creatorOptions) => createSecureQueryCreator(creatorOptions, { method: 'DELETE', client, authProvider });
|
|
4271
4439
|
};
|
|
4440
|
+
/** A query creator that creates a PATCH query */
|
|
4272
4441
|
const createPatchQuery = (client) => {
|
|
4273
4442
|
return (creatorOptions) => createQueryCreator(creatorOptions, { method: 'PATCH', client });
|
|
4274
4443
|
};
|
|
4444
|
+
/** A query creator that creates a secure PATCH query (requires authentication) */
|
|
4275
4445
|
const createSecurePatchQuery = (client, authProvider) => {
|
|
4276
4446
|
return (creatorOptions) => createSecureQueryCreator(creatorOptions, { method: 'PATCH', client, authProvider });
|
|
4277
4447
|
};
|
|
4278
4448
|
|
|
4449
|
+
const createGqlExecuteFn = (executeOptions) => {
|
|
4450
|
+
const executeState = setupQueryExecuteState();
|
|
4451
|
+
const reset = () => resetExecuteState({ executeState, executeOptions });
|
|
4452
|
+
const exec = (executeArgs) => {
|
|
4453
|
+
const { args = executeOptions.state.args(), options } = executeArgs ?? {};
|
|
4454
|
+
cleanupPreviousExecute({ executeOptions, executeState });
|
|
4455
|
+
// TODO: This should get cleaned up
|
|
4456
|
+
const tpl = executeOptions.creator.query;
|
|
4457
|
+
const query = transformGql(tpl);
|
|
4458
|
+
let gqlParams = query(args?.variables);
|
|
4459
|
+
if (args?.queryParams && executeOptions.creatorInternals.transport === 'GET') {
|
|
4460
|
+
gqlParams = { ...gqlParams, ...args.queryParams };
|
|
4461
|
+
}
|
|
4462
|
+
const computedArgs = args ?? {};
|
|
4463
|
+
if (executeOptions.creatorInternals.transport === 'GET') {
|
|
4464
|
+
computedArgs.queryParams = gqlParams;
|
|
4465
|
+
}
|
|
4466
|
+
else {
|
|
4467
|
+
computedArgs.body = gqlParams;
|
|
4468
|
+
}
|
|
4469
|
+
const normalizedOpts = {
|
|
4470
|
+
creator: {
|
|
4471
|
+
route: (executeOptions.creator.route ?? ''),
|
|
4472
|
+
},
|
|
4473
|
+
creatorInternals: {
|
|
4474
|
+
client: executeOptions.creatorInternals.client,
|
|
4475
|
+
method: executeOptions.creatorInternals.transport,
|
|
4476
|
+
},
|
|
4477
|
+
deps: executeOptions.deps,
|
|
4478
|
+
queryConfig: executeOptions.queryConfig,
|
|
4479
|
+
state: executeOptions.state,
|
|
4480
|
+
};
|
|
4481
|
+
queryExecute({
|
|
4482
|
+
executeOptions: normalizedOpts,
|
|
4483
|
+
executeState,
|
|
4484
|
+
args: computedArgs,
|
|
4485
|
+
options,
|
|
4486
|
+
internalOptions: {
|
|
4487
|
+
useQueryRepositoryCache: executeOptions.creatorInternals.method === 'QUERY',
|
|
4488
|
+
},
|
|
4489
|
+
transformResponse: (originalResponse) => {
|
|
4490
|
+
if (originalResponse && 'data' in originalResponse) {
|
|
4491
|
+
return originalResponse.data;
|
|
4492
|
+
}
|
|
4493
|
+
return originalResponse;
|
|
4494
|
+
},
|
|
4495
|
+
});
|
|
4496
|
+
};
|
|
4497
|
+
exec['reset'] = reset;
|
|
4498
|
+
exec['currentRepositoryKey'] = executeState.previousKey.asReadonly();
|
|
4499
|
+
return exec;
|
|
4500
|
+
};
|
|
4501
|
+
|
|
4502
|
+
const isCreateGqlQueryOptions = (options) => {
|
|
4503
|
+
return 'transport' in options.creatorInternals;
|
|
4504
|
+
};
|
|
4505
|
+
const createGqlQuery = (options) => {
|
|
4506
|
+
const deps = setupQueryDependencies({ clientConfig: options.creatorInternals.client });
|
|
4507
|
+
const state = setupQueryState({});
|
|
4508
|
+
const { creator, creatorInternals, queryConfig } = options;
|
|
4509
|
+
const flags = getQueryFeatureUsage(options);
|
|
4510
|
+
const execute = createGqlExecuteFn({
|
|
4511
|
+
deps,
|
|
4512
|
+
state,
|
|
4513
|
+
creator,
|
|
4514
|
+
creatorInternals,
|
|
4515
|
+
queryConfig,
|
|
4516
|
+
});
|
|
4517
|
+
const featureFnContext = {
|
|
4518
|
+
state,
|
|
4519
|
+
execute,
|
|
4520
|
+
flags,
|
|
4521
|
+
deps,
|
|
4522
|
+
};
|
|
4523
|
+
applyQueryFeatures(options.features, featureFnContext);
|
|
4524
|
+
maybeExecute({ execute, flags });
|
|
4525
|
+
return createQueryObject({ state, execute, deps });
|
|
4526
|
+
};
|
|
4527
|
+
|
|
4528
|
+
const createGqlQueryCreator = (options, internals) => {
|
|
4529
|
+
function queryCreator(...args) {
|
|
4530
|
+
const { features, queryConfig } = splitQueryConfig(args);
|
|
4531
|
+
return createGqlQuery({
|
|
4532
|
+
creator: options,
|
|
4533
|
+
creatorInternals: internals,
|
|
4534
|
+
features,
|
|
4535
|
+
queryConfig,
|
|
4536
|
+
});
|
|
4537
|
+
}
|
|
4538
|
+
return queryCreator;
|
|
4539
|
+
};
|
|
4540
|
+
|
|
4541
|
+
/** A query creator that creates a GQL query where the payload is sent via GET (query params) */
|
|
4542
|
+
const createGqlQueryViaGet = (client) => {
|
|
4543
|
+
return (creatorOptions) => createGqlQueryCreator(creatorOptions, { method: 'QUERY', client, transport: 'GET' });
|
|
4544
|
+
};
|
|
4545
|
+
/** A query creator that creates a GQL query where the payload is sent via POST (body) */
|
|
4546
|
+
const createGqlQueryViaPost = (client) => {
|
|
4547
|
+
return (creatorOptions) => createGqlQueryCreator(creatorOptions, { method: 'QUERY', client, transport: 'POST' });
|
|
4548
|
+
};
|
|
4549
|
+
/** A query creator that creates a GQL mutation where the payload is sent via GET (query params) */
|
|
4550
|
+
const createGqlMutationViaGet = (client) => {
|
|
4551
|
+
return (creatorOptions) => createGqlQueryCreator(creatorOptions, { method: 'MUTATE', client, transport: 'GET' });
|
|
4552
|
+
};
|
|
4553
|
+
/** A query creator that creates a GQL mutation where the payload is sent via POST (body) */
|
|
4554
|
+
const createGqlMutationViaPost = (client) => {
|
|
4555
|
+
return (creatorOptions) => createGqlQueryCreator(creatorOptions, { method: 'MUTATE', client, transport: 'POST' });
|
|
4556
|
+
};
|
|
4557
|
+
|
|
4558
|
+
const roomAlreadyJoined = (room) => {
|
|
4559
|
+
return new RuntimeError(1000 /* QueryRuntimeErrorCode.ROOM_ALREADY_JOINED */, `Tried joining the room "${room}" but it has already been joined.`);
|
|
4560
|
+
};
|
|
4561
|
+
const roomNotJoined = (room) => {
|
|
4562
|
+
return new RuntimeError(1001 /* QueryRuntimeErrorCode.ROOM_NOT_JOINED */, `Tried leaving the room "${room}" but it has not been joined.`);
|
|
4563
|
+
};
|
|
4564
|
+
const messageMalformed = () => {
|
|
4565
|
+
return new RuntimeError(1002 /* QueryRuntimeErrorCode.MESSAGE_MALFORMED */, 'A message has been received but it is malformed (cannot be parsed as JSON).');
|
|
4566
|
+
};
|
|
4567
|
+
|
|
4568
|
+
const createWebSocketClient = (config) => {
|
|
4569
|
+
const joinedRooms = new Set();
|
|
4570
|
+
const socket = io(config.url, {
|
|
4571
|
+
withCredentials: true,
|
|
4572
|
+
autoConnect: false,
|
|
4573
|
+
});
|
|
4574
|
+
const currentEvent = signal(null);
|
|
4575
|
+
const isConnected = signal(false);
|
|
4576
|
+
const joinRoom = (room) => {
|
|
4577
|
+
if (joinedRooms.has(room)) {
|
|
4578
|
+
if (isDevMode())
|
|
4579
|
+
throw roomAlreadyJoined(room);
|
|
4580
|
+
return;
|
|
4581
|
+
}
|
|
4582
|
+
socket.emit('join-room', room);
|
|
4583
|
+
joinedRooms.add(room);
|
|
4584
|
+
};
|
|
4585
|
+
const joinComputedRoom = (room) => {
|
|
4586
|
+
const pre = previousSignalValue(computed(() => room()));
|
|
4587
|
+
effect(() => {
|
|
4588
|
+
const current = room();
|
|
4589
|
+
untracked(() => {
|
|
4590
|
+
const previous = pre();
|
|
4591
|
+
if (previous === current)
|
|
4592
|
+
return;
|
|
4593
|
+
if (previous)
|
|
4594
|
+
leaveRoom(previous);
|
|
4595
|
+
if (current)
|
|
4596
|
+
joinRoom(current);
|
|
4597
|
+
});
|
|
4598
|
+
});
|
|
4599
|
+
inject(DestroyRef).onDestroy(() => {
|
|
4600
|
+
const current = room();
|
|
4601
|
+
if (current)
|
|
4602
|
+
leaveRoom(current);
|
|
4603
|
+
});
|
|
4604
|
+
};
|
|
4605
|
+
const leaveRoom = (room) => {
|
|
4606
|
+
if (!joinedRooms.has(room)) {
|
|
4607
|
+
if (isDevMode())
|
|
4608
|
+
throw roomNotJoined(room);
|
|
4609
|
+
return;
|
|
4610
|
+
}
|
|
4611
|
+
socket.emit('leave-room', room);
|
|
4612
|
+
joinedRooms.delete(room);
|
|
4613
|
+
};
|
|
4614
|
+
const leaveAllRooms = () => {
|
|
4615
|
+
joinedRooms.forEach((room) => leaveRoom(room));
|
|
4616
|
+
joinedRooms.clear();
|
|
4617
|
+
};
|
|
4618
|
+
const setupWebSocketConnectionListener = () => {
|
|
4619
|
+
socket.on('connect', () => {
|
|
4620
|
+
isConnected.set(true);
|
|
4621
|
+
joinedRooms.forEach((room) => joinRoom(room));
|
|
4622
|
+
});
|
|
4623
|
+
socket.on('disconnect', () => isConnected.set(false));
|
|
4624
|
+
};
|
|
4625
|
+
const setupWebSocketListener = () => {
|
|
4626
|
+
socket.onAny((data) => {
|
|
4627
|
+
try {
|
|
4628
|
+
const json = JSON.parse(data);
|
|
4629
|
+
currentEvent.set(json);
|
|
4630
|
+
}
|
|
4631
|
+
catch (error) {
|
|
4632
|
+
console.error(error);
|
|
4633
|
+
if (isDevMode())
|
|
4634
|
+
throw messageMalformed();
|
|
4635
|
+
}
|
|
4636
|
+
});
|
|
4637
|
+
};
|
|
4638
|
+
inject(DestroyRef).onDestroy(() => socket.disconnect());
|
|
4639
|
+
setupWebSocketConnectionListener();
|
|
4640
|
+
setupWebSocketListener();
|
|
4641
|
+
socket.connect();
|
|
4642
|
+
const client = {
|
|
4643
|
+
joinRoom,
|
|
4644
|
+
joinComputedRoom,
|
|
4645
|
+
leaveRoom,
|
|
4646
|
+
leaveAllRooms,
|
|
4647
|
+
currentEvent: currentEvent.asReadonly(),
|
|
4648
|
+
isConnected: isConnected.asReadonly(),
|
|
4649
|
+
};
|
|
4650
|
+
return client;
|
|
4651
|
+
};
|
|
4652
|
+
const provideWebSocketClient = (config) => {
|
|
4653
|
+
return {
|
|
4654
|
+
provide: config.token,
|
|
4655
|
+
useFactory: () => createWebSocketClient(config),
|
|
4656
|
+
};
|
|
4657
|
+
};
|
|
4658
|
+
|
|
4659
|
+
const createWebSocketClientConfig = (options) => {
|
|
4660
|
+
const token = new InjectionToken(`WebSocketClient_${options.name}`);
|
|
4661
|
+
const clientConfig = {
|
|
4662
|
+
token,
|
|
4663
|
+
name: options.name,
|
|
4664
|
+
url: options.url,
|
|
4665
|
+
};
|
|
4666
|
+
return clientConfig;
|
|
4667
|
+
};
|
|
4668
|
+
|
|
4279
4669
|
var index = /*#__PURE__*/Object.freeze({
|
|
4280
4670
|
__proto__: null,
|
|
4281
|
-
|
|
4671
|
+
CLEAR_QUERY_ARGS: CLEAR_QUERY_ARGS,
|
|
4282
4672
|
QUERY_EFFECT_ERROR_MESSAGE: QUERY_EFFECT_ERROR_MESSAGE,
|
|
4283
4673
|
SPEED_BUFFER_TIME_IN_MS: SPEED_BUFFER_TIME_IN_MS,
|
|
4284
4674
|
applyQueryFeatures: applyQueryFeatures,
|
|
4285
4675
|
bearerExpiresInPropertyNotNumber: bearerExpiresInPropertyNotNumber,
|
|
4676
|
+
buildQueryCacheKey: buildQueryCacheKey,
|
|
4286
4677
|
cleanupPreviousExecute: cleanupPreviousExecute,
|
|
4287
4678
|
contentfulGqlLikePaginationAdapter: contentfulGqlLikePaginationAdapter,
|
|
4288
4679
|
cookieLoginTriedButCookieDisabled: cookieLoginTriedButCookieDisabled,
|
|
@@ -4291,8 +4682,15 @@ var index = /*#__PURE__*/Object.freeze({
|
|
|
4291
4682
|
createDeleteQuery: createDeleteQuery,
|
|
4292
4683
|
createExecuteFn: createExecuteFn,
|
|
4293
4684
|
createGetQuery: createGetQuery,
|
|
4685
|
+
createGqlExecuteFn: createGqlExecuteFn,
|
|
4686
|
+
createGqlMutationViaGet: createGqlMutationViaGet,
|
|
4687
|
+
createGqlMutationViaPost: createGqlMutationViaPost,
|
|
4688
|
+
createGqlQuery: createGqlQuery,
|
|
4689
|
+
createGqlQueryCreator: createGqlQueryCreator,
|
|
4690
|
+
createGqlQueryViaGet: createGqlQueryViaGet,
|
|
4691
|
+
createGqlQueryViaPost: createGqlQueryViaPost,
|
|
4294
4692
|
createHttpRequest: createHttpRequest,
|
|
4295
|
-
|
|
4693
|
+
createPagedQueryStack: createPagedQueryStack,
|
|
4296
4694
|
createPatchQuery: createPatchQuery,
|
|
4297
4695
|
createPostQuery: createPostQuery,
|
|
4298
4696
|
createPutQuery: createPutQuery,
|
|
@@ -4312,6 +4710,8 @@ var index = /*#__PURE__*/Object.freeze({
|
|
|
4312
4710
|
createSecurePutQuery: createSecurePutQuery,
|
|
4313
4711
|
createSecureQuery: createSecureQuery,
|
|
4314
4712
|
createSecureQueryCreator: createSecureQueryCreator,
|
|
4713
|
+
createWebSocketClient: createWebSocketClient,
|
|
4714
|
+
createWebSocketClientConfig: createWebSocketClientConfig,
|
|
4315
4715
|
defaultResponseTransformerResponseNotContainingAccessToken: defaultResponseTransformerResponseNotContainingAccessToken,
|
|
4316
4716
|
defaultResponseTransformerResponseNotContainingRefreshToken: defaultResponseTransformerResponseNotContainingRefreshToken,
|
|
4317
4717
|
defaultResponseTransformerResponseNotObject: defaultResponseTransformerResponseNotObject,
|
|
@@ -4320,33 +4720,40 @@ var index = /*#__PURE__*/Object.freeze({
|
|
|
4320
4720
|
enableCookieCalledWithoutCookieConfig: enableCookieCalledWithoutCookieConfig,
|
|
4321
4721
|
ethletePaginationAdapter: ethletePaginationAdapter,
|
|
4322
4722
|
extractExpiresInSeconds: extractExpiresInSeconds,
|
|
4723
|
+
fakePaginationAdapter: fakePaginationAdapter,
|
|
4323
4724
|
getQueryFeatureUsage: getQueryFeatureUsage,
|
|
4324
4725
|
ggLikePaginationAdapter: ggLikePaginationAdapter,
|
|
4726
|
+
isCreateGqlQueryOptions: isCreateGqlQueryOptions,
|
|
4325
4727
|
loginCalledWithoutConfig: loginCalledWithoutConfig,
|
|
4326
4728
|
loginWithTokenCalledWithoutConfig: loginWithTokenCalledWithoutConfig,
|
|
4327
4729
|
maybeExecute: maybeExecute,
|
|
4328
|
-
|
|
4329
|
-
|
|
4330
|
-
|
|
4730
|
+
normalizeQueryRepositoryKey: normalizeQueryRepositoryKey,
|
|
4731
|
+
pagedQueryStackNextPageCalledWithoutPreviousPage: pagedQueryStackNextPageCalledWithoutPreviousPage,
|
|
4732
|
+
pagedQueryStackPageBiggerThanTotalPages: pagedQueryStackPageBiggerThanTotalPages,
|
|
4733
|
+
pagedQueryStackPreviousPageCalledButAlreadyAtFirstPage: pagedQueryStackPreviousPageCalledButAlreadyAtFirstPage,
|
|
4331
4734
|
provideBearerAuthProvider: provideBearerAuthProvider,
|
|
4332
4735
|
provideQueryClient: provideQueryClient,
|
|
4736
|
+
provideWebSocketClient: provideWebSocketClient,
|
|
4333
4737
|
queryEffect: queryEffect,
|
|
4334
4738
|
queryExecute: queryExecute,
|
|
4335
4739
|
queryFeatureUsedMultipleTimes: queryFeatureUsedMultipleTimes,
|
|
4740
|
+
queryStackWithArgsUsed: queryStackWithArgsUsed,
|
|
4336
4741
|
refreshTokenCalledWithoutConfig: refreshTokenCalledWithoutConfig,
|
|
4337
4742
|
resetExecuteState: resetExecuteState,
|
|
4338
4743
|
selectRoleCalledWithoutConfig: selectRoleCalledWithoutConfig,
|
|
4339
4744
|
setupQueryDependencies: setupQueryDependencies,
|
|
4340
4745
|
setupQueryExecuteState: setupQueryExecuteState,
|
|
4341
4746
|
setupQueryState: setupQueryState,
|
|
4747
|
+
shouldAutoExecuteGqlQuery: shouldAutoExecuteGqlQuery,
|
|
4342
4748
|
shouldAutoExecuteQuery: shouldAutoExecuteQuery,
|
|
4749
|
+
shouldCacheQuery: shouldCacheQuery,
|
|
4343
4750
|
shouldRetryRequest: shouldRetryRequest,
|
|
4344
4751
|
splitQueryConfig: splitQueryConfig,
|
|
4345
4752
|
transformArrayResponse: transformArrayResponse,
|
|
4346
4753
|
transformPaginatedResponse: transformPaginatedResponse,
|
|
4347
4754
|
unableToDecryptBearerToken: unableToDecryptBearerToken,
|
|
4755
|
+
uncacheableRequestHasAllowCacheParam: uncacheableRequestHasAllowCacheParam,
|
|
4348
4756
|
uncacheableRequestHasCacheKeyParam: uncacheableRequestHasCacheKeyParam,
|
|
4349
|
-
uncacheableRequestHasSkipCacheParam: uncacheableRequestHasSkipCacheParam,
|
|
4350
4757
|
withArgs: withArgs,
|
|
4351
4758
|
withArgsQueryFeatureMissingButRouteIsFunction: withArgsQueryFeatureMissingButRouteIsFunction,
|
|
4352
4759
|
withAutoRefresh: withAutoRefresh,
|
|
@@ -4458,6 +4865,7 @@ const transformToSortQueryParam = (value) => {
|
|
|
4458
4865
|
|
|
4459
4866
|
const ET_ARR_PREFIX = 'ET_ARR__';
|
|
4460
4867
|
class QueryField {
|
|
4868
|
+
data;
|
|
4461
4869
|
get control() {
|
|
4462
4870
|
return this.data.control;
|
|
4463
4871
|
}
|
|
@@ -4468,12 +4876,70 @@ class QueryField {
|
|
|
4468
4876
|
const IGNORED_FILTER_COUNT_FIELDS = ['page', 'skip', 'take', 'limit', 'sort', 'sortBy', 'sortOrder', 'query', 'search'];
|
|
4469
4877
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
4470
4878
|
class QueryForm {
|
|
4879
|
+
_fields;
|
|
4880
|
+
_options;
|
|
4881
|
+
_destroy$ = createDestroy();
|
|
4882
|
+
_unobserveTrigger$ = new Subject();
|
|
4883
|
+
_router = inject(Router);
|
|
4884
|
+
_activatedRoute = inject(ActivatedRoute);
|
|
4885
|
+
_defaultValues = this._extractDefaultValues();
|
|
4886
|
+
_zone = inject(NgZone);
|
|
4887
|
+
_didValueChanges$ = new Subject();
|
|
4888
|
+
_isObserving = false;
|
|
4889
|
+
_skipNextResets = false;
|
|
4890
|
+
_queryParamChanges$ = toObservable(injectQueryParamChanges());
|
|
4891
|
+
_queryParams = injectQueryParams();
|
|
4892
|
+
/**
|
|
4893
|
+
* The angular form group that contains all the fields.
|
|
4894
|
+
*
|
|
4895
|
+
* **Do not** use any of the following methods on this form group:
|
|
4896
|
+
* - `setValue`: Use `QueryForm.setValue` instead.
|
|
4897
|
+
* - `patchValue`: Use `QueryForm.patchValue` instead.
|
|
4898
|
+
* - `valueChanges`: Use `QueryForm.changes$` instead.
|
|
4899
|
+
* - `value`: Use `QueryForm.value` instead.
|
|
4900
|
+
* - `controls`: Use `QueryForm.controls` instead.
|
|
4901
|
+
*/
|
|
4902
|
+
form = this._setupFormGroup();
|
|
4903
|
+
_lastFormValue$ = new BehaviorSubject(null);
|
|
4904
|
+
_currentFormValue$ = new BehaviorSubject(this._formValue);
|
|
4471
4905
|
get _formValue() {
|
|
4472
4906
|
return this.form.getRawValue();
|
|
4473
4907
|
}
|
|
4474
4908
|
get _form() {
|
|
4475
4909
|
return this.form;
|
|
4476
4910
|
}
|
|
4911
|
+
_changes$ = new BehaviorSubject({
|
|
4912
|
+
previousValue: null,
|
|
4913
|
+
currentValue: this.form.getRawValue(),
|
|
4914
|
+
});
|
|
4915
|
+
changes$ = this._changes$.asObservable();
|
|
4916
|
+
currentValue$ = this._changes$.pipe(map(({ currentValue }) => currentValue));
|
|
4917
|
+
previousValue$ = this._changes$.pipe(map(({ previousValue }) => previousValue));
|
|
4918
|
+
changes = toSignal(this.changes$);
|
|
4919
|
+
currentValue = toSignal(this.currentValue$);
|
|
4920
|
+
previousValue = toSignal(this.previousValue$);
|
|
4921
|
+
/**
|
|
4922
|
+
* The number of active filters.
|
|
4923
|
+
*
|
|
4924
|
+
* Excludes the following fields by default:
|
|
4925
|
+
* - `page`
|
|
4926
|
+
* - `skip`
|
|
4927
|
+
* - `take`
|
|
4928
|
+
* - `limit`
|
|
4929
|
+
* - `sort`
|
|
4930
|
+
* - `sortBy`
|
|
4931
|
+
* - `sortOrder`
|
|
4932
|
+
* - `query`
|
|
4933
|
+
* - `search`
|
|
4934
|
+
*/
|
|
4935
|
+
activeFilterCount$ = this.changes$.pipe(map(({ currentValue }) => Object.entries(currentValue)
|
|
4936
|
+
.map(([key, value]) => {
|
|
4937
|
+
if (IGNORED_FILTER_COUNT_FIELDS.includes(key) || this._fields[key]?.data.skipInFilterCount) {
|
|
4938
|
+
return true;
|
|
4939
|
+
}
|
|
4940
|
+
return this._isDefaultValue(key, value);
|
|
4941
|
+
})
|
|
4942
|
+
.filter((v) => v === false).length));
|
|
4477
4943
|
get controls() {
|
|
4478
4944
|
return this.form.controls;
|
|
4479
4945
|
}
|
|
@@ -4490,62 +4956,6 @@ class QueryForm {
|
|
|
4490
4956
|
constructor(_fields, _options) {
|
|
4491
4957
|
this._fields = _fields;
|
|
4492
4958
|
this._options = _options;
|
|
4493
|
-
this._destroy$ = createDestroy();
|
|
4494
|
-
this._unobserveTrigger$ = new Subject();
|
|
4495
|
-
this._router = inject(Router);
|
|
4496
|
-
this._activatedRoute = inject(ActivatedRoute);
|
|
4497
|
-
this._defaultValues = this._extractDefaultValues();
|
|
4498
|
-
this._zone = inject(NgZone);
|
|
4499
|
-
this._didValueChanges$ = new Subject();
|
|
4500
|
-
this._isObserving = false;
|
|
4501
|
-
this._skipNextResets = false;
|
|
4502
|
-
this._queryParamChanges$ = toObservable(injectQueryParamChanges());
|
|
4503
|
-
this._queryParams = injectQueryParams();
|
|
4504
|
-
/**
|
|
4505
|
-
* The angular form group that contains all the fields.
|
|
4506
|
-
*
|
|
4507
|
-
* **Do not** use any of the following methods on this form group:
|
|
4508
|
-
* - `setValue`: Use `QueryForm.setValue` instead.
|
|
4509
|
-
* - `patchValue`: Use `QueryForm.patchValue` instead.
|
|
4510
|
-
* - `valueChanges`: Use `QueryForm.changes$` instead.
|
|
4511
|
-
* - `value`: Use `QueryForm.value` instead.
|
|
4512
|
-
* - `controls`: Use `QueryForm.controls` instead.
|
|
4513
|
-
*/
|
|
4514
|
-
this.form = this._setupFormGroup();
|
|
4515
|
-
this._lastFormValue$ = new BehaviorSubject(null);
|
|
4516
|
-
this._currentFormValue$ = new BehaviorSubject(this._formValue);
|
|
4517
|
-
this._changes$ = new BehaviorSubject({
|
|
4518
|
-
previousValue: null,
|
|
4519
|
-
currentValue: this.form.getRawValue(),
|
|
4520
|
-
});
|
|
4521
|
-
this.changes$ = this._changes$.asObservable();
|
|
4522
|
-
this.currentValue$ = this._changes$.pipe(map(({ currentValue }) => currentValue));
|
|
4523
|
-
this.previousValue$ = this._changes$.pipe(map(({ previousValue }) => previousValue));
|
|
4524
|
-
this.changes = toSignal(this.changes$);
|
|
4525
|
-
this.currentValue = toSignal(this.currentValue$);
|
|
4526
|
-
this.previousValue = toSignal(this.previousValue$);
|
|
4527
|
-
/**
|
|
4528
|
-
* The number of active filters.
|
|
4529
|
-
*
|
|
4530
|
-
* Excludes the following fields by default:
|
|
4531
|
-
* - `page`
|
|
4532
|
-
* - `skip`
|
|
4533
|
-
* - `take`
|
|
4534
|
-
* - `limit`
|
|
4535
|
-
* - `sort`
|
|
4536
|
-
* - `sortBy`
|
|
4537
|
-
* - `sortOrder`
|
|
4538
|
-
* - `query`
|
|
4539
|
-
* - `search`
|
|
4540
|
-
*/
|
|
4541
|
-
this.activeFilterCount$ = this.changes$.pipe(map(({ currentValue }) => Object.entries(currentValue)
|
|
4542
|
-
.map(([key, value]) => {
|
|
4543
|
-
if (IGNORED_FILTER_COUNT_FIELDS.includes(key) || this._fields[key]?.data.skipInFilterCount) {
|
|
4544
|
-
return true;
|
|
4545
|
-
}
|
|
4546
|
-
return this._isDefaultValue(key, value);
|
|
4547
|
-
})
|
|
4548
|
-
.filter((v) => v === false).length));
|
|
4549
4959
|
assertInInjectionContext(QueryForm);
|
|
4550
4960
|
inject(DestroyRef).onDestroy(() => this._cleanup());
|
|
4551
4961
|
}
|
|
@@ -4867,5 +5277,5 @@ class QueryForm {
|
|
|
4867
5277
|
* Generated bundle index. Do not edit.
|
|
4868
5278
|
*/
|
|
4869
5279
|
|
|
4870
|
-
export { BasicAuthProvider, BearerAuthProvider, CustomHeaderAuthProvider, EntityStore, index as ExperimentalQuery, INFINITY_QUERY_TOKEN, InfinityQuery, InfinityQueryDirective, InfinityQueryTriggerDirective, QUERY_CLIENT_DEVTOOLS_TOKEN, Query, QueryClient, QueryCreator, QueryDevtoolsComponent, QueryDirective, QueryError, QueryField, QueryForm, QueryShortNamePipe, QueryStore, addQueryContainerHandling, buildErrorMessage, buildQueryCacheKey, buildQueryString, buildRoute, buildTimestampFromSeconds, castQueryCreatorTypes, computeQueryAuthHeader, computeQueryBody, computeQueryHeaders, computeQueryMethod, computeQueryQueryParams, createInfinityQueryConfig, createQueryCollection, createQueryCollectionSignal, createQueryCollectionSubject, decryptBearer, deepFreeze, def, detectContentTypeHeader, extractExpiresInSeconds$1 as extractExpiresInSeconds, extractQuery, filterFailure, filterNull, filterQueryStates, filterSuccess, forEachHeader, getDefaultHeaders, getResponseUrl, gql, hasHeader, ignoreAutoRefresh, insertFrom, invalidBaseRouteError, invalidBodyError, invalidRouteError, isAutoRefresh, isBasicAuthProvider, isBearerAuthProvider, isClassValidatorError, isCustomHeaderAuthProvider, isEmptyString, isGqlQueryConfig, isNaN$1 as isNaN, isQuery, isQueryCollection, isQueryStateCancelled, isQueryStateFailure, isQueryStateLoading, isQueryStatePrepared, isQueryStateSuccess, isRequestError, isSymfonyError, isSymfonyFormViolationListError, isSymfonyListError, isSymfonyPagerfantaOutOfRangeError, mapToPaginated, mergeHeaders, paginatedEntityValueUpdater, parseAllXhrResponseHeaders, pathParamsMissingInRouteFunctionError, provideQueryClientForDevtools, queryArrayComputed, queryComputed, queryComputedTillTruthy, queryStateAlreadyHasKeyError, queryStateCannotTransformError, queryStateDoesNotContainKeyError, queryStateErrorSignal, queryStateLoadingSignal, queryStateResponseSignal, queryStateSignal, removeFrom, request, resetPageOnError, serializeBody, shouldCacheQuery, shouldRetryRequest$1 as shouldRetryRequest, skipPaginationPageParamCalculator, switchQueryCollectionState, switchQueryState, takeUntilResponse, toQuerySignal, toQuerySubject, transformGql, transformMethod, transformToBoolean, transformToBooleanArray, transformToDate, transformToDateArray, transformToNumber, transformToNumberArray, transformToSort, transformToSortQueryParam, transformToString, transformToStringArray };
|
|
5280
|
+
export { BasicAuthProvider, BearerAuthProvider, CustomHeaderAuthProvider, EntityStore, index as ExperimentalQuery, INFINITY_QUERY_TOKEN, InfinityQuery, InfinityQueryDirective, InfinityQueryTriggerDirective, QUERY_CLIENT_DEVTOOLS_TOKEN, Query, QueryClient, QueryCreator, QueryDevtoolsComponent, QueryDirective, QueryError, QueryField, QueryForm, QueryShortNamePipe, QueryStore, addQueryContainerHandling, buildErrorMessage, buildQueryCacheKey$1 as buildQueryCacheKey, buildQueryString, buildRoute, buildTimestampFromSeconds, castQueryCreatorTypes, computeQueryAuthHeader, computeQueryBody, computeQueryHeaders, computeQueryMethod, computeQueryQueryParams, createInfinityQueryConfig, createQueryCollection, createQueryCollectionSignal, createQueryCollectionSubject, decryptBearer, deepFreeze, def, detectContentTypeHeader, extractExpiresInSeconds$1 as extractExpiresInSeconds, extractQuery, filterFailure, filterNull, filterQueryStates, filterSuccess, forEachHeader, getDefaultHeaders, getResponseUrl, gql, hasHeader, ignoreAutoRefresh, insertFrom, invalidBaseRouteError, invalidBodyError, invalidRouteError, isAutoRefresh, isBasicAuthProvider, isBearerAuthProvider, isClassValidatorError, isCustomHeaderAuthProvider, isEmptyString, isGqlQueryConfig, isNaN$1 as isNaN, isQuery, isQueryCollection, isQueryStateCancelled, isQueryStateFailure, isQueryStateLoading, isQueryStatePrepared, isQueryStateSuccess, isRequestError, isSymfonyError, isSymfonyFormViolationListError, isSymfonyListError, isSymfonyPagerfantaOutOfRangeError, mapToPaginated, mergeHeaders, paginatedEntityValueUpdater, parseAllXhrResponseHeaders, pathParamsMissingInRouteFunctionError, provideQueryClientForDevtools, queryArrayComputed, queryComputed, queryComputedTillTruthy, queryStateAlreadyHasKeyError, queryStateCannotTransformError, queryStateDoesNotContainKeyError, queryStateErrorSignal, queryStateLoadingSignal, queryStateResponseSignal, queryStateSignal, removeFrom, request, resetPageOnError, serializeBody, shouldCacheQuery$1 as shouldCacheQuery, shouldRetryRequest$1 as shouldRetryRequest, skipPaginationPageParamCalculator, switchQueryCollectionState, switchQueryState, takeUntilResponse, toQuerySignal, toQuerySubject, transformGql, transformMethod, transformToBoolean, transformToBooleanArray, transformToDate, transformToDateArray, transformToNumber, transformToNumberArray, transformToSort, transformToSortQueryParam, transformToString, transformToStringArray };
|
|
4871
5281
|
//# sourceMappingURL=ethlete-query.mjs.map
|