@ethlete/query 4.7.5 → 4.7.7

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,
815
1080
  /**
816
1081
  * @internal
817
1082
  */
818
- _routeWithParams, _args) {
1083
+ _routeWithParams,
1084
+ /**
1085
+ * @internal
1086
+ */
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,50 @@ 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(() => {
1532
+ if (!s._dictionary)
1533
+ return null;
1534
+ return Array.from(s._dictionary).reduce((obj, [key, value]) => {
1535
+ obj[key] = value;
1536
+ return obj;
1537
+ }, {});
1538
+ })) ?? of(null)));
1229
1539
  this.queryHistory = signal([]);
1540
+ this.stringifiedQueryConfig = computed(() => {
1541
+ const query = this.selectedQuery();
1542
+ if (!query)
1543
+ return null;
1544
+ const cfg = query._queryConfig;
1545
+ const route = typeof cfg.route === 'string' ? cfg.route : cfg.route ? cfg.route({}).replace(/undefined/g, ':param') : null;
1546
+ const sharedCfg = {
1547
+ method: cfg.method,
1548
+ secure: cfg.secure,
1549
+ route,
1550
+ reportProgress: cfg.reportProgress,
1551
+ responseType: cfg.responseType,
1552
+ withCredentials: cfg.withCredentials,
1553
+ autoRefreshOn: cfg.autoRefreshOn,
1554
+ enableSmartPolling: cfg.enableSmartPolling,
1555
+ hasEntityStore: !!cfg.entity,
1556
+ };
1557
+ if (isGqlQueryConfig(cfg)) {
1558
+ return {
1559
+ ...sharedCfg,
1560
+ query: cfg.query,
1561
+ transferVia: cfg.transferVia,
1562
+ };
1563
+ }
1564
+ return {
1565
+ ...sharedCfg,
1566
+ };
1567
+ });
1230
1568
  this.trackByClient = (_, { client }) => client.config.baseRoute;
1231
1569
  this.trackByQuery = (_, { _id }) => _id;
1232
1570
  this.selectedClientIdCtrl.valueChanges
@@ -1235,6 +1573,19 @@ class QueryDevtoolsComponent {
1235
1573
  this.queryStore$
1236
1574
  .pipe(switchMap((s) => s.storeChange$.pipe(startWith(''), map(() => s._store), tap((s) => this._queries$.next(Array.from(s.values()))), takeUntil(this._destroy$))))
1237
1575
  .subscribe();
1576
+ this.queryStore$
1577
+ .pipe(switchMap((s) => s.queryCreated$.pipe(tap((query) => {
1578
+ const currentHistory = this.queryHistory();
1579
+ if (!currentHistory)
1580
+ return;
1581
+ const currentHistoryClone = [...currentHistory];
1582
+ if (!currentHistory.some((q) => q._id === query._id)) {
1583
+ currentHistoryClone.unshift(query);
1584
+ }
1585
+ currentHistoryClone.splice(50);
1586
+ this.queryHistory.set(currentHistoryClone);
1587
+ }), takeUntil(this._destroy$))))
1588
+ .subscribe();
1238
1589
  this._queries$
1239
1590
  .pipe(tap((queries) => {
1240
1591
  const currentHistory = this.queryHistory();
@@ -1242,7 +1593,7 @@ class QueryDevtoolsComponent {
1242
1593
  return;
1243
1594
  const currentHistoryClone = [...currentHistory];
1244
1595
  for (const query of queries) {
1245
- if (!currentHistoryClone.includes(query)) {
1596
+ if (!currentHistoryClone.some((q) => q._id === query._id)) {
1246
1597
  currentHistoryClone.unshift(query);
1247
1598
  }
1248
1599
  }
@@ -1257,6 +1608,9 @@ class QueryDevtoolsComponent {
1257
1608
  snapLayout: this.snapLayout(),
1258
1609
  showResponse: this.showResponse(),
1259
1610
  showRawResponse: this.showRawResponse(),
1611
+ showQueryConfig: this.showQueryConfig(),
1612
+ showEntityStoreValue: this.showEntityStoreValue(),
1613
+ showArguments: this.showArguments(),
1260
1614
  selectedClientId: this.selectedClientId(),
1261
1615
  selectedQueryPath: this.selectedQueryId(),
1262
1616
  queryListMode: this.queryListMode(),
@@ -1271,6 +1625,9 @@ class QueryDevtoolsComponent {
1271
1625
  this.snapLayout.set(parsed.snapLayout ?? 'full');
1272
1626
  this.showResponse.set(parsed.showResponse ?? false);
1273
1627
  this.showRawResponse.set(parsed.showRawResponse ?? false);
1628
+ this.showQueryConfig.set(parsed.showQueryConfig ?? false);
1629
+ this.showEntityStoreValue.set(parsed.showEntityStoreValue ?? false);
1630
+ this.showArguments.set(parsed.showArguments ?? false);
1274
1631
  this.selectedClientIdCtrl.setValue(parsed.selectedClientId ?? 0);
1275
1632
  this.selectedQueryId.set(parsed.selectedQueryPath ?? null);
1276
1633
  this.queryListMode.set(parsed.queryListMode ?? 'live');
@@ -1288,9 +1645,18 @@ class QueryDevtoolsComponent {
1288
1645
  this._cdr.markForCheck();
1289
1646
  });
1290
1647
  }
1648
+ toggleShowQueryConfig() {
1649
+ this.showQueryConfig.set(!this.showQueryConfig());
1650
+ }
1291
1651
  toggleShowRawResponse() {
1292
1652
  this.showRawResponse.set(!this.showRawResponse());
1293
1653
  }
1654
+ toggleShowEntityStoreValue() {
1655
+ this.showEntityStoreValue.set(!this.showEntityStoreValue());
1656
+ }
1657
+ toggleShowArguments() {
1658
+ this.showArguments.set(!this.showArguments());
1659
+ }
1294
1660
  selectSnapLayout(layout) {
1295
1661
  this.snapLayout.set(layout);
1296
1662
  }
@@ -1304,13 +1670,13 @@ class QueryDevtoolsComponent {
1304
1670
  this.queryHistory.set([]);
1305
1671
  }
1306
1672
  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 }); }
1673
+ 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
1674
  }
1309
1675
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.6", ngImport: i0, type: QueryDevtoolsComponent, decorators: [{
1310
1676
  type: Component,
1311
1677
  args: [{ selector: 'et-query-devtools', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.ShadowDom, host: {
1312
1678
  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"] }]
1679
+ }, 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
1680
  }], ctorParameters: function () { return []; } });
1315
1681
 
1316
1682
  class QueryDirective {
@@ -1820,7 +2186,13 @@ function flatten(arr) {
1820
2186
  class EntityStore {
1821
2187
  constructor(_config) {
1822
2188
  this._config = _config;
2189
+ /**
2190
+ * @internal
2191
+ */
1823
2192
  this._dictionary = new Map();
2193
+ /**
2194
+ * @internal
2195
+ */
1824
2196
  this._change$ = new Subject();
1825
2197
  }
1826
2198
  select(keyOrKeys) {
@@ -1951,261 +2323,6 @@ const removeFrom = (store, { where, id }) => {
1951
2323
  .subscribe();
1952
2324
  };
1953
2325
 
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
2326
  const ET_ARR_PREFIX = 'ET_ARR__';
2210
2327
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
2211
2328
  class QueryFormGroup extends FormGroup {
@@ -2566,5 +2683,5 @@ const def = () => null;
2566
2683
  * Generated bundle index. Do not edit.
2567
2684
  */
2568
2685
 
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 };
2686
+ 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
2687
  //# sourceMappingURL=ethlete-query.mjs.map