@ethlete/query 5.23.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 +6 -0
- package/fesm2022/ethlete-query.mjs +1039 -651
- 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/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} +15 -2
- 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/{query-utils.d.ts → http/query-utils.d.ts} +25 -15
- 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/package.json +8 -7
- package/lib/experimental/paged-query.d.ts +0 -77
- 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/{http-request.d.ts → http/http-request.d.ts} +0 -0
- /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, syncSignal, getCookie, setCookie, deleteCookie, DelayableDirective, nextFrame, RuntimeError, isObject, getDomain, 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,
|
|
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';
|
|
@@ -694,67 +699,71 @@ const deepFreeze = (object) => {
|
|
|
694
699
|
const def = () => null;
|
|
695
700
|
|
|
696
701
|
class QueryCreator {
|
|
702
|
+
_queryConfig;
|
|
703
|
+
_client;
|
|
704
|
+
_store;
|
|
697
705
|
constructor(_queryConfig, _client, _store) {
|
|
698
706
|
this._queryConfig = _queryConfig;
|
|
699
707
|
this._client = _client;
|
|
700
708
|
this._store = _store;
|
|
701
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
702
|
-
// @ts-ignore
|
|
703
|
-
this.prepare = (args) => {
|
|
704
|
-
const route = buildRoute({
|
|
705
|
-
base: this._client.config.baseRoute,
|
|
706
|
-
route: this._queryConfig.route,
|
|
707
|
-
pathParams: args?.pathParams,
|
|
708
|
-
queryParams: computeQueryQueryParams({ config: this._queryConfig, client: this._client, args }),
|
|
709
|
-
queryParamConfig: this._client.config.request?.queryParams,
|
|
710
|
-
});
|
|
711
|
-
const cacheKey = (args?.config?.queryStoreCacheKey ?? '') + buildQueryCacheKey(route, args);
|
|
712
|
-
if (shouldCacheQuery(this._queryConfig.method) && !args?.config?.skipQueryStore) {
|
|
713
|
-
const existingQuery = this._store.get(cacheKey);
|
|
714
|
-
if (existingQuery) {
|
|
715
|
-
return existingQuery;
|
|
716
|
-
}
|
|
717
|
-
}
|
|
718
|
-
const query = new Query(this._client, this._queryConfig, route, args ?? {}, cacheKey);
|
|
719
|
-
if (shouldCacheQuery(this._queryConfig.method) && !args?.config?.skipQueryStore) {
|
|
720
|
-
this._store.add(cacheKey, query);
|
|
721
|
-
}
|
|
722
|
-
this._store._dispatchQueryCreated(query);
|
|
723
|
-
return query;
|
|
724
|
-
};
|
|
725
|
-
this.createSubject = (initialValue, config) => {
|
|
726
|
-
assertInInjectionContext(this.createSubject);
|
|
727
|
-
const subject = new BehaviorSubject(initialValue ?? null);
|
|
728
|
-
addQueryContainerHandling(subject, () => subject.getValue(), config);
|
|
729
|
-
return subject;
|
|
730
|
-
};
|
|
731
|
-
this.createSignal = (initialValue, config) => {
|
|
732
|
-
assertInInjectionContext(this.createSignal);
|
|
733
|
-
const _signal = signal(initialValue ?? null);
|
|
734
|
-
addQueryContainerHandling(toObservable(_signal), () => _signal(), config);
|
|
735
|
-
return _signal;
|
|
736
|
-
};
|
|
737
|
-
/**
|
|
738
|
-
* @deprecated Use `myQuery.createSubject()` or `myQuery.createSignal()` instead. Will be removed in v6.
|
|
739
|
-
*/
|
|
740
|
-
this.behaviorSubject = (initialValue) => new BehaviorSubject(initialValue ?? null);
|
|
741
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);
|
|
742
750
|
}
|
|
743
751
|
|
|
744
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();
|
|
745
765
|
constructor(_config) {
|
|
746
766
|
this._config = _config;
|
|
747
|
-
/**
|
|
748
|
-
* @internal
|
|
749
|
-
*/
|
|
750
|
-
this._store = new Map();
|
|
751
|
-
this._garbageCollector = null;
|
|
752
|
-
this._isInLowResourceMode = false;
|
|
753
|
-
this._lastBlurTimestamp = Date.now();
|
|
754
|
-
this._storeChange$ = new Subject();
|
|
755
|
-
this._queryCreated$ = new Subject();
|
|
756
|
-
this.storeChange$ = this._storeChange$.asObservable();
|
|
757
|
-
this.queryCreated$ = this._queryCreated$.asObservable();
|
|
758
767
|
this._initSmartQueryHandling();
|
|
759
768
|
}
|
|
760
769
|
add(id, query) {
|
|
@@ -885,6 +894,11 @@ class QueryStore {
|
|
|
885
894
|
}
|
|
886
895
|
|
|
887
896
|
class QueryClient {
|
|
897
|
+
_clientConfig;
|
|
898
|
+
/**
|
|
899
|
+
* @internal
|
|
900
|
+
*/
|
|
901
|
+
_store;
|
|
888
902
|
get config() {
|
|
889
903
|
return this._clientConfig;
|
|
890
904
|
}
|
|
@@ -894,64 +908,9 @@ class QueryClient {
|
|
|
894
908
|
get authProvider$() {
|
|
895
909
|
return this._authProvider$.asObservable() ?? this._clientConfig.parent?._authProvider$.asObservable() ?? null;
|
|
896
910
|
}
|
|
911
|
+
_authProvider$ = new BehaviorSubject(null);
|
|
897
912
|
constructor(_clientConfig) {
|
|
898
913
|
this._clientConfig = _clientConfig;
|
|
899
|
-
this._authProvider$ = new BehaviorSubject(null);
|
|
900
|
-
this.get = (queryConfig) => this.fetch({
|
|
901
|
-
...queryConfig,
|
|
902
|
-
method: 'GET',
|
|
903
|
-
});
|
|
904
|
-
this.post = (queryConfig) => this.fetch({
|
|
905
|
-
...queryConfig,
|
|
906
|
-
method: 'POST',
|
|
907
|
-
});
|
|
908
|
-
this.put = (queryConfig) => this.fetch({
|
|
909
|
-
...queryConfig,
|
|
910
|
-
method: 'PUT',
|
|
911
|
-
});
|
|
912
|
-
this.patch = (queryConfig) => this.fetch({
|
|
913
|
-
...queryConfig,
|
|
914
|
-
method: 'PATCH',
|
|
915
|
-
});
|
|
916
|
-
this.delete = (queryConfig) => this.fetch({
|
|
917
|
-
...queryConfig,
|
|
918
|
-
method: 'DELETE',
|
|
919
|
-
});
|
|
920
|
-
this.gqlQuery = (queryConfig) => this.fetch({
|
|
921
|
-
...queryConfig,
|
|
922
|
-
method: 'GQL_QUERY',
|
|
923
|
-
});
|
|
924
|
-
this.gqlMutate = (queryConfig) => this.fetch({
|
|
925
|
-
...queryConfig,
|
|
926
|
-
method: 'GQL_MUTATE',
|
|
927
|
-
});
|
|
928
|
-
this.fetch = (queryConfig) => new QueryCreator(queryConfig, this, this._store);
|
|
929
|
-
this.setAuthProvider = (authProvider) => {
|
|
930
|
-
if (this.authProvider) {
|
|
931
|
-
this.authProvider?.cleanUp();
|
|
932
|
-
}
|
|
933
|
-
this._authProvider$.next(authProvider);
|
|
934
|
-
};
|
|
935
|
-
this.setDefaultHeaders = (config) => {
|
|
936
|
-
if (!this._clientConfig.request) {
|
|
937
|
-
this._clientConfig.request = {
|
|
938
|
-
headers: config.headers ?? undefined,
|
|
939
|
-
};
|
|
940
|
-
}
|
|
941
|
-
else {
|
|
942
|
-
this._clientConfig.request.headers = config.headers ?? undefined;
|
|
943
|
-
}
|
|
944
|
-
if (config.refreshQueriesInUse) {
|
|
945
|
-
this._store.refreshQueriesInUse({ purgeUnused: true, ignoreCacheValidity: true });
|
|
946
|
-
}
|
|
947
|
-
};
|
|
948
|
-
this.clearAuthProvider = () => {
|
|
949
|
-
this.authProvider?.cleanUp();
|
|
950
|
-
this._authProvider$.next(null);
|
|
951
|
-
};
|
|
952
|
-
this._updateBaseRoute = (route) => {
|
|
953
|
-
this._clientConfig.baseRoute = route;
|
|
954
|
-
};
|
|
955
914
|
this._store = new QueryStore({
|
|
956
915
|
enableChangeLogging: _clientConfig.logging?.queryStateChanges,
|
|
957
916
|
enableGarbageCollectorLogging: _clientConfig.logging?.queryStateGarbageCollector,
|
|
@@ -959,12 +918,67 @@ class QueryClient {
|
|
|
959
918
|
enableSmartPolling: _clientConfig.request?.enableSmartPolling ?? true,
|
|
960
919
|
});
|
|
961
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
|
+
};
|
|
962
976
|
}
|
|
963
977
|
|
|
964
|
-
const shouldCacheQuery = (method) => {
|
|
978
|
+
const shouldCacheQuery$1 = (method) => {
|
|
965
979
|
return method === 'GET' || method === 'OPTIONS' || method === 'HEAD' || method === 'GQL_QUERY';
|
|
966
980
|
};
|
|
967
|
-
const buildQueryCacheKey = (route, args) => {
|
|
981
|
+
const buildQueryCacheKey$1 = (route, args) => {
|
|
968
982
|
const variables = JSON.stringify(args?.variables || {})
|
|
969
983
|
// replace all curly braces with empty string
|
|
970
984
|
.replace(/{|}/g, '')
|
|
@@ -988,12 +1002,14 @@ const transformGql = (str) => {
|
|
|
988
1002
|
return function (variables) {
|
|
989
1003
|
const data = { query: str };
|
|
990
1004
|
if (variables)
|
|
991
|
-
data['variables'] =
|
|
1005
|
+
data['variables'] = variables;
|
|
992
1006
|
if (name && name.length) {
|
|
993
1007
|
const operationName = name[2];
|
|
994
1008
|
if (operationName)
|
|
995
1009
|
data['operationName'] = name[2];
|
|
996
1010
|
}
|
|
1011
|
+
// minify the query
|
|
1012
|
+
data.query = data.query.replace(/\s+/g, ' ').trim();
|
|
997
1013
|
return data;
|
|
998
1014
|
};
|
|
999
1015
|
};
|
|
@@ -1248,6 +1264,36 @@ const paginatedEntityValueUpdater = (findFn) => ({ response, rawResponse, entity
|
|
|
1248
1264
|
|
|
1249
1265
|
let _nextQueryId = 0;
|
|
1250
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
|
+
});
|
|
1251
1297
|
get _nextId() {
|
|
1252
1298
|
return ++this._currentLocalId;
|
|
1253
1299
|
}
|
|
@@ -1314,7 +1360,7 @@ class Query {
|
|
|
1314
1360
|
return this._queryConfig.entity?.store ?? null;
|
|
1315
1361
|
}
|
|
1316
1362
|
get canBeCached() {
|
|
1317
|
-
return shouldCacheQuery(this._queryConfig.method);
|
|
1363
|
+
return shouldCacheQuery$1(this._queryConfig.method);
|
|
1318
1364
|
}
|
|
1319
1365
|
get _isInMockMode() {
|
|
1320
1366
|
return !!this._arguments?.mock;
|
|
@@ -1341,31 +1387,6 @@ class Query {
|
|
|
1341
1387
|
this._routeWithParams = _routeWithParams;
|
|
1342
1388
|
this._arguments = _arguments;
|
|
1343
1389
|
this._queryStoreKey = _queryStoreKey;
|
|
1344
|
-
this._id = _nextQueryId++;
|
|
1345
|
-
this._currentLocalId = 0;
|
|
1346
|
-
this._pollingSubscription = null;
|
|
1347
|
-
this._onAbort$ = new Subject();
|
|
1348
|
-
this._currentPollConfig = null;
|
|
1349
|
-
/**
|
|
1350
|
-
* @internal
|
|
1351
|
-
* Used to track which components depend on this query.
|
|
1352
|
-
* The key is the component's _tNode index.
|
|
1353
|
-
* The value is the number of times the component has subscribed to this query.
|
|
1354
|
-
* The value might increase since we cant distinguish between a component and a host directive applied to it.
|
|
1355
|
-
*/
|
|
1356
|
-
this._dependents = {};
|
|
1357
|
-
/**
|
|
1358
|
-
* @internal
|
|
1359
|
-
*/
|
|
1360
|
-
this._dependentsChanged$ = new ReplaySubject();
|
|
1361
|
-
/**
|
|
1362
|
-
* @internal
|
|
1363
|
-
*/
|
|
1364
|
-
this._isPollingPaused = false;
|
|
1365
|
-
this._state$ = new BehaviorSubject({
|
|
1366
|
-
type: "PREPARED" /* QueryStateType.Prepared */,
|
|
1367
|
-
meta: { id: this._currentLocalId, triggeredVia: 'program' },
|
|
1368
|
-
});
|
|
1369
1390
|
}
|
|
1370
1391
|
execute(options = {}) {
|
|
1371
1392
|
const { skipCache = false, _triggeredVia: triggeredVia = 'program', cancelPrevious = false } = options;
|
|
@@ -1694,6 +1715,13 @@ const decryptBearer = (token) => {
|
|
|
1694
1715
|
};
|
|
1695
1716
|
|
|
1696
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
|
+
});
|
|
1697
1725
|
get header() {
|
|
1698
1726
|
return { Authorization: `Bearer ${this._tokens$.getValue().token}` };
|
|
1699
1727
|
}
|
|
@@ -1716,12 +1744,6 @@ class BearerAuthProvider {
|
|
|
1716
1744
|
}
|
|
1717
1745
|
constructor(_config) {
|
|
1718
1746
|
this._config = _config;
|
|
1719
|
-
this._destroy$ = new Subject();
|
|
1720
|
-
this._currentRefreshQuery$ = new BehaviorSubject(null);
|
|
1721
|
-
this._tokens$ = new BehaviorSubject({
|
|
1722
|
-
token: null,
|
|
1723
|
-
refreshToken: null,
|
|
1724
|
-
});
|
|
1725
1747
|
const cookieEnabled = _config.refreshConfig?.cookieEnabled ?? true;
|
|
1726
1748
|
const cookieToken = _config.refreshConfig?.cookieName && cookieEnabled ? (getCookie(_config.refreshConfig.cookieName) ?? null) : null;
|
|
1727
1749
|
this._tokens$.next({
|
|
@@ -1862,25 +1884,22 @@ const isClassValidatorError = (error) => {
|
|
|
1862
1884
|
};
|
|
1863
1885
|
|
|
1864
1886
|
class QueryDirective {
|
|
1865
|
-
|
|
1866
|
-
|
|
1867
|
-
|
|
1868
|
-
|
|
1869
|
-
|
|
1870
|
-
|
|
1871
|
-
|
|
1872
|
-
|
|
1873
|
-
|
|
1874
|
-
|
|
1875
|
-
|
|
1876
|
-
|
|
1877
|
-
|
|
1878
|
-
|
|
1879
|
-
|
|
1880
|
-
|
|
1881
|
-
};
|
|
1882
|
-
this._cache = false;
|
|
1883
|
-
}
|
|
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
|
+
};
|
|
1884
1903
|
get query() {
|
|
1885
1904
|
return this._query;
|
|
1886
1905
|
}
|
|
@@ -1888,12 +1907,14 @@ class QueryDirective {
|
|
|
1888
1907
|
this._query = v;
|
|
1889
1908
|
this._subscribeToQuery();
|
|
1890
1909
|
}
|
|
1910
|
+
_query;
|
|
1891
1911
|
get cache() {
|
|
1892
1912
|
return this._cache;
|
|
1893
1913
|
}
|
|
1894
1914
|
set cache(v) {
|
|
1895
1915
|
this._cache = v;
|
|
1896
1916
|
}
|
|
1917
|
+
_cache = false;
|
|
1897
1918
|
static ngTemplateContextGuard(dir, ctx) {
|
|
1898
1919
|
return true;
|
|
1899
1920
|
}
|
|
@@ -1962,10 +1983,10 @@ class QueryDirective {
|
|
|
1962
1983
|
this._viewContainerRef.createEmbeddedView(this._mainTemplateRef, this._viewContext);
|
|
1963
1984
|
}
|
|
1964
1985
|
}
|
|
1965
|
-
static
|
|
1966
|
-
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 });
|
|
1967
1988
|
}
|
|
1968
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.
|
|
1989
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.4", ngImport: i0, type: QueryDirective, decorators: [{
|
|
1969
1990
|
type: Directive,
|
|
1970
1991
|
args: [{
|
|
1971
1992
|
selector: '[etQuery]',
|
|
@@ -1980,6 +2001,58 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.5", ngImpor
|
|
|
1980
2001
|
}] } });
|
|
1981
2002
|
|
|
1982
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 }));
|
|
1983
2056
|
get currentPage$() {
|
|
1984
2057
|
return this._currentPage$.asObservable();
|
|
1985
2058
|
}
|
|
@@ -2013,56 +2086,7 @@ class InfinityQuery {
|
|
|
2013
2086
|
constructor(_config, _destroy$) {
|
|
2014
2087
|
this._config = _config;
|
|
2015
2088
|
this._destroy$ = _destroy$;
|
|
2016
|
-
this.
|
|
2017
|
-
this._currentPage$ = new BehaviorSubject(null);
|
|
2018
|
-
this._currentCalculatedPage$ = new BehaviorSubject(null);
|
|
2019
|
-
this._totalPages$ = new BehaviorSubject(null);
|
|
2020
|
-
this._itemsPerPage$ = new BehaviorSubject(this._config.limitParam?.value ?? 10);
|
|
2021
|
-
this._data$ = this._queries$.pipe(switchMap((queries) => {
|
|
2022
|
-
if (!queries.length) {
|
|
2023
|
-
return of([]);
|
|
2024
|
-
}
|
|
2025
|
-
return combineLatest(queries.map((query) => query.state$.pipe(filterSuccess(), map((state) => ({ state, query })))));
|
|
2026
|
-
}), tap((stateMaps) => {
|
|
2027
|
-
const lastState = stateMaps[stateMaps.length - 1]?.state;
|
|
2028
|
-
const lastQuery = stateMaps[stateMaps.length - 1]?.query;
|
|
2029
|
-
if (!lastState || !lastQuery) {
|
|
2030
|
-
return;
|
|
2031
|
-
}
|
|
2032
|
-
const totalPages = this._config.response.totalPagesExtractor?.({
|
|
2033
|
-
response: lastState.response,
|
|
2034
|
-
itemsPerPage: this.itemsPerPage,
|
|
2035
|
-
args: lastQuery._arguments,
|
|
2036
|
-
}) ??
|
|
2037
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
2038
|
-
lastState.response?.totalPages ??
|
|
2039
|
-
null;
|
|
2040
|
-
this._totalPages$.next(totalPages);
|
|
2041
|
-
}), map((stateMaps) => {
|
|
2042
|
-
if (!stateMaps.length) {
|
|
2043
|
-
return null;
|
|
2044
|
-
}
|
|
2045
|
-
const fullData = stateMaps.reduce((acc, stateMap) => {
|
|
2046
|
-
const valExtractFn = this._config?.response?.valueExtractor;
|
|
2047
|
-
let data = valExtractFn
|
|
2048
|
-
? valExtractFn?.(stateMap.state.response)
|
|
2049
|
-
: stateMap.state.response;
|
|
2050
|
-
if (this._config.response.reverse) {
|
|
2051
|
-
data = [...data].reverse();
|
|
2052
|
-
}
|
|
2053
|
-
if (this._config.response.appendItemsTo === 'start') {
|
|
2054
|
-
acc.unshift(...data);
|
|
2055
|
-
}
|
|
2056
|
-
else {
|
|
2057
|
-
acc.push(...data);
|
|
2058
|
-
}
|
|
2059
|
-
return acc;
|
|
2060
|
-
},
|
|
2061
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
2062
|
-
[]);
|
|
2063
|
-
return fullData;
|
|
2064
|
-
}), shareReplay({ bufferSize: 1, refCount: true }));
|
|
2065
|
-
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);
|
|
2066
2090
|
}
|
|
2067
2091
|
nextPage() {
|
|
2068
2092
|
const newPage = (this._currentPage$.value ?? 0) + 1;
|
|
@@ -2154,6 +2178,28 @@ const skipPaginationPageParamCalculator = ({ page, itemsPerPage }) => itemsPerPa
|
|
|
2154
2178
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2155
2179
|
const INFINITY_QUERY_TOKEN = new InjectionToken('INFINITY_QUERY_TOKEN');
|
|
2156
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([]);
|
|
2157
2203
|
get infinityQuery() {
|
|
2158
2204
|
return this._infinityQuery;
|
|
2159
2205
|
}
|
|
@@ -2163,6 +2209,7 @@ class InfinityQueryDirective {
|
|
|
2163
2209
|
this._infinityQueryInstance = this._setupInfinityQuery(v);
|
|
2164
2210
|
this._infinityQueryInstance.nextPage();
|
|
2165
2211
|
}
|
|
2212
|
+
_infinityQuery;
|
|
2166
2213
|
get context() {
|
|
2167
2214
|
return this._viewContext;
|
|
2168
2215
|
}
|
|
@@ -2172,33 +2219,11 @@ class InfinityQueryDirective {
|
|
|
2172
2219
|
get data$() {
|
|
2173
2220
|
return this._data$.asObservable();
|
|
2174
2221
|
}
|
|
2222
|
+
data = toSignal(this._data$, { requireSync: true });
|
|
2175
2223
|
static ngTemplateContextGuard(dir, ctx) {
|
|
2176
2224
|
return true;
|
|
2177
2225
|
}
|
|
2178
2226
|
constructor() {
|
|
2179
|
-
this._queryConfigChanged$ = new Subject();
|
|
2180
|
-
this._viewContext = {
|
|
2181
|
-
$implicit: null,
|
|
2182
|
-
etInfinityQuery: null,
|
|
2183
|
-
loading: false,
|
|
2184
|
-
error: null,
|
|
2185
|
-
isFirstLoad: false,
|
|
2186
|
-
canLoadMore: false,
|
|
2187
|
-
currentPage: null,
|
|
2188
|
-
currentCalculatedPage: null,
|
|
2189
|
-
totalPages: null,
|
|
2190
|
-
itemsPerPage: null,
|
|
2191
|
-
currentQuery: null,
|
|
2192
|
-
};
|
|
2193
|
-
this._infinityQueryInstance = null;
|
|
2194
|
-
this._destroy$ = createDestroy();
|
|
2195
|
-
this._cdr = inject(ChangeDetectorRef);
|
|
2196
|
-
this._viewContainerRef = inject(ViewContainerRef);
|
|
2197
|
-
this._mainTemplateRef = inject((TemplateRef));
|
|
2198
|
-
this._errorHandler = inject(ErrorHandler);
|
|
2199
|
-
this._delayable = inject(DelayableDirective, { host: true });
|
|
2200
|
-
this._data$ = new BehaviorSubject([]);
|
|
2201
|
-
this.data = toSignal(this._data$, { requireSync: true });
|
|
2202
2227
|
this._viewContainerRef.createEmbeddedView(this._mainTemplateRef, this._viewContext);
|
|
2203
2228
|
}
|
|
2204
2229
|
_setupInfinityQuery(config) {
|
|
@@ -2272,10 +2297,10 @@ class InfinityQueryDirective {
|
|
|
2272
2297
|
this._viewContext.currentQuery = null;
|
|
2273
2298
|
this._data$.next([]);
|
|
2274
2299
|
}
|
|
2275
|
-
static
|
|
2276
|
-
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 });
|
|
2277
2302
|
}
|
|
2278
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.
|
|
2303
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.4", ngImport: i0, type: InfinityQueryDirective, decorators: [{
|
|
2279
2304
|
type: Directive,
|
|
2280
2305
|
args: [{
|
|
2281
2306
|
selector: '[etInfinityQuery]',
|
|
@@ -2290,14 +2315,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.5", ngImpor
|
|
|
2290
2315
|
}] } });
|
|
2291
2316
|
|
|
2292
2317
|
class InfinityQueryTriggerDirective {
|
|
2293
|
-
|
|
2294
|
-
|
|
2295
|
-
|
|
2296
|
-
|
|
2297
|
-
|
|
2298
|
-
|
|
2299
|
-
this.scrollContainerSelector = null;
|
|
2300
|
-
}
|
|
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;
|
|
2301
2324
|
ngOnInit() {
|
|
2302
2325
|
const isInteractive = this._elementRef.nativeElement.tagName === 'BUTTON';
|
|
2303
2326
|
if (isInteractive) {
|
|
@@ -2327,10 +2350,10 @@ class InfinityQueryTriggerDirective {
|
|
|
2327
2350
|
});
|
|
2328
2351
|
this._observer.observe(this._elementRef.nativeElement);
|
|
2329
2352
|
}
|
|
2330
|
-
static
|
|
2331
|
-
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 });
|
|
2332
2355
|
}
|
|
2333
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.
|
|
2356
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.4", ngImport: i0, type: InfinityQueryTriggerDirective, decorators: [{
|
|
2334
2357
|
type: Directive,
|
|
2335
2358
|
args: [{
|
|
2336
2359
|
selector: '[etInfinityQueryTrigger], et-infinity-query-trigger',
|
|
@@ -2354,10 +2377,10 @@ class QueryShortNamePipe {
|
|
|
2354
2377
|
}
|
|
2355
2378
|
return route;
|
|
2356
2379
|
}
|
|
2357
|
-
static
|
|
2358
|
-
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" });
|
|
2359
2382
|
}
|
|
2360
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.
|
|
2383
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.4", ngImport: i0, type: QueryShortNamePipe, decorators: [{
|
|
2361
2384
|
type: Pipe,
|
|
2362
2385
|
args: [{ name: 'queryShortName', standalone: true }]
|
|
2363
2386
|
}] });
|
|
@@ -2375,161 +2398,159 @@ const provideQueryClientForDevtools = (queryClient) => {
|
|
|
2375
2398
|
};
|
|
2376
2399
|
|
|
2377
2400
|
class QueryDevtoolsComponent {
|
|
2378
|
-
|
|
2379
|
-
|
|
2380
|
-
|
|
2381
|
-
|
|
2382
|
-
|
|
2383
|
-
|
|
2384
|
-
|
|
2385
|
-
|
|
2386
|
-
|
|
2387
|
-
|
|
2388
|
-
|
|
2389
|
-
|
|
2390
|
-
|
|
2391
|
-
|
|
2392
|
-
|
|
2393
|
-
|
|
2394
|
-
|
|
2395
|
-
this.
|
|
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
|
-
|
|
2452
|
-
|
|
2453
|
-
|
|
2454
|
-
|
|
2455
|
-
|
|
2456
|
-
|
|
2457
|
-
|
|
2458
|
-
if (isGqlQueryConfig(cfg)) {
|
|
2459
|
-
return {
|
|
2460
|
-
...sharedCfg,
|
|
2461
|
-
query: cfg.query,
|
|
2462
|
-
transferVia: cfg.transferVia,
|
|
2463
|
-
};
|
|
2464
|
-
}
|
|
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)) {
|
|
2465
2481
|
return {
|
|
2466
2482
|
...sharedCfg,
|
|
2483
|
+
query: cfg.query,
|
|
2484
|
+
transferVia: cfg.transferVia,
|
|
2467
2485
|
};
|
|
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
|
-
|
|
2512
|
-
|
|
2513
|
-
|
|
2514
|
-
|
|
2515
|
-
|
|
2516
|
-
|
|
2517
|
-
|
|
2518
|
-
|
|
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',
|
|
2519
2540
|
},
|
|
2520
|
-
}
|
|
2521
|
-
}
|
|
2522
|
-
|
|
2523
|
-
|
|
2524
|
-
|
|
2525
|
-
|
|
2526
|
-
|
|
2527
|
-
|
|
2528
|
-
}
|
|
2529
|
-
}
|
|
2530
|
-
}
|
|
2531
|
-
|
|
2532
|
-
|
|
2541
|
+
},
|
|
2542
|
+
};
|
|
2543
|
+
}
|
|
2544
|
+
else {
|
|
2545
|
+
return {
|
|
2546
|
+
type: 'UnknownAuthProvider',
|
|
2547
|
+
header: () => provider.header,
|
|
2548
|
+
provider: provider,
|
|
2549
|
+
config: {},
|
|
2550
|
+
};
|
|
2551
|
+
}
|
|
2552
|
+
});
|
|
2553
|
+
constructor() {
|
|
2533
2554
|
this.selectedClientIdCtrl.valueChanges
|
|
2534
2555
|
.pipe(tap(() => this.clearQueryHistory()), takeUntil(this._destroy$))
|
|
2535
2556
|
.subscribe();
|
|
@@ -2609,6 +2630,8 @@ class QueryDevtoolsComponent {
|
|
|
2609
2630
|
this.viewMode.set(parsed.viewMode ?? 'query');
|
|
2610
2631
|
}
|
|
2611
2632
|
}
|
|
2633
|
+
trackByClient = (_, { client }) => client.config.baseRoute;
|
|
2634
|
+
trackByQuery = (_, { _id }) => _id;
|
|
2612
2635
|
toggleOpen() {
|
|
2613
2636
|
this.isOpen.set(!this.isOpen());
|
|
2614
2637
|
}
|
|
@@ -2648,10 +2671,10 @@ class QueryDevtoolsComponent {
|
|
|
2648
2671
|
clearQueryHistory() {
|
|
2649
2672
|
this.queryHistory$.next([]);
|
|
2650
2673
|
}
|
|
2651
|
-
static
|
|
2652
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.5", 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 });
|
|
2653
2676
|
}
|
|
2654
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.
|
|
2677
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.4", ngImport: i0, type: QueryDevtoolsComponent, decorators: [{
|
|
2655
2678
|
type: Component,
|
|
2656
2679
|
args: [{ selector: 'et-query-devtools', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.ShadowDom, host: {
|
|
2657
2680
|
class: 'et-query-devtools',
|
|
@@ -2659,6 +2682,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.5", ngImpor
|
|
|
2659
2682
|
}], ctorParameters: () => [] });
|
|
2660
2683
|
|
|
2661
2684
|
class EntityStoreError extends Error {
|
|
2685
|
+
detail;
|
|
2662
2686
|
constructor(message, detail) {
|
|
2663
2687
|
super(message);
|
|
2664
2688
|
this.detail = detail;
|
|
@@ -2669,16 +2693,17 @@ function flatten(arr) {
|
|
|
2669
2693
|
return arr.reduce((acc, val) => acc.concat(val), []);
|
|
2670
2694
|
}
|
|
2671
2695
|
class EntityStore {
|
|
2696
|
+
_config;
|
|
2697
|
+
/**
|
|
2698
|
+
* @internal
|
|
2699
|
+
*/
|
|
2700
|
+
_dictionary = new Map();
|
|
2701
|
+
/**
|
|
2702
|
+
* @internal
|
|
2703
|
+
*/
|
|
2704
|
+
_change$ = new Subject();
|
|
2672
2705
|
constructor(_config) {
|
|
2673
2706
|
this._config = _config;
|
|
2674
|
-
/**
|
|
2675
|
-
* @internal
|
|
2676
|
-
*/
|
|
2677
|
-
this._dictionary = new Map();
|
|
2678
|
-
/**
|
|
2679
|
-
* @internal
|
|
2680
|
-
*/
|
|
2681
|
-
this._change$ = new Subject();
|
|
2682
2707
|
}
|
|
2683
2708
|
select(keyOrKeys) {
|
|
2684
2709
|
if (Array.isArray(keyOrKeys)) {
|
|
@@ -2813,71 +2838,74 @@ const removeFrom = (store, { where, id }) => {
|
|
|
2813
2838
|
};
|
|
2814
2839
|
|
|
2815
2840
|
const queryFeatureUsedMultipleTimes = (type) => {
|
|
2816
|
-
return new RuntimeError(0 /*
|
|
2841
|
+
return new RuntimeError(0 /* QueryRuntimeErrorCode.QUERY_FEATURE_USED_MULTIPLE_TIMES */, `The query feature "${type}()" was used multiple times.`);
|
|
2817
2842
|
};
|
|
2818
2843
|
const withArgsQueryFeatureMissingButRouteIsFunction = () => {
|
|
2819
|
-
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.`);
|
|
2820
2845
|
};
|
|
2821
2846
|
const withPollingUsedOnUnsupportedHttpMethod = (method) => {
|
|
2822
|
-
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.`);
|
|
2823
2848
|
};
|
|
2824
2849
|
const withAutoRefreshUsedOnUnsupportedHttpMethod = (method) => {
|
|
2825
|
-
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.`);
|
|
2826
2851
|
};
|
|
2827
2852
|
const withAutoRefreshUsedInManualQuery = () => {
|
|
2828
|
-
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.` +
|
|
2829
2854
|
` If this is intentional, set "ignoreOnlyManualExecution" to true inside the auto refresh config.`);
|
|
2830
2855
|
};
|
|
2831
2856
|
const cookieLoginTriedButCookieDisabled = () => {
|
|
2832
|
-
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.`);
|
|
2833
2858
|
};
|
|
2834
2859
|
const enableCookieCalledWithoutCookieConfig = () => {
|
|
2835
|
-
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.`);
|
|
2836
2861
|
};
|
|
2837
2862
|
const disableCookieCalledWithoutCookieConfig = () => {
|
|
2838
|
-
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.`);
|
|
2839
2864
|
};
|
|
2840
2865
|
const loginCalledWithoutConfig = () => {
|
|
2841
|
-
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.`);
|
|
2842
2867
|
};
|
|
2843
2868
|
const loginWithTokenCalledWithoutConfig = () => {
|
|
2844
|
-
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.`);
|
|
2845
2870
|
};
|
|
2846
2871
|
const refreshTokenCalledWithoutConfig = () => {
|
|
2847
|
-
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.`);
|
|
2848
2873
|
};
|
|
2849
2874
|
const selectRoleCalledWithoutConfig = () => {
|
|
2850
|
-
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.`);
|
|
2851
2876
|
};
|
|
2852
2877
|
const defaultResponseTransformerResponseNotObject = (currentType) => {
|
|
2853
|
-
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}".`);
|
|
2854
2879
|
};
|
|
2855
2880
|
const defaultResponseTransformerResponseNotContainingAccessToken = () => {
|
|
2856
|
-
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.`);
|
|
2857
2882
|
};
|
|
2858
2883
|
const defaultResponseTransformerResponseNotContainingRefreshToken = () => {
|
|
2859
|
-
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.`);
|
|
2860
2885
|
};
|
|
2861
2886
|
const unableToDecryptBearerToken = (token) => {
|
|
2862
|
-
return new RuntimeError(210 /*
|
|
2887
|
+
return new RuntimeError(210 /* QueryRuntimeErrorCode.UNABLE_TO_DECRYPT_BEARER_TOKEN */, `The bearer token could not be decrypted: ${token}`);
|
|
2863
2888
|
};
|
|
2864
2889
|
const bearerExpiresInPropertyNotNumber = (expiresIn) => {
|
|
2865
|
-
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}`);
|
|
2866
2891
|
};
|
|
2867
2892
|
const uncacheableRequestHasCacheKeyParam = (key) => {
|
|
2868
|
-
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.`);
|
|
2869
2894
|
};
|
|
2870
2895
|
const uncacheableRequestHasAllowCacheParam = () => {
|
|
2871
|
-
return new RuntimeError(301 /*
|
|
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.`);
|
|
2872
2897
|
};
|
|
2873
|
-
const
|
|
2874
|
-
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}".`);
|
|
2875
2900
|
};
|
|
2876
|
-
const
|
|
2877
|
-
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.`);
|
|
2878
2903
|
};
|
|
2879
|
-
const
|
|
2880
|
-
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.`);
|
|
2881
2909
|
};
|
|
2882
2910
|
|
|
2883
2911
|
const defaultResponseTransformer = (response) => {
|
|
@@ -3041,10 +3069,10 @@ const createBearerAuthProvider = (options) => {
|
|
|
3041
3069
|
};
|
|
3042
3070
|
const logout = () => {
|
|
3043
3071
|
deleteCookie$1();
|
|
3044
|
-
loginQuery?.query.
|
|
3045
|
-
tokenLoginQuery?.query.
|
|
3046
|
-
tokenRefreshQuery?.query.
|
|
3047
|
-
selectRoleQuery?.query.
|
|
3072
|
+
loginQuery?.query.reset();
|
|
3073
|
+
tokenLoginQuery?.query.reset();
|
|
3074
|
+
tokenRefreshQuery?.query.reset();
|
|
3075
|
+
selectRoleQuery?.query.reset();
|
|
3048
3076
|
latestNonInternalQuery.set(null);
|
|
3049
3077
|
};
|
|
3050
3078
|
const enableCookie = () => {
|
|
@@ -3136,29 +3164,81 @@ const createBearerAuthProviderConfig = (options) => {
|
|
|
3136
3164
|
return bearerAuthProviderConfig;
|
|
3137
3165
|
};
|
|
3138
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
|
+
|
|
3139
3228
|
/**
|
|
3140
|
-
* Returning this inside
|
|
3229
|
+
* Returning this inside a withArgs feature will reset the query args to null.
|
|
3141
3230
|
* This will also pause polling and auto refresh until new args are set.
|
|
3142
3231
|
*/
|
|
3143
|
-
const
|
|
3232
|
+
const CLEAR_QUERY_ARGS = Symbol('CLEAR_QUERY_ARGS');
|
|
3144
3233
|
const QUERY_EFFECT_ERROR_MESSAGE = 'Effect triggered too often. This is probably due to a circular dependency inside the query.';
|
|
3145
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. */
|
|
3146
3235
|
const queryEffect = (fn, errorMessage, options) => {
|
|
3147
3236
|
let lastTriggerTs = 0;
|
|
3148
3237
|
let illegalWrites = 0;
|
|
3149
|
-
// The first run should be synchronous anf not depend on the angular scheduler
|
|
3150
|
-
if (options?.injector) {
|
|
3151
|
-
runInInjectionContext(options.injector, () => fn());
|
|
3152
|
-
}
|
|
3153
|
-
else {
|
|
3154
|
-
fn();
|
|
3155
|
-
}
|
|
3156
3238
|
let isFirstRun = true;
|
|
3157
|
-
|
|
3158
|
-
|
|
3159
|
-
|
|
3160
|
-
return;
|
|
3161
|
-
}
|
|
3239
|
+
const activeConsumer = getActiveConsumer();
|
|
3240
|
+
setActiveConsumer(null);
|
|
3241
|
+
const eff = effect(() => {
|
|
3162
3242
|
if (isDevMode()) {
|
|
3163
3243
|
const now = performance.now();
|
|
3164
3244
|
if (now - lastTriggerTs < 100) {
|
|
@@ -3169,12 +3249,20 @@ const queryEffect = (fn, errorMessage, options) => {
|
|
|
3169
3249
|
}
|
|
3170
3250
|
lastTriggerTs = now;
|
|
3171
3251
|
}
|
|
3172
|
-
fn();
|
|
3173
|
-
|
|
3252
|
+
fn(isFirstRun);
|
|
3253
|
+
if (isFirstRun) {
|
|
3254
|
+
isFirstRun = false;
|
|
3255
|
+
}
|
|
3256
|
+
}, options);
|
|
3257
|
+
setActiveConsumer(activeConsumer);
|
|
3258
|
+
return eff;
|
|
3174
3259
|
};
|
|
3175
3260
|
const shouldAutoExecuteQuery = (method) => {
|
|
3176
3261
|
return method === 'GET' || method === 'HEAD' || method === 'OPTIONS';
|
|
3177
3262
|
};
|
|
3263
|
+
const shouldAutoExecuteGqlQuery = (method) => {
|
|
3264
|
+
return method === 'QUERY';
|
|
3265
|
+
};
|
|
3178
3266
|
const extractExpiresInSeconds = (headers) => {
|
|
3179
3267
|
const cacheControl = headers.get('cache-control');
|
|
3180
3268
|
const age = headers.get('age');
|
|
@@ -3231,8 +3319,8 @@ const shouldRetryRequest = (options) => {
|
|
|
3231
3319
|
return { retry: false };
|
|
3232
3320
|
}
|
|
3233
3321
|
const { status, error: detail, headers } = error;
|
|
3234
|
-
// Retry on 5xx errors
|
|
3235
|
-
if (status >=
|
|
3322
|
+
// Retry on 5xx errors (except 500 internal server error since those are usually not recoverable)
|
|
3323
|
+
if (status >= 501) {
|
|
3236
3324
|
// Don't retry if a requested page is out of range
|
|
3237
3325
|
if (isSymfonyPagerfantaOutOfRangeError(detail)) {
|
|
3238
3326
|
return { retry: false };
|
|
@@ -3260,9 +3348,11 @@ const shouldRetryRequest = (options) => {
|
|
|
3260
3348
|
return { retry: false };
|
|
3261
3349
|
};
|
|
3262
3350
|
const getQueryFeatureUsage = (options) => {
|
|
3263
|
-
const { creator,
|
|
3351
|
+
const { creator, features, queryConfig } = options;
|
|
3264
3352
|
const hasWithArgsFeature = features.some((f) => f.type == "withArgs" /* QueryFeatureType.WithArgs */);
|
|
3265
|
-
const shouldAutoExecuteMethod =
|
|
3353
|
+
const shouldAutoExecuteMethod = isCreateGqlQueryOptions(options)
|
|
3354
|
+
? shouldAutoExecuteGqlQuery(options.creatorInternals.method)
|
|
3355
|
+
: shouldAutoExecuteQuery(options.creatorInternals.method);
|
|
3266
3356
|
const shouldAutoExecute = shouldAutoExecuteMethod && !queryConfig.onlyManualExecution;
|
|
3267
3357
|
const hasRouteFunction = typeof creator.route === 'function';
|
|
3268
3358
|
if (hasRouteFunction && !hasWithArgsFeature) {
|
|
@@ -3273,12 +3363,16 @@ const getQueryFeatureUsage = (options) => {
|
|
|
3273
3363
|
shouldAutoExecuteMethod,
|
|
3274
3364
|
shouldAutoExecute,
|
|
3275
3365
|
hasRouteFunction,
|
|
3366
|
+
onlyManualExecution: queryConfig.onlyManualExecution,
|
|
3367
|
+
method: isCreateGqlQueryOptions(options)
|
|
3368
|
+
? `GQL ${options.creatorInternals.method}`
|
|
3369
|
+
: options.creatorInternals.method,
|
|
3276
3370
|
};
|
|
3277
3371
|
return featureFnContext;
|
|
3278
3372
|
};
|
|
3279
|
-
const applyQueryFeatures = (
|
|
3373
|
+
const applyQueryFeatures = (features, context) => {
|
|
3280
3374
|
const featureTypes = new Set();
|
|
3281
|
-
for (const feature of
|
|
3375
|
+
for (const feature of features) {
|
|
3282
3376
|
if (featureTypes.has(feature.type)) {
|
|
3283
3377
|
throw queryFeatureUsedMultipleTimes(feature.type);
|
|
3284
3378
|
}
|
|
@@ -3286,13 +3380,16 @@ const applyQueryFeatures = (options, context) => {
|
|
|
3286
3380
|
feature.fn(context);
|
|
3287
3381
|
}
|
|
3288
3382
|
};
|
|
3383
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
3289
3384
|
const maybeExecute = (options) => {
|
|
3290
3385
|
if (options.flags.shouldAutoExecute && !options.flags.hasRouteFunction && !options.flags.hasWithArgsFeature) {
|
|
3291
3386
|
options.execute();
|
|
3292
3387
|
}
|
|
3293
3388
|
};
|
|
3294
3389
|
const createQueryObject = (options) => {
|
|
3295
|
-
const { state, execute,
|
|
3390
|
+
const { state, execute, deps } = options;
|
|
3391
|
+
const destroy = () => deps.injector.destroy();
|
|
3392
|
+
const createSnapshot = createQuerySnapshotFn({ state, deps, execute });
|
|
3296
3393
|
const query = {
|
|
3297
3394
|
execute,
|
|
3298
3395
|
args: state.args.asReadonly(),
|
|
@@ -3301,12 +3398,44 @@ const createQueryObject = (options) => {
|
|
|
3301
3398
|
loading: state.loading.asReadonly(),
|
|
3302
3399
|
error: state.error.asReadonly(),
|
|
3303
3400
|
lastTimeExecutedAt: state.lastTimeExecutedAt.asReadonly(),
|
|
3304
|
-
id: execute.currentRepositoryKey,
|
|
3401
|
+
id: normalizeQueryRepositoryKey(execute.currentRepositoryKey),
|
|
3305
3402
|
createSnapshot,
|
|
3306
|
-
|
|
3403
|
+
reset: execute.reset,
|
|
3404
|
+
subtle: {
|
|
3405
|
+
destroy,
|
|
3406
|
+
},
|
|
3307
3407
|
};
|
|
3308
3408
|
return query;
|
|
3309
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
|
+
};
|
|
3310
3439
|
|
|
3311
3440
|
const SPEED_BUFFER_TIME_IN_MS = 2000;
|
|
3312
3441
|
const createHttpRequest = (options) => {
|
|
@@ -3459,6 +3588,15 @@ const createHttpRequest = (options) => {
|
|
|
3459
3588
|
const createQueryFeature = (config) => {
|
|
3460
3589
|
return config;
|
|
3461
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
|
+
*/
|
|
3462
3600
|
const withArgs = (args) => {
|
|
3463
3601
|
return createQueryFeature({
|
|
3464
3602
|
type: "withArgs" /* QueryFeatureType.WithArgs */,
|
|
@@ -3469,7 +3607,7 @@ const withArgs = (args) => {
|
|
|
3469
3607
|
if (currArgsNow === null)
|
|
3470
3608
|
return;
|
|
3471
3609
|
untracked(() => {
|
|
3472
|
-
if (currArgsNow ===
|
|
3610
|
+
if (currArgsNow === CLEAR_QUERY_ARGS) {
|
|
3473
3611
|
context.state.args.set(null);
|
|
3474
3612
|
return;
|
|
3475
3613
|
}
|
|
@@ -3481,12 +3619,19 @@ const withArgs = (args) => {
|
|
|
3481
3619
|
},
|
|
3482
3620
|
});
|
|
3483
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
|
+
*/
|
|
3484
3629
|
const withPolling = (options) => {
|
|
3485
3630
|
return createQueryFeature({
|
|
3486
3631
|
type: "withPolling" /* QueryFeatureType.WithPolling */,
|
|
3487
3632
|
fn: (context) => {
|
|
3488
3633
|
if (!context.flags.shouldAutoExecuteMethod) {
|
|
3489
|
-
throw withPollingUsedOnUnsupportedHttpMethod(context.
|
|
3634
|
+
throw withPollingUsedOnUnsupportedHttpMethod(context.flags.method);
|
|
3490
3635
|
}
|
|
3491
3636
|
let intervalId = null;
|
|
3492
3637
|
queryEffect(() => {
|
|
@@ -3494,7 +3639,9 @@ const withPolling = (options) => {
|
|
|
3494
3639
|
untracked(() => {
|
|
3495
3640
|
if (intervalId !== null)
|
|
3496
3641
|
clearInterval(intervalId);
|
|
3497
|
-
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)
|
|
3498
3645
|
return;
|
|
3499
3646
|
if (options.executeInitially) {
|
|
3500
3647
|
context.execute({ args });
|
|
@@ -3508,68 +3655,78 @@ const withPolling = (options) => {
|
|
|
3508
3655
|
},
|
|
3509
3656
|
});
|
|
3510
3657
|
};
|
|
3658
|
+
/** A query feature that can be used to log the latest http event */
|
|
3511
3659
|
const withLogging = (options) => {
|
|
3512
3660
|
return createQueryFeature({
|
|
3513
3661
|
type: "withLogging" /* QueryFeatureType.WithLogging */,
|
|
3514
3662
|
fn: (context) => {
|
|
3515
|
-
|
|
3663
|
+
queryEffect(() => {
|
|
3516
3664
|
const event = context.state.latestHttpEvent();
|
|
3517
3665
|
if (event === null)
|
|
3518
3666
|
return;
|
|
3519
3667
|
untracked(() => {
|
|
3520
3668
|
options.logFn(event);
|
|
3521
3669
|
});
|
|
3522
|
-
}, { injector: context.deps.injector });
|
|
3670
|
+
}, QUERY_EFFECT_ERROR_MESSAGE, { injector: context.deps.injector });
|
|
3523
3671
|
},
|
|
3524
3672
|
});
|
|
3525
3673
|
};
|
|
3674
|
+
/** A query feature that can be used to handle errors */
|
|
3526
3675
|
const withErrorHandling = (options) => {
|
|
3527
3676
|
return createQueryFeature({
|
|
3528
3677
|
type: "withErrorHandling" /* QueryFeatureType.WithErrorHandling */,
|
|
3529
3678
|
fn: (context) => {
|
|
3530
|
-
|
|
3679
|
+
queryEffect(() => {
|
|
3531
3680
|
const error = context.state.error();
|
|
3532
3681
|
if (error === null)
|
|
3533
3682
|
return;
|
|
3534
3683
|
untracked(() => {
|
|
3535
3684
|
options.handler(error);
|
|
3536
3685
|
});
|
|
3537
|
-
}, { injector: context.deps.injector });
|
|
3686
|
+
}, QUERY_EFFECT_ERROR_MESSAGE, { injector: context.deps.injector });
|
|
3538
3687
|
},
|
|
3539
3688
|
});
|
|
3540
3689
|
};
|
|
3690
|
+
/** A query feature that can be used to handle successful responses */
|
|
3541
3691
|
const withSuccessHandling = (options) => {
|
|
3542
3692
|
return createQueryFeature({
|
|
3543
3693
|
type: "withSuccessHandling" /* QueryFeatureType.WithSuccessHandling */,
|
|
3544
3694
|
fn: (context) => {
|
|
3545
|
-
|
|
3695
|
+
queryEffect(() => {
|
|
3546
3696
|
const response = context.state.response();
|
|
3547
3697
|
if (response === null)
|
|
3548
3698
|
return;
|
|
3549
3699
|
untracked(() => {
|
|
3550
3700
|
options.handler(response);
|
|
3551
3701
|
});
|
|
3552
|
-
}, { injector: context.deps.injector });
|
|
3702
|
+
}, QUERY_EFFECT_ERROR_MESSAGE, { injector: context.deps.injector });
|
|
3553
3703
|
},
|
|
3554
3704
|
});
|
|
3555
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
|
+
*/
|
|
3556
3711
|
const withAutoRefresh = (options) => {
|
|
3557
3712
|
return createQueryFeature({
|
|
3558
3713
|
type: "withAutoRefresh" /* QueryFeatureType.WithAutoRefresh */,
|
|
3559
3714
|
fn: (context) => {
|
|
3560
3715
|
if (!context.flags.shouldAutoExecuteMethod) {
|
|
3561
|
-
throw withAutoRefreshUsedOnUnsupportedHttpMethod(context.
|
|
3716
|
+
throw withAutoRefreshUsedOnUnsupportedHttpMethod(context.flags.method);
|
|
3562
3717
|
}
|
|
3563
|
-
if (context.
|
|
3564
|
-
throw
|
|
3718
|
+
if (context.flags.onlyManualExecution && !options.ignoreOnlyManualExecution) {
|
|
3719
|
+
throw withAutoRefreshUsedInManualQuery();
|
|
3565
3720
|
}
|
|
3566
3721
|
queryEffect(() => {
|
|
3567
|
-
for (const signal of options.
|
|
3722
|
+
for (const signal of options.onSignalChanges) {
|
|
3568
3723
|
signal();
|
|
3569
3724
|
}
|
|
3570
3725
|
untracked(() => {
|
|
3571
3726
|
const args = context.state.args();
|
|
3572
|
-
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)
|
|
3573
3730
|
return;
|
|
3574
3731
|
context.execute({ args });
|
|
3575
3732
|
});
|
|
@@ -3578,10 +3735,12 @@ const withAutoRefresh = (options) => {
|
|
|
3578
3735
|
});
|
|
3579
3736
|
};
|
|
3580
3737
|
|
|
3738
|
+
/** Transforms an array of arrays into a single array and filters out `null` values. */
|
|
3581
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. */
|
|
3582
3741
|
const transformPaginatedResponse = (responses) => responses.filter((r) => !!r).flatMap((r) => r.items);
|
|
3583
|
-
const createQueryStack = (
|
|
3584
|
-
const { append =
|
|
3742
|
+
const createQueryStack = (options) => {
|
|
3743
|
+
const { args, queryCreator, dependencies, append, features = [], appendFn = (oldQueries, newQueries) => {
|
|
3585
3744
|
const queries = [...oldQueries, ...newQueries];
|
|
3586
3745
|
const lastQuery = newQueries[newQueries.length - 1] ?? oldQueries[oldQueries.length - 1] ?? null;
|
|
3587
3746
|
return { queries, lastQuery };
|
|
@@ -3589,9 +3748,21 @@ const createQueryStack = (computation, options) => {
|
|
|
3589
3748
|
const injector = inject(Injector);
|
|
3590
3749
|
const queries = signal([]);
|
|
3591
3750
|
const lastQuery = signal(null);
|
|
3751
|
+
const hasWithArgsFeature = features.some((f) => f.type == "withArgs" /* QueryFeatureType.WithArgs */);
|
|
3752
|
+
if (hasWithArgsFeature) {
|
|
3753
|
+
throw queryStackWithArgsUsed();
|
|
3754
|
+
}
|
|
3592
3755
|
effect(() => {
|
|
3593
|
-
|
|
3594
|
-
|
|
3756
|
+
// Clear the stack if dependencies change
|
|
3757
|
+
dependencies?.();
|
|
3758
|
+
untracked(() => clear());
|
|
3759
|
+
});
|
|
3760
|
+
effect(() => {
|
|
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)));
|
|
3595
3766
|
untracked(() => {
|
|
3596
3767
|
const oldQueries = queries();
|
|
3597
3768
|
if (append) {
|
|
@@ -3602,7 +3773,7 @@ const createQueryStack = (computation, options) => {
|
|
|
3602
3773
|
else {
|
|
3603
3774
|
for (const oldQuery of oldQueries) {
|
|
3604
3775
|
if (!newQueries.some((q) => q.id() === oldQuery.id())) {
|
|
3605
|
-
oldQuery.destroy();
|
|
3776
|
+
oldQuery.subtle.destroy();
|
|
3606
3777
|
}
|
|
3607
3778
|
}
|
|
3608
3779
|
queries.set(newQueries);
|
|
@@ -3625,7 +3796,7 @@ const createQueryStack = (computation, options) => {
|
|
|
3625
3796
|
};
|
|
3626
3797
|
const clear = () => {
|
|
3627
3798
|
for (const query of queries()) {
|
|
3628
|
-
query.destroy();
|
|
3799
|
+
query.subtle.destroy();
|
|
3629
3800
|
}
|
|
3630
3801
|
queries.set([]);
|
|
3631
3802
|
lastQuery.set(null);
|
|
@@ -3684,23 +3855,31 @@ const contentfulGqlLikePaginationAdapter = (response) => {
|
|
|
3684
3855
|
};
|
|
3685
3856
|
return pagination;
|
|
3686
3857
|
};
|
|
3687
|
-
const
|
|
3688
|
-
|
|
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;
|
|
3689
3872
|
const currentPageArgs = signal(null);
|
|
3690
3873
|
const initialPage = signal(options.initialPage ?? 1);
|
|
3691
3874
|
const loadedMinPage = signal(initialPage());
|
|
3692
3875
|
const loadedMaxPage = signal(initialPage());
|
|
3693
3876
|
const lastResetTimestamp = signal(Date.now());
|
|
3694
3877
|
const pageDirection = signal('next');
|
|
3695
|
-
const stack = createQueryStack(
|
|
3696
|
-
|
|
3697
|
-
|
|
3698
|
-
return null;
|
|
3699
|
-
return queryCreator(withArgs(() => {
|
|
3700
|
-
return args;
|
|
3701
|
-
}));
|
|
3702
|
-
}, {
|
|
3878
|
+
const stack = createQueryStack({
|
|
3879
|
+
args: () => currentPageArgs(),
|
|
3880
|
+
queryCreator,
|
|
3703
3881
|
append: true,
|
|
3882
|
+
features,
|
|
3704
3883
|
appendFn: (oldQueries, newQueries) => {
|
|
3705
3884
|
const newQuery = newQueries[0];
|
|
3706
3885
|
const dir = pageDirection();
|
|
@@ -3737,7 +3916,7 @@ const createPagedQuery = (options) => {
|
|
|
3737
3916
|
const page = loadedMinPage() - 1;
|
|
3738
3917
|
if (page < 1) {
|
|
3739
3918
|
if (isDevMode()) {
|
|
3740
|
-
throw
|
|
3919
|
+
throw pagedQueryStackPreviousPageCalledButAlreadyAtFirstPage();
|
|
3741
3920
|
}
|
|
3742
3921
|
return;
|
|
3743
3922
|
}
|
|
@@ -3750,13 +3929,13 @@ const createPagedQuery = (options) => {
|
|
|
3750
3929
|
const currentPagination = pagination();
|
|
3751
3930
|
if (!currentPagination) {
|
|
3752
3931
|
if (isDevMode()) {
|
|
3753
|
-
throw
|
|
3932
|
+
throw pagedQueryStackNextPageCalledWithoutPreviousPage();
|
|
3754
3933
|
}
|
|
3755
3934
|
return;
|
|
3756
3935
|
}
|
|
3757
3936
|
if (page > currentPagination.totalPages) {
|
|
3758
3937
|
if (isDevMode()) {
|
|
3759
|
-
throw
|
|
3938
|
+
throw pagedQueryStackPageBiggerThanTotalPages(page, currentPagination.totalPages);
|
|
3760
3939
|
}
|
|
3761
3940
|
return;
|
|
3762
3941
|
}
|
|
@@ -3839,7 +4018,7 @@ const createPagedQuery = (options) => {
|
|
|
3839
4018
|
error: stack.error,
|
|
3840
4019
|
lastQuery: stack.lastQuery,
|
|
3841
4020
|
isFirstLoad,
|
|
3842
|
-
queries: stack.queries
|
|
4021
|
+
queries: stack.queries,
|
|
3843
4022
|
reset,
|
|
3844
4023
|
execute,
|
|
3845
4024
|
};
|
|
@@ -3850,12 +4029,32 @@ const setupQueryDependencies = (options) => {
|
|
|
3850
4029
|
const environmentInjector = inject(EnvironmentInjector);
|
|
3851
4030
|
const queryEnvironmentInjector = createEnvironmentInjector([], environmentInjector);
|
|
3852
4031
|
const destroyRef = queryEnvironmentInjector.get(DestroyRef);
|
|
4032
|
+
const scopeDestroyRef = inject(DestroyRef);
|
|
3853
4033
|
const client = inject(options.clientConfig.token);
|
|
3854
4034
|
const dependencies = {
|
|
3855
4035
|
destroyRef,
|
|
4036
|
+
scopeDestroyRef,
|
|
3856
4037
|
client,
|
|
3857
4038
|
injector: queryEnvironmentInjector,
|
|
3858
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
|
+
});
|
|
3859
4058
|
return dependencies;
|
|
3860
4059
|
};
|
|
3861
4060
|
|
|
@@ -3878,7 +4077,7 @@ const setupQueryExecuteState = () => {
|
|
|
3878
4077
|
};
|
|
3879
4078
|
};
|
|
3880
4079
|
const queryExecute = (options) => {
|
|
3881
|
-
const { executeOptions, args, executeState, options: runQueryOptions } = options;
|
|
4080
|
+
const { executeOptions, args, executeState, options: runQueryOptions, internalOptions: internalRunQueryOptions, transformResponse, } = options;
|
|
3882
4081
|
const { deps, state, creator, creatorInternals, queryConfig } = executeOptions;
|
|
3883
4082
|
const { key, request } = deps.client.repository.request({
|
|
3884
4083
|
route: creator.route,
|
|
@@ -3893,11 +4092,13 @@ const queryExecute = (options) => {
|
|
|
3893
4092
|
destroyRef: deps.destroyRef,
|
|
3894
4093
|
key: queryConfig.key,
|
|
3895
4094
|
previousKey: executeState.previousKey(),
|
|
4095
|
+
internalRunQueryOptions,
|
|
3896
4096
|
runQueryOptions,
|
|
3897
4097
|
});
|
|
3898
4098
|
executeState.previousKey.set(key);
|
|
4099
|
+
const responseSignal = transformResponse ? computed(() => transformResponse(request.response())) : request.response;
|
|
3899
4100
|
runInInjectionContext(deps.injector, () => {
|
|
3900
|
-
const responseRef = syncSignal(
|
|
4101
|
+
const responseRef = syncSignal(responseSignal, state.response);
|
|
3901
4102
|
const loadingRef = syncSignal(request.loading, state.loading);
|
|
3902
4103
|
const errorRef = syncSignal(request.error, state.error);
|
|
3903
4104
|
const latestHttpEventRef = syncSignal(request.currentEvent, state.latestHttpEvent);
|
|
@@ -3924,88 +4125,22 @@ const createExecuteFn = (executeOptions) => {
|
|
|
3924
4125
|
return exec;
|
|
3925
4126
|
};
|
|
3926
4127
|
|
|
3927
|
-
const setupQueryState = (options) => {
|
|
3928
|
-
const response = signal(null);
|
|
3929
|
-
const args = signal(null);
|
|
3930
|
-
const latestHttpEvent = signal(null);
|
|
3931
|
-
const error = signal(null);
|
|
3932
|
-
const loading = signal(null);
|
|
3933
|
-
const lastTimeExecutedAt = signal(null);
|
|
3934
|
-
const state = {
|
|
3935
|
-
response,
|
|
3936
|
-
args,
|
|
3937
|
-
latestHttpEvent,
|
|
3938
|
-
loading,
|
|
3939
|
-
error,
|
|
3940
|
-
lastTimeExecutedAt,
|
|
3941
|
-
};
|
|
3942
|
-
return state;
|
|
3943
|
-
};
|
|
3944
|
-
|
|
3945
|
-
const createQuerySnapshotFn = (options) => {
|
|
3946
|
-
const { state, deps } = options;
|
|
3947
|
-
const snapshotFn = () => {
|
|
3948
|
-
const snapshotState = setupQueryState({});
|
|
3949
|
-
const isAlive = signal(true);
|
|
3950
|
-
const killEffectRef = effect(() => {
|
|
3951
|
-
const currentLoading = state.loading();
|
|
3952
|
-
const currentError = state.error();
|
|
3953
|
-
const currentResponse = state.response();
|
|
3954
|
-
const currentArgs = state.args();
|
|
3955
|
-
const currentLatestHttpEvent = state.latestHttpEvent();
|
|
3956
|
-
const currentLastTimeExecutedAt = state.lastTimeExecutedAt();
|
|
3957
|
-
untracked(() => {
|
|
3958
|
-
snapshotState.args.set(currentArgs);
|
|
3959
|
-
snapshotState.error.set(currentError);
|
|
3960
|
-
snapshotState.lastTimeExecutedAt.set(currentLastTimeExecutedAt);
|
|
3961
|
-
snapshotState.latestHttpEvent.set(currentLatestHttpEvent);
|
|
3962
|
-
snapshotState.loading.set(currentLoading);
|
|
3963
|
-
snapshotState.response.set(currentResponse);
|
|
3964
|
-
if (currentLoading)
|
|
3965
|
-
return;
|
|
3966
|
-
if (!currentResponse && !currentError)
|
|
3967
|
-
return;
|
|
3968
|
-
// kill the effect once loading is done and we either have a response or an error
|
|
3969
|
-
killEffectRef.destroy();
|
|
3970
|
-
isAlive.set(false);
|
|
3971
|
-
});
|
|
3972
|
-
}, { injector: deps.injector });
|
|
3973
|
-
const snapshot = {
|
|
3974
|
-
args: snapshotState.args.asReadonly(),
|
|
3975
|
-
response: snapshotState.response.asReadonly(),
|
|
3976
|
-
latestHttpEvent: snapshotState.latestHttpEvent.asReadonly(),
|
|
3977
|
-
loading: snapshotState.loading.asReadonly(),
|
|
3978
|
-
error: snapshotState.error.asReadonly(),
|
|
3979
|
-
lastTimeExecutedAt: snapshotState.lastTimeExecutedAt.asReadonly(),
|
|
3980
|
-
isAlive: isAlive.asReadonly(),
|
|
3981
|
-
id: options.execute.currentRepositoryKey,
|
|
3982
|
-
};
|
|
3983
|
-
return snapshot;
|
|
3984
|
-
};
|
|
3985
|
-
return snapshotFn;
|
|
3986
|
-
};
|
|
3987
|
-
|
|
3988
4128
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
3989
4129
|
const createQuery = (options) => {
|
|
3990
4130
|
const deps = setupQueryDependencies({ clientConfig: options.creatorInternals.client });
|
|
3991
4131
|
const state = setupQueryState({});
|
|
3992
4132
|
const { creator, creatorInternals, queryConfig } = options;
|
|
3993
4133
|
const flags = getQueryFeatureUsage(options);
|
|
3994
|
-
const execute = createExecuteFn({ deps, state, creator, creatorInternals, queryConfig
|
|
3995
|
-
const createSnapshot = createQuerySnapshotFn({ state, deps, execute });
|
|
3996
|
-
const destroy = () => deps.injector.destroy();
|
|
4134
|
+
const execute = createExecuteFn({ deps, state, creator, creatorInternals, queryConfig });
|
|
3997
4135
|
const featureFnContext = {
|
|
3998
4136
|
state,
|
|
3999
|
-
queryConfig,
|
|
4000
|
-
creatorConfig: creator,
|
|
4001
|
-
creatorInternals,
|
|
4002
4137
|
execute,
|
|
4003
4138
|
flags,
|
|
4004
4139
|
deps,
|
|
4005
4140
|
};
|
|
4006
|
-
applyQueryFeatures(options, featureFnContext);
|
|
4141
|
+
applyQueryFeatures(options.features, featureFnContext);
|
|
4007
4142
|
maybeExecute({ execute, flags });
|
|
4008
|
-
return createQueryObject({ state, execute,
|
|
4143
|
+
return createQueryObject({ state, execute, deps });
|
|
4009
4144
|
};
|
|
4010
4145
|
|
|
4011
4146
|
const createQueryRepository = (config) => {
|
|
@@ -4013,7 +4148,9 @@ const createQueryRepository = (config) => {
|
|
|
4013
4148
|
const cache = new Map();
|
|
4014
4149
|
const request = (options) => {
|
|
4015
4150
|
const { args, clientOptions, runQueryOptions } = options;
|
|
4016
|
-
const shouldCache =
|
|
4151
|
+
const shouldCache = options.internalRunQueryOptions?.useQueryRepositoryCache === false
|
|
4152
|
+
? false
|
|
4153
|
+
: shouldCacheQuery(options.method) || options.internalRunQueryOptions?.useQueryRepositoryCache === true;
|
|
4017
4154
|
if (!shouldCache && options.key)
|
|
4018
4155
|
throw uncacheableRequestHasCacheKeyParam(options.key);
|
|
4019
4156
|
if (!shouldCache && runQueryOptions?.allowCache)
|
|
@@ -4030,8 +4167,7 @@ const createQueryRepository = (config) => {
|
|
|
4030
4167
|
body: args?.body,
|
|
4031
4168
|
queryParams: args?.queryParams,
|
|
4032
4169
|
pathParams: args?.pathParams,
|
|
4033
|
-
|
|
4034
|
-
// headers: args?.headers,
|
|
4170
|
+
headers: args?.headers,
|
|
4035
4171
|
});
|
|
4036
4172
|
const previousKey = options.previousKey;
|
|
4037
4173
|
if (key !== previousKey && previousKey) {
|
|
@@ -4113,6 +4249,10 @@ const provideQueryClient = (config) => {
|
|
|
4113
4249
|
};
|
|
4114
4250
|
};
|
|
4115
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
|
+
*/
|
|
4116
4256
|
const createQueryClientConfig = (options) => {
|
|
4117
4257
|
const token = new InjectionToken(`QueryClient_${options.name}`);
|
|
4118
4258
|
const clientConfig = {
|
|
@@ -4120,6 +4260,9 @@ const createQueryClientConfig = (options) => {
|
|
|
4120
4260
|
token,
|
|
4121
4261
|
name: options.name,
|
|
4122
4262
|
queryString: options.queryString,
|
|
4263
|
+
// createHttpRequest will use fallbacks if these are not provided
|
|
4264
|
+
cacheAdapter: options.cacheAdapter,
|
|
4265
|
+
retryFn: options.retryFn,
|
|
4123
4266
|
};
|
|
4124
4267
|
return clientConfig;
|
|
4125
4268
|
};
|
|
@@ -4236,22 +4379,17 @@ const createSecureQuery = (options) => {
|
|
|
4236
4379
|
state,
|
|
4237
4380
|
creator,
|
|
4238
4381
|
creatorInternals,
|
|
4239
|
-
queryConfig
|
|
4382
|
+
queryConfig,
|
|
4240
4383
|
});
|
|
4241
|
-
const createSnapshot = createQuerySnapshotFn({ state, deps, execute });
|
|
4242
|
-
const destroy = () => deps.injector.destroy();
|
|
4243
4384
|
const featureFnContext = {
|
|
4385
|
+
deps,
|
|
4244
4386
|
state,
|
|
4245
|
-
queryConfig,
|
|
4246
|
-
creatorConfig: creator,
|
|
4247
|
-
creatorInternals,
|
|
4248
4387
|
execute,
|
|
4249
4388
|
flags,
|
|
4250
|
-
deps,
|
|
4251
4389
|
};
|
|
4252
|
-
applyQueryFeatures(options, featureFnContext);
|
|
4390
|
+
applyQueryFeatures(options.features, featureFnContext);
|
|
4253
4391
|
maybeExecute({ execute, flags });
|
|
4254
|
-
return createQueryObject({ state, execute,
|
|
4392
|
+
return createQueryObject({ state, execute, deps });
|
|
4255
4393
|
};
|
|
4256
4394
|
|
|
4257
4395
|
const createSecureQueryCreator = (options, internals) => {
|
|
@@ -4267,44 +4405,275 @@ const createSecureQueryCreator = (options, internals) => {
|
|
|
4267
4405
|
return queryCreator;
|
|
4268
4406
|
};
|
|
4269
4407
|
|
|
4408
|
+
/** A query creator that creates a GET query */
|
|
4270
4409
|
const createGetQuery = (client) => {
|
|
4271
4410
|
return (creatorOptions) => createQueryCreator(creatorOptions, { method: 'GET', client });
|
|
4272
4411
|
};
|
|
4412
|
+
/** A query creator that creates a secure GET query (requires authentication) */
|
|
4273
4413
|
const createSecureGetQuery = (client, authProvider) => {
|
|
4274
4414
|
return (creatorOptions) => createSecureQueryCreator(creatorOptions, { method: 'GET', client, authProvider });
|
|
4275
4415
|
};
|
|
4416
|
+
/** A query creator that creates a POST query */
|
|
4276
4417
|
const createPostQuery = (client) => {
|
|
4277
4418
|
return (creatorOptions) => createQueryCreator(creatorOptions, { method: 'POST', client });
|
|
4278
4419
|
};
|
|
4420
|
+
/** A query creator that creates a secure POST query (requires authentication) */
|
|
4279
4421
|
const createSecurePostQuery = (client, authProvider) => {
|
|
4280
4422
|
return (creatorOptions) => createSecureQueryCreator(creatorOptions, { method: 'POST', client, authProvider });
|
|
4281
4423
|
};
|
|
4424
|
+
/** A query creator that creates a PUT query */
|
|
4282
4425
|
const createPutQuery = (client) => {
|
|
4283
4426
|
return (creatorOptions) => createQueryCreator(creatorOptions, { method: 'PUT', client });
|
|
4284
4427
|
};
|
|
4428
|
+
/** A query creator that creates a secure PUT query (requires authentication) */
|
|
4285
4429
|
const createSecurePutQuery = (client, authProvider) => {
|
|
4286
4430
|
return (creatorOptions) => createSecureQueryCreator(creatorOptions, { method: 'PUT', client, authProvider });
|
|
4287
4431
|
};
|
|
4432
|
+
/** A query creator that creates a DELETE query */
|
|
4288
4433
|
const createDeleteQuery = (client) => {
|
|
4289
4434
|
return (creatorOptions) => createQueryCreator(creatorOptions, { method: 'DELETE', client });
|
|
4290
4435
|
};
|
|
4436
|
+
/** A query creator that creates a secure DELETE query (requires authentication) */
|
|
4291
4437
|
const createSecureDeleteQuery = (client, authProvider) => {
|
|
4292
4438
|
return (creatorOptions) => createSecureQueryCreator(creatorOptions, { method: 'DELETE', client, authProvider });
|
|
4293
4439
|
};
|
|
4440
|
+
/** A query creator that creates a PATCH query */
|
|
4294
4441
|
const createPatchQuery = (client) => {
|
|
4295
4442
|
return (creatorOptions) => createQueryCreator(creatorOptions, { method: 'PATCH', client });
|
|
4296
4443
|
};
|
|
4444
|
+
/** A query creator that creates a secure PATCH query (requires authentication) */
|
|
4297
4445
|
const createSecurePatchQuery = (client, authProvider) => {
|
|
4298
4446
|
return (creatorOptions) => createSecureQueryCreator(creatorOptions, { method: 'PATCH', client, authProvider });
|
|
4299
4447
|
};
|
|
4300
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
|
+
|
|
4301
4669
|
var index = /*#__PURE__*/Object.freeze({
|
|
4302
4670
|
__proto__: null,
|
|
4303
|
-
|
|
4671
|
+
CLEAR_QUERY_ARGS: CLEAR_QUERY_ARGS,
|
|
4304
4672
|
QUERY_EFFECT_ERROR_MESSAGE: QUERY_EFFECT_ERROR_MESSAGE,
|
|
4305
4673
|
SPEED_BUFFER_TIME_IN_MS: SPEED_BUFFER_TIME_IN_MS,
|
|
4306
4674
|
applyQueryFeatures: applyQueryFeatures,
|
|
4307
4675
|
bearerExpiresInPropertyNotNumber: bearerExpiresInPropertyNotNumber,
|
|
4676
|
+
buildQueryCacheKey: buildQueryCacheKey,
|
|
4308
4677
|
cleanupPreviousExecute: cleanupPreviousExecute,
|
|
4309
4678
|
contentfulGqlLikePaginationAdapter: contentfulGqlLikePaginationAdapter,
|
|
4310
4679
|
cookieLoginTriedButCookieDisabled: cookieLoginTriedButCookieDisabled,
|
|
@@ -4313,8 +4682,15 @@ var index = /*#__PURE__*/Object.freeze({
|
|
|
4313
4682
|
createDeleteQuery: createDeleteQuery,
|
|
4314
4683
|
createExecuteFn: createExecuteFn,
|
|
4315
4684
|
createGetQuery: createGetQuery,
|
|
4685
|
+
createGqlExecuteFn: createGqlExecuteFn,
|
|
4686
|
+
createGqlMutationViaGet: createGqlMutationViaGet,
|
|
4687
|
+
createGqlMutationViaPost: createGqlMutationViaPost,
|
|
4688
|
+
createGqlQuery: createGqlQuery,
|
|
4689
|
+
createGqlQueryCreator: createGqlQueryCreator,
|
|
4690
|
+
createGqlQueryViaGet: createGqlQueryViaGet,
|
|
4691
|
+
createGqlQueryViaPost: createGqlQueryViaPost,
|
|
4316
4692
|
createHttpRequest: createHttpRequest,
|
|
4317
|
-
|
|
4693
|
+
createPagedQueryStack: createPagedQueryStack,
|
|
4318
4694
|
createPatchQuery: createPatchQuery,
|
|
4319
4695
|
createPostQuery: createPostQuery,
|
|
4320
4696
|
createPutQuery: createPutQuery,
|
|
@@ -4334,6 +4710,8 @@ var index = /*#__PURE__*/Object.freeze({
|
|
|
4334
4710
|
createSecurePutQuery: createSecurePutQuery,
|
|
4335
4711
|
createSecureQuery: createSecureQuery,
|
|
4336
4712
|
createSecureQueryCreator: createSecureQueryCreator,
|
|
4713
|
+
createWebSocketClient: createWebSocketClient,
|
|
4714
|
+
createWebSocketClientConfig: createWebSocketClientConfig,
|
|
4337
4715
|
defaultResponseTransformerResponseNotContainingAccessToken: defaultResponseTransformerResponseNotContainingAccessToken,
|
|
4338
4716
|
defaultResponseTransformerResponseNotContainingRefreshToken: defaultResponseTransformerResponseNotContainingRefreshToken,
|
|
4339
4717
|
defaultResponseTransformerResponseNotObject: defaultResponseTransformerResponseNotObject,
|
|
@@ -4342,26 +4720,33 @@ var index = /*#__PURE__*/Object.freeze({
|
|
|
4342
4720
|
enableCookieCalledWithoutCookieConfig: enableCookieCalledWithoutCookieConfig,
|
|
4343
4721
|
ethletePaginationAdapter: ethletePaginationAdapter,
|
|
4344
4722
|
extractExpiresInSeconds: extractExpiresInSeconds,
|
|
4723
|
+
fakePaginationAdapter: fakePaginationAdapter,
|
|
4345
4724
|
getQueryFeatureUsage: getQueryFeatureUsage,
|
|
4346
4725
|
ggLikePaginationAdapter: ggLikePaginationAdapter,
|
|
4726
|
+
isCreateGqlQueryOptions: isCreateGqlQueryOptions,
|
|
4347
4727
|
loginCalledWithoutConfig: loginCalledWithoutConfig,
|
|
4348
4728
|
loginWithTokenCalledWithoutConfig: loginWithTokenCalledWithoutConfig,
|
|
4349
4729
|
maybeExecute: maybeExecute,
|
|
4350
|
-
|
|
4351
|
-
|
|
4352
|
-
|
|
4730
|
+
normalizeQueryRepositoryKey: normalizeQueryRepositoryKey,
|
|
4731
|
+
pagedQueryStackNextPageCalledWithoutPreviousPage: pagedQueryStackNextPageCalledWithoutPreviousPage,
|
|
4732
|
+
pagedQueryStackPageBiggerThanTotalPages: pagedQueryStackPageBiggerThanTotalPages,
|
|
4733
|
+
pagedQueryStackPreviousPageCalledButAlreadyAtFirstPage: pagedQueryStackPreviousPageCalledButAlreadyAtFirstPage,
|
|
4353
4734
|
provideBearerAuthProvider: provideBearerAuthProvider,
|
|
4354
4735
|
provideQueryClient: provideQueryClient,
|
|
4736
|
+
provideWebSocketClient: provideWebSocketClient,
|
|
4355
4737
|
queryEffect: queryEffect,
|
|
4356
4738
|
queryExecute: queryExecute,
|
|
4357
4739
|
queryFeatureUsedMultipleTimes: queryFeatureUsedMultipleTimes,
|
|
4740
|
+
queryStackWithArgsUsed: queryStackWithArgsUsed,
|
|
4358
4741
|
refreshTokenCalledWithoutConfig: refreshTokenCalledWithoutConfig,
|
|
4359
4742
|
resetExecuteState: resetExecuteState,
|
|
4360
4743
|
selectRoleCalledWithoutConfig: selectRoleCalledWithoutConfig,
|
|
4361
4744
|
setupQueryDependencies: setupQueryDependencies,
|
|
4362
4745
|
setupQueryExecuteState: setupQueryExecuteState,
|
|
4363
4746
|
setupQueryState: setupQueryState,
|
|
4747
|
+
shouldAutoExecuteGqlQuery: shouldAutoExecuteGqlQuery,
|
|
4364
4748
|
shouldAutoExecuteQuery: shouldAutoExecuteQuery,
|
|
4749
|
+
shouldCacheQuery: shouldCacheQuery,
|
|
4365
4750
|
shouldRetryRequest: shouldRetryRequest,
|
|
4366
4751
|
splitQueryConfig: splitQueryConfig,
|
|
4367
4752
|
transformArrayResponse: transformArrayResponse,
|
|
@@ -4480,6 +4865,7 @@ const transformToSortQueryParam = (value) => {
|
|
|
4480
4865
|
|
|
4481
4866
|
const ET_ARR_PREFIX = 'ET_ARR__';
|
|
4482
4867
|
class QueryField {
|
|
4868
|
+
data;
|
|
4483
4869
|
get control() {
|
|
4484
4870
|
return this.data.control;
|
|
4485
4871
|
}
|
|
@@ -4490,12 +4876,70 @@ class QueryField {
|
|
|
4490
4876
|
const IGNORED_FILTER_COUNT_FIELDS = ['page', 'skip', 'take', 'limit', 'sort', 'sortBy', 'sortOrder', 'query', 'search'];
|
|
4491
4877
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
4492
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);
|
|
4493
4905
|
get _formValue() {
|
|
4494
4906
|
return this.form.getRawValue();
|
|
4495
4907
|
}
|
|
4496
4908
|
get _form() {
|
|
4497
4909
|
return this.form;
|
|
4498
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));
|
|
4499
4943
|
get controls() {
|
|
4500
4944
|
return this.form.controls;
|
|
4501
4945
|
}
|
|
@@ -4512,62 +4956,6 @@ class QueryForm {
|
|
|
4512
4956
|
constructor(_fields, _options) {
|
|
4513
4957
|
this._fields = _fields;
|
|
4514
4958
|
this._options = _options;
|
|
4515
|
-
this._destroy$ = createDestroy();
|
|
4516
|
-
this._unobserveTrigger$ = new Subject();
|
|
4517
|
-
this._router = inject(Router);
|
|
4518
|
-
this._activatedRoute = inject(ActivatedRoute);
|
|
4519
|
-
this._defaultValues = this._extractDefaultValues();
|
|
4520
|
-
this._zone = inject(NgZone);
|
|
4521
|
-
this._didValueChanges$ = new Subject();
|
|
4522
|
-
this._isObserving = false;
|
|
4523
|
-
this._skipNextResets = false;
|
|
4524
|
-
this._queryParamChanges$ = toObservable(injectQueryParamChanges());
|
|
4525
|
-
this._queryParams = injectQueryParams();
|
|
4526
|
-
/**
|
|
4527
|
-
* The angular form group that contains all the fields.
|
|
4528
|
-
*
|
|
4529
|
-
* **Do not** use any of the following methods on this form group:
|
|
4530
|
-
* - `setValue`: Use `QueryForm.setValue` instead.
|
|
4531
|
-
* - `patchValue`: Use `QueryForm.patchValue` instead.
|
|
4532
|
-
* - `valueChanges`: Use `QueryForm.changes$` instead.
|
|
4533
|
-
* - `value`: Use `QueryForm.value` instead.
|
|
4534
|
-
* - `controls`: Use `QueryForm.controls` instead.
|
|
4535
|
-
*/
|
|
4536
|
-
this.form = this._setupFormGroup();
|
|
4537
|
-
this._lastFormValue$ = new BehaviorSubject(null);
|
|
4538
|
-
this._currentFormValue$ = new BehaviorSubject(this._formValue);
|
|
4539
|
-
this._changes$ = new BehaviorSubject({
|
|
4540
|
-
previousValue: null,
|
|
4541
|
-
currentValue: this.form.getRawValue(),
|
|
4542
|
-
});
|
|
4543
|
-
this.changes$ = this._changes$.asObservable();
|
|
4544
|
-
this.currentValue$ = this._changes$.pipe(map(({ currentValue }) => currentValue));
|
|
4545
|
-
this.previousValue$ = this._changes$.pipe(map(({ previousValue }) => previousValue));
|
|
4546
|
-
this.changes = toSignal(this.changes$);
|
|
4547
|
-
this.currentValue = toSignal(this.currentValue$);
|
|
4548
|
-
this.previousValue = toSignal(this.previousValue$);
|
|
4549
|
-
/**
|
|
4550
|
-
* The number of active filters.
|
|
4551
|
-
*
|
|
4552
|
-
* Excludes the following fields by default:
|
|
4553
|
-
* - `page`
|
|
4554
|
-
* - `skip`
|
|
4555
|
-
* - `take`
|
|
4556
|
-
* - `limit`
|
|
4557
|
-
* - `sort`
|
|
4558
|
-
* - `sortBy`
|
|
4559
|
-
* - `sortOrder`
|
|
4560
|
-
* - `query`
|
|
4561
|
-
* - `search`
|
|
4562
|
-
*/
|
|
4563
|
-
this.activeFilterCount$ = this.changes$.pipe(map(({ currentValue }) => Object.entries(currentValue)
|
|
4564
|
-
.map(([key, value]) => {
|
|
4565
|
-
if (IGNORED_FILTER_COUNT_FIELDS.includes(key) || this._fields[key]?.data.skipInFilterCount) {
|
|
4566
|
-
return true;
|
|
4567
|
-
}
|
|
4568
|
-
return this._isDefaultValue(key, value);
|
|
4569
|
-
})
|
|
4570
|
-
.filter((v) => v === false).length));
|
|
4571
4959
|
assertInInjectionContext(QueryForm);
|
|
4572
4960
|
inject(DestroyRef).onDestroy(() => this._cleanup());
|
|
4573
4961
|
}
|
|
@@ -4889,5 +5277,5 @@ class QueryForm {
|
|
|
4889
5277
|
* Generated bundle index. Do not edit.
|
|
4890
5278
|
*/
|
|
4891
5279
|
|
|
4892
|
-
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 };
|
|
4893
5281
|
//# sourceMappingURL=ethlete-query.mjs.map
|