@ethlete/query 5.8.1 → 5.9.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,11 +1,11 @@
1
- import * as i1$1 from '@ethlete/core';
2
- import { createDestroy, getCookie, setCookie, deleteCookie, nextFrame, DelayableDirective, RouterStateService, clone, equal, ET_PROPERTY_REMOVED } from '@ethlete/core';
3
- import { Observable, takeUntil, startWith, pairwise, tap, switchMap, of, BehaviorSubject, Subject, fromEvent, timer, take, filter, takeWhile, map, shareReplay, ReplaySubject, interval, skip, combineLatest, withLatestFrom, debounceTime, merge } from 'rxjs';
1
+ import * as i1 from '@ethlete/core';
2
+ import { createDestroy, getCookie, setCookie, deleteCookie, DelayableDirective, nextFrame, RouterStateService, clone, equal, ET_PROPERTY_REMOVED } from '@ethlete/core';
3
+ import { Observable, takeUntil, startWith, pairwise, tap, switchMap, of, BehaviorSubject, Subject, fromEvent, timer, take, filter, takeWhile, map, shareReplay, ReplaySubject, combineLatest, interval, skip, withLatestFrom, debounceTime, merge } from 'rxjs';
4
4
  import * as i0 from '@angular/core';
5
- import { assertInInjectionContext, inject, Injector, computed, signal, isDevMode, untracked, Pipe, InjectionToken, ChangeDetectorRef, effect, Component, ChangeDetectionStrategy, ViewEncapsulation, TemplateRef, ViewContainerRef, ErrorHandler, Directive, Input, ElementRef, NgZone } from '@angular/core';
5
+ import { assertInInjectionContext, inject, Injector, computed, signal, isDevMode, untracked, TemplateRef, ViewContainerRef, ErrorHandler, ChangeDetectorRef, Directive, Input, InjectionToken, ElementRef, Pipe, effect, Component, ChangeDetectionStrategy, ViewEncapsulation, NgZone } from '@angular/core';
6
6
  import { toSignal, toObservable, takeUntilDestroyed } from '@angular/core/rxjs-interop';
7
7
  import { AsyncPipe, JsonPipe, NgClass } from '@angular/common';
8
- import * as i1 from '@angular/forms';
8
+ import * as i1$1 from '@angular/forms';
9
9
  import { FormControl, ReactiveFormsModule, FormGroup } from '@angular/forms';
10
10
  import { Router, ActivatedRoute } from '@angular/router';
11
11
 
@@ -1369,25 +1369,49 @@ class Query {
1369
1369
  }
1370
1370
  }
1371
1371
  this._updateState({ type: "LOADING" /* QueryStateType.Loading */, meta });
1372
- const method = computeQueryMethod({ config: queryConfig, client: this._client });
1373
- const body = computeQueryBody({ config: queryConfig, client: this._client, args: this._arguments, method });
1374
- const headers = computeQueryHeaders({ client: this._client, config: queryConfig, args: this._arguments });
1375
1372
  if (this._isInMockMode) {
1376
- this._mockRequest(headers, meta, options);
1373
+ this._mockRequest({}, meta, options);
1377
1374
  }
1378
1375
  else {
1379
- request({
1380
- urlWithParams: this._routeWithParams,
1381
- method,
1382
- body,
1383
- headers,
1384
- reportProgress: queryConfig.reportProgress,
1385
- responseType: queryConfig.responseType,
1386
- withCredentials: queryConfig.withCredentials,
1387
- cacheAdapter: this._client.config.request?.cacheAdapter,
1388
- retryFn: this._client.config.request?.retryFn,
1389
- })
1390
- .pipe(tap((state) => this._updateEntityState(state, meta, options)), takeUntil(this._onAbort$))
1376
+ let goSignal = of(true);
1377
+ if (authProvider &&
1378
+ isBearerAuthProvider(authProvider) &&
1379
+ queryConfig.secure &&
1380
+ !isQueryStateSuccess(authProvider.currentRefreshQuery?.rawState)) {
1381
+ // On page load the query might be executed before the auth provider has been initialized.
1382
+ // In this case we need to wait for the auth provider to be ready before we can execute the query.
1383
+ goSignal = combineLatest([
1384
+ // The tokens might get set without a refresh query being created (e.g.) directly after login.
1385
+ authProvider.currentRefreshQuery$.pipe(switchQueryState(), takeUntilResponse()),
1386
+ authProvider.tokens$.pipe(take(1)),
1387
+ ]).pipe(takeUntil(this._onAbort$), filter(([state, tokens]) => {
1388
+ if (state) {
1389
+ return !isQueryStateLoading(state);
1390
+ }
1391
+ return !!tokens;
1392
+ }), tap(([state]) => {
1393
+ if (isQueryStateFailure(state)) {
1394
+ this._updateEntityState({ type: 'failure', error: state.error, headers: {} }, meta, options);
1395
+ }
1396
+ }), map(() => true), take(1));
1397
+ }
1398
+ goSignal
1399
+ .pipe(switchMap(() => {
1400
+ const method = computeQueryMethod({ config: queryConfig, client: this._client });
1401
+ const body = computeQueryBody({ config: queryConfig, client: this._client, args: this._arguments, method });
1402
+ const headers = computeQueryHeaders({ client: this._client, config: queryConfig, args: this._arguments });
1403
+ return request({
1404
+ urlWithParams: this._routeWithParams,
1405
+ method,
1406
+ body,
1407
+ headers,
1408
+ reportProgress: queryConfig.reportProgress,
1409
+ responseType: queryConfig.responseType,
1410
+ withCredentials: queryConfig.withCredentials,
1411
+ cacheAdapter: this._client.config.request?.cacheAdapter,
1412
+ retryFn: this._client.config.request?.retryFn,
1413
+ }).pipe(tap((state) => this._updateEntityState(state, meta, options)), takeUntil(this._onAbort$));
1414
+ }))
1391
1415
  .subscribe();
1392
1416
  }
1393
1417
  return this;
@@ -1815,253 +1839,6 @@ const isClassValidatorError = (error) => {
1815
1839
  return typeof error === 'object' && error !== null && 'statusCode' in error && 'message' in error && 'error' in error;
1816
1840
  };
1817
1841
 
1818
- class QueryShortNamePipe {
1819
- transform(value) {
1820
- const route = value._routeWithParams;
1821
- if (typeof route === 'string') {
1822
- // 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
1823
- // we want to extract the last 3 parts of the url, so we get: repos/EladBezalel/etimo-achievements
1824
- const parts = route.split('/');
1825
- if (parts.length > 3) {
1826
- return `.../${parts.slice(parts.length - 3).join('/')}`;
1827
- }
1828
- return route;
1829
- }
1830
- console.log(route);
1831
- return route;
1832
- }
1833
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.0", ngImport: i0, type: QueryShortNamePipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
1834
- static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "17.3.0", ngImport: i0, type: QueryShortNamePipe, isStandalone: true, name: "queryShortName" }); }
1835
- }
1836
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.0", ngImport: i0, type: QueryShortNamePipe, decorators: [{
1837
- type: Pipe,
1838
- args: [{ name: 'queryShortName', standalone: true }]
1839
- }] });
1840
-
1841
- const QUERY_CLIENT_DEVTOOLS_TOKEN = new InjectionToken('QUERY_CLIENT_DEVTOOLS_TOKEN');
1842
- const provideQueryClientForDevtools = (queryClient) => {
1843
- if (!isDevMode()) {
1844
- console.warn('You are using the Query Devtools in production mode. This increases the size of your bundle and should only be used for development purposes.');
1845
- }
1846
- return {
1847
- provide: QUERY_CLIENT_DEVTOOLS_TOKEN,
1848
- useValue: queryClient,
1849
- multi: true,
1850
- };
1851
- };
1852
-
1853
- class QueryDevtoolsComponent {
1854
- constructor() {
1855
- this._cdr = inject(ChangeDetectorRef);
1856
- this._destroy$ = createDestroy();
1857
- this.queryClientConfigs = inject(QUERY_CLIENT_DEVTOOLS_TOKEN);
1858
- this.isOpen = signal(false);
1859
- this.isTranslucent = signal(false);
1860
- this.snapLayout = signal('full');
1861
- this.queryListMode = signal('live');
1862
- this.showResponse = signal(false);
1863
- this.showRawResponse = signal(false);
1864
- this.showQueryConfig = signal(false);
1865
- this.showEntityStoreValue = signal(false);
1866
- this.showArguments = signal(false);
1867
- this.selectedClientIdCtrl = new FormControl(0);
1868
- this.selectedClientId = toSignal(this.selectedClientIdCtrl.valueChanges.pipe(startWith(this.selectedClientIdCtrl.value)));
1869
- this.selectedQueryId = signal(null);
1870
- this.selectedClientConfig = computed(() => {
1871
- if (this.queryClientConfigs.length === 1) {
1872
- return this.queryClientConfigs[0];
1873
- }
1874
- const index = this.selectedClientId() ?? 0;
1875
- const cfg = this.queryClientConfigs[index];
1876
- if (!cfg) {
1877
- return this.queryClientConfigs[0];
1878
- }
1879
- return cfg;
1880
- });
1881
- this.queryStore = computed(() => {
1882
- const config = this.selectedClientConfig();
1883
- return config.client._store;
1884
- });
1885
- this.queryStore$ = toObservable(this.queryStore);
1886
- this._queries$ = new BehaviorSubject([]);
1887
- this.queries = toSignal(this._queries$);
1888
- this.selectedQuery = computed(() => {
1889
- const id = this.selectedQueryId();
1890
- const mode = this.queryListMode();
1891
- if (id === null || !mode) {
1892
- return null;
1893
- }
1894
- if (mode === 'live') {
1895
- return this.queries()?.find((q) => q._id === id) ?? null;
1896
- }
1897
- return this.queryHistory$.getValue()?.find((q) => q._id === id) ?? null;
1898
- });
1899
- this.selectedQuery$ = toObservable(this.selectedQuery);
1900
- this.selectedQueryEntityStore = computed(() => {
1901
- const query = this.selectedQuery();
1902
- if (!query)
1903
- return null;
1904
- return query.store;
1905
- });
1906
- this.selectedQueryEntityStore$ = toObservable(this.selectedQueryEntityStore);
1907
- this.selectedQueryEntityStoreValue$ = this.selectedQueryEntityStore$.pipe(switchMap((s) => s?._change$.pipe(startWith(''), map(() => {
1908
- if (!s._dictionary)
1909
- return null;
1910
- return Array.from(s._dictionary).reduce((obj, [key, value]) => {
1911
- obj[key] = value;
1912
- return obj;
1913
- }, {});
1914
- })) ?? of(null)));
1915
- this.queryHistory$ = new BehaviorSubject([]);
1916
- this.stringifiedQueryConfig = computed(() => {
1917
- const query = this.selectedQuery();
1918
- if (!query)
1919
- return null;
1920
- const cfg = query._queryConfig;
1921
- const route = typeof cfg.route === 'string' ? cfg.route : cfg.route ? cfg.route({}).replace(/undefined/g, ':param') : null;
1922
- const sharedCfg = {
1923
- method: cfg.method,
1924
- secure: cfg.secure,
1925
- route,
1926
- reportProgress: cfg.reportProgress,
1927
- responseType: cfg.responseType,
1928
- withCredentials: cfg.withCredentials,
1929
- autoRefreshOn: cfg.autoRefreshOn,
1930
- enableSmartPolling: cfg.enableSmartPolling,
1931
- hasEntityStore: !!cfg.entity,
1932
- };
1933
- if (isGqlQueryConfig(cfg)) {
1934
- return {
1935
- ...sharedCfg,
1936
- query: cfg.query,
1937
- transferVia: cfg.transferVia,
1938
- };
1939
- }
1940
- return {
1941
- ...sharedCfg,
1942
- };
1943
- });
1944
- this.trackByClient = (_, { client }) => client.config.baseRoute;
1945
- this.trackByQuery = (_, { _id }) => _id;
1946
- this.selectedClientIdCtrl.valueChanges
1947
- .pipe(tap(() => this.clearQueryHistory()), takeUntil(this._destroy$))
1948
- .subscribe();
1949
- this.selectedQuery$
1950
- .pipe(switchMap((q) => q?._dependentsChanged$ ?? of(null)), tap(() => this._cdr.markForCheck()), takeUntilDestroyed())
1951
- .subscribe();
1952
- this.queryStore$
1953
- .pipe(switchMap((s) => s.storeChange$.pipe(startWith(''), map(() => s._store), tap((s) => {
1954
- untracked(() => {
1955
- this._queries$.next(Array.from(s.values()));
1956
- });
1957
- }), takeUntil(this._destroy$))))
1958
- .subscribe();
1959
- this.queryStore$
1960
- .pipe(switchMap((s) => s.queryCreated$.pipe(tap((query) => {
1961
- const currentHistory = this.queryHistory$.getValue();
1962
- if (!currentHistory)
1963
- return;
1964
- const currentHistoryClone = [...currentHistory];
1965
- if (!currentHistory.some((q) => q._id === query._id)) {
1966
- currentHistoryClone.unshift(query);
1967
- }
1968
- currentHistoryClone.splice(50);
1969
- this.queryHistory$.next(currentHistoryClone);
1970
- }), takeUntil(this._destroy$))))
1971
- .subscribe();
1972
- this._queries$
1973
- .pipe(tap((queries) => {
1974
- const currentHistory = this.queryHistory$.getValue();
1975
- if (!queries || !currentHistory)
1976
- return;
1977
- const currentHistoryClone = [...currentHistory];
1978
- for (const query of queries) {
1979
- if (!currentHistoryClone.some((q) => q._id === query._id)) {
1980
- currentHistoryClone.unshift(query);
1981
- }
1982
- }
1983
- currentHistoryClone.splice(50);
1984
- this.queryHistory$.next(currentHistoryClone);
1985
- }), takeUntil(this._destroy$))
1986
- .subscribe();
1987
- effect(() => {
1988
- const devtoolConfig = {
1989
- isOpen: this.isOpen(),
1990
- isTranslucent: this.isTranslucent(),
1991
- snapLayout: this.snapLayout(),
1992
- showResponse: this.showResponse(),
1993
- showRawResponse: this.showRawResponse(),
1994
- showQueryConfig: this.showQueryConfig(),
1995
- showEntityStoreValue: this.showEntityStoreValue(),
1996
- showArguments: this.showArguments(),
1997
- selectedClientId: this.selectedClientId(),
1998
- selectedQueryPath: this.selectedQueryId(),
1999
- queryListMode: this.queryListMode(),
2000
- };
2001
- window.localStorage.setItem('ethlete:query:devtools', JSON.stringify(devtoolConfig));
2002
- }, { allowSignalWrites: true });
2003
- const initialConfig = window.localStorage.getItem('ethlete:query:devtools');
2004
- if (initialConfig) {
2005
- const parsed = JSON.parse(initialConfig);
2006
- this.isOpen.set(parsed.isOpen ?? false);
2007
- this.isTranslucent.set(parsed.isTranslucent ?? false);
2008
- this.snapLayout.set(parsed.snapLayout ?? 'full');
2009
- this.showResponse.set(parsed.showResponse ?? false);
2010
- this.showRawResponse.set(parsed.showRawResponse ?? false);
2011
- this.showQueryConfig.set(parsed.showQueryConfig ?? false);
2012
- this.showEntityStoreValue.set(parsed.showEntityStoreValue ?? false);
2013
- this.showArguments.set(parsed.showArguments ?? false);
2014
- this.selectedClientIdCtrl.setValue(parsed.selectedClientId ?? 0);
2015
- this.selectedQueryId.set(parsed.selectedQueryPath ?? null);
2016
- this.queryListMode.set(parsed.queryListMode ?? 'live');
2017
- }
2018
- }
2019
- toggleOpen() {
2020
- this.isOpen.set(!this.isOpen());
2021
- }
2022
- toggleTranslucent() {
2023
- this.isTranslucent.set(!this.isTranslucent());
2024
- }
2025
- toggleShowResponse() {
2026
- this.showResponse.set(!this.showResponse());
2027
- nextFrame(() => {
2028
- this._cdr.markForCheck();
2029
- });
2030
- }
2031
- toggleShowQueryConfig() {
2032
- this.showQueryConfig.set(!this.showQueryConfig());
2033
- }
2034
- toggleShowRawResponse() {
2035
- this.showRawResponse.set(!this.showRawResponse());
2036
- }
2037
- toggleShowEntityStoreValue() {
2038
- this.showEntityStoreValue.set(!this.showEntityStoreValue());
2039
- }
2040
- toggleShowArguments() {
2041
- this.showArguments.set(!this.showArguments());
2042
- }
2043
- selectSnapLayout(layout) {
2044
- this.snapLayout.set(layout);
2045
- }
2046
- selectQueryListMode(mode) {
2047
- this.queryListMode.set(mode);
2048
- }
2049
- selectQuery(query) {
2050
- this.selectedQueryId.set(query._id);
2051
- }
2052
- clearQueryHistory() {
2053
- this.queryHistory$.next([]);
2054
- }
2055
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.0", ngImport: i0, type: QueryDevtoolsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
2056
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.0", type: QueryDevtoolsComponent, isStandalone: true, selector: "et-query-devtools", host: { classAttribute: "et-query-devtools" }, ngImport: i0, template: "@if (!isOpen()) {\n <button (click)=\"toggleOpen()\" class=\"et-query-devtools-open-btn et-qd-chip\">Open Devtools</button>\n}\n\n@if (isOpen()) {\n <div\n [class.et-query-devtools-container--transparent]=\"isTranslucent()\"\n class=\"et-query-devtools-container et-query-devtools-container--snap-{{ snapLayout() }}\"\n >\n <header class=\"et-qd-header\">\n <h3 class=\"et-qd-header__title\">Query Devtools</h3>\n\n <div class=\"et-qd-header__select\">\n <label for=\"et-query-client-instance\">Client instance</label>\n <select [formControl]=\"selectedClientIdCtrl\" id=\"et-query-client-instance\">\n @for (clientConfig of queryClientConfigs; track trackByClient(i, clientConfig); let i = $index) {\n <option [value]=\"i\">\n {{ clientConfig.displayName ?? clientConfig.client.config.baseRoute }}\n </option>\n }\n </select>\n </div>\n\n <button (click)=\"toggleOpen()\" class=\"et-qd-btn et-qd-btn-secondary\">Close</button>\n </header>\n\n <div class=\"et-qd-sub-header\">\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': !isTranslucent() }\"\n (click)=\"toggleTranslucent()\"\n class=\"et-qd-chip et-qd-translucent-clickable\"\n >\n Translucent\n </button>\n <div class=\"et-qd-sub-header__divider\"></div>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': snapLayout() !== 'full' }\"\n (click)=\"selectSnapLayout('full')\"\n class=\"et-qd-chip\"\n >\n Fullscreen\n </button>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': snapLayout() !== 'top' }\"\n (click)=\"selectSnapLayout('top')\"\n class=\"et-qd-chip\"\n >\n Top\n </button>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': snapLayout() !== 'bottom' }\"\n (click)=\"selectSnapLayout('bottom')\"\n class=\"et-qd-chip\"\n >\n Bottom\n </button>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': snapLayout() !== 'left' }\"\n (click)=\"selectSnapLayout('left')\"\n class=\"et-qd-chip\"\n >\n Left\n </button>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': snapLayout() !== 'right' }\"\n (click)=\"selectSnapLayout('right')\"\n class=\"et-qd-chip\"\n >\n Right\n </button>\n </div>\n\n @if (selectedClientConfig(); as cfg) {\n <div class=\"et-qd-client\">\n <p class=\"et-qd-client__title\">{{ cfg.displayName ?? cfg.client.config.baseRoute }}</p>\n\n <div class=\"et-qd-client__actions\">\n <button (click)=\"cfg.client._store.refreshQueriesInUse()\" class=\"et-qd-chip\">Refresh all</button>\n <button (click)=\"cfg.client._store.refreshQueriesInUse({ ignoreCacheValidity: true })\" class=\"et-qd-chip\">\n Refresh all (ignore caches)\n </button>\n <button\n (click)=\"cfg.client._store.refreshQueriesInUse({ ignoreCacheValidity: true, purgeUnused: true })\"\n class=\"et-qd-chip\"\n >\n Refresh all (ignore caches & purge unused)\n </button>\n </div>\n </div>\n }\n\n @if (selectedClientConfig(); as cfg) {\n <div class=\"et-qd-queries\">\n <p class=\"et-qd-queries__title\">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$ | async)?.length ?? 0 }}/50)\n </button>\n @if (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 }\n </div>\n\n <div class=\"et-qd-queries__browser\">\n @if (queryListMode() === 'live') {\n <ul class=\"et-qd-queries__browser-list\">\n @for (query of queries(); track trackByQuery($index, query)) {\n <li>\n <button [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 }\n </ul>\n }\n @if (queryListMode() === 'history') {\n <ul class=\"et-qd-queries__browser-list\">\n @for (query of queryHistory$ | async; track trackByQuery($index, query)) {\n <li>\n <button [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 }\n </ul>\n }\n <div class=\"et-qd-queries__browser-detail\">\n @if (selectedQuery(); as query) {\n <p class=\"et-qd-queries__browser-detail__title\">\n {{ query._queryConfig.method }} {{ query._routeWithParams }}\n </p>\n\n <div class=\"et-qd-queries__actions\">\n <button (click)=\"query.execute()\" class=\"et-qd-chip et-qd-chip-bordered\">Execute</button>\n <button (click)=\"query.execute({ skipCache: true })\" class=\"et-qd-chip et-qd-chip-bordered\">\n Execute (ignore cache)\n </button>\n\n <button (click)=\"query.abort()\" class=\"et-qd-chip et-qd-chip-bordered\">Abort</button>\n <div class=\"et-qd-queries__divider\"></div>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': !query.isPolling }\"\n (click)=\"query.poll({ interval: 5000, takeUntil: _destroy$ })\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Poll\n </button>\n\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': query.isPolling }\"\n (click)=\"query.stopPolling()\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Stop polling\n </button>\n @if (query.isPolling || query._isPollingPaused) {\n <button (click)=\"query.pausePolling()\" class=\"et-qd-chip et-qd-chip-secondary et-qd-chip-bordered\">\n Pause polling\n </button>\n <button (click)=\"query.resumePolling()\" class=\"et-qd-chip et-qd-chip-secondary et-qd-chip-bordered\">\n Resume polling\n </button>\n }\n </div>\n\n <div class=\"et-qd-list\">\n <div class=\"et-qd-list-item\">\n <p>State type</p>\n <pre>{{ query.rawState.type }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Dependents</p>\n <pre>{{ query._dependents | json }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Is expired</p>\n <pre>{{ query.isExpired }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Is in use</p>\n <pre>{{ query.isInUse }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Subscriber count</p>\n <pre>{{ query._subscriberCount }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Is polling</p>\n <pre>{{ query.isPolling }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Is polling paused</p>\n <pre>{{ query._isPollingPaused }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Enable smart polling</p>\n <pre>{{ query._enableSmartPolling }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Query store key</p>\n <pre>{{ query._queryStoreKey }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Arguments</p>\n\n <div>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': !showArguments() }\"\n (click)=\"toggleShowArguments()\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Toggle\n </button>\n </div>\n @if (showArguments()) {\n <pre>{{ query._arguments | json }}</pre>\n }\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>State</p>\n <p><i> Warning, this will cause a subscription if shown!</i></p>\n <div>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': !showResponse() }\"\n (click)=\"toggleShowResponse()\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Toggle\n </button>\n </div>\n @if (showResponse()) {\n <pre>{{ query.state$ | async | json }}</pre>\n }\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Raw state</p>\n <p><i> The query state unaffected by entity stores</i></p>\n\n <div>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': !showRawResponse() }\"\n (click)=\"toggleShowRawResponse()\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Toggle\n </button>\n </div>\n @if (showRawResponse()) {\n <pre>{{ query.rawState | json }}</pre>\n }\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Query config</p>\n\n <div>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': !showQueryConfig() }\"\n (click)=\"toggleShowQueryConfig()\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Toggle\n </button>\n </div>\n @if (showQueryConfig()) {\n <pre>{{ stringifiedQueryConfig() | json }}</pre>\n }\n </div>\n\n @if (!!query._queryConfig.entity) {\n <div class=\"et-qd-list-item\">\n <p>Entity store value</p>\n\n <div>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': !showEntityStoreValue() }\"\n (click)=\"toggleShowEntityStoreValue()\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Toggle\n </button>\n </div>\n @if (showEntityStoreValue()) {\n <pre>{{ selectedQueryEntityStoreValue$ | async | json }}</pre>\n }\n </div>\n }\n </div>\n }\n </div>\n </div>\n </div>\n }\n </div>\n}\n", styles: [":host{position:fixed;top:0;z-index:1000000;font-size:14px;color:#fff}.et-query-devtools-container{position:fixed;inset:0;background-color:#25292e;z-index:10000;overflow:auto;font-family:monospace;display:grid;grid-template-rows:auto auto auto minmax(0,1fr)}.et-query-devtools-container.et-query-devtools-container--transparent{opacity:.25;pointer-events:none}.et-query-devtools-container.et-query-devtools-container--transparent .et-query-devtools-translucent-btn{pointer-events:all}.et-query-devtools-container.et-query-devtools-container--snap-left{inset-inline-start:0;inset-block-start:0;inset-block-end:0;width:50%;border-right:1px solid rgb(37,41,46)}.et-query-devtools-container.et-query-devtools-container--snap-right{inset-inline-start:unset;inset-inline-end:0;inset-block-start:0;inset-block-end:0;width:50%;border-left:1px solid rgb(37,41,46)}.et-query-devtools-container.et-query-devtools-container--snap-top{inset-inline-start:0;inset-block-start:0;inset-inline-end:0;height:50%;border-bottom:1px solid rgb(37,41,46)}.et-query-devtools-container.et-query-devtools-container--snap-bottom{inset-inline-start:0;inset-block-start:unset;inset-block-end:0;inset-inline-end:0;height:50%;border-top:1px solid rgb(37,41,46)}.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: "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 }); }
2057
- }
2058
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.0", ngImport: i0, type: QueryDevtoolsComponent, decorators: [{
2059
- type: Component,
2060
- args: [{ selector: 'et-query-devtools', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.ShadowDom, host: {
2061
- class: 'et-query-devtools',
2062
- }, imports: [AsyncPipe, JsonPipe, ReactiveFormsModule, NgClass, QueryShortNamePipe], template: "@if (!isOpen()) {\n <button (click)=\"toggleOpen()\" class=\"et-query-devtools-open-btn et-qd-chip\">Open Devtools</button>\n}\n\n@if (isOpen()) {\n <div\n [class.et-query-devtools-container--transparent]=\"isTranslucent()\"\n class=\"et-query-devtools-container et-query-devtools-container--snap-{{ snapLayout() }}\"\n >\n <header class=\"et-qd-header\">\n <h3 class=\"et-qd-header__title\">Query Devtools</h3>\n\n <div class=\"et-qd-header__select\">\n <label for=\"et-query-client-instance\">Client instance</label>\n <select [formControl]=\"selectedClientIdCtrl\" id=\"et-query-client-instance\">\n @for (clientConfig of queryClientConfigs; track trackByClient(i, clientConfig); let i = $index) {\n <option [value]=\"i\">\n {{ clientConfig.displayName ?? clientConfig.client.config.baseRoute }}\n </option>\n }\n </select>\n </div>\n\n <button (click)=\"toggleOpen()\" class=\"et-qd-btn et-qd-btn-secondary\">Close</button>\n </header>\n\n <div class=\"et-qd-sub-header\">\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': !isTranslucent() }\"\n (click)=\"toggleTranslucent()\"\n class=\"et-qd-chip et-qd-translucent-clickable\"\n >\n Translucent\n </button>\n <div class=\"et-qd-sub-header__divider\"></div>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': snapLayout() !== 'full' }\"\n (click)=\"selectSnapLayout('full')\"\n class=\"et-qd-chip\"\n >\n Fullscreen\n </button>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': snapLayout() !== 'top' }\"\n (click)=\"selectSnapLayout('top')\"\n class=\"et-qd-chip\"\n >\n Top\n </button>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': snapLayout() !== 'bottom' }\"\n (click)=\"selectSnapLayout('bottom')\"\n class=\"et-qd-chip\"\n >\n Bottom\n </button>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': snapLayout() !== 'left' }\"\n (click)=\"selectSnapLayout('left')\"\n class=\"et-qd-chip\"\n >\n Left\n </button>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': snapLayout() !== 'right' }\"\n (click)=\"selectSnapLayout('right')\"\n class=\"et-qd-chip\"\n >\n Right\n </button>\n </div>\n\n @if (selectedClientConfig(); as cfg) {\n <div class=\"et-qd-client\">\n <p class=\"et-qd-client__title\">{{ cfg.displayName ?? cfg.client.config.baseRoute }}</p>\n\n <div class=\"et-qd-client__actions\">\n <button (click)=\"cfg.client._store.refreshQueriesInUse()\" class=\"et-qd-chip\">Refresh all</button>\n <button (click)=\"cfg.client._store.refreshQueriesInUse({ ignoreCacheValidity: true })\" class=\"et-qd-chip\">\n Refresh all (ignore caches)\n </button>\n <button\n (click)=\"cfg.client._store.refreshQueriesInUse({ ignoreCacheValidity: true, purgeUnused: true })\"\n class=\"et-qd-chip\"\n >\n Refresh all (ignore caches & purge unused)\n </button>\n </div>\n </div>\n }\n\n @if (selectedClientConfig(); as cfg) {\n <div class=\"et-qd-queries\">\n <p class=\"et-qd-queries__title\">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$ | async)?.length ?? 0 }}/50)\n </button>\n @if (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 }\n </div>\n\n <div class=\"et-qd-queries__browser\">\n @if (queryListMode() === 'live') {\n <ul class=\"et-qd-queries__browser-list\">\n @for (query of queries(); track trackByQuery($index, query)) {\n <li>\n <button [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 }\n </ul>\n }\n @if (queryListMode() === 'history') {\n <ul class=\"et-qd-queries__browser-list\">\n @for (query of queryHistory$ | async; track trackByQuery($index, query)) {\n <li>\n <button [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 }\n </ul>\n }\n <div class=\"et-qd-queries__browser-detail\">\n @if (selectedQuery(); as query) {\n <p class=\"et-qd-queries__browser-detail__title\">\n {{ query._queryConfig.method }} {{ query._routeWithParams }}\n </p>\n\n <div class=\"et-qd-queries__actions\">\n <button (click)=\"query.execute()\" class=\"et-qd-chip et-qd-chip-bordered\">Execute</button>\n <button (click)=\"query.execute({ skipCache: true })\" class=\"et-qd-chip et-qd-chip-bordered\">\n Execute (ignore cache)\n </button>\n\n <button (click)=\"query.abort()\" class=\"et-qd-chip et-qd-chip-bordered\">Abort</button>\n <div class=\"et-qd-queries__divider\"></div>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': !query.isPolling }\"\n (click)=\"query.poll({ interval: 5000, takeUntil: _destroy$ })\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Poll\n </button>\n\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': query.isPolling }\"\n (click)=\"query.stopPolling()\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Stop polling\n </button>\n @if (query.isPolling || query._isPollingPaused) {\n <button (click)=\"query.pausePolling()\" class=\"et-qd-chip et-qd-chip-secondary et-qd-chip-bordered\">\n Pause polling\n </button>\n <button (click)=\"query.resumePolling()\" class=\"et-qd-chip et-qd-chip-secondary et-qd-chip-bordered\">\n Resume polling\n </button>\n }\n </div>\n\n <div class=\"et-qd-list\">\n <div class=\"et-qd-list-item\">\n <p>State type</p>\n <pre>{{ query.rawState.type }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Dependents</p>\n <pre>{{ query._dependents | json }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Is expired</p>\n <pre>{{ query.isExpired }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Is in use</p>\n <pre>{{ query.isInUse }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Subscriber count</p>\n <pre>{{ query._subscriberCount }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Is polling</p>\n <pre>{{ query.isPolling }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Is polling paused</p>\n <pre>{{ query._isPollingPaused }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Enable smart polling</p>\n <pre>{{ query._enableSmartPolling }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Query store key</p>\n <pre>{{ query._queryStoreKey }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Arguments</p>\n\n <div>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': !showArguments() }\"\n (click)=\"toggleShowArguments()\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Toggle\n </button>\n </div>\n @if (showArguments()) {\n <pre>{{ query._arguments | json }}</pre>\n }\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>State</p>\n <p><i> Warning, this will cause a subscription if shown!</i></p>\n <div>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': !showResponse() }\"\n (click)=\"toggleShowResponse()\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Toggle\n </button>\n </div>\n @if (showResponse()) {\n <pre>{{ query.state$ | async | json }}</pre>\n }\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Raw state</p>\n <p><i> The query state unaffected by entity stores</i></p>\n\n <div>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': !showRawResponse() }\"\n (click)=\"toggleShowRawResponse()\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Toggle\n </button>\n </div>\n @if (showRawResponse()) {\n <pre>{{ query.rawState | json }}</pre>\n }\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Query config</p>\n\n <div>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': !showQueryConfig() }\"\n (click)=\"toggleShowQueryConfig()\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Toggle\n </button>\n </div>\n @if (showQueryConfig()) {\n <pre>{{ stringifiedQueryConfig() | json }}</pre>\n }\n </div>\n\n @if (!!query._queryConfig.entity) {\n <div class=\"et-qd-list-item\">\n <p>Entity store value</p>\n\n <div>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': !showEntityStoreValue() }\"\n (click)=\"toggleShowEntityStoreValue()\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Toggle\n </button>\n </div>\n @if (showEntityStoreValue()) {\n <pre>{{ selectedQueryEntityStoreValue$ | async | json }}</pre>\n }\n </div>\n }\n </div>\n }\n </div>\n </div>\n </div>\n }\n </div>\n}\n", styles: [":host{position:fixed;top:0;z-index:1000000;font-size:14px;color:#fff}.et-query-devtools-container{position:fixed;inset:0;background-color:#25292e;z-index:10000;overflow:auto;font-family:monospace;display:grid;grid-template-rows:auto auto auto minmax(0,1fr)}.et-query-devtools-container.et-query-devtools-container--transparent{opacity:.25;pointer-events:none}.et-query-devtools-container.et-query-devtools-container--transparent .et-query-devtools-translucent-btn{pointer-events:all}.et-query-devtools-container.et-query-devtools-container--snap-left{inset-inline-start:0;inset-block-start:0;inset-block-end:0;width:50%;border-right:1px solid rgb(37,41,46)}.et-query-devtools-container.et-query-devtools-container--snap-right{inset-inline-start:unset;inset-inline-end:0;inset-block-start:0;inset-block-end:0;width:50%;border-left:1px solid rgb(37,41,46)}.et-query-devtools-container.et-query-devtools-container--snap-top{inset-inline-start:0;inset-block-start:0;inset-inline-end:0;height:50%;border-bottom:1px solid rgb(37,41,46)}.et-query-devtools-container.et-query-devtools-container--snap-bottom{inset-inline-start:0;inset-block-start:unset;inset-block-end:0;inset-inline-end:0;height:50%;border-top:1px solid rgb(37,41,46)}.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"] }]
2063
- }], ctorParameters: () => [] });
2064
-
2065
1842
  class QueryDirective {
2066
1843
  constructor() {
2067
1844
  this._mainTemplateRef = inject(TemplateRef);
@@ -2163,10 +1940,10 @@ class QueryDirective {
2163
1940
  this._viewContainerRef.createEmbeddedView(this._mainTemplateRef, this._viewContext);
2164
1941
  }
2165
1942
  }
2166
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.0", ngImport: i0, type: QueryDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
2167
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.3.0", type: QueryDirective, isStandalone: true, selector: "[etQuery]", inputs: { query: ["etQuery", "query"], cache: ["etQueryCache", "cache"] }, ngImport: i0 }); }
1943
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.3", ngImport: i0, type: QueryDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
1944
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.3.3", type: QueryDirective, isStandalone: true, selector: "[etQuery]", inputs: { query: ["etQuery", "query"], cache: ["etQueryCache", "cache"] }, ngImport: i0 }); }
2168
1945
  }
2169
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.0", ngImport: i0, type: QueryDirective, decorators: [{
1946
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.3", ngImport: i0, type: QueryDirective, decorators: [{
2170
1947
  type: Directive,
2171
1948
  args: [{
2172
1949
  // eslint-disable-next-line @angular-eslint/directive-selector
@@ -2240,6 +2017,9 @@ class InfinityQuery {
2240
2017
  null;
2241
2018
  this._totalPages$.next(totalPages);
2242
2019
  }), map((stateMaps) => {
2020
+ if (!stateMaps.length) {
2021
+ return null;
2022
+ }
2243
2023
  const fullData = stateMaps.reduce((acc, stateMap) => {
2244
2024
  if (isQueryStateSuccess(stateMap.state)) {
2245
2025
  const valExtractFn = this._config?.response?.valueExtractor;
@@ -2351,32 +2131,6 @@ const skipPaginationPageParamCalculator = ({ page, itemsPerPage }) => itemsPerPa
2351
2131
  /* eslint-disable @typescript-eslint/no-explicit-any */
2352
2132
  const INFINITY_QUERY_TOKEN = new InjectionToken('INFINITY_QUERY_TOKEN');
2353
2133
  class InfinityQueryDirective {
2354
- constructor() {
2355
- this._queryConfigChanged$ = new Subject();
2356
- this._viewContext = {
2357
- $implicit: null,
2358
- etInfinityQuery: null,
2359
- loading: false,
2360
- error: null,
2361
- isFirstLoad: false,
2362
- canLoadMore: false,
2363
- currentPage: null,
2364
- currentCalculatedPage: null,
2365
- totalPages: null,
2366
- itemsPerPage: null,
2367
- currentQuery: null,
2368
- };
2369
- this._infinityQueryInstance = null;
2370
- this._destroy$ = createDestroy();
2371
- this._cdr = inject(ChangeDetectorRef);
2372
- this._viewContainerRef = inject(ViewContainerRef);
2373
- this._mainTemplateRef = inject((TemplateRef));
2374
- this._errorHandler = inject(ErrorHandler);
2375
- this._delayable = inject(DelayableDirective, { host: true });
2376
- this._data$ = new BehaviorSubject([]);
2377
- this._didReceiveFirstData$ = new BehaviorSubject(false);
2378
- this._isMainViewCreated = false;
2379
- }
2380
2134
  get infinityQuery() {
2381
2135
  return this._infinityQuery;
2382
2136
  }
@@ -2384,7 +2138,7 @@ class InfinityQueryDirective {
2384
2138
  this._cleanup();
2385
2139
  this._infinityQuery = v;
2386
2140
  this._infinityQueryInstance = this._setupInfinityQuery(v);
2387
- this.loadNextPage();
2141
+ this._infinityQueryInstance.nextPage();
2388
2142
  }
2389
2143
  get context() {
2390
2144
  return this._viewContext;
@@ -2401,25 +2155,50 @@ class InfinityQueryDirective {
2401
2155
  static ngTemplateContextGuard(dir, ctx) {
2402
2156
  return true;
2403
2157
  }
2404
- ngOnInit() {
2405
- this._renderMainView();
2158
+ constructor() {
2159
+ this._queryConfigChanged$ = new Subject();
2160
+ this._viewContext = {
2161
+ $implicit: null,
2162
+ etInfinityQuery: null,
2163
+ loading: false,
2164
+ error: null,
2165
+ isFirstLoad: false,
2166
+ canLoadMore: false,
2167
+ currentPage: null,
2168
+ currentCalculatedPage: null,
2169
+ totalPages: null,
2170
+ itemsPerPage: null,
2171
+ currentQuery: null,
2172
+ };
2173
+ this._infinityQueryInstance = null;
2174
+ this._destroy$ = createDestroy();
2175
+ this._cdr = inject(ChangeDetectorRef);
2176
+ this._viewContainerRef = inject(ViewContainerRef);
2177
+ this._mainTemplateRef = inject((TemplateRef));
2178
+ this._errorHandler = inject(ErrorHandler);
2179
+ this._delayable = inject(DelayableDirective, { host: true });
2180
+ this._data$ = new BehaviorSubject([]);
2181
+ this._viewContainerRef.createEmbeddedView(this._mainTemplateRef, this._viewContext);
2406
2182
  }
2407
2183
  _setupInfinityQuery(config) {
2408
2184
  const instance = new InfinityQuery(config);
2409
2185
  combineLatest([
2410
2186
  instance.currentQuery$.pipe(switchQueryState(), withLatestFrom(instance.currentQuery$)),
2411
2187
  this._delayable.isDelayed$,
2412
- this._didReceiveFirstData$,
2188
+ instance.data$,
2413
2189
  ])
2414
- .pipe(tap(([[state, currentQuery], isDelayed, didReceiveFirstData]) => {
2190
+ .pipe(tap(([[state, currentQuery], isDelayed, infinityArray]) => {
2415
2191
  this._viewContext.currentPage = instance.currentPage;
2416
2192
  this._viewContext.totalPages = instance.totalPages;
2417
2193
  this._viewContext.itemsPerPage = instance.itemsPerPage;
2418
2194
  this._viewContext.canLoadMore =
2419
- (instance.totalPages && instance.currentPage && instance.totalPages > instance.currentPage) || false;
2195
+ (instance.totalPages !== null &&
2196
+ instance.currentPage !== null &&
2197
+ instance.totalPages > instance.currentPage) ||
2198
+ false;
2420
2199
  this._viewContext.currentCalculatedPage = instance.currentCalculatedPage;
2421
2200
  this._viewContext.currentQuery = currentQuery;
2422
- if (isQueryStateLoading(state) || isDelayed || (!didReceiveFirstData && isQueryStateSuccess(state))) {
2201
+ if (isQueryStateLoading(state) || isDelayed || !infinityArray) {
2423
2202
  this._viewContext.loading = true;
2424
2203
  this._viewContext.error = null;
2425
2204
  this._viewContext.isFirstLoad = this.context.etInfinityQuery === null;
@@ -2434,29 +2213,9 @@ class InfinityQueryDirective {
2434
2213
  this._viewContext.loading = false;
2435
2214
  this._viewContext.error = null;
2436
2215
  this._viewContext.isFirstLoad = false;
2437
- }
2438
- else {
2439
- this._viewContext.loading = false;
2440
- this._viewContext.error = null;
2441
- this._viewContext.etInfinityQuery = null;
2442
- this._viewContext.$implicit = null;
2443
- this._viewContext.isFirstLoad = false;
2444
- this._viewContext.canLoadMore = false;
2445
- this._viewContext.currentPage = null;
2446
- this._viewContext.itemsPerPage = null;
2447
- this._viewContext.totalPages = null;
2448
- this._viewContext.currentQuery = null;
2449
- this._data$.next([]);
2450
- }
2451
- this._cdr.markForCheck();
2452
- }), takeUntil(this._destroy$), takeUntil(this._queryConfigChanged$))
2453
- .subscribe();
2454
- instance.data$
2455
- .pipe(skip(1), tap((data) => {
2456
- this._viewContext.etInfinityQuery = this._viewContext.$implicit = data;
2457
- this._data$.next(data);
2458
- if (!this._didReceiveFirstData$.getValue()) {
2459
- this._didReceiveFirstData$.next(true);
2216
+ this._viewContext.etInfinityQuery = this._viewContext.$implicit =
2217
+ infinityArray;
2218
+ this._data$.next(infinityArray);
2460
2219
  }
2461
2220
  this._cdr.markForCheck();
2462
2221
  }), takeUntil(this._destroy$), takeUntil(this._queryConfigChanged$))
@@ -2478,12 +2237,6 @@ class InfinityQueryDirective {
2478
2237
  }
2479
2238
  this._infinityQueryInstance.reset(newConfig);
2480
2239
  }
2481
- _renderMainView() {
2482
- if (!this._isMainViewCreated) {
2483
- this._isMainViewCreated = true;
2484
- this._viewContainerRef.createEmbeddedView(this._mainTemplateRef, this._viewContext);
2485
- }
2486
- }
2487
2240
  _cleanup() {
2488
2241
  this._queryConfigChanged$.next(true);
2489
2242
  this._viewContext.loading = false;
@@ -2498,10 +2251,10 @@ class InfinityQueryDirective {
2498
2251
  this._viewContext.currentQuery = null;
2499
2252
  this._data$.next([]);
2500
2253
  }
2501
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.0", ngImport: i0, type: InfinityQueryDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
2502
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.3.0", type: InfinityQueryDirective, isStandalone: true, selector: "[etInfinityQuery]", inputs: { infinityQuery: ["etInfinityQuery", "infinityQuery"] }, providers: [{ provide: INFINITY_QUERY_TOKEN, useExisting: InfinityQueryDirective }], exportAs: ["etInfinityQuery"], hostDirectives: [{ directive: i1$1.DelayableDirective }], ngImport: i0 }); }
2254
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.3", ngImport: i0, type: InfinityQueryDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
2255
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.3.3", type: InfinityQueryDirective, isStandalone: true, selector: "[etInfinityQuery]", inputs: { infinityQuery: ["etInfinityQuery", "infinityQuery"] }, providers: [{ provide: INFINITY_QUERY_TOKEN, useExisting: InfinityQueryDirective }], exportAs: ["etInfinityQuery"], hostDirectives: [{ directive: i1.DelayableDirective }], ngImport: i0 }); }
2503
2256
  }
2504
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.0", ngImport: i0, type: InfinityQueryDirective, decorators: [{
2257
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.3", ngImport: i0, type: InfinityQueryDirective, decorators: [{
2505
2258
  type: Directive,
2506
2259
  args: [{
2507
2260
  // eslint-disable-next-line @angular-eslint/directive-selector
@@ -2511,7 +2264,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.0", ngImpor
2511
2264
  providers: [{ provide: INFINITY_QUERY_TOKEN, useExisting: InfinityQueryDirective }],
2512
2265
  hostDirectives: [DelayableDirective],
2513
2266
  }]
2514
- }], propDecorators: { infinityQuery: [{
2267
+ }], ctorParameters: () => [], propDecorators: { infinityQuery: [{
2515
2268
  type: Input,
2516
2269
  args: ['etInfinityQuery']
2517
2270
  }] } });
@@ -2554,10 +2307,10 @@ class InfinityQueryTriggerDirective {
2554
2307
  });
2555
2308
  this._observer.observe(this._elementRef.nativeElement);
2556
2309
  }
2557
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.0", ngImport: i0, type: InfinityQueryTriggerDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
2558
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.3.0", type: InfinityQueryTriggerDirective, isStandalone: true, selector: "[etInfinityQueryTrigger], et-infinity-query-trigger", inputs: { scrollContainerSelector: "scrollContainerSelector" }, ngImport: i0 }); }
2310
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.3", ngImport: i0, type: InfinityQueryTriggerDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
2311
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.3.3", type: InfinityQueryTriggerDirective, isStandalone: true, selector: "[etInfinityQueryTrigger], et-infinity-query-trigger", inputs: { scrollContainerSelector: "scrollContainerSelector" }, ngImport: i0 }); }
2559
2312
  }
2560
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.0", ngImport: i0, type: InfinityQueryTriggerDirective, decorators: [{
2313
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.3", ngImport: i0, type: InfinityQueryTriggerDirective, decorators: [{
2561
2314
  type: Directive,
2562
2315
  args: [{
2563
2316
  // eslint-disable-next-line @angular-eslint/directive-selector
@@ -2568,6 +2321,324 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.0", ngImpor
2568
2321
  type: Input
2569
2322
  }] } });
2570
2323
 
2324
+ class QueryShortNamePipe {
2325
+ transform(value) {
2326
+ const route = value._routeWithParams;
2327
+ if (typeof route === 'string') {
2328
+ // 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
2329
+ // we want to extract the last 3 parts of the url, so we get: repos/EladBezalel/etimo-achievements
2330
+ const parts = route.split('/');
2331
+ if (parts.length > 3) {
2332
+ return `.../${parts.slice(parts.length - 3).join('/')}`;
2333
+ }
2334
+ return route;
2335
+ }
2336
+ return route;
2337
+ }
2338
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.3", ngImport: i0, type: QueryShortNamePipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
2339
+ static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "17.3.3", ngImport: i0, type: QueryShortNamePipe, isStandalone: true, name: "queryShortName" }); }
2340
+ }
2341
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.3", ngImport: i0, type: QueryShortNamePipe, decorators: [{
2342
+ type: Pipe,
2343
+ args: [{ name: 'queryShortName', standalone: true }]
2344
+ }] });
2345
+
2346
+ const QUERY_CLIENT_DEVTOOLS_TOKEN = new InjectionToken('QUERY_CLIENT_DEVTOOLS_TOKEN');
2347
+ const provideQueryClientForDevtools = (queryClient) => {
2348
+ if (!isDevMode()) {
2349
+ console.warn('You are using the Query Devtools in production mode. This increases the size of your bundle and should only be used for development purposes.');
2350
+ }
2351
+ return {
2352
+ provide: QUERY_CLIENT_DEVTOOLS_TOKEN,
2353
+ useValue: queryClient,
2354
+ multi: true,
2355
+ };
2356
+ };
2357
+
2358
+ class QueryDevtoolsComponent {
2359
+ constructor() {
2360
+ this._cdr = inject(ChangeDetectorRef);
2361
+ this._destroy$ = createDestroy();
2362
+ this.queryClientConfigs = inject(QUERY_CLIENT_DEVTOOLS_TOKEN);
2363
+ this.isOpen = signal(false);
2364
+ this.isTranslucent = signal(false);
2365
+ this.snapLayout = signal('full');
2366
+ this.queryListMode = signal('live');
2367
+ this.viewMode = signal('query');
2368
+ this.showResponse = signal(false);
2369
+ this.showRawResponse = signal(false);
2370
+ this.showQueryConfig = signal(false);
2371
+ this.showEntityStoreValue = signal(false);
2372
+ this.showArguments = signal(false);
2373
+ this.selectedClientIdCtrl = new FormControl(0);
2374
+ this.selectedClientId = toSignal(this.selectedClientIdCtrl.valueChanges.pipe(startWith(this.selectedClientIdCtrl.value)));
2375
+ this.selectedQueryId = signal(null);
2376
+ this.selectedClientConfig = computed(() => {
2377
+ if (this.queryClientConfigs.length === 1) {
2378
+ return this.queryClientConfigs[0];
2379
+ }
2380
+ const index = this.selectedClientId() ?? 0;
2381
+ const cfg = this.queryClientConfigs[index];
2382
+ if (!cfg) {
2383
+ return this.queryClientConfigs[0];
2384
+ }
2385
+ return cfg;
2386
+ });
2387
+ this.queryStore = computed(() => {
2388
+ const config = this.selectedClientConfig();
2389
+ return config.client._store;
2390
+ });
2391
+ this.queryStore$ = toObservable(this.queryStore);
2392
+ this._queries$ = new BehaviorSubject([]);
2393
+ this.queries = toSignal(this._queries$);
2394
+ this.selectedQuery = computed(() => {
2395
+ const id = this.selectedQueryId();
2396
+ const mode = this.queryListMode();
2397
+ if (id === null || !mode) {
2398
+ return null;
2399
+ }
2400
+ if (mode === 'live') {
2401
+ return this.queries()?.find((q) => q._id === id) ?? null;
2402
+ }
2403
+ return this.queryHistory$.getValue()?.find((q) => q._id === id) ?? null;
2404
+ });
2405
+ this.selectedQuery$ = toObservable(this.selectedQuery);
2406
+ this.selectedQueryEntityStore = computed(() => {
2407
+ const query = this.selectedQuery();
2408
+ if (!query)
2409
+ return null;
2410
+ return query.store;
2411
+ });
2412
+ this.selectedQueryEntityStore$ = toObservable(this.selectedQueryEntityStore);
2413
+ this.selectedQueryEntityStoreValue$ = this.selectedQueryEntityStore$.pipe(switchMap((s) => s?._change$.pipe(startWith(''), map(() => {
2414
+ if (!s._dictionary)
2415
+ return null;
2416
+ return Array.from(s._dictionary).reduce((obj, [key, value]) => {
2417
+ obj[key] = value;
2418
+ return obj;
2419
+ }, {});
2420
+ })) ?? of(null)));
2421
+ this.queryHistory$ = new BehaviorSubject([]);
2422
+ this.stringifiedQueryConfig = computed(() => {
2423
+ const query = this.selectedQuery();
2424
+ if (!query)
2425
+ return null;
2426
+ const cfg = query._queryConfig;
2427
+ const route = typeof cfg.route === 'string' ? cfg.route : cfg.route ? cfg.route({}).replace(/undefined/g, ':param') : null;
2428
+ const sharedCfg = {
2429
+ method: cfg.method,
2430
+ secure: cfg.secure,
2431
+ route,
2432
+ reportProgress: cfg.reportProgress,
2433
+ responseType: cfg.responseType,
2434
+ withCredentials: cfg.withCredentials,
2435
+ autoRefreshOn: cfg.autoRefreshOn,
2436
+ enableSmartPolling: cfg.enableSmartPolling,
2437
+ hasEntityStore: !!cfg.entity,
2438
+ };
2439
+ if (isGqlQueryConfig(cfg)) {
2440
+ return {
2441
+ ...sharedCfg,
2442
+ query: cfg.query,
2443
+ transferVia: cfg.transferVia,
2444
+ };
2445
+ }
2446
+ return {
2447
+ ...sharedCfg,
2448
+ };
2449
+ });
2450
+ this.authProvider = toSignal(toObservable(this.selectedClientConfig).pipe(switchMap((c) => c.client.authProvider$)));
2451
+ this.authProviderDetails = computed(() => {
2452
+ const provider = this.authProvider();
2453
+ if (!provider)
2454
+ return null;
2455
+ if (provider instanceof CustomHeaderAuthProvider) {
2456
+ return {
2457
+ type: 'CustomHeaderAuthProvider',
2458
+ header: () => provider.header,
2459
+ provider: provider,
2460
+ config: {
2461
+ name: provider._config.name,
2462
+ value: provider._config.value,
2463
+ },
2464
+ };
2465
+ }
2466
+ else if (provider instanceof BasicAuthProvider) {
2467
+ return {
2468
+ type: 'BasicAuthProvider',
2469
+ header: () => provider.header,
2470
+ provider: provider,
2471
+ config: {
2472
+ username: provider._config.username,
2473
+ password: provider._config.password,
2474
+ },
2475
+ };
2476
+ }
2477
+ else if (isBearerAuthProvider(provider)) {
2478
+ const refreshCfg = provider._config.refreshConfig;
2479
+ return {
2480
+ type: 'BearerAuthProvider',
2481
+ header: () => provider.header,
2482
+ provider: provider,
2483
+ config: {
2484
+ token: provider._config.token,
2485
+ refreshConfig: {
2486
+ refreshOnUnauthorizedResponse: refreshCfg?.refreshOnUnauthorizedResponse ?? 'true (default)',
2487
+ token: refreshCfg?.token,
2488
+ cookieName: refreshCfg?.cookieName,
2489
+ cookieDomain: refreshCfg?.cookieDomain ?? 'current origin (default)',
2490
+ cookieExpiresInDays: refreshCfg?.cookieExpiresInDays ?? '30 (default)',
2491
+ cookiePath: refreshCfg?.cookiePath ?? '/ (default)',
2492
+ cookieEnabled: refreshCfg?.cookieEnabled ?? 'true (default)',
2493
+ cookieSameSite: refreshCfg?.cookieSameSite ?? 'lax (default)',
2494
+ refreshBuffer: refreshCfg?.refreshBuffer ?? '30000 (default)',
2495
+ expiresInPropertyName: refreshCfg?.expiresInPropertyName ?? 'exp (default)',
2496
+ strategy: refreshCfg?.strategy ?? 'AuthBearerRefreshStrategy.BeforeExpiration (default)',
2497
+ requestArgsAdapter: refreshCfg?.requestArgsAdapter ? 'custom' : 'default',
2498
+ responseAdapter: refreshCfg?.responseAdapter ? 'custom' : 'default',
2499
+ },
2500
+ },
2501
+ };
2502
+ }
2503
+ else {
2504
+ return {
2505
+ type: 'UnknownAuthProvider',
2506
+ header: () => provider.header,
2507
+ provider: provider,
2508
+ config: {},
2509
+ };
2510
+ }
2511
+ });
2512
+ this.trackByClient = (_, { client }) => client.config.baseRoute;
2513
+ this.trackByQuery = (_, { _id }) => _id;
2514
+ this.selectedClientIdCtrl.valueChanges
2515
+ .pipe(tap(() => this.clearQueryHistory()), takeUntil(this._destroy$))
2516
+ .subscribe();
2517
+ this.selectedQuery$
2518
+ .pipe(switchMap((q) => q?._dependentsChanged$ ?? of(null)), tap(() => this._cdr.markForCheck()), takeUntilDestroyed())
2519
+ .subscribe();
2520
+ toObservable(this.authProviderDetails)
2521
+ .pipe(switchMap((ap) => (ap?.type === 'BearerAuthProvider' ? ap.provider.tokens$ : of(null))))
2522
+ .pipe(tap(() => this._cdr.markForCheck()), takeUntilDestroyed())
2523
+ .subscribe();
2524
+ this.queryStore$
2525
+ .pipe(switchMap((s) => s.storeChange$.pipe(startWith(''), map(() => s._store), tap((s) => {
2526
+ untracked(() => {
2527
+ this._queries$.next(Array.from(s.values()));
2528
+ });
2529
+ }), takeUntil(this._destroy$))))
2530
+ .subscribe();
2531
+ this.queryStore$
2532
+ .pipe(switchMap((s) => s.queryCreated$.pipe(tap((query) => {
2533
+ const currentHistory = this.queryHistory$.getValue();
2534
+ if (!currentHistory)
2535
+ return;
2536
+ const currentHistoryClone = [...currentHistory];
2537
+ if (!currentHistory.some((q) => q._id === query._id)) {
2538
+ currentHistoryClone.unshift(query);
2539
+ }
2540
+ currentHistoryClone.splice(50);
2541
+ this.queryHistory$.next(currentHistoryClone);
2542
+ }), takeUntil(this._destroy$))))
2543
+ .subscribe();
2544
+ this._queries$
2545
+ .pipe(tap((queries) => {
2546
+ const currentHistory = this.queryHistory$.getValue();
2547
+ if (!queries || !currentHistory)
2548
+ return;
2549
+ const currentHistoryClone = [...currentHistory];
2550
+ for (const query of queries) {
2551
+ if (!currentHistoryClone.some((q) => q._id === query._id)) {
2552
+ currentHistoryClone.unshift(query);
2553
+ }
2554
+ }
2555
+ currentHistoryClone.splice(50);
2556
+ this.queryHistory$.next(currentHistoryClone);
2557
+ }), takeUntil(this._destroy$))
2558
+ .subscribe();
2559
+ effect(() => {
2560
+ const devtoolConfig = {
2561
+ isOpen: this.isOpen(),
2562
+ isTranslucent: this.isTranslucent(),
2563
+ snapLayout: this.snapLayout(),
2564
+ showResponse: this.showResponse(),
2565
+ showRawResponse: this.showRawResponse(),
2566
+ showQueryConfig: this.showQueryConfig(),
2567
+ showEntityStoreValue: this.showEntityStoreValue(),
2568
+ showArguments: this.showArguments(),
2569
+ selectedClientId: this.selectedClientId(),
2570
+ selectedQueryPath: this.selectedQueryId(),
2571
+ queryListMode: this.queryListMode(),
2572
+ viewMode: this.viewMode(),
2573
+ };
2574
+ window.localStorage.setItem('ethlete:query:devtools', JSON.stringify(devtoolConfig));
2575
+ }, { allowSignalWrites: true });
2576
+ const initialConfig = window.localStorage.getItem('ethlete:query:devtools');
2577
+ if (initialConfig) {
2578
+ const parsed = JSON.parse(initialConfig);
2579
+ this.isOpen.set(parsed.isOpen ?? false);
2580
+ this.isTranslucent.set(parsed.isTranslucent ?? false);
2581
+ this.snapLayout.set(parsed.snapLayout ?? 'full');
2582
+ this.showResponse.set(parsed.showResponse ?? false);
2583
+ this.showRawResponse.set(parsed.showRawResponse ?? false);
2584
+ this.showQueryConfig.set(parsed.showQueryConfig ?? false);
2585
+ this.showEntityStoreValue.set(parsed.showEntityStoreValue ?? false);
2586
+ this.showArguments.set(parsed.showArguments ?? false);
2587
+ this.selectedClientIdCtrl.setValue(parsed.selectedClientId ?? 0);
2588
+ this.selectedQueryId.set(parsed.selectedQueryPath ?? null);
2589
+ this.queryListMode.set(parsed.queryListMode ?? 'live');
2590
+ this.viewMode.set(parsed.viewMode ?? 'query');
2591
+ }
2592
+ }
2593
+ toggleOpen() {
2594
+ this.isOpen.set(!this.isOpen());
2595
+ }
2596
+ toggleTranslucent() {
2597
+ this.isTranslucent.set(!this.isTranslucent());
2598
+ }
2599
+ toggleShowResponse() {
2600
+ this.showResponse.set(!this.showResponse());
2601
+ nextFrame(() => {
2602
+ this._cdr.markForCheck();
2603
+ });
2604
+ }
2605
+ toggleShowQueryConfig() {
2606
+ this.showQueryConfig.set(!this.showQueryConfig());
2607
+ }
2608
+ toggleShowRawResponse() {
2609
+ this.showRawResponse.set(!this.showRawResponse());
2610
+ }
2611
+ toggleShowEntityStoreValue() {
2612
+ this.showEntityStoreValue.set(!this.showEntityStoreValue());
2613
+ }
2614
+ toggleShowArguments() {
2615
+ this.showArguments.set(!this.showArguments());
2616
+ }
2617
+ selectSnapLayout(layout) {
2618
+ this.snapLayout.set(layout);
2619
+ }
2620
+ selectQueryListMode(mode) {
2621
+ this.queryListMode.set(mode);
2622
+ }
2623
+ selectViewMode(mode) {
2624
+ this.viewMode.set(mode);
2625
+ }
2626
+ selectQuery(query) {
2627
+ this.selectedQueryId.set(query._id);
2628
+ }
2629
+ clearQueryHistory() {
2630
+ this.queryHistory$.next([]);
2631
+ }
2632
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.3", ngImport: i0, type: QueryDevtoolsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
2633
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.3", type: QueryDevtoolsComponent, isStandalone: true, selector: "et-query-devtools", host: { classAttribute: "et-query-devtools" }, ngImport: i0, template: "@if (!isOpen()) {\n <button (click)=\"toggleOpen()\" class=\"et-query-devtools-open-btn et-qd-chip\">Open Devtools</button>\n}\n\n@if (isOpen()) {\n <div\n [class.et-query-devtools-container--transparent]=\"isTranslucent()\"\n class=\"et-query-devtools-container et-query-devtools-container--snap-{{ snapLayout() }}\"\n >\n <header class=\"et-qd-header\">\n <h3 class=\"et-qd-header__title\">Query Devtools</h3>\n\n <div class=\"et-qd-header__select\">\n <label for=\"et-query-client-instance\">Client instance</label>\n <select [formControl]=\"selectedClientIdCtrl\" id=\"et-query-client-instance\">\n @for (clientConfig of queryClientConfigs; track trackByClient(i, clientConfig); let i = $index) {\n <option [value]=\"i\">\n {{ clientConfig.displayName ?? clientConfig.client.config.baseRoute }}\n </option>\n }\n </select>\n </div>\n\n <button (click)=\"toggleOpen()\" class=\"et-qd-btn et-qd-btn-secondary\">Close</button>\n </header>\n\n <div class=\"et-qd-sub-header\">\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': !isTranslucent() }\"\n (click)=\"toggleTranslucent()\"\n class=\"et-qd-chip et-qd-translucent-clickable\"\n >\n Translucent\n </button>\n <div class=\"et-qd-sub-header__divider\"></div>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': snapLayout() !== 'full' }\"\n (click)=\"selectSnapLayout('full')\"\n class=\"et-qd-chip\"\n >\n Fullscreen\n </button>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': snapLayout() !== 'top' }\"\n (click)=\"selectSnapLayout('top')\"\n class=\"et-qd-chip\"\n >\n Top\n </button>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': snapLayout() !== 'bottom' }\"\n (click)=\"selectSnapLayout('bottom')\"\n class=\"et-qd-chip\"\n >\n Bottom\n </button>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': snapLayout() !== 'left' }\"\n (click)=\"selectSnapLayout('left')\"\n class=\"et-qd-chip\"\n >\n Left\n </button>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': snapLayout() !== 'right' }\"\n (click)=\"selectSnapLayout('right')\"\n class=\"et-qd-chip\"\n >\n Right\n </button>\n </div>\n\n @if (selectedClientConfig(); as cfg) {\n <div class=\"et-qd-client\">\n <p class=\"et-qd-client__title\">{{ cfg.displayName ?? cfg.client.config.baseRoute }}</p>\n\n <div class=\"et-qd-client__actions\">\n <button (click)=\"cfg.client._store.refreshQueriesInUse()\" class=\"et-qd-chip\">Refresh all</button>\n <button (click)=\"cfg.client._store.refreshQueriesInUse({ ignoreCacheValidity: true })\" class=\"et-qd-chip\">\n Refresh all (ignore caches)\n </button>\n <button\n (click)=\"cfg.client._store.refreshQueriesInUse({ ignoreCacheValidity: true, purgeUnused: true })\"\n class=\"et-qd-chip\"\n >\n Refresh all (ignore caches & purge unused)\n </button>\n </div>\n </div>\n }\n\n @if (selectedClientConfig(); as cfg) {\n <div class=\"et-qd-queries\">\n <p class=\"et-qd-queries__title\">Inspector</p>\n <div class=\"et-qd-queries__actions\">\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': queryListMode() !== 'live' || viewMode() !== 'query' }\"\n (click)=\"selectQueryListMode('live'); selectViewMode('query')\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Live Queries ({{ queries()?.length ?? 0 }})\n </button>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': queryListMode() !== 'history' || viewMode() !== 'query' }\"\n (click)=\"selectQueryListMode('history'); selectViewMode('query')\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Query History ({{ (queryHistory$ | async)?.length ?? 0 }}/50)\n </button>\n @if (queryListMode() === 'history' && viewMode() === 'query') {\n <div class=\"et-qd-queries__divider\"></div>\n <button (click)=\"clearQueryHistory()\" class=\"et-qd-chip et-qd-chip-bordered\">Clear history</button>\n }\n\n <div class=\"et-qd-queries__divider\"></div>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': viewMode() !== 'authProvider' }\"\n (click)=\"selectViewMode('authProvider')\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Auth Provider\n </button>\n </div>\n\n @if (viewMode() === 'query') {\n <div class=\"et-qd-queries__browser\">\n @if (queryListMode() === 'live') {\n <ul class=\"et-qd-queries__browser-list\">\n @for (query of queries(); track trackByQuery($index, query)) {\n <li>\n <button\n [class.et-qd-query--active]=\"selectedQuery()?._id === query._id\"\n (click)=\"selectQuery(query)\"\n >\n <span> {{ query._queryConfig.method }}</span>\n <span> {{ query | queryShortName }}</span>\n </button>\n </li>\n }\n </ul>\n }\n @if (queryListMode() === 'history') {\n <ul class=\"et-qd-queries__browser-list\">\n @for (query of queryHistory$ | async; track trackByQuery($index, query)) {\n <li>\n <button\n [class.et-qd-query--active]=\"selectedQuery()?._id === query._id\"\n (click)=\"selectQuery(query)\"\n >\n <span> {{ query._queryConfig.method }}</span>\n <span> {{ query | queryShortName }}</span>\n </button>\n </li>\n }\n </ul>\n }\n <div class=\"et-qd-queries__browser-detail\">\n @if (selectedQuery(); as query) {\n <p class=\"et-qd-queries__browser-detail__title\">\n {{ query._queryConfig.method }} {{ query._routeWithParams }}\n </p>\n\n <div class=\"et-qd-queries__actions\">\n <button (click)=\"query.execute()\" class=\"et-qd-chip et-qd-chip-bordered\">Execute</button>\n <button (click)=\"query.execute({ skipCache: true })\" class=\"et-qd-chip et-qd-chip-bordered\">\n Execute (ignore cache)\n </button>\n\n <button (click)=\"query.abort()\" class=\"et-qd-chip et-qd-chip-bordered\">Abort</button>\n <div class=\"et-qd-queries__divider\"></div>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': !query.isPolling }\"\n (click)=\"query.poll({ interval: 5000, takeUntil: _destroy$ })\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Poll\n </button>\n\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': query.isPolling }\"\n (click)=\"query.stopPolling()\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Stop polling\n </button>\n @if (query.isPolling || query._isPollingPaused) {\n <button (click)=\"query.pausePolling()\" class=\"et-qd-chip et-qd-chip-secondary et-qd-chip-bordered\">\n Pause polling\n </button>\n <button (click)=\"query.resumePolling()\" class=\"et-qd-chip et-qd-chip-secondary et-qd-chip-bordered\">\n Resume polling\n </button>\n }\n </div>\n\n <div class=\"et-qd-list\">\n <div class=\"et-qd-list-item\">\n <p>State type</p>\n <pre>{{ query.rawState.type }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Dependents</p>\n <pre>{{ query._dependents | json }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Is expired</p>\n <pre>{{ query.isExpired }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Is in use</p>\n <pre>{{ query.isInUse }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Subscriber count</p>\n <pre>{{ query._subscriberCount }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Is polling</p>\n <pre>{{ query.isPolling }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Is polling paused</p>\n <pre>{{ query._isPollingPaused }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Enable smart polling</p>\n <pre>{{ query._enableSmartPolling }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Query store key</p>\n <pre>{{ query._queryStoreKey }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Arguments</p>\n\n <div>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': !showArguments() }\"\n (click)=\"toggleShowArguments()\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Toggle\n </button>\n </div>\n @if (showArguments()) {\n <pre>{{ query._arguments | json }}</pre>\n }\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>State</p>\n <p><i> Warning, this will cause a subscription if shown!</i></p>\n <div>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': !showResponse() }\"\n (click)=\"toggleShowResponse()\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Toggle\n </button>\n </div>\n @if (showResponse()) {\n <pre>{{ query.state$ | async | json }}</pre>\n }\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Raw state</p>\n <p><i> The query state unaffected by entity stores</i></p>\n\n <div>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': !showRawResponse() }\"\n (click)=\"toggleShowRawResponse()\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Toggle\n </button>\n </div>\n @if (showRawResponse()) {\n <pre>{{ query.rawState | json }}</pre>\n }\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Query config</p>\n\n <div>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': !showQueryConfig() }\"\n (click)=\"toggleShowQueryConfig()\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Toggle\n </button>\n </div>\n @if (showQueryConfig()) {\n <pre>{{ stringifiedQueryConfig() | json }}</pre>\n }\n </div>\n\n @if (!!query._queryConfig.entity) {\n <div class=\"et-qd-list-item\">\n <p>Entity store value</p>\n\n <div>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': !showEntityStoreValue() }\"\n (click)=\"toggleShowEntityStoreValue()\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Toggle\n </button>\n </div>\n @if (showEntityStoreValue()) {\n <pre>{{ selectedQueryEntityStoreValue$ | async | json }}</pre>\n }\n </div>\n }\n </div>\n }\n </div>\n </div>\n } @else if (viewMode() === 'authProvider') {\n <div class=\"et-qd-auth-provider__viewer\">\n @if (authProviderDetails(); as details) {\n <div class=\"et-qd-list\">\n <div class=\"et-qd-list-item\">\n <p>Type</p>\n <pre>{{ details.type }}</pre>\n </div>\n <div class=\"et-qd-list-item\">\n <p>Header value</p>\n <pre>{{ details.header() | json }}</pre>\n </div>\n <div class=\"et-qd-list-item\">\n <p>Config</p>\n <pre>{{ details.config | json }}</pre>\n </div>\n\n @if (details.type === 'BearerAuthProvider') {\n <div class=\"et-qd-list-item\">\n <p>Tokens</p>\n <pre>{{ details.provider.tokens$ | async | json }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Should refresh on unauthorized response</p>\n <pre>{{ details.provider.shouldRefreshOnUnauthorizedResponse }}</pre>\n </div>\n\n <ng-container\n *etQuery=\"\n details.provider.currentRefreshQuery$ | async as response;\n loading as loading;\n error as error;\n query as query\n \"\n >\n <div class=\"et-qd-list-item\">\n <p>Refresh query response</p>\n\n <div>\n <button (click)=\"details.provider._refreshQuery()\" class=\"et-qd-chip et-qd-chip-bordered\">\n Refresh\n </button>\n </div>\n <pre>{{ response | json }}</pre>\n </div>\n <div class=\"et-qd-list-item\">\n <p>Refresh query loading</p>\n <pre>{{ loading }}</pre>\n </div>\n <div class=\"et-qd-list-item\">\n <p>Refresh query error</p>\n <pre>{{ error ?? 'null' }}</pre>\n </div>\n <div class=\"et-qd-list-item\">\n <p>State</p>\n <pre>{{ query?.state$ | async | json }}</pre>\n </div>\n </ng-container>\n }\n </div>\n } @else {\n <p>No auth provider set</p>\n }\n </div>\n }\n </div>\n }\n </div>\n}\n", styles: [":host{position:fixed;top:0;z-index:1000000;font-size:14px;color:#fff}.et-query-devtools-container{position:fixed;inset:0;background-color:#25292e;z-index:10000;overflow:auto;font-family:monospace;display:grid;grid-template-rows:auto auto auto minmax(0,1fr)}.et-query-devtools-container.et-query-devtools-container--transparent{opacity:.25;pointer-events:none}.et-query-devtools-container.et-query-devtools-container--transparent .et-query-devtools-translucent-btn{pointer-events:all}.et-query-devtools-container.et-query-devtools-container--snap-left{inset-inline-start:0;inset-block-start:0;inset-block-end:0;width:50%;border-right:1px solid rgb(37,41,46)}.et-query-devtools-container.et-query-devtools-container--snap-right{inset-inline-start:unset;inset-inline-end:0;inset-block-start:0;inset-block-end:0;width:50%;border-left:1px solid rgb(37,41,46)}.et-query-devtools-container.et-query-devtools-container--snap-top{inset-inline-start:0;inset-block-start:0;inset-inline-end:0;height:50%;border-bottom:1px solid rgb(37,41,46)}.et-query-devtools-container.et-query-devtools-container--snap-bottom{inset-inline-start:0;inset-block-start:unset;inset-block-end:0;inset-inline-end:0;height:50%;border-top:1px solid rgb(37,41,46)}.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-auth-provider__viewer{border-top:1px solid #3c424a;margin-left:-12px;margin-right:-12px;margin-bottom:-12px;padding:12px;overflow-y:auto;overflow-x:hidden}.et-qd-list{display:grid;gap:12px}.et-qd-list-item{display:grid}.et-qd-list-item p{font-weight:700;margin:0;padding-bottom:8px}.et-qd-list-item p+p{margin-top:-8px}.et-qd-list-item div+pre{margin-top:8px}.et-qd-list-item pre{margin:0;padding:4px;background-color:#0e1012;border-radius:4px;max-height:450px;overflow:auto}\n"], dependencies: [{ kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "pipe", type: JsonPipe, name: "json" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1$1.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1$1.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "pipe", type: QueryShortNamePipe, name: "queryShortName" }, { kind: "directive", type: QueryDirective, selector: "[etQuery]", inputs: ["etQuery", "etQueryCache"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.ShadowDom }); }
2634
+ }
2635
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.3", ngImport: i0, type: QueryDevtoolsComponent, decorators: [{
2636
+ type: Component,
2637
+ args: [{ selector: 'et-query-devtools', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.ShadowDom, host: {
2638
+ class: 'et-query-devtools',
2639
+ }, imports: [AsyncPipe, JsonPipe, ReactiveFormsModule, NgClass, QueryShortNamePipe, QueryDirective], template: "@if (!isOpen()) {\n <button (click)=\"toggleOpen()\" class=\"et-query-devtools-open-btn et-qd-chip\">Open Devtools</button>\n}\n\n@if (isOpen()) {\n <div\n [class.et-query-devtools-container--transparent]=\"isTranslucent()\"\n class=\"et-query-devtools-container et-query-devtools-container--snap-{{ snapLayout() }}\"\n >\n <header class=\"et-qd-header\">\n <h3 class=\"et-qd-header__title\">Query Devtools</h3>\n\n <div class=\"et-qd-header__select\">\n <label for=\"et-query-client-instance\">Client instance</label>\n <select [formControl]=\"selectedClientIdCtrl\" id=\"et-query-client-instance\">\n @for (clientConfig of queryClientConfigs; track trackByClient(i, clientConfig); let i = $index) {\n <option [value]=\"i\">\n {{ clientConfig.displayName ?? clientConfig.client.config.baseRoute }}\n </option>\n }\n </select>\n </div>\n\n <button (click)=\"toggleOpen()\" class=\"et-qd-btn et-qd-btn-secondary\">Close</button>\n </header>\n\n <div class=\"et-qd-sub-header\">\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': !isTranslucent() }\"\n (click)=\"toggleTranslucent()\"\n class=\"et-qd-chip et-qd-translucent-clickable\"\n >\n Translucent\n </button>\n <div class=\"et-qd-sub-header__divider\"></div>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': snapLayout() !== 'full' }\"\n (click)=\"selectSnapLayout('full')\"\n class=\"et-qd-chip\"\n >\n Fullscreen\n </button>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': snapLayout() !== 'top' }\"\n (click)=\"selectSnapLayout('top')\"\n class=\"et-qd-chip\"\n >\n Top\n </button>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': snapLayout() !== 'bottom' }\"\n (click)=\"selectSnapLayout('bottom')\"\n class=\"et-qd-chip\"\n >\n Bottom\n </button>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': snapLayout() !== 'left' }\"\n (click)=\"selectSnapLayout('left')\"\n class=\"et-qd-chip\"\n >\n Left\n </button>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': snapLayout() !== 'right' }\"\n (click)=\"selectSnapLayout('right')\"\n class=\"et-qd-chip\"\n >\n Right\n </button>\n </div>\n\n @if (selectedClientConfig(); as cfg) {\n <div class=\"et-qd-client\">\n <p class=\"et-qd-client__title\">{{ cfg.displayName ?? cfg.client.config.baseRoute }}</p>\n\n <div class=\"et-qd-client__actions\">\n <button (click)=\"cfg.client._store.refreshQueriesInUse()\" class=\"et-qd-chip\">Refresh all</button>\n <button (click)=\"cfg.client._store.refreshQueriesInUse({ ignoreCacheValidity: true })\" class=\"et-qd-chip\">\n Refresh all (ignore caches)\n </button>\n <button\n (click)=\"cfg.client._store.refreshQueriesInUse({ ignoreCacheValidity: true, purgeUnused: true })\"\n class=\"et-qd-chip\"\n >\n Refresh all (ignore caches & purge unused)\n </button>\n </div>\n </div>\n }\n\n @if (selectedClientConfig(); as cfg) {\n <div class=\"et-qd-queries\">\n <p class=\"et-qd-queries__title\">Inspector</p>\n <div class=\"et-qd-queries__actions\">\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': queryListMode() !== 'live' || viewMode() !== 'query' }\"\n (click)=\"selectQueryListMode('live'); selectViewMode('query')\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Live Queries ({{ queries()?.length ?? 0 }})\n </button>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': queryListMode() !== 'history' || viewMode() !== 'query' }\"\n (click)=\"selectQueryListMode('history'); selectViewMode('query')\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Query History ({{ (queryHistory$ | async)?.length ?? 0 }}/50)\n </button>\n @if (queryListMode() === 'history' && viewMode() === 'query') {\n <div class=\"et-qd-queries__divider\"></div>\n <button (click)=\"clearQueryHistory()\" class=\"et-qd-chip et-qd-chip-bordered\">Clear history</button>\n }\n\n <div class=\"et-qd-queries__divider\"></div>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': viewMode() !== 'authProvider' }\"\n (click)=\"selectViewMode('authProvider')\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Auth Provider\n </button>\n </div>\n\n @if (viewMode() === 'query') {\n <div class=\"et-qd-queries__browser\">\n @if (queryListMode() === 'live') {\n <ul class=\"et-qd-queries__browser-list\">\n @for (query of queries(); track trackByQuery($index, query)) {\n <li>\n <button\n [class.et-qd-query--active]=\"selectedQuery()?._id === query._id\"\n (click)=\"selectQuery(query)\"\n >\n <span> {{ query._queryConfig.method }}</span>\n <span> {{ query | queryShortName }}</span>\n </button>\n </li>\n }\n </ul>\n }\n @if (queryListMode() === 'history') {\n <ul class=\"et-qd-queries__browser-list\">\n @for (query of queryHistory$ | async; track trackByQuery($index, query)) {\n <li>\n <button\n [class.et-qd-query--active]=\"selectedQuery()?._id === query._id\"\n (click)=\"selectQuery(query)\"\n >\n <span> {{ query._queryConfig.method }}</span>\n <span> {{ query | queryShortName }}</span>\n </button>\n </li>\n }\n </ul>\n }\n <div class=\"et-qd-queries__browser-detail\">\n @if (selectedQuery(); as query) {\n <p class=\"et-qd-queries__browser-detail__title\">\n {{ query._queryConfig.method }} {{ query._routeWithParams }}\n </p>\n\n <div class=\"et-qd-queries__actions\">\n <button (click)=\"query.execute()\" class=\"et-qd-chip et-qd-chip-bordered\">Execute</button>\n <button (click)=\"query.execute({ skipCache: true })\" class=\"et-qd-chip et-qd-chip-bordered\">\n Execute (ignore cache)\n </button>\n\n <button (click)=\"query.abort()\" class=\"et-qd-chip et-qd-chip-bordered\">Abort</button>\n <div class=\"et-qd-queries__divider\"></div>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': !query.isPolling }\"\n (click)=\"query.poll({ interval: 5000, takeUntil: _destroy$ })\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Poll\n </button>\n\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': query.isPolling }\"\n (click)=\"query.stopPolling()\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Stop polling\n </button>\n @if (query.isPolling || query._isPollingPaused) {\n <button (click)=\"query.pausePolling()\" class=\"et-qd-chip et-qd-chip-secondary et-qd-chip-bordered\">\n Pause polling\n </button>\n <button (click)=\"query.resumePolling()\" class=\"et-qd-chip et-qd-chip-secondary et-qd-chip-bordered\">\n Resume polling\n </button>\n }\n </div>\n\n <div class=\"et-qd-list\">\n <div class=\"et-qd-list-item\">\n <p>State type</p>\n <pre>{{ query.rawState.type }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Dependents</p>\n <pre>{{ query._dependents | json }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Is expired</p>\n <pre>{{ query.isExpired }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Is in use</p>\n <pre>{{ query.isInUse }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Subscriber count</p>\n <pre>{{ query._subscriberCount }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Is polling</p>\n <pre>{{ query.isPolling }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Is polling paused</p>\n <pre>{{ query._isPollingPaused }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Enable smart polling</p>\n <pre>{{ query._enableSmartPolling }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Query store key</p>\n <pre>{{ query._queryStoreKey }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Arguments</p>\n\n <div>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': !showArguments() }\"\n (click)=\"toggleShowArguments()\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Toggle\n </button>\n </div>\n @if (showArguments()) {\n <pre>{{ query._arguments | json }}</pre>\n }\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>State</p>\n <p><i> Warning, this will cause a subscription if shown!</i></p>\n <div>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': !showResponse() }\"\n (click)=\"toggleShowResponse()\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Toggle\n </button>\n </div>\n @if (showResponse()) {\n <pre>{{ query.state$ | async | json }}</pre>\n }\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Raw state</p>\n <p><i> The query state unaffected by entity stores</i></p>\n\n <div>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': !showRawResponse() }\"\n (click)=\"toggleShowRawResponse()\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Toggle\n </button>\n </div>\n @if (showRawResponse()) {\n <pre>{{ query.rawState | json }}</pre>\n }\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Query config</p>\n\n <div>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': !showQueryConfig() }\"\n (click)=\"toggleShowQueryConfig()\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Toggle\n </button>\n </div>\n @if (showQueryConfig()) {\n <pre>{{ stringifiedQueryConfig() | json }}</pre>\n }\n </div>\n\n @if (!!query._queryConfig.entity) {\n <div class=\"et-qd-list-item\">\n <p>Entity store value</p>\n\n <div>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': !showEntityStoreValue() }\"\n (click)=\"toggleShowEntityStoreValue()\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Toggle\n </button>\n </div>\n @if (showEntityStoreValue()) {\n <pre>{{ selectedQueryEntityStoreValue$ | async | json }}</pre>\n }\n </div>\n }\n </div>\n }\n </div>\n </div>\n } @else if (viewMode() === 'authProvider') {\n <div class=\"et-qd-auth-provider__viewer\">\n @if (authProviderDetails(); as details) {\n <div class=\"et-qd-list\">\n <div class=\"et-qd-list-item\">\n <p>Type</p>\n <pre>{{ details.type }}</pre>\n </div>\n <div class=\"et-qd-list-item\">\n <p>Header value</p>\n <pre>{{ details.header() | json }}</pre>\n </div>\n <div class=\"et-qd-list-item\">\n <p>Config</p>\n <pre>{{ details.config | json }}</pre>\n </div>\n\n @if (details.type === 'BearerAuthProvider') {\n <div class=\"et-qd-list-item\">\n <p>Tokens</p>\n <pre>{{ details.provider.tokens$ | async | json }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Should refresh on unauthorized response</p>\n <pre>{{ details.provider.shouldRefreshOnUnauthorizedResponse }}</pre>\n </div>\n\n <ng-container\n *etQuery=\"\n details.provider.currentRefreshQuery$ | async as response;\n loading as loading;\n error as error;\n query as query\n \"\n >\n <div class=\"et-qd-list-item\">\n <p>Refresh query response</p>\n\n <div>\n <button (click)=\"details.provider._refreshQuery()\" class=\"et-qd-chip et-qd-chip-bordered\">\n Refresh\n </button>\n </div>\n <pre>{{ response | json }}</pre>\n </div>\n <div class=\"et-qd-list-item\">\n <p>Refresh query loading</p>\n <pre>{{ loading }}</pre>\n </div>\n <div class=\"et-qd-list-item\">\n <p>Refresh query error</p>\n <pre>{{ error ?? 'null' }}</pre>\n </div>\n <div class=\"et-qd-list-item\">\n <p>State</p>\n <pre>{{ query?.state$ | async | json }}</pre>\n </div>\n </ng-container>\n }\n </div>\n } @else {\n <p>No auth provider set</p>\n }\n </div>\n }\n </div>\n }\n </div>\n}\n", styles: [":host{position:fixed;top:0;z-index:1000000;font-size:14px;color:#fff}.et-query-devtools-container{position:fixed;inset:0;background-color:#25292e;z-index:10000;overflow:auto;font-family:monospace;display:grid;grid-template-rows:auto auto auto minmax(0,1fr)}.et-query-devtools-container.et-query-devtools-container--transparent{opacity:.25;pointer-events:none}.et-query-devtools-container.et-query-devtools-container--transparent .et-query-devtools-translucent-btn{pointer-events:all}.et-query-devtools-container.et-query-devtools-container--snap-left{inset-inline-start:0;inset-block-start:0;inset-block-end:0;width:50%;border-right:1px solid rgb(37,41,46)}.et-query-devtools-container.et-query-devtools-container--snap-right{inset-inline-start:unset;inset-inline-end:0;inset-block-start:0;inset-block-end:0;width:50%;border-left:1px solid rgb(37,41,46)}.et-query-devtools-container.et-query-devtools-container--snap-top{inset-inline-start:0;inset-block-start:0;inset-inline-end:0;height:50%;border-bottom:1px solid rgb(37,41,46)}.et-query-devtools-container.et-query-devtools-container--snap-bottom{inset-inline-start:0;inset-block-start:unset;inset-block-end:0;inset-inline-end:0;height:50%;border-top:1px solid rgb(37,41,46)}.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-auth-provider__viewer{border-top:1px solid #3c424a;margin-left:-12px;margin-right:-12px;margin-bottom:-12px;padding:12px;overflow-y:auto;overflow-x:hidden}.et-qd-list{display:grid;gap:12px}.et-qd-list-item{display:grid}.et-qd-list-item p{font-weight:700;margin:0;padding-bottom:8px}.et-qd-list-item p+p{margin-top:-8px}.et-qd-list-item div+pre{margin-top:8px}.et-qd-list-item pre{margin:0;padding:4px;background-color:#0e1012;border-radius:4px;max-height:450px;overflow:auto}\n"] }]
2640
+ }], ctorParameters: () => [] });
2641
+
2571
2642
  class EntityStoreError extends Error {
2572
2643
  constructor(message, detail) {
2573
2644
  super(message);
@@ -3154,6 +3225,8 @@ class QueryForm {
3154
3225
  }
3155
3226
  }
3156
3227
 
3228
+ // Burst cache
3229
+
3157
3230
  /**
3158
3231
  * Generated bundle index. Do not edit.
3159
3232
  */