@ethlete/query 4.7.5 → 4.7.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,8 +1,8 @@
1
1
  import * as i1$1 from '@ethlete/core';
2
2
  import { getCookie, setCookie, deleteCookie, createDestroy, nextFrame, DelayableDirective, RouterStateService, clone, equal, ET_PROPERTY_REMOVED } from '@ethlete/core';
3
- import { Observable, filter, takeWhile, switchMap, of, tap, BehaviorSubject, shareReplay, Subject, takeUntil, interval, skip, map, timer, startWith, combineLatest, withLatestFrom, fromEvent, debounceTime, take, concat } from 'rxjs';
3
+ import { Observable, BehaviorSubject, Subject, fromEvent, timer, takeUntil, take, filter, takeWhile, switchMap, of, tap, shareReplay, interval, skip, map, startWith, combineLatest, withLatestFrom, debounceTime, concat } from 'rxjs';
4
4
  import * as i0 from '@angular/core';
5
- import { isDevMode, InjectionToken, inject, ChangeDetectorRef, signal, computed, effect, Component, ChangeDetectionStrategy, ViewEncapsulation, TemplateRef, ViewContainerRef, ErrorHandler, Directive, Input, ElementRef, NgZone, assertInInjectionContext } from '@angular/core';
5
+ import { isDevMode, Pipe, InjectionToken, inject, ChangeDetectorRef, signal, computed, effect, Component, ChangeDetectionStrategy, ViewEncapsulation, TemplateRef, ViewContainerRef, ErrorHandler, Directive, Input, ElementRef, NgZone, assertInInjectionContext } from '@angular/core';
6
6
  import { NgIf, NgFor, AsyncPipe, JsonPipe, NgClass } from '@angular/common';
7
7
  import { toSignal, toObservable } from '@angular/core/rxjs-interop';
8
8
  import * as i1 from '@angular/forms';
@@ -493,6 +493,270 @@ const request = (config) => {
493
493
  });
494
494
  };
495
495
 
496
+ class QueryCreator {
497
+ constructor(_queryConfig, _client, _store) {
498
+ this._queryConfig = _queryConfig;
499
+ this._client = _client;
500
+ this._store = _store;
501
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
502
+ // @ts-ignore
503
+ this.prepare = (args) => {
504
+ const route = buildRoute({
505
+ base: this._client.config.baseRoute,
506
+ route: this._queryConfig.route,
507
+ pathParams: args?.pathParams,
508
+ queryParams: computeQueryQueryParams({ config: this._queryConfig, client: this._client, args }),
509
+ queryParamConfig: this._client.config.request?.queryParams,
510
+ });
511
+ const cacheKey = isGqlQueryConfig(this._queryConfig) ? buildGqlCacheKey(this._queryConfig, args) : route;
512
+ if (shouldCacheQuery(this._queryConfig.method)) {
513
+ const existingQuery = this._store.get(cacheKey);
514
+ if (existingQuery) {
515
+ return existingQuery;
516
+ }
517
+ }
518
+ const query = new Query(this._client, this._queryConfig, route, args ?? {});
519
+ if (shouldCacheQuery(this._queryConfig.method)) {
520
+ this._store.add(cacheKey, query);
521
+ }
522
+ this._store._dispatchQueryCreated(query);
523
+ return query;
524
+ };
525
+ this.behaviorSubject = (initialValue) => new BehaviorSubject(initialValue ?? null);
526
+ }
527
+ }
528
+
529
+ class QueryStore {
530
+ constructor(_config) {
531
+ this._config = _config;
532
+ /**
533
+ * @internal
534
+ */
535
+ this._store = new Map();
536
+ this._garbageCollector = null;
537
+ this._isInLowResourceMode = false;
538
+ this._lastBlurTimestamp = Date.now();
539
+ this._storeChange$ = new Subject();
540
+ this._queryCreated$ = new Subject();
541
+ this.storeChange$ = this._storeChange$.asObservable();
542
+ this.queryCreated$ = this._queryCreated$.asObservable();
543
+ this._initSmartQueryHandling();
544
+ }
545
+ add(id, query) {
546
+ this._store.set(id, query);
547
+ this._initGarbageCollector();
548
+ this._logState(id, query, 'SET');
549
+ this._storeChange$.next(id);
550
+ }
551
+ get(id) {
552
+ return this._store.get(id) ?? null;
553
+ }
554
+ remove(id) {
555
+ this._store.delete(id);
556
+ this._logState(id, null, 'REMOVE');
557
+ this._storeChange$.next(id);
558
+ }
559
+ forEach(callback) {
560
+ for (const [key, query] of this._store) {
561
+ callback(query, key);
562
+ }
563
+ }
564
+ refreshQueriesInUse(config) {
565
+ const { ignoreCacheValidity, purgeUnused } = config ?? {};
566
+ for (const [key, query] of this._store) {
567
+ if (query.isInUse &&
568
+ (query.isExpired || ignoreCacheValidity) &&
569
+ query.autoRefreshOnConfig.queryClientDefaultHeadersChange) {
570
+ query.execute({ skipCache: true, _triggeredVia: 'auto' });
571
+ }
572
+ else if (purgeUnused && !query.isInUse) {
573
+ this.remove(key);
574
+ }
575
+ }
576
+ }
577
+ /**
578
+ * @internal
579
+ */
580
+ _dispatchQueryCreated(query) {
581
+ this._queryCreated$.next(query);
582
+ }
583
+ _initSmartQueryHandling() {
584
+ const windowBlur$ = fromEvent(window, 'blur');
585
+ const windowFocus$ = fromEvent(window, 'focus');
586
+ windowBlur$.subscribe(() => {
587
+ timer(5000)
588
+ .pipe(takeUntil(windowFocus$), take(1))
589
+ .subscribe(() => {
590
+ this._lastBlurTimestamp = Date.now();
591
+ this._isInLowResourceMode = true;
592
+ this._stopGarbageCollector();
593
+ if (this._config?.enableSmartPolling) {
594
+ this.forEach((query) => {
595
+ if (!query.isPolling || !query._enableSmartPolling) {
596
+ return;
597
+ }
598
+ query.pausePolling();
599
+ });
600
+ }
601
+ });
602
+ });
603
+ windowFocus$.subscribe(() => {
604
+ if (!this._isInLowResourceMode) {
605
+ return;
606
+ }
607
+ this._isInLowResourceMode = false;
608
+ if (this._config?.enableSmartPolling || this._config?.autoRefreshQueriesOnWindowFocus) {
609
+ this.forEach((query) => {
610
+ if (this._config?.enableSmartPolling && query._isPollingPaused) {
611
+ query.resumePolling();
612
+ }
613
+ if (Date.now() - this._lastBlurTimestamp > 15000) {
614
+ if (this._config?.autoRefreshQueriesOnWindowFocus &&
615
+ query.isExpired &&
616
+ query.isInUse &&
617
+ query.autoRefreshOnConfig.windowFocus) {
618
+ query.execute({ skipCache: true, _triggeredVia: 'auto' });
619
+ }
620
+ }
621
+ });
622
+ }
623
+ this._initGarbageCollector();
624
+ });
625
+ }
626
+ _logState(key, item, operation) {
627
+ if (!this._config?.enableChangeLogging)
628
+ return;
629
+ const stateAsJson = {};
630
+ this._store.forEach((value, key) => {
631
+ stateAsJson[key] = value;
632
+ });
633
+ console.log(`%c[${operation}] ${key}`, 'font-weight: bold');
634
+ console.log({ operation, key, item });
635
+ console.log(stateAsJson);
636
+ }
637
+ _initGarbageCollector() {
638
+ if (this._garbageCollector !== null) {
639
+ return;
640
+ }
641
+ this._logGarbageCollector('Start');
642
+ this._garbageCollector = window.setInterval(() => {
643
+ this._runGarbageCollector();
644
+ }, 15000);
645
+ }
646
+ _stopGarbageCollector() {
647
+ if (this._garbageCollector !== null) {
648
+ window.clearInterval(this._garbageCollector);
649
+ this._garbageCollector = null;
650
+ this._logGarbageCollector('Stop');
651
+ }
652
+ }
653
+ _runGarbageCollector() {
654
+ this._logGarbageCollector('Collecting...');
655
+ this._store.forEach((item, key) => {
656
+ if (item.isExpired && !item.isInUse) {
657
+ this.remove(key);
658
+ }
659
+ });
660
+ this._logGarbageCollector('Collection done');
661
+ if (!this._store.size) {
662
+ this._stopGarbageCollector();
663
+ }
664
+ }
665
+ _logGarbageCollector(action) {
666
+ if (!this._config?.enableGarbageCollectorLogging)
667
+ return;
668
+ console.log(`%cGC: ${action}`, 'color: yellow; font-weight: bold');
669
+ }
670
+ }
671
+
672
+ class QueryClient {
673
+ get config() {
674
+ return this._clientConfig;
675
+ }
676
+ get authProvider() {
677
+ return this._authProvider$.getValue() ?? this._clientConfig.parent?._authProvider$.getValue() ?? null;
678
+ }
679
+ get authProvider$() {
680
+ return this._authProvider$.asObservable() ?? this._clientConfig.parent?._authProvider$.asObservable() ?? null;
681
+ }
682
+ constructor(_clientConfig) {
683
+ this._clientConfig = _clientConfig;
684
+ this._authProvider$ = new BehaviorSubject(null);
685
+ this.get = (queryConfig) => this.fetch({
686
+ ...queryConfig,
687
+ method: 'GET',
688
+ });
689
+ this.post = (queryConfig) => this.fetch({
690
+ ...queryConfig,
691
+ method: 'POST',
692
+ });
693
+ this.put = (queryConfig) => this.fetch({
694
+ ...queryConfig,
695
+ method: 'PUT',
696
+ });
697
+ this.patch = (queryConfig) => this.fetch({
698
+ ...queryConfig,
699
+ method: 'PATCH',
700
+ });
701
+ this.delete = (queryConfig) => this.fetch({
702
+ ...queryConfig,
703
+ method: 'DELETE',
704
+ });
705
+ this.gqlQuery = (queryConfig) => this.fetch({
706
+ ...queryConfig,
707
+ method: 'GQL_QUERY',
708
+ });
709
+ this.gqlMutate = (queryConfig) => this.fetch({
710
+ ...queryConfig,
711
+ method: 'GQL_MUTATE',
712
+ });
713
+ this.fetch = (queryConfig) => new QueryCreator(queryConfig, this, this._store);
714
+ this.setAuthProvider = (authProvider) => {
715
+ if (this.authProvider) {
716
+ throw new Error('The auth provider is already set. Please call clearAuthProvider() first.');
717
+ }
718
+ this._authProvider$.next(authProvider);
719
+ };
720
+ this.setDefaultHeaders = (config) => {
721
+ if (!this._clientConfig.request) {
722
+ this._clientConfig.request = {
723
+ headers: config.headers ?? undefined,
724
+ };
725
+ }
726
+ else {
727
+ this._clientConfig.request.headers = config.headers ?? undefined;
728
+ }
729
+ if (config.refreshQueriesInUse) {
730
+ this._store.refreshQueriesInUse({ purgeUnused: true, ignoreCacheValidity: true });
731
+ }
732
+ };
733
+ this.clearAuthProvider = () => {
734
+ this.authProvider?.cleanUp();
735
+ this._authProvider$.next(null);
736
+ };
737
+ this._store = new QueryStore({
738
+ enableChangeLogging: _clientConfig.logging?.queryStateChanges,
739
+ enableGarbageCollectorLogging: _clientConfig.logging?.queryStateGarbageCollector,
740
+ autoRefreshQueriesOnWindowFocus: _clientConfig.request?.autoRefreshQueriesOnWindowFocus ?? true,
741
+ enableSmartPolling: _clientConfig.request?.enableSmartPolling ?? true,
742
+ });
743
+ }
744
+ }
745
+
746
+ const shouldCacheQuery = (method) => {
747
+ return method === 'GET' || method === 'OPTIONS' || method === 'HEAD' || method === 'GQL_QUERY';
748
+ };
749
+ const buildGqlCacheKey = (config, args) => {
750
+ const { query } = config;
751
+ const variables = args?.variables || {};
752
+ const queryWithoutNewLinesAndWhitespace = query.replace(/\s/g, '');
753
+ const queryFirst50Chars = queryWithoutNewLinesAndWhitespace.slice(0, 50);
754
+ const queryMiddle25Chars = queryWithoutNewLinesAndWhitespace.slice(queryWithoutNewLinesAndWhitespace.length / 2 - 25, queryWithoutNewLinesAndWhitespace.length / 2 + 25);
755
+ const queryLast50Chars = queryWithoutNewLinesAndWhitespace.slice(-50);
756
+ const vars = JSON.stringify(variables);
757
+ return `${queryFirst50Chars}...${queryMiddle25Chars}...${queryLast50Chars}...${vars}`;
758
+ };
759
+
496
760
  const getOpName = /(query|mutation) ?([\w\d-_]+)? ?\(.*?\)? \{/;
497
761
  const transformGql = (str) => {
498
762
  str = Array.isArray(str) ? str.join('') : str;
@@ -802,24 +1066,29 @@ class Query {
802
1066
  get _enableSmartPolling() {
803
1067
  return this._queryConfig.enableSmartPolling ?? true;
804
1068
  }
805
- /**
806
- * @internal
807
- */
808
- get _arguments() {
809
- return this._args;
810
- }
811
1069
  get store() {
812
1070
  return this._queryConfig.entity?.store ?? null;
813
1071
  }
814
- constructor(_client, _queryConfig,
1072
+ get canBeCached() {
1073
+ return shouldCacheQuery(this._queryConfig.method);
1074
+ }
1075
+ constructor(_client,
1076
+ /**
1077
+ * @internal
1078
+ */
1079
+ _queryConfig,
1080
+ /**
1081
+ * @internal
1082
+ */
1083
+ _routeWithParams,
815
1084
  /**
816
1085
  * @internal
817
1086
  */
818
- _routeWithParams, _args) {
1087
+ _arguments) {
819
1088
  this._client = _client;
820
1089
  this._queryConfig = _queryConfig;
821
1090
  this._routeWithParams = _routeWithParams;
822
- this._args = _args;
1091
+ this._arguments = _arguments;
823
1092
  this._id = _nextQueryId++;
824
1093
  this._currentLocalId = 0;
825
1094
  this._pollingSubscription = null;
@@ -856,8 +1125,8 @@ class Query {
856
1125
  }
857
1126
  this._state$.next({ type: "LOADING" /* QueryStateType.Loading */, meta });
858
1127
  const method = computeQueryMethod({ config: queryConfig, client: this._client });
859
- const body = computeQueryBody({ config: queryConfig, client: this._client, args: this._args, method });
860
- const headers = computeQueryHeaders({ client: this._client, config: queryConfig, args: this._args });
1128
+ const body = computeQueryBody({ config: queryConfig, client: this._client, args: this._arguments, method });
1129
+ const headers = computeQueryHeaders({ client: this._client, config: queryConfig, args: this._arguments });
861
1130
  request({
862
1131
  urlWithParams: this._routeWithParams,
863
1132
  method,
@@ -945,9 +1214,9 @@ class Query {
945
1214
  ? response['data']
946
1215
  : response;
947
1216
  if (this._queryConfig.entity && this._queryConfig.entity.set) {
948
- const id = this._queryConfig.entity?.id({ args: this._args, response: responseData });
1217
+ const id = this._queryConfig.entity?.id({ args: this._arguments, response: responseData });
949
1218
  this._queryConfig.entity?.set({
950
- args: this._args,
1219
+ args: this._arguments,
951
1220
  response: responseData,
952
1221
  id,
953
1222
  store: this._queryConfig.entity.store,
@@ -991,9 +1260,9 @@ class Query {
991
1260
  if (!isQueryStateSuccess(s) || !this._queryConfig.entity?.get) {
992
1261
  return of(s);
993
1262
  }
994
- const id = this._queryConfig.entity.id({ args: this._args, response: s.response });
1263
+ const id = this._queryConfig.entity.id({ args: this._arguments, response: s.response });
995
1264
  return this._queryConfig.entity
996
- .get({ args: this._args, id, response: s.response, store: this._queryConfig.entity.store })
1265
+ .get({ args: this._arguments, id, response: s.response, store: this._queryConfig.entity.store })
997
1266
  .pipe(map((v) => ({ ...s, response: v })));
998
1267
  }
999
1268
  }
@@ -1175,6 +1444,29 @@ const isClassValidatorError = (error) => {
1175
1444
  return typeof error === 'object' && error !== null && 'statusCode' in error && 'message' in error && 'error' in error;
1176
1445
  };
1177
1446
 
1447
+ class QueryShortNamePipe {
1448
+ transform(value) {
1449
+ const route = value._routeWithParams;
1450
+ if (typeof route === 'string') {
1451
+ // given an url that looks like this: https://api.github.com/repos/EladBezalel/etimo-achievements or https://api.github.com/repos/EladBezalel/etimo-achievements?test=1&test2=2
1452
+ // we want to extract the last 3 parts of the url, so we get: repos/EladBezalel/etimo-achievements
1453
+ const parts = route.split('/');
1454
+ if (parts.length > 3) {
1455
+ return `.../${parts.slice(parts.length - 3).join('/')}`;
1456
+ }
1457
+ return route;
1458
+ }
1459
+ console.log(route);
1460
+ return route;
1461
+ }
1462
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.6", ngImport: i0, type: QueryShortNamePipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
1463
+ static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "16.1.6", ngImport: i0, type: QueryShortNamePipe, isStandalone: true, name: "queryShortName" }); }
1464
+ }
1465
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.6", ngImport: i0, type: QueryShortNamePipe, decorators: [{
1466
+ type: Pipe,
1467
+ args: [{ name: 'queryShortName', standalone: true }]
1468
+ }] });
1469
+
1178
1470
  const QUERY_CLIENT_DEVTOOLS_TOKEN = new InjectionToken('QUERY_CLIENT_DEVTOOLS_TOKEN');
1179
1471
  const provideQueryClientForDevtools = (queryClient) => {
1180
1472
  if (!isDevMode()) {
@@ -1198,6 +1490,9 @@ class QueryDevtoolsComponent {
1198
1490
  this.queryListMode = signal('live');
1199
1491
  this.showResponse = signal(false);
1200
1492
  this.showRawResponse = signal(false);
1493
+ this.showQueryConfig = signal(false);
1494
+ this.showEntityStoreValue = signal(false);
1495
+ this.showArguments = signal(false);
1201
1496
  this.selectedClientIdCtrl = new FormControl(0);
1202
1497
  this.selectedClientId = toSignal(this.selectedClientIdCtrl.valueChanges.pipe(startWith(this.selectedClientIdCtrl.value)));
1203
1498
  this.selectedQueryId = signal(null);
@@ -1226,7 +1521,43 @@ class QueryDevtoolsComponent {
1226
1521
  }
1227
1522
  return this.queryHistory()?.find((q) => q._id === id) ?? null;
1228
1523
  });
1524
+ this.selectedQueryEntityStore = computed(() => {
1525
+ const query = this.selectedQuery();
1526
+ if (!query)
1527
+ return null;
1528
+ return query.store;
1529
+ });
1530
+ this.selectedQueryEntityStore$ = toObservable(this.selectedQueryEntityStore);
1531
+ this.selectedQueryEntityStoreValue$ = this.selectedQueryEntityStore$.pipe(switchMap((s) => s?._change$.pipe(startWith(''), map(() => s?._dictionary ?? null)) ?? of(null)));
1229
1532
  this.queryHistory = signal([]);
1533
+ this.stringifiedQueryConfig = computed(() => {
1534
+ const query = this.selectedQuery();
1535
+ if (!query)
1536
+ return null;
1537
+ const cfg = query._queryConfig;
1538
+ const route = typeof cfg.route === 'string' ? cfg.route : cfg.route ? cfg.route({}).replace(/undefined/g, ':param') : null;
1539
+ const sharedCfg = {
1540
+ method: cfg.method,
1541
+ secure: cfg.secure,
1542
+ route,
1543
+ reportProgress: cfg.reportProgress,
1544
+ responseType: cfg.responseType,
1545
+ withCredentials: cfg.withCredentials,
1546
+ autoRefreshOn: cfg.autoRefreshOn,
1547
+ enableSmartPolling: cfg.enableSmartPolling,
1548
+ hasEntityStore: !!cfg.entity,
1549
+ };
1550
+ if (isGqlQueryConfig(cfg)) {
1551
+ return {
1552
+ ...sharedCfg,
1553
+ query: cfg.query,
1554
+ transferVia: cfg.transferVia,
1555
+ };
1556
+ }
1557
+ return {
1558
+ ...sharedCfg,
1559
+ };
1560
+ });
1230
1561
  this.trackByClient = (_, { client }) => client.config.baseRoute;
1231
1562
  this.trackByQuery = (_, { _id }) => _id;
1232
1563
  this.selectedClientIdCtrl.valueChanges
@@ -1235,6 +1566,19 @@ class QueryDevtoolsComponent {
1235
1566
  this.queryStore$
1236
1567
  .pipe(switchMap((s) => s.storeChange$.pipe(startWith(''), map(() => s._store), tap((s) => this._queries$.next(Array.from(s.values()))), takeUntil(this._destroy$))))
1237
1568
  .subscribe();
1569
+ this.queryStore$
1570
+ .pipe(switchMap((s) => s.queryCreated$.pipe(tap((query) => {
1571
+ const currentHistory = this.queryHistory();
1572
+ if (!currentHistory)
1573
+ return;
1574
+ const currentHistoryClone = [...currentHistory];
1575
+ if (!currentHistory.some((q) => q._id === query._id)) {
1576
+ currentHistoryClone.unshift(query);
1577
+ }
1578
+ currentHistoryClone.splice(50);
1579
+ this.queryHistory.set(currentHistoryClone);
1580
+ }), takeUntil(this._destroy$))))
1581
+ .subscribe();
1238
1582
  this._queries$
1239
1583
  .pipe(tap((queries) => {
1240
1584
  const currentHistory = this.queryHistory();
@@ -1242,7 +1586,7 @@ class QueryDevtoolsComponent {
1242
1586
  return;
1243
1587
  const currentHistoryClone = [...currentHistory];
1244
1588
  for (const query of queries) {
1245
- if (!currentHistoryClone.includes(query)) {
1589
+ if (!currentHistoryClone.some((q) => q._id === query._id)) {
1246
1590
  currentHistoryClone.unshift(query);
1247
1591
  }
1248
1592
  }
@@ -1257,6 +1601,9 @@ class QueryDevtoolsComponent {
1257
1601
  snapLayout: this.snapLayout(),
1258
1602
  showResponse: this.showResponse(),
1259
1603
  showRawResponse: this.showRawResponse(),
1604
+ showQueryConfig: this.showQueryConfig(),
1605
+ showEntityStoreValue: this.showEntityStoreValue(),
1606
+ showArguments: this.showArguments(),
1260
1607
  selectedClientId: this.selectedClientId(),
1261
1608
  selectedQueryPath: this.selectedQueryId(),
1262
1609
  queryListMode: this.queryListMode(),
@@ -1271,6 +1618,9 @@ class QueryDevtoolsComponent {
1271
1618
  this.snapLayout.set(parsed.snapLayout ?? 'full');
1272
1619
  this.showResponse.set(parsed.showResponse ?? false);
1273
1620
  this.showRawResponse.set(parsed.showRawResponse ?? false);
1621
+ this.showQueryConfig.set(parsed.showQueryConfig ?? false);
1622
+ this.showEntityStoreValue.set(parsed.showEntityStoreValue ?? false);
1623
+ this.showArguments.set(parsed.showArguments ?? false);
1274
1624
  this.selectedClientIdCtrl.setValue(parsed.selectedClientId ?? 0);
1275
1625
  this.selectedQueryId.set(parsed.selectedQueryPath ?? null);
1276
1626
  this.queryListMode.set(parsed.queryListMode ?? 'live');
@@ -1288,9 +1638,18 @@ class QueryDevtoolsComponent {
1288
1638
  this._cdr.markForCheck();
1289
1639
  });
1290
1640
  }
1641
+ toggleShowQueryConfig() {
1642
+ this.showQueryConfig.set(!this.showQueryConfig());
1643
+ }
1291
1644
  toggleShowRawResponse() {
1292
1645
  this.showRawResponse.set(!this.showRawResponse());
1293
1646
  }
1647
+ toggleShowEntityStoreValue() {
1648
+ this.showEntityStoreValue.set(!this.showEntityStoreValue());
1649
+ }
1650
+ toggleShowArguments() {
1651
+ this.showArguments.set(!this.showArguments());
1652
+ }
1294
1653
  selectSnapLayout(layout) {
1295
1654
  this.snapLayout.set(layout);
1296
1655
  }
@@ -1304,13 +1663,13 @@ class QueryDevtoolsComponent {
1304
1663
  this.queryHistory.set([]);
1305
1664
  }
1306
1665
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.6", ngImport: i0, type: QueryDevtoolsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1307
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.6", type: QueryDevtoolsComponent, isStandalone: true, selector: "et-query-devtools", host: { classAttribute: "et-query-devtools" }, ngImport: i0, template: "<button *ngIf=\"!isOpen()\" (click)=\"toggleOpen()\" class=\"et-query-devtools-open-btn et-qd-chip\">Open Devtools</button>\n\n<div\n *ngIf=\"isOpen()\"\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 <option *ngFor=\"let clientConfig of queryClientConfigs; index as i; trackBy: trackByClient\" [value]=\"i\">\n {{ clientConfig.displayName ?? clientConfig.client.config.baseRoute }}\n </option>\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 <div *ngIf=\"selectedClientConfig() as cfg\" 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 <div *ngIf=\"selectedClientConfig() as cfg\" class=\"et-qd-queries\">\n <p class=\"et-qd-queries__title\">Query browser</p>\n <div class=\"et-qd-queries__actions\">\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': queryListMode() !== 'live' }\"\n (click)=\"selectQueryListMode('live')\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Live ({{ queries()?.length ?? 0 }})\n </button>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': queryListMode() !== 'history' }\"\n (click)=\"selectQueryListMode('history')\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n History ({{ queryHistory().length }}/50)\n </button>\n <ng-container *ngIf=\"queryListMode() === 'history'\">\n <div class=\"et-qd-queries__divider\"></div>\n <button (click)=\"clearQueryHistory()\" class=\"et-qd-chip et-qd-chip-bordered\">Clear history</button>\n </ng-container>\n </div>\n\n <div class=\"et-qd-queries__browser\">\n <ul *ngIf=\"queryListMode() === 'live'\" class=\"et-qd-queries__browser-list\">\n <li *ngFor=\"let query of queries(); trackBy: trackByQuery\">\n <button [class.et-qd-query--active]=\"selectedQuery()?._id === query._id\" (click)=\"selectQuery(query)\">\n <span> {{ query._routeWithParams }}</span>\n </button>\n </li>\n </ul>\n <ul *ngIf=\"queryListMode() === 'history'\" class=\"et-qd-queries__browser-list\">\n <li *ngFor=\"let query of queryHistory(); trackBy: trackByQuery\">\n <button [class.et-qd-query--active]=\"selectedQuery()?._id === query._id\" (click)=\"selectQuery(query)\">\n {{ query._routeWithParams }}\n </button>\n </li>\n </ul>\n <div class=\"et-qd-queries__browser-detail\">\n <ng-container *ngIf=\"selectedQuery() as query\">\n <p class=\"et-qd-queries__browser-detail__title\">{{ query._routeWithParams }}</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 <ng-container *ngIf=\"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 </ng-container>\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>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>Arguments</p>\n <pre>{{ query._arguments | json }}</pre>\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 <pre *ngIf=\"showResponse()\">{{ query.state$ | async | json }}</pre>\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 <pre *ngIf=\"showRawResponse()\">{{ query.rawState | json }}</pre>\n </div>\n </div>\n </ng-container>\n </div>\n </div>\n </div>\n</div>\n", styles: [".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)}.et-query-devtools-open-btn{position:fixed;inset-inline-start:0;inset-block-start:0;z-index:9999;all:unset;font-family:monospace}.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 #3c424a;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 #3c424a;margin-bottom:-12px}.et-qd-queries__browser-list{border-right:1px solid #3c424a;list-style:none;padding:0;margin:0;display:grid;grid-auto-flow:row;grid-auto-rows:50px;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 #3c424a;background-color:#25292e;color:#fff;text-align:left;padding:12px;height:100%;transition:all .3s ease-in-out;cursor:pointer}.et-qd-queries__browser-list li button span{display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2;overflow:hidden}.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-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: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: NgFor, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "pipe", type: JsonPipe, name: "json" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.ShadowDom }); }
1666
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.6", type: QueryDevtoolsComponent, isStandalone: true, selector: "et-query-devtools", host: { classAttribute: "et-query-devtools" }, ngImport: i0, template: "<button *ngIf=\"!isOpen()\" (click)=\"toggleOpen()\" class=\"et-query-devtools-open-btn et-qd-chip\">Open Devtools</button>\n\n<div\n *ngIf=\"isOpen()\"\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 <option *ngFor=\"let clientConfig of queryClientConfigs; index as i; trackBy: trackByClient\" [value]=\"i\">\n {{ clientConfig.displayName ?? clientConfig.client.config.baseRoute }}\n </option>\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 <div *ngIf=\"selectedClientConfig() as cfg\" 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 <div *ngIf=\"selectedClientConfig() as cfg\" class=\"et-qd-queries\">\n <p class=\"et-qd-queries__title\">Query browser</p>\n <div class=\"et-qd-queries__actions\">\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': queryListMode() !== 'live' }\"\n (click)=\"selectQueryListMode('live')\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Live ({{ queries()?.length ?? 0 }})\n </button>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': queryListMode() !== 'history' }\"\n (click)=\"selectQueryListMode('history')\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n History ({{ queryHistory().length }}/50)\n </button>\n <ng-container *ngIf=\"queryListMode() === 'history'\">\n <div class=\"et-qd-queries__divider\"></div>\n <button (click)=\"clearQueryHistory()\" class=\"et-qd-chip et-qd-chip-bordered\">Clear history</button>\n </ng-container>\n </div>\n\n <div class=\"et-qd-queries__browser\">\n <ul *ngIf=\"queryListMode() === 'live'\" class=\"et-qd-queries__browser-list\">\n <li *ngFor=\"let query of queries(); trackBy: trackByQuery\">\n <button [class.et-qd-query--active]=\"selectedQuery()?._id === query._id\" (click)=\"selectQuery(query)\">\n <span> {{ query._queryConfig.method }}</span>\n <span> {{ query | queryShortName }}</span>\n </button>\n </li>\n </ul>\n <ul *ngIf=\"queryListMode() === 'history'\" class=\"et-qd-queries__browser-list\">\n <li *ngFor=\"let query of queryHistory(); trackBy: trackByQuery\">\n <button [class.et-qd-query--active]=\"selectedQuery()?._id === query._id\" (click)=\"selectQuery(query)\">\n <span> {{ query._queryConfig.method }}</span>\n <span> {{ query | queryShortName }}</span>\n </button>\n </li>\n </ul>\n <div class=\"et-qd-queries__browser-detail\">\n <ng-container *ngIf=\"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 <ng-container *ngIf=\"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 </ng-container>\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>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>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 <pre *ngIf=\"showArguments()\">{{ query._arguments | json }}</pre>\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 <pre *ngIf=\"showResponse()\">{{ query.state$ | async | json }}</pre>\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 <pre *ngIf=\"showRawResponse()\">{{ query.rawState | json }}</pre>\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 <pre *ngIf=\"showQueryConfig()\">{{ stringifiedQueryConfig() | json }}</pre>\n </div>\n\n <div *ngIf=\"!!query._queryConfig.entity\" 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 <pre *ngIf=\"showEntityStoreValue()\">{{ selectedQueryEntityStoreValue$ | async | json }}</pre>\n </div>\n </div>\n </ng-container>\n </div>\n </div>\n </div>\n</div>\n", styles: [".et-query-devtools{position:fixed;top:0;z-index:1000000;font-size:14px}.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)}.et-query-devtools-open-btn{position:fixed;inset-inline-start:0;inset-block-start:0;z-index:9999;all:unset;font-family:monospace}.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 #3c424a;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 #3c424a;margin-bottom:-12px}.et-qd-queries__browser-list{border-right:1px solid #3c424a;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 #3c424a;background-color:#25292e;color:#fff;text-align:left;padding:12px;height:100%;transition:all .3s ease-in-out;cursor:pointer;display:grid;gap:2px}.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-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: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: NgFor, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "pipe", type: JsonPipe, name: "json" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.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" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.ShadowDom }); }
1308
1667
  }
1309
1668
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.6", ngImport: i0, type: QueryDevtoolsComponent, decorators: [{
1310
1669
  type: Component,
1311
1670
  args: [{ selector: 'et-query-devtools', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.ShadowDom, host: {
1312
1671
  class: 'et-query-devtools',
1313
- }, imports: [NgIf, NgFor, AsyncPipe, JsonPipe, ReactiveFormsModule, NgClass], hostDirectives: [], template: "<button *ngIf=\"!isOpen()\" (click)=\"toggleOpen()\" class=\"et-query-devtools-open-btn et-qd-chip\">Open Devtools</button>\n\n<div\n *ngIf=\"isOpen()\"\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 <option *ngFor=\"let clientConfig of queryClientConfigs; index as i; trackBy: trackByClient\" [value]=\"i\">\n {{ clientConfig.displayName ?? clientConfig.client.config.baseRoute }}\n </option>\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 <div *ngIf=\"selectedClientConfig() as cfg\" 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 <div *ngIf=\"selectedClientConfig() as cfg\" class=\"et-qd-queries\">\n <p class=\"et-qd-queries__title\">Query browser</p>\n <div class=\"et-qd-queries__actions\">\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': queryListMode() !== 'live' }\"\n (click)=\"selectQueryListMode('live')\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Live ({{ queries()?.length ?? 0 }})\n </button>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': queryListMode() !== 'history' }\"\n (click)=\"selectQueryListMode('history')\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n History ({{ queryHistory().length }}/50)\n </button>\n <ng-container *ngIf=\"queryListMode() === 'history'\">\n <div class=\"et-qd-queries__divider\"></div>\n <button (click)=\"clearQueryHistory()\" class=\"et-qd-chip et-qd-chip-bordered\">Clear history</button>\n </ng-container>\n </div>\n\n <div class=\"et-qd-queries__browser\">\n <ul *ngIf=\"queryListMode() === 'live'\" class=\"et-qd-queries__browser-list\">\n <li *ngFor=\"let query of queries(); trackBy: trackByQuery\">\n <button [class.et-qd-query--active]=\"selectedQuery()?._id === query._id\" (click)=\"selectQuery(query)\">\n <span> {{ query._routeWithParams }}</span>\n </button>\n </li>\n </ul>\n <ul *ngIf=\"queryListMode() === 'history'\" class=\"et-qd-queries__browser-list\">\n <li *ngFor=\"let query of queryHistory(); trackBy: trackByQuery\">\n <button [class.et-qd-query--active]=\"selectedQuery()?._id === query._id\" (click)=\"selectQuery(query)\">\n {{ query._routeWithParams }}\n </button>\n </li>\n </ul>\n <div class=\"et-qd-queries__browser-detail\">\n <ng-container *ngIf=\"selectedQuery() as query\">\n <p class=\"et-qd-queries__browser-detail__title\">{{ query._routeWithParams }}</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 <ng-container *ngIf=\"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 </ng-container>\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>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>Arguments</p>\n <pre>{{ query._arguments | json }}</pre>\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 <pre *ngIf=\"showResponse()\">{{ query.state$ | async | json }}</pre>\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 <pre *ngIf=\"showRawResponse()\">{{ query.rawState | json }}</pre>\n </div>\n </div>\n </ng-container>\n </div>\n </div>\n </div>\n</div>\n", styles: [".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)}.et-query-devtools-open-btn{position:fixed;inset-inline-start:0;inset-block-start:0;z-index:9999;all:unset;font-family:monospace}.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 #3c424a;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 #3c424a;margin-bottom:-12px}.et-qd-queries__browser-list{border-right:1px solid #3c424a;list-style:none;padding:0;margin:0;display:grid;grid-auto-flow:row;grid-auto-rows:50px;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 #3c424a;background-color:#25292e;color:#fff;text-align:left;padding:12px;height:100%;transition:all .3s ease-in-out;cursor:pointer}.et-qd-queries__browser-list li button span{display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2;overflow:hidden}.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-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"] }]
1672
+ }, imports: [NgIf, NgFor, AsyncPipe, JsonPipe, ReactiveFormsModule, NgClass, QueryShortNamePipe], hostDirectives: [], template: "<button *ngIf=\"!isOpen()\" (click)=\"toggleOpen()\" class=\"et-query-devtools-open-btn et-qd-chip\">Open Devtools</button>\n\n<div\n *ngIf=\"isOpen()\"\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 <option *ngFor=\"let clientConfig of queryClientConfigs; index as i; trackBy: trackByClient\" [value]=\"i\">\n {{ clientConfig.displayName ?? clientConfig.client.config.baseRoute }}\n </option>\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 <div *ngIf=\"selectedClientConfig() as cfg\" 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 <div *ngIf=\"selectedClientConfig() as cfg\" class=\"et-qd-queries\">\n <p class=\"et-qd-queries__title\">Query browser</p>\n <div class=\"et-qd-queries__actions\">\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': queryListMode() !== 'live' }\"\n (click)=\"selectQueryListMode('live')\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Live ({{ queries()?.length ?? 0 }})\n </button>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': queryListMode() !== 'history' }\"\n (click)=\"selectQueryListMode('history')\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n History ({{ queryHistory().length }}/50)\n </button>\n <ng-container *ngIf=\"queryListMode() === 'history'\">\n <div class=\"et-qd-queries__divider\"></div>\n <button (click)=\"clearQueryHistory()\" class=\"et-qd-chip et-qd-chip-bordered\">Clear history</button>\n </ng-container>\n </div>\n\n <div class=\"et-qd-queries__browser\">\n <ul *ngIf=\"queryListMode() === 'live'\" class=\"et-qd-queries__browser-list\">\n <li *ngFor=\"let query of queries(); trackBy: trackByQuery\">\n <button [class.et-qd-query--active]=\"selectedQuery()?._id === query._id\" (click)=\"selectQuery(query)\">\n <span> {{ query._queryConfig.method }}</span>\n <span> {{ query | queryShortName }}</span>\n </button>\n </li>\n </ul>\n <ul *ngIf=\"queryListMode() === 'history'\" class=\"et-qd-queries__browser-list\">\n <li *ngFor=\"let query of queryHistory(); trackBy: trackByQuery\">\n <button [class.et-qd-query--active]=\"selectedQuery()?._id === query._id\" (click)=\"selectQuery(query)\">\n <span> {{ query._queryConfig.method }}</span>\n <span> {{ query | queryShortName }}</span>\n </button>\n </li>\n </ul>\n <div class=\"et-qd-queries__browser-detail\">\n <ng-container *ngIf=\"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 <ng-container *ngIf=\"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 </ng-container>\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>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>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 <pre *ngIf=\"showArguments()\">{{ query._arguments | json }}</pre>\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 <pre *ngIf=\"showResponse()\">{{ query.state$ | async | json }}</pre>\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 <pre *ngIf=\"showRawResponse()\">{{ query.rawState | json }}</pre>\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 <pre *ngIf=\"showQueryConfig()\">{{ stringifiedQueryConfig() | json }}</pre>\n </div>\n\n <div *ngIf=\"!!query._queryConfig.entity\" 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 <pre *ngIf=\"showEntityStoreValue()\">{{ selectedQueryEntityStoreValue$ | async | json }}</pre>\n </div>\n </div>\n </ng-container>\n </div>\n </div>\n </div>\n</div>\n", styles: [".et-query-devtools{position:fixed;top:0;z-index:1000000;font-size:14px}.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)}.et-query-devtools-open-btn{position:fixed;inset-inline-start:0;inset-block-start:0;z-index:9999;all:unset;font-family:monospace}.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 #3c424a;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 #3c424a;margin-bottom:-12px}.et-qd-queries__browser-list{border-right:1px solid #3c424a;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 #3c424a;background-color:#25292e;color:#fff;text-align:left;padding:12px;height:100%;transition:all .3s ease-in-out;cursor:pointer;display:grid;gap:2px}.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-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"] }]
1314
1673
  }], ctorParameters: function () { return []; } });
1315
1674
 
1316
1675
  class QueryDirective {
@@ -1820,7 +2179,13 @@ function flatten(arr) {
1820
2179
  class EntityStore {
1821
2180
  constructor(_config) {
1822
2181
  this._config = _config;
2182
+ /**
2183
+ * @internal
2184
+ */
1823
2185
  this._dictionary = new Map();
2186
+ /**
2187
+ * @internal
2188
+ */
1824
2189
  this._change$ = new Subject();
1825
2190
  }
1826
2191
  select(keyOrKeys) {
@@ -1951,261 +2316,6 @@ const removeFrom = (store, { where, id }) => {
1951
2316
  .subscribe();
1952
2317
  };
1953
2318
 
1954
- class QueryCreator {
1955
- constructor(_queryConfig, _client, _store) {
1956
- this._queryConfig = _queryConfig;
1957
- this._client = _client;
1958
- this._store = _store;
1959
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
1960
- // @ts-ignore
1961
- this.prepare = (args) => {
1962
- const route = buildRoute({
1963
- base: this._client.config.baseRoute,
1964
- route: this._queryConfig.route,
1965
- pathParams: args?.pathParams,
1966
- queryParams: computeQueryQueryParams({ config: this._queryConfig, client: this._client, args }),
1967
- queryParamConfig: this._client.config.request?.queryParams,
1968
- });
1969
- const cacheKey = isGqlQueryConfig(this._queryConfig) ? buildGqlCacheKey(this._queryConfig, args) : route;
1970
- if (shouldCacheQuery(this._queryConfig.method)) {
1971
- const existingQuery = this._store.get(cacheKey);
1972
- if (existingQuery) {
1973
- return existingQuery;
1974
- }
1975
- }
1976
- const query = new Query(this._client, this._queryConfig, route, args ?? {});
1977
- if (shouldCacheQuery(this._queryConfig.method)) {
1978
- this._store.add(cacheKey, query);
1979
- }
1980
- return query;
1981
- };
1982
- this.behaviorSubject = (initialValue) => new BehaviorSubject(initialValue ?? null);
1983
- }
1984
- }
1985
-
1986
- class QueryStore {
1987
- constructor(_config) {
1988
- this._config = _config;
1989
- /**
1990
- * @internal
1991
- */
1992
- this._store = new Map();
1993
- this._garbageCollector = null;
1994
- this._isInLowResourceMode = false;
1995
- this._lastBlurTimestamp = Date.now();
1996
- this._storeChange$ = new Subject();
1997
- this.storeChange$ = this._storeChange$.asObservable();
1998
- this._initSmartQueryHandling();
1999
- }
2000
- add(id, query) {
2001
- this._store.set(id, query);
2002
- this._initGarbageCollector();
2003
- this._logState(id, query, 'SET');
2004
- this._storeChange$.next(id);
2005
- }
2006
- get(id) {
2007
- return this._store.get(id) ?? null;
2008
- }
2009
- remove(id) {
2010
- this._store.delete(id);
2011
- this._logState(id, null, 'REMOVE');
2012
- this._storeChange$.next(id);
2013
- }
2014
- forEach(callback) {
2015
- for (const [key, query] of this._store) {
2016
- callback(query, key);
2017
- }
2018
- }
2019
- refreshQueriesInUse(config) {
2020
- const { ignoreCacheValidity, purgeUnused } = config ?? {};
2021
- for (const [key, query] of this._store) {
2022
- if (query.isInUse &&
2023
- (query.isExpired || ignoreCacheValidity) &&
2024
- query.autoRefreshOnConfig.queryClientDefaultHeadersChange) {
2025
- query.execute({ skipCache: true, _triggeredVia: 'auto' });
2026
- }
2027
- else if (purgeUnused && !query.isInUse) {
2028
- this.remove(key);
2029
- }
2030
- }
2031
- }
2032
- _initSmartQueryHandling() {
2033
- const windowBlur$ = fromEvent(window, 'blur');
2034
- const windowFocus$ = fromEvent(window, 'focus');
2035
- windowBlur$.subscribe(() => {
2036
- timer(5000)
2037
- .pipe(takeUntil(windowFocus$), take(1))
2038
- .subscribe(() => {
2039
- this._lastBlurTimestamp = Date.now();
2040
- this._isInLowResourceMode = true;
2041
- this._stopGarbageCollector();
2042
- if (this._config?.enableSmartPolling) {
2043
- this.forEach((query) => {
2044
- if (!query.isPolling || !query._enableSmartPolling) {
2045
- return;
2046
- }
2047
- query.pausePolling();
2048
- });
2049
- }
2050
- });
2051
- });
2052
- windowFocus$.subscribe(() => {
2053
- if (!this._isInLowResourceMode) {
2054
- return;
2055
- }
2056
- this._isInLowResourceMode = false;
2057
- if (this._config?.enableSmartPolling || this._config?.autoRefreshQueriesOnWindowFocus) {
2058
- this.forEach((query) => {
2059
- if (this._config?.enableSmartPolling && query._isPollingPaused) {
2060
- query.resumePolling();
2061
- }
2062
- if (Date.now() - this._lastBlurTimestamp > 15000) {
2063
- if (this._config?.autoRefreshQueriesOnWindowFocus &&
2064
- query.isExpired &&
2065
- query.isInUse &&
2066
- query.autoRefreshOnConfig.windowFocus) {
2067
- query.execute({ skipCache: true, _triggeredVia: 'auto' });
2068
- }
2069
- }
2070
- });
2071
- }
2072
- this._initGarbageCollector();
2073
- });
2074
- }
2075
- _logState(key, item, operation) {
2076
- if (!this._config?.enableChangeLogging)
2077
- return;
2078
- const stateAsJson = {};
2079
- this._store.forEach((value, key) => {
2080
- stateAsJson[key] = value;
2081
- });
2082
- console.log(`%c[${operation}] ${key}`, 'font-weight: bold');
2083
- console.log({ operation, key, item });
2084
- console.log(stateAsJson);
2085
- }
2086
- _initGarbageCollector() {
2087
- if (this._garbageCollector !== null) {
2088
- return;
2089
- }
2090
- this._logGarbageCollector('Start');
2091
- this._garbageCollector = window.setInterval(() => {
2092
- this._runGarbageCollector();
2093
- }, 15000);
2094
- }
2095
- _stopGarbageCollector() {
2096
- if (this._garbageCollector !== null) {
2097
- window.clearInterval(this._garbageCollector);
2098
- this._garbageCollector = null;
2099
- this._logGarbageCollector('Stop');
2100
- }
2101
- }
2102
- _runGarbageCollector() {
2103
- this._logGarbageCollector('Collecting...');
2104
- this._store.forEach((item, key) => {
2105
- if (item.isExpired && !item.isInUse) {
2106
- this.remove(key);
2107
- }
2108
- });
2109
- this._logGarbageCollector('Collection done');
2110
- if (!this._store.size) {
2111
- this._stopGarbageCollector();
2112
- }
2113
- }
2114
- _logGarbageCollector(action) {
2115
- if (!this._config?.enableGarbageCollectorLogging)
2116
- return;
2117
- console.log(`%cGC: ${action}`, 'color: yellow; font-weight: bold');
2118
- }
2119
- }
2120
-
2121
- class QueryClient {
2122
- get config() {
2123
- return this._clientConfig;
2124
- }
2125
- get authProvider() {
2126
- return this._authProvider$.getValue() ?? this._clientConfig.parent?._authProvider$.getValue() ?? null;
2127
- }
2128
- get authProvider$() {
2129
- return this._authProvider$.asObservable() ?? this._clientConfig.parent?._authProvider$.asObservable() ?? null;
2130
- }
2131
- constructor(_clientConfig) {
2132
- this._clientConfig = _clientConfig;
2133
- this._authProvider$ = new BehaviorSubject(null);
2134
- this.get = (queryConfig) => this.fetch({
2135
- ...queryConfig,
2136
- method: 'GET',
2137
- });
2138
- this.post = (queryConfig) => this.fetch({
2139
- ...queryConfig,
2140
- method: 'POST',
2141
- });
2142
- this.put = (queryConfig) => this.fetch({
2143
- ...queryConfig,
2144
- method: 'PUT',
2145
- });
2146
- this.patch = (queryConfig) => this.fetch({
2147
- ...queryConfig,
2148
- method: 'PATCH',
2149
- });
2150
- this.delete = (queryConfig) => this.fetch({
2151
- ...queryConfig,
2152
- method: 'DELETE',
2153
- });
2154
- this.gqlQuery = (queryConfig) => this.fetch({
2155
- ...queryConfig,
2156
- method: 'GQL_QUERY',
2157
- });
2158
- this.gqlMutate = (queryConfig) => this.fetch({
2159
- ...queryConfig,
2160
- method: 'GQL_MUTATE',
2161
- });
2162
- this.fetch = (queryConfig) => new QueryCreator(queryConfig, this, this._store);
2163
- this.setAuthProvider = (authProvider) => {
2164
- if (this.authProvider) {
2165
- throw new Error('The auth provider is already set. Please call clearAuthProvider() first.');
2166
- }
2167
- this._authProvider$.next(authProvider);
2168
- };
2169
- this.setDefaultHeaders = (config) => {
2170
- if (!this._clientConfig.request) {
2171
- this._clientConfig.request = {
2172
- headers: config.headers ?? undefined,
2173
- };
2174
- }
2175
- else {
2176
- this._clientConfig.request.headers = config.headers ?? undefined;
2177
- }
2178
- if (config.refreshQueriesInUse) {
2179
- this._store.refreshQueriesInUse({ purgeUnused: true, ignoreCacheValidity: true });
2180
- }
2181
- };
2182
- this.clearAuthProvider = () => {
2183
- this.authProvider?.cleanUp();
2184
- this._authProvider$.next(null);
2185
- };
2186
- this._store = new QueryStore({
2187
- enableChangeLogging: _clientConfig.logging?.queryStateChanges,
2188
- enableGarbageCollectorLogging: _clientConfig.logging?.queryStateGarbageCollector,
2189
- autoRefreshQueriesOnWindowFocus: _clientConfig.request?.autoRefreshQueriesOnWindowFocus ?? true,
2190
- enableSmartPolling: _clientConfig.request?.enableSmartPolling ?? true,
2191
- });
2192
- }
2193
- }
2194
-
2195
- const shouldCacheQuery = (method) => {
2196
- return method === 'GET' || method === 'OPTIONS' || method === 'HEAD' || method === 'GQL_QUERY';
2197
- };
2198
- const buildGqlCacheKey = (config, args) => {
2199
- const { query } = config;
2200
- const variables = args?.variables || {};
2201
- const queryWithoutNewLinesAndWhitespace = query.replace(/\s/g, '');
2202
- const queryFirst50Chars = queryWithoutNewLinesAndWhitespace.slice(0, 50);
2203
- const queryMiddle25Chars = queryWithoutNewLinesAndWhitespace.slice(queryWithoutNewLinesAndWhitespace.length / 2 - 25, queryWithoutNewLinesAndWhitespace.length / 2 + 25);
2204
- const queryLast50Chars = queryWithoutNewLinesAndWhitespace.slice(-50);
2205
- const vars = JSON.stringify(variables);
2206
- return `${queryFirst50Chars}...${queryMiddle25Chars}...${queryLast50Chars}...${vars}`;
2207
- };
2208
-
2209
2319
  const ET_ARR_PREFIX = 'ET_ARR__';
2210
2320
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
2211
2321
  class QueryFormGroup extends FormGroup {
@@ -2566,5 +2676,5 @@ const def = () => null;
2566
2676
  * Generated bundle index. Do not edit.
2567
2677
  */
2568
2678
 
2569
- export { BasicAuthProvider, BearerAuthProvider, CustomHeaderAuthProvider, EntityStore, INFINITY_QUERY_TOKEN, InfinityQuery, InfinityQueryDirective, InfinityQueryTriggerDirective, QUERY_CLIENT_DEVTOOLS_TOKEN, Query, QueryClient, QueryCreator, QueryDevtoolsComponent, QueryDirective, QueryError, QueryField, QueryForm, QueryFormGroup, QueryStore, buildErrorMessage, buildGqlCacheKey, buildQueryString, buildRoute, buildTimestampFromSeconds, castQueryCreatorTypes, computeQueryAuthHeader, computeQueryBody, computeQueryHeaders, computeQueryMethod, computeQueryQueryParams, createInfinityQueryConfig, createQueryCollection, decryptBearer, deepFreeze, def, detectContentTypeHeader, 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, isSymfonyPagerfantaOutOfRangeError, mapToPaginated, mergeHeaders, paginatedEntityValueUpdater, parseAllXhrResponseHeaders, pathParamsMissingInRouteFunctionError, provideQueryClientForDevtools, queryStateAlreadyHasKeyError, queryStateCannotTransformError, queryStateDoesNotContainKeyError, removeFrom, request, resetPageOnError, serializeBody, shouldCacheQuery, shouldRetryRequest, skipPaginationPageParamCalculator, switchQueryCollectionState, switchQueryState, takeUntilResponse, transformGql, transformMethod, transformToBoolean, transformToBooleanArray, transformToDate, transformToDateArray, transformToNumber, transformToNumberArray, transformToSort, transformToSortQueryParam, transformToString, transformToStringArray };
2679
+ export { BasicAuthProvider, BearerAuthProvider, CustomHeaderAuthProvider, EntityStore, INFINITY_QUERY_TOKEN, InfinityQuery, InfinityQueryDirective, InfinityQueryTriggerDirective, QUERY_CLIENT_DEVTOOLS_TOKEN, Query, QueryClient, QueryCreator, QueryDevtoolsComponent, QueryDirective, QueryError, QueryField, QueryForm, QueryFormGroup, QueryShortNamePipe, QueryStore, buildErrorMessage, buildGqlCacheKey, buildQueryString, buildRoute, buildTimestampFromSeconds, castQueryCreatorTypes, computeQueryAuthHeader, computeQueryBody, computeQueryHeaders, computeQueryMethod, computeQueryQueryParams, createInfinityQueryConfig, createQueryCollection, decryptBearer, deepFreeze, def, detectContentTypeHeader, 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, isSymfonyPagerfantaOutOfRangeError, mapToPaginated, mergeHeaders, paginatedEntityValueUpdater, parseAllXhrResponseHeaders, pathParamsMissingInRouteFunctionError, provideQueryClientForDevtools, queryStateAlreadyHasKeyError, queryStateCannotTransformError, queryStateDoesNotContainKeyError, removeFrom, request, resetPageOnError, serializeBody, shouldCacheQuery, shouldRetryRequest, skipPaginationPageParamCalculator, switchQueryCollectionState, switchQueryState, takeUntilResponse, transformGql, transformMethod, transformToBoolean, transformToBooleanArray, transformToDate, transformToDateArray, transformToNumber, transformToNumberArray, transformToSort, transformToSortQueryParam, transformToString, transformToStringArray };
2570
2680
  //# sourceMappingURL=ethlete-query.mjs.map