@ethlete/query 5.16.2 → 5.18.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/esm2022/index.mjs +2 -1
  3. package/esm2022/lib/devtools/components/query-devtools/query-devtools.component.mjs +3 -3
  4. package/esm2022/lib/devtools/pipes/query-short-name.pipe.mjs +3 -3
  5. package/esm2022/lib/directives/infinity-query-trigger.directive.mjs +3 -3
  6. package/esm2022/lib/directives/infinity-query.directive.mjs +3 -3
  7. package/esm2022/lib/directives/query.directive.mjs +3 -3
  8. package/esm2022/lib/experimental/bearer-auth-provider-config.mjs +19 -0
  9. package/esm2022/lib/experimental/bearer-auth-provider.mjs +245 -0
  10. package/esm2022/lib/experimental/http-request.mjs +153 -0
  11. package/esm2022/lib/experimental/index.mjs +21 -0
  12. package/esm2022/lib/experimental/query-client-config.mjs +13 -0
  13. package/esm2022/lib/experimental/query-client.mjs +16 -0
  14. package/esm2022/lib/experimental/query-creator-templates.mjs +33 -0
  15. package/esm2022/lib/experimental/query-creator.mjs +28 -0
  16. package/esm2022/lib/experimental/query-dependencies.mjs +14 -0
  17. package/esm2022/lib/experimental/query-errors.mjs +55 -0
  18. package/esm2022/lib/experimental/query-execute-utils.mjs +57 -0
  19. package/esm2022/lib/experimental/query-execute.mjs +12 -0
  20. package/esm2022/lib/experimental/query-features.mjs +126 -0
  21. package/esm2022/lib/experimental/query-repository.mjs +91 -0
  22. package/esm2022/lib/experimental/query-snapshot.mjs +44 -0
  23. package/esm2022/lib/experimental/query-state.mjs +20 -0
  24. package/esm2022/lib/experimental/query-utils.mjs +148 -0
  25. package/esm2022/lib/experimental/query.mjs +37 -0
  26. package/esm2022/lib/experimental/secure-query-creator.mjs +15 -0
  27. package/esm2022/lib/experimental/secure-query-execute.mjs +77 -0
  28. package/esm2022/lib/experimental/secure-query.mjs +41 -0
  29. package/esm2022/lib/query/query.mjs +3 -2
  30. package/esm2022/lib/query/query.types.mjs +1 -1
  31. package/esm2022/lib/query-form/query-form.mjs +32 -11
  32. package/fesm2022/ethlete-query.mjs +1313 -31
  33. package/fesm2022/ethlete-query.mjs.map +1 -1
  34. package/index.d.ts +1 -0
  35. package/lib/experimental/bearer-auth-provider-config.d.ts +111 -0
  36. package/lib/experimental/bearer-auth-provider.d.ts +63 -0
  37. package/lib/experimental/http-request.d.ts +55 -0
  38. package/lib/experimental/index.d.ts +20 -0
  39. package/lib/experimental/query-client-config.d.ts +18 -0
  40. package/lib/experimental/query-client.d.ts +10 -0
  41. package/lib/experimental/query-creator-templates.d.ts +14 -0
  42. package/lib/experimental/query-creator.d.ts +39 -0
  43. package/lib/experimental/query-dependencies.d.ts +12 -0
  44. package/lib/experimental/query-errors.d.ts +39 -0
  45. package/lib/experimental/query-execute-utils.d.ts +20 -0
  46. package/lib/experimental/query-execute.d.ts +16 -0
  47. package/lib/experimental/query-features.d.ts +45 -0
  48. package/lib/experimental/query-repository.d.ts +31 -0
  49. package/lib/experimental/query-snapshot.d.ts +8 -0
  50. package/lib/experimental/query-state.d.ts +14 -0
  51. package/lib/experimental/query-utils.d.ts +41 -0
  52. package/lib/experimental/query.d.ts +41 -0
  53. package/lib/experimental/secure-query-creator.d.ts +7 -0
  54. package/lib/experimental/secure-query-execute.d.ts +7 -0
  55. package/lib/experimental/secure-query.d.ts +6 -0
  56. package/lib/query/query.types.d.ts +2 -1
  57. package/lib/query-form/query-form.d.ts +3 -1
  58. package/package.json +1 -1
@@ -1,12 +1,13 @@
1
1
  import * as i1 from '@ethlete/core';
2
- import { createDestroy, computedTillTruthy, 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';
2
+ import { createDestroy, computedTillTruthy, getCookie, setCookie, deleteCookie, DelayableDirective, nextFrame, RuntimeError, isObject, getDomain, syncSignal, injectQueryParamChanges, injectQueryParams, clone, equal, ET_PROPERTY_REMOVED } from '@ethlete/core';
3
+ import { Observable, takeUntil, startWith, pairwise, tap, switchMap, of, BehaviorSubject, Subject, fromEvent, timer, take, filter, takeWhile, map, shareReplay, ReplaySubject, combineLatest, interval, skip, withLatestFrom, debounceTime, Subscription, retry, throwError, catchError, merge } from 'rxjs';
4
4
  import * as i0 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';
5
+ import { assertInInjectionContext, inject, Injector, computed, signal, isDevMode, untracked, TemplateRef, ViewContainerRef, ErrorHandler, ChangeDetectorRef, Directive, Input, InjectionToken, ElementRef, Pipe, effect, Component, ChangeDetectionStrategy, ViewEncapsulation, DestroyRef, runInInjectionContext, 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
8
  import * as i1$1 from '@angular/forms';
9
9
  import { FormControl, ReactiveFormsModule, FormGroup } from '@angular/forms';
10
+ import { HttpErrorResponse, HttpStatusCode, HttpEventType, HttpClient, HttpHeaders } from '@angular/common/http';
10
11
  import { Router, ActivatedRoute } from '@angular/router';
11
12
 
12
13
  class CustomHeaderAuthProvider {
@@ -154,7 +155,7 @@ const buildQueryString = (params, config) => {
154
155
  }
155
156
  return queryParams.length ? queryParams.join('&') : null;
156
157
  };
157
- const extractExpiresInSeconds = (headers) => {
158
+ const extractExpiresInSeconds$1 = (headers) => {
158
159
  const cacheControl = headers['cache-control'];
159
160
  const age = headers['age'];
160
161
  const expires = headers['expires'];
@@ -292,7 +293,7 @@ const getResponseUrl = (xhr) => {
292
293
  }
293
294
  return null;
294
295
  };
295
- const shouldRetryRequest = (config) => {
296
+ const shouldRetryRequest$1 = (config) => {
296
297
  const defaultRetryDelay = 1000 + 1000 * config.currentRetryCount;
297
298
  if (config.currentRetryCount > 3) {
298
299
  return { retry: false };
@@ -339,7 +340,7 @@ const request = (config) => {
339
340
  const responseType = config.responseType || 'json';
340
341
  const body = config.body || null;
341
342
  const url = config.urlWithParams.split('?')[0] || '';
342
- const retryFn = config.retryFn || shouldRetryRequest;
343
+ const retryFn = config.retryFn || shouldRetryRequest$1;
343
344
  let currentRetryCount = 0;
344
345
  let retryTimeout = null;
345
346
  return new Observable((observer) => {
@@ -432,7 +433,7 @@ const request = (config) => {
432
433
  headers,
433
434
  response: body,
434
435
  };
435
- const expiresInSeconds = config.cacheAdapter?.(headers) ?? extractExpiresInSeconds(headers);
436
+ const expiresInSeconds = config.cacheAdapter?.(headers) ?? extractExpiresInSeconds$1(headers);
436
437
  const expiresInTimestamp = buildTimestampFromSeconds(expiresInSeconds);
437
438
  if (expiresInTimestamp) {
438
439
  successEvent.expiresInTimestamp = expiresInTimestamp;
@@ -1512,7 +1513,7 @@ class Query {
1512
1513
  break;
1513
1514
  }
1514
1515
  case 'success': {
1515
- const { response, expiresInTimestamp } = requestEvent;
1516
+ const { response, expiresInTimestamp, headers } = requestEvent;
1516
1517
  const isGql = isGqlQueryConfig(this._queryConfig);
1517
1518
  const responseData = isGql && typeof response === 'object' && !!response && 'data' in response
1518
1519
  ? response['data']
@@ -1529,6 +1530,7 @@ class Query {
1529
1530
  this._updateState({
1530
1531
  type: "SUCCESS" /* QueryStateType.Success */,
1531
1532
  response: responseData,
1533
+ headers: headers,
1532
1534
  meta: { ...meta, expiresAt: expiresInTimestamp },
1533
1535
  });
1534
1536
  break;
@@ -1957,10 +1959,10 @@ class QueryDirective {
1957
1959
  this._viewContainerRef.createEmbeddedView(this._mainTemplateRef, this._viewContext);
1958
1960
  }
1959
1961
  }
1960
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.1.1", ngImport: i0, type: QueryDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
1961
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.1.1", type: QueryDirective, isStandalone: true, selector: "[etQuery]", inputs: { query: ["etQuery", "query"], cache: ["etQueryCache", "cache"] }, ngImport: i0 }); }
1962
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.1.4", ngImport: i0, type: QueryDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
1963
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.1.4", type: QueryDirective, isStandalone: true, selector: "[etQuery]", inputs: { query: ["etQuery", "query"], cache: ["etQueryCache", "cache"] }, ngImport: i0 }); }
1962
1964
  }
1963
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.1.1", ngImport: i0, type: QueryDirective, decorators: [{
1965
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.1.4", ngImport: i0, type: QueryDirective, decorators: [{
1964
1966
  type: Directive,
1965
1967
  args: [{
1966
1968
  // eslint-disable-next-line @angular-eslint/directive-selector
@@ -2268,10 +2270,10 @@ class InfinityQueryDirective {
2268
2270
  this._viewContext.currentQuery = null;
2269
2271
  this._data$.next([]);
2270
2272
  }
2271
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.1.1", ngImport: i0, type: InfinityQueryDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
2272
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.1.1", 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 }); }
2273
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.1.4", ngImport: i0, type: InfinityQueryDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
2274
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.1.4", type: InfinityQueryDirective, isStandalone: true, selector: "[etInfinityQuery]", inputs: { infinityQuery: ["etInfinityQuery", "infinityQuery"] }, providers: [{ provide: INFINITY_QUERY_TOKEN, useExisting: InfinityQueryDirective }], exportAs: ["etInfinityQuery"], hostDirectives: [{ directive: i1.DelayableDirective }], ngImport: i0 }); }
2273
2275
  }
2274
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.1.1", ngImport: i0, type: InfinityQueryDirective, decorators: [{
2276
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.1.4", ngImport: i0, type: InfinityQueryDirective, decorators: [{
2275
2277
  type: Directive,
2276
2278
  args: [{
2277
2279
  // eslint-disable-next-line @angular-eslint/directive-selector
@@ -2324,10 +2326,10 @@ class InfinityQueryTriggerDirective {
2324
2326
  });
2325
2327
  this._observer.observe(this._elementRef.nativeElement);
2326
2328
  }
2327
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.1.1", ngImport: i0, type: InfinityQueryTriggerDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
2328
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.1.1", type: InfinityQueryTriggerDirective, isStandalone: true, selector: "[etInfinityQueryTrigger], et-infinity-query-trigger", inputs: { scrollContainerSelector: "scrollContainerSelector" }, ngImport: i0 }); }
2329
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.1.4", ngImport: i0, type: InfinityQueryTriggerDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
2330
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.1.4", type: InfinityQueryTriggerDirective, isStandalone: true, selector: "[etInfinityQueryTrigger], et-infinity-query-trigger", inputs: { scrollContainerSelector: "scrollContainerSelector" }, ngImport: i0 }); }
2329
2331
  }
2330
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.1.1", ngImport: i0, type: InfinityQueryTriggerDirective, decorators: [{
2332
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.1.4", ngImport: i0, type: InfinityQueryTriggerDirective, decorators: [{
2331
2333
  type: Directive,
2332
2334
  args: [{
2333
2335
  // eslint-disable-next-line @angular-eslint/directive-selector
@@ -2352,10 +2354,10 @@ class QueryShortNamePipe {
2352
2354
  }
2353
2355
  return route;
2354
2356
  }
2355
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.1.1", ngImport: i0, type: QueryShortNamePipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
2356
- static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "18.1.1", ngImport: i0, type: QueryShortNamePipe, isStandalone: true, name: "queryShortName" }); }
2357
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.1.4", ngImport: i0, type: QueryShortNamePipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
2358
+ static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "18.1.4", ngImport: i0, type: QueryShortNamePipe, isStandalone: true, name: "queryShortName" }); }
2357
2359
  }
2358
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.1.1", ngImport: i0, type: QueryShortNamePipe, decorators: [{
2360
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.1.4", ngImport: i0, type: QueryShortNamePipe, decorators: [{
2359
2361
  type: Pipe,
2360
2362
  args: [{ name: 'queryShortName', standalone: true }]
2361
2363
  }] });
@@ -2646,10 +2648,10 @@ class QueryDevtoolsComponent {
2646
2648
  clearQueryHistory() {
2647
2649
  this.queryHistory$.next([]);
2648
2650
  }
2649
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.1.1", ngImport: i0, type: QueryDevtoolsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
2650
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.1.1", type: QueryDevtoolsComponent, isStandalone: true, selector: "et-query-devtools", host: { classAttribute: "et-query-devtools" }, ngImport: i0, template: "@if (!isOpen()) {\n <button (click)=\"toggleOpen()\" class=\"et-query-devtools-open-btn et-qd-chip\">Query Devtools</button>\n}\n\n@if (isOpen()) {\n <div\n [class.et-query-devtools-container--transparent]=\"isTranslucent()\"\n class=\"et-query-devtools-container et-query-devtools-container--snap-{{ snapLayout() }}\"\n >\n <header class=\"et-qd-header\">\n <h3 class=\"et-qd-header__title\">Query Devtools</h3>\n\n <div class=\"et-qd-header__select\">\n <label for=\"et-query-client-instance\">Client instance</label>\n <select [formControl]=\"selectedClientIdCtrl\" id=\"et-query-client-instance\">\n @for (clientConfig of queryClientConfigs; track trackByClient(i, clientConfig); let i = $index) {\n <option [value]=\"i\">\n {{ clientConfig.displayName ?? clientConfig.client.config.baseRoute }}\n </option>\n }\n </select>\n </div>\n\n <button (click)=\"toggleOpen()\" class=\"et-qd-btn et-qd-btn-secondary\">Close</button>\n </header>\n\n <div class=\"et-qd-sub-header\">\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': !isTranslucent() }\"\n (click)=\"toggleTranslucent()\"\n class=\"et-qd-chip et-qd-translucent-clickable\"\n >\n Translucent\n </button>\n <div class=\"et-qd-sub-header__divider\"></div>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': snapLayout() !== 'full' }\"\n (click)=\"selectSnapLayout('full')\"\n class=\"et-qd-chip\"\n >\n Fullscreen\n </button>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': snapLayout() !== 'top' }\"\n (click)=\"selectSnapLayout('top')\"\n class=\"et-qd-chip\"\n >\n Top\n </button>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': snapLayout() !== 'bottom' }\"\n (click)=\"selectSnapLayout('bottom')\"\n class=\"et-qd-chip\"\n >\n Bottom\n </button>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': snapLayout() !== 'left' }\"\n (click)=\"selectSnapLayout('left')\"\n class=\"et-qd-chip\"\n >\n Left\n </button>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': snapLayout() !== 'right' }\"\n (click)=\"selectSnapLayout('right')\"\n class=\"et-qd-chip\"\n >\n Right\n </button>\n </div>\n\n @if (selectedClientConfig(); as cfg) {\n <div class=\"et-qd-client\">\n <p class=\"et-qd-client__title\">{{ cfg.displayName ?? cfg.client.config.baseRoute }}</p>\n\n <div class=\"et-qd-client__actions\">\n <button (click)=\"cfg.client._store.refreshQueriesInUse()\" class=\"et-qd-chip\">Refresh all</button>\n <button (click)=\"cfg.client._store.refreshQueriesInUse({ ignoreCacheValidity: true })\" class=\"et-qd-chip\">\n Refresh all (ignore caches)\n </button>\n <button\n (click)=\"cfg.client._store.refreshQueriesInUse({ ignoreCacheValidity: true, purgeUnused: true })\"\n class=\"et-qd-chip\"\n >\n Refresh all (ignore caches & purge unused)\n </button>\n </div>\n </div>\n }\n\n @if (selectedClientConfig(); as cfg) {\n <div class=\"et-qd-queries\">\n <p class=\"et-qd-queries__title\">Inspector</p>\n <div class=\"et-qd-queries__actions\">\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': queryListMode() !== 'live' || viewMode() !== 'query' }\"\n (click)=\"selectQueryListMode('live'); selectViewMode('query')\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Live Queries ({{ queries()?.length ?? 0 }})\n </button>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': queryListMode() !== 'history' || viewMode() !== 'query' }\"\n (click)=\"selectQueryListMode('history'); selectViewMode('query')\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Query History ({{ (queryHistory$ | async)?.length ?? 0 }}/50)\n </button>\n @if (queryListMode() === 'history' && viewMode() === 'query') {\n <div class=\"et-qd-queries__divider\"></div>\n <button (click)=\"clearQueryHistory()\" class=\"et-qd-chip et-qd-chip-bordered\">Clear history</button>\n }\n\n <div class=\"et-qd-queries__divider\"></div>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': viewMode() !== 'authProvider' }\"\n (click)=\"selectViewMode('authProvider')\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Auth Provider\n </button>\n </div>\n\n @if (viewMode() === 'query') {\n <div class=\"et-qd-queries__browser\">\n @if (queryListMode() === 'live') {\n <ul class=\"et-qd-queries__browser-list\">\n @for (query of queries(); track trackByQuery($index, query)) {\n <li>\n <button\n [class.et-qd-query--active]=\"selectedQuery()?._id === query._id\"\n (click)=\"selectQuery(query)\"\n >\n <span> {{ query._queryConfig.method }}</span>\n <span> {{ query | queryShortName }}</span>\n </button>\n </li>\n }\n </ul>\n }\n @if (queryListMode() === 'history') {\n <ul class=\"et-qd-queries__browser-list\">\n @for (query of queryHistory$ | async; track trackByQuery($index, query)) {\n <li>\n <button\n [class.et-qd-query--active]=\"selectedQuery()?._id === query._id\"\n (click)=\"selectQuery(query)\"\n >\n <span> {{ query._queryConfig.method }}</span>\n <span> {{ query | queryShortName }}</span>\n </button>\n </li>\n }\n </ul>\n }\n <div class=\"et-qd-queries__browser-detail\">\n @if (selectedQuery(); as query) {\n <p class=\"et-qd-queries__browser-detail__title\">\n {{ query._queryConfig.method }} {{ query._routeWithParams }}\n </p>\n\n <div class=\"et-qd-queries__actions\">\n <button (click)=\"query.execute()\" class=\"et-qd-chip et-qd-chip-bordered\">Execute</button>\n <button (click)=\"query.execute({ skipCache: true })\" class=\"et-qd-chip et-qd-chip-bordered\">\n Execute (ignore cache)\n </button>\n\n <button (click)=\"query.abort()\" class=\"et-qd-chip et-qd-chip-bordered\">Abort</button>\n <div class=\"et-qd-queries__divider\"></div>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': !query.isPolling }\"\n (click)=\"query.poll({ interval: 5000, takeUntil: _destroy$ })\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Poll\n </button>\n\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': query.isPolling }\"\n (click)=\"query.stopPolling()\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Stop polling\n </button>\n @if (query.isPolling || query._isPollingPaused) {\n <button (click)=\"query.pausePolling()\" class=\"et-qd-chip et-qd-chip-secondary et-qd-chip-bordered\">\n Pause polling\n </button>\n <button (click)=\"query.resumePolling()\" class=\"et-qd-chip et-qd-chip-secondary et-qd-chip-bordered\">\n Resume polling\n </button>\n }\n </div>\n\n <div class=\"et-qd-list\">\n <div class=\"et-qd-list-item\">\n <p>State type</p>\n <pre>{{ query.rawState.type }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Dependents</p>\n <pre>{{ query._dependents | json }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Is expired</p>\n <pre>{{ query.isExpired }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Is in use</p>\n <pre>{{ query.isInUse }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Subscriber count</p>\n <pre>{{ query._subscriberCount }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Is polling</p>\n <pre>{{ query.isPolling }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Is polling paused</p>\n <pre>{{ query._isPollingPaused }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Enable smart polling</p>\n <pre>{{ query._enableSmartPolling }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Query store key</p>\n <pre>{{ query._queryStoreKey }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Arguments</p>\n\n <div>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': !showArguments() }\"\n (click)=\"toggleShowArguments()\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Toggle\n </button>\n </div>\n @if (showArguments()) {\n <pre>{{ query._arguments | json }}</pre>\n }\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>State</p>\n <p><i> Warning, this will cause a subscription if shown!</i></p>\n <div>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': !showResponse() }\"\n (click)=\"toggleShowResponse()\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Toggle\n </button>\n </div>\n @if (showResponse()) {\n <pre>{{ query.state$ | async | json }}</pre>\n }\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Raw state</p>\n <p><i> The query state unaffected by entity stores</i></p>\n\n <div>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': !showRawResponse() }\"\n (click)=\"toggleShowRawResponse()\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Toggle\n </button>\n </div>\n @if (showRawResponse()) {\n <pre>{{ query.rawState | json }}</pre>\n }\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Query config</p>\n\n <div>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': !showQueryConfig() }\"\n (click)=\"toggleShowQueryConfig()\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Toggle\n </button>\n </div>\n @if (showQueryConfig()) {\n <pre>{{ stringifiedQueryConfig() | json }}</pre>\n }\n </div>\n\n @if (!!query._queryConfig.entity) {\n <div class=\"et-qd-list-item\">\n <p>Entity store value</p>\n\n <div>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': !showEntityStoreValue() }\"\n (click)=\"toggleShowEntityStoreValue()\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Toggle\n </button>\n </div>\n @if (showEntityStoreValue()) {\n <pre>{{ selectedQueryEntityStoreValue$ | async | json }}</pre>\n }\n </div>\n }\n </div>\n }\n </div>\n </div>\n } @else if (viewMode() === 'authProvider') {\n <div class=\"et-qd-auth-provider__viewer\">\n @if (authProviderDetails(); as details) {\n <div class=\"et-qd-list\">\n <div class=\"et-qd-list-item\">\n <p>Type</p>\n <pre>{{ details.type }}</pre>\n </div>\n <div class=\"et-qd-list-item\">\n <p>Header value</p>\n <pre>{{ details.header() | json }}</pre>\n </div>\n <div class=\"et-qd-list-item\">\n <p>Config</p>\n <pre>{{ details.config | json }}</pre>\n </div>\n\n @if (details.type === 'BearerAuthProvider') {\n <div class=\"et-qd-list-item\">\n <p>Tokens</p>\n <pre>{{ details.provider.tokens$ | async | json }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Should refresh on unauthorized response</p>\n <pre>{{ details.provider.shouldRefreshOnUnauthorizedResponse }}</pre>\n </div>\n\n <ng-container\n *etQuery=\"\n details.provider.currentRefreshQuery$ | async as response;\n loading as loading;\n error as error;\n query as query\n \"\n >\n <div class=\"et-qd-list-item\">\n <p>Refresh query response</p>\n\n <div>\n <button (click)=\"details.provider._refreshQuery()\" class=\"et-qd-chip et-qd-chip-bordered\">\n Refresh\n </button>\n </div>\n <pre>{{ response | json }}</pre>\n </div>\n <div class=\"et-qd-list-item\">\n <p>Refresh query loading</p>\n <pre>{{ loading }}</pre>\n </div>\n <div class=\"et-qd-list-item\">\n <p>Refresh query error</p>\n <pre>{{ error ?? 'null' }}</pre>\n </div>\n <div class=\"et-qd-list-item\">\n <p>State</p>\n <pre>{{ query?.state$ | async | json }}</pre>\n </div>\n </ng-container>\n }\n </div>\n } @else {\n <p>No auth provider set</p>\n }\n </div>\n }\n </div>\n }\n </div>\n}\n", styles: [":host{position:fixed;top:0;z-index:1000000;font-size:14px;color:#fff}.et-query-devtools-container{position:fixed;inset:0;background-color:#25292e;z-index:10000;overflow:auto;font-family:monospace;display:grid;grid-template-rows:auto auto auto minmax(0,1fr)}.et-query-devtools-container.et-query-devtools-container--transparent{opacity:.25;pointer-events:none}.et-query-devtools-container.et-query-devtools-container--transparent .et-query-devtools-translucent-btn{pointer-events:all}.et-query-devtools-container.et-query-devtools-container--snap-left{inset-inline-start:0;inset-block-start:0;inset-block-end:0;width:50%;border-right:1px solid rgb(37,41,46)}.et-query-devtools-container.et-query-devtools-container--snap-right{inset-inline-start:unset;inset-inline-end:0;inset-block-start:0;inset-block-end:0;width:50%;border-left:1px solid rgb(37,41,46)}.et-query-devtools-container.et-query-devtools-container--snap-top{inset-inline-start:0;inset-block-start:0;inset-inline-end:0;height:50%;border-bottom:1px solid rgb(37,41,46)}.et-query-devtools-container.et-query-devtools-container--snap-bottom{inset-inline-start:0;inset-block-start:unset;inset-block-end:0;inset-inline-end:0;height:50%;border-top:1px solid rgb(37,41,46)}button.et-query-devtools-open-btn{position:fixed;inset-inline-end:20px;inset-block-end:0;z-index:9999;font-family:monospace;border-radius:3px 3px 0 0;line-height:14px;font-size:12px}.et-qd-header{background-color:#00ffa1;padding:12px;display:grid;grid-template-columns:1fr auto auto;gap:12px;align-items:center}.et-qd-header__title{color:#25292e;margin:0;font-size:22px}.et-qd-header__select{display:grid;background-color:#25292e;border-radius:10px;overflow:hidden}.et-qd-header__select select{width:250px;color:#fff;padding:3px 10px 2px;border:none;background-color:#25292e;font-family:monospace}.et-qd-header__select label{padding:3px 10px;color:#25292e;font-size:12px;font-weight:700;color:#fff;border-bottom:1px solid gray}.et-qd-sub-header{background-color:#00b371;padding:12px;display:flex;gap:12px;flex-wrap:wrap}.et-qd-sub-header__divider{width:1px;background-color:#25292e}.et-qd-btn{background-color:#00ffa1;color:#25292e;border:none;padding:12px;cursor:pointer;font-size:14px;font-weight:700;text-align:center;text-decoration:none;display:inline-block;width:100%;transition:all .3s ease-in-out;font-family:monospace;border-radius:10px}.et-qd-btn:hover{background-color:#00cc81}.et-qd-btn.et-qd-btn-secondary{background-color:#25292e;color:#00ffa1}.et-qd-btn.et-qd-btn-secondary:hover{background-color:#3c424a}.et-qd-chip{background-color:#00ffa1;color:#25292e;border:none;padding:4px 9px;cursor:pointer;font-size:12px;font-weight:700;text-align:center;text-decoration:none;display:inline-block;transition:all .3s ease-in-out;font-family:monospace;border-radius:10px}.et-qd-chip:hover{background-color:#00cc81}.et-qd-chip.et-qd-chip-secondary{background-color:#25292e;color:#00ffa1}.et-qd-chip.et-qd-chip-secondary:hover{background-color:#3c424a}.et-qd-chip.et-qd-chip-bordered{border:1px solid rgb(0,255,161)}.et-qd-translucent-clickable{pointer-events:all}.et-qd-client{border-bottom:1px solid #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;grid-template-columns:auto minmax(0,1fr);gap:2px;display:block}.et-qd-queries__browser-list li button span{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.et-qd-queries__browser-list li button span:first-of-type{font-weight:700}.et-qd-queries__browser-list li button:hover,.et-qd-queries__browser-list li button.et-qd-query--active{background-color:#30363c}.et-qd-queries__browser-detail{padding:12px;overflow-y:auto;overflow-x:hidden}.et-qd-queries__browser-detail__title{margin:0;font-size:14px;color:#fff;font-weight:700}.et-qd-auth-provider__viewer{border-top:1px solid #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 }); }
2651
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.1.4", ngImport: i0, type: QueryDevtoolsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
2652
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.1.4", type: QueryDevtoolsComponent, isStandalone: true, selector: "et-query-devtools", host: { classAttribute: "et-query-devtools" }, ngImport: i0, template: "@if (!isOpen()) {\n <button (click)=\"toggleOpen()\" class=\"et-query-devtools-open-btn et-qd-chip\">Query Devtools</button>\n}\n\n@if (isOpen()) {\n <div\n [class.et-query-devtools-container--transparent]=\"isTranslucent()\"\n class=\"et-query-devtools-container et-query-devtools-container--snap-{{ snapLayout() }}\"\n >\n <header class=\"et-qd-header\">\n <h3 class=\"et-qd-header__title\">Query Devtools</h3>\n\n <div class=\"et-qd-header__select\">\n <label for=\"et-query-client-instance\">Client instance</label>\n <select [formControl]=\"selectedClientIdCtrl\" id=\"et-query-client-instance\">\n @for (clientConfig of queryClientConfigs; track trackByClient(i, clientConfig); let i = $index) {\n <option [value]=\"i\">\n {{ clientConfig.displayName ?? clientConfig.client.config.baseRoute }}\n </option>\n }\n </select>\n </div>\n\n <button (click)=\"toggleOpen()\" class=\"et-qd-btn et-qd-btn-secondary\">Close</button>\n </header>\n\n <div class=\"et-qd-sub-header\">\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': !isTranslucent() }\"\n (click)=\"toggleTranslucent()\"\n class=\"et-qd-chip et-qd-translucent-clickable\"\n >\n Translucent\n </button>\n <div class=\"et-qd-sub-header__divider\"></div>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': snapLayout() !== 'full' }\"\n (click)=\"selectSnapLayout('full')\"\n class=\"et-qd-chip\"\n >\n Fullscreen\n </button>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': snapLayout() !== 'top' }\"\n (click)=\"selectSnapLayout('top')\"\n class=\"et-qd-chip\"\n >\n Top\n </button>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': snapLayout() !== 'bottom' }\"\n (click)=\"selectSnapLayout('bottom')\"\n class=\"et-qd-chip\"\n >\n Bottom\n </button>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': snapLayout() !== 'left' }\"\n (click)=\"selectSnapLayout('left')\"\n class=\"et-qd-chip\"\n >\n Left\n </button>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': snapLayout() !== 'right' }\"\n (click)=\"selectSnapLayout('right')\"\n class=\"et-qd-chip\"\n >\n Right\n </button>\n </div>\n\n @if (selectedClientConfig(); as cfg) {\n <div class=\"et-qd-client\">\n <p class=\"et-qd-client__title\">{{ cfg.displayName ?? cfg.client.config.baseRoute }}</p>\n\n <div class=\"et-qd-client__actions\">\n <button (click)=\"cfg.client._store.refreshQueriesInUse()\" class=\"et-qd-chip\">Refresh all</button>\n <button (click)=\"cfg.client._store.refreshQueriesInUse({ ignoreCacheValidity: true })\" class=\"et-qd-chip\">\n Refresh all (ignore caches)\n </button>\n <button\n (click)=\"cfg.client._store.refreshQueriesInUse({ ignoreCacheValidity: true, purgeUnused: true })\"\n class=\"et-qd-chip\"\n >\n Refresh all (ignore caches & purge unused)\n </button>\n </div>\n </div>\n }\n\n @if (selectedClientConfig(); as cfg) {\n <div class=\"et-qd-queries\">\n <p class=\"et-qd-queries__title\">Inspector</p>\n <div class=\"et-qd-queries__actions\">\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': queryListMode() !== 'live' || viewMode() !== 'query' }\"\n (click)=\"selectQueryListMode('live'); selectViewMode('query')\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Live Queries ({{ queries()?.length ?? 0 }})\n </button>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': queryListMode() !== 'history' || viewMode() !== 'query' }\"\n (click)=\"selectQueryListMode('history'); selectViewMode('query')\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Query History ({{ (queryHistory$ | async)?.length ?? 0 }}/50)\n </button>\n @if (queryListMode() === 'history' && viewMode() === 'query') {\n <div class=\"et-qd-queries__divider\"></div>\n <button (click)=\"clearQueryHistory()\" class=\"et-qd-chip et-qd-chip-bordered\">Clear history</button>\n }\n\n <div class=\"et-qd-queries__divider\"></div>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': viewMode() !== 'authProvider' }\"\n (click)=\"selectViewMode('authProvider')\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Auth Provider\n </button>\n </div>\n\n @if (viewMode() === 'query') {\n <div class=\"et-qd-queries__browser\">\n @if (queryListMode() === 'live') {\n <ul class=\"et-qd-queries__browser-list\">\n @for (query of queries(); track trackByQuery($index, query)) {\n <li>\n <button\n [class.et-qd-query--active]=\"selectedQuery()?._id === query._id\"\n (click)=\"selectQuery(query)\"\n >\n <span> {{ query._queryConfig.method }}</span>\n <span> {{ query | queryShortName }}</span>\n </button>\n </li>\n }\n </ul>\n }\n @if (queryListMode() === 'history') {\n <ul class=\"et-qd-queries__browser-list\">\n @for (query of queryHistory$ | async; track trackByQuery($index, query)) {\n <li>\n <button\n [class.et-qd-query--active]=\"selectedQuery()?._id === query._id\"\n (click)=\"selectQuery(query)\"\n >\n <span> {{ query._queryConfig.method }}</span>\n <span> {{ query | queryShortName }}</span>\n </button>\n </li>\n }\n </ul>\n }\n <div class=\"et-qd-queries__browser-detail\">\n @if (selectedQuery(); as query) {\n <p class=\"et-qd-queries__browser-detail__title\">\n {{ query._queryConfig.method }} {{ query._routeWithParams }}\n </p>\n\n <div class=\"et-qd-queries__actions\">\n <button (click)=\"query.execute()\" class=\"et-qd-chip et-qd-chip-bordered\">Execute</button>\n <button (click)=\"query.execute({ skipCache: true })\" class=\"et-qd-chip et-qd-chip-bordered\">\n Execute (ignore cache)\n </button>\n\n <button (click)=\"query.abort()\" class=\"et-qd-chip et-qd-chip-bordered\">Abort</button>\n <div class=\"et-qd-queries__divider\"></div>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': !query.isPolling }\"\n (click)=\"query.poll({ interval: 5000, takeUntil: _destroy$ })\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Poll\n </button>\n\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': query.isPolling }\"\n (click)=\"query.stopPolling()\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Stop polling\n </button>\n @if (query.isPolling || query._isPollingPaused) {\n <button (click)=\"query.pausePolling()\" class=\"et-qd-chip et-qd-chip-secondary et-qd-chip-bordered\">\n Pause polling\n </button>\n <button (click)=\"query.resumePolling()\" class=\"et-qd-chip et-qd-chip-secondary et-qd-chip-bordered\">\n Resume polling\n </button>\n }\n </div>\n\n <div class=\"et-qd-list\">\n <div class=\"et-qd-list-item\">\n <p>State type</p>\n <pre>{{ query.rawState.type }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Dependents</p>\n <pre>{{ query._dependents | json }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Is expired</p>\n <pre>{{ query.isExpired }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Is in use</p>\n <pre>{{ query.isInUse }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Subscriber count</p>\n <pre>{{ query._subscriberCount }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Is polling</p>\n <pre>{{ query.isPolling }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Is polling paused</p>\n <pre>{{ query._isPollingPaused }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Enable smart polling</p>\n <pre>{{ query._enableSmartPolling }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Query store key</p>\n <pre>{{ query._queryStoreKey }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Arguments</p>\n\n <div>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': !showArguments() }\"\n (click)=\"toggleShowArguments()\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Toggle\n </button>\n </div>\n @if (showArguments()) {\n <pre>{{ query._arguments | json }}</pre>\n }\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>State</p>\n <p><i> Warning, this will cause a subscription if shown!</i></p>\n <div>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': !showResponse() }\"\n (click)=\"toggleShowResponse()\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Toggle\n </button>\n </div>\n @if (showResponse()) {\n <pre>{{ query.state$ | async | json }}</pre>\n }\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Raw state</p>\n <p><i> The query state unaffected by entity stores</i></p>\n\n <div>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': !showRawResponse() }\"\n (click)=\"toggleShowRawResponse()\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Toggle\n </button>\n </div>\n @if (showRawResponse()) {\n <pre>{{ query.rawState | json }}</pre>\n }\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Query config</p>\n\n <div>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': !showQueryConfig() }\"\n (click)=\"toggleShowQueryConfig()\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Toggle\n </button>\n </div>\n @if (showQueryConfig()) {\n <pre>{{ stringifiedQueryConfig() | json }}</pre>\n }\n </div>\n\n @if (!!query._queryConfig.entity) {\n <div class=\"et-qd-list-item\">\n <p>Entity store value</p>\n\n <div>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': !showEntityStoreValue() }\"\n (click)=\"toggleShowEntityStoreValue()\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Toggle\n </button>\n </div>\n @if (showEntityStoreValue()) {\n <pre>{{ selectedQueryEntityStoreValue$ | async | json }}</pre>\n }\n </div>\n }\n </div>\n }\n </div>\n </div>\n } @else if (viewMode() === 'authProvider') {\n <div class=\"et-qd-auth-provider__viewer\">\n @if (authProviderDetails(); as details) {\n <div class=\"et-qd-list\">\n <div class=\"et-qd-list-item\">\n <p>Type</p>\n <pre>{{ details.type }}</pre>\n </div>\n <div class=\"et-qd-list-item\">\n <p>Header value</p>\n <pre>{{ details.header() | json }}</pre>\n </div>\n <div class=\"et-qd-list-item\">\n <p>Config</p>\n <pre>{{ details.config | json }}</pre>\n </div>\n\n @if (details.type === 'BearerAuthProvider') {\n <div class=\"et-qd-list-item\">\n <p>Tokens</p>\n <pre>{{ details.provider.tokens$ | async | json }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Should refresh on unauthorized response</p>\n <pre>{{ details.provider.shouldRefreshOnUnauthorizedResponse }}</pre>\n </div>\n\n <ng-container\n *etQuery=\"\n details.provider.currentRefreshQuery$ | async as response;\n loading as loading;\n error as error;\n query as query\n \"\n >\n <div class=\"et-qd-list-item\">\n <p>Refresh query response</p>\n\n <div>\n <button (click)=\"details.provider._refreshQuery()\" class=\"et-qd-chip et-qd-chip-bordered\">\n Refresh\n </button>\n </div>\n <pre>{{ response | json }}</pre>\n </div>\n <div class=\"et-qd-list-item\">\n <p>Refresh query loading</p>\n <pre>{{ loading }}</pre>\n </div>\n <div class=\"et-qd-list-item\">\n <p>Refresh query error</p>\n <pre>{{ error ?? 'null' }}</pre>\n </div>\n <div class=\"et-qd-list-item\">\n <p>State</p>\n <pre>{{ query?.state$ | async | json }}</pre>\n </div>\n </ng-container>\n }\n </div>\n } @else {\n <p>No auth provider set</p>\n }\n </div>\n }\n </div>\n }\n </div>\n}\n", styles: [":host{position:fixed;top:0;z-index:1000000;font-size:14px;color:#fff}.et-query-devtools-container{position:fixed;inset:0;background-color:#25292e;z-index:10000;overflow:auto;font-family:monospace;display:grid;grid-template-rows:auto auto auto minmax(0,1fr)}.et-query-devtools-container.et-query-devtools-container--transparent{opacity:.25;pointer-events:none}.et-query-devtools-container.et-query-devtools-container--transparent .et-query-devtools-translucent-btn{pointer-events:all}.et-query-devtools-container.et-query-devtools-container--snap-left{inset-inline-start:0;inset-block-start:0;inset-block-end:0;width:50%;border-right:1px solid rgb(37,41,46)}.et-query-devtools-container.et-query-devtools-container--snap-right{inset-inline-start:unset;inset-inline-end:0;inset-block-start:0;inset-block-end:0;width:50%;border-left:1px solid rgb(37,41,46)}.et-query-devtools-container.et-query-devtools-container--snap-top{inset-inline-start:0;inset-block-start:0;inset-inline-end:0;height:50%;border-bottom:1px solid rgb(37,41,46)}.et-query-devtools-container.et-query-devtools-container--snap-bottom{inset-inline-start:0;inset-block-start:unset;inset-block-end:0;inset-inline-end:0;height:50%;border-top:1px solid rgb(37,41,46)}button.et-query-devtools-open-btn{position:fixed;inset-inline-end:20px;inset-block-end:0;z-index:9999;font-family:monospace;border-radius:3px 3px 0 0;line-height:14px;font-size:12px}.et-qd-header{background-color:#00ffa1;padding:12px;display:grid;grid-template-columns:1fr auto auto;gap:12px;align-items:center}.et-qd-header__title{color:#25292e;margin:0;font-size:22px}.et-qd-header__select{display:grid;background-color:#25292e;border-radius:10px;overflow:hidden}.et-qd-header__select select{width:250px;color:#fff;padding:3px 10px 2px;border:none;background-color:#25292e;font-family:monospace}.et-qd-header__select label{padding:3px 10px;color:#25292e;font-size:12px;font-weight:700;color:#fff;border-bottom:1px solid gray}.et-qd-sub-header{background-color:#00b371;padding:12px;display:flex;gap:12px;flex-wrap:wrap}.et-qd-sub-header__divider{width:1px;background-color:#25292e}.et-qd-btn{background-color:#00ffa1;color:#25292e;border:none;padding:12px;cursor:pointer;font-size:14px;font-weight:700;text-align:center;text-decoration:none;display:inline-block;width:100%;transition:all .3s ease-in-out;font-family:monospace;border-radius:10px}.et-qd-btn:hover{background-color:#00cc81}.et-qd-btn.et-qd-btn-secondary{background-color:#25292e;color:#00ffa1}.et-qd-btn.et-qd-btn-secondary:hover{background-color:#3c424a}.et-qd-chip{background-color:#00ffa1;color:#25292e;border:none;padding:4px 9px;cursor:pointer;font-size:12px;font-weight:700;text-align:center;text-decoration:none;display:inline-block;transition:all .3s ease-in-out;font-family:monospace;border-radius:10px}.et-qd-chip:hover{background-color:#00cc81}.et-qd-chip.et-qd-chip-secondary{background-color:#25292e;color:#00ffa1}.et-qd-chip.et-qd-chip-secondary:hover{background-color:#3c424a}.et-qd-chip.et-qd-chip-bordered{border:1px solid rgb(0,255,161)}.et-qd-translucent-clickable{pointer-events:all}.et-qd-client{border-bottom:1px solid #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;grid-template-columns:auto minmax(0,1fr);gap:2px;display:block}.et-qd-queries__browser-list li button span{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.et-qd-queries__browser-list li button span:first-of-type{font-weight:700}.et-qd-queries__browser-list li button:hover,.et-qd-queries__browser-list li button.et-qd-query--active{background-color:#30363c}.et-qd-queries__browser-detail{padding:12px;overflow-y:auto;overflow-x:hidden}.et-qd-queries__browser-detail__title{margin:0;font-size:14px;color:#fff;font-weight:700}.et-qd-auth-provider__viewer{border-top:1px solid #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 }); }
2651
2653
  }
2652
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.1.1", ngImport: i0, type: QueryDevtoolsComponent, decorators: [{
2654
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.1.4", ngImport: i0, type: QueryDevtoolsComponent, decorators: [{
2653
2655
  type: Component,
2654
2656
  args: [{ selector: 'et-query-devtools', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.ShadowDom, host: {
2655
2657
  class: 'et-query-devtools',
@@ -2810,6 +2812,1265 @@ const removeFrom = (store, { where, id }) => {
2810
2812
  .subscribe();
2811
2813
  };
2812
2814
 
2815
+ /* eslint-disable @typescript-eslint/no-empty-function */
2816
+ const queryFeatureUsedMultipleTimes = (type) => {
2817
+ return new RuntimeError(0 /* RuntimeErrorCode.QUERY_FEATURE_USED_MULTIPLE_TIMES */, `The query feature "${type}()" was used multiple times.`);
2818
+ };
2819
+ const withArgsQueryFeatureMissingButRouteIsFunction = () => {
2820
+ return new RuntimeError(100 /* RuntimeErrorCode.WITH_ARGS_QUERY_FEATURE_MISSING_BUT_ROUTE_IS_FUNCTION */, `This queries route is a function, but a "withArgs()" feature is missing.`);
2821
+ };
2822
+ const withPollingUsedOnUnsupportedHttpMethod = (method) => {
2823
+ return new RuntimeError(101 /* RuntimeErrorCode.WITH_POLLING_USED_ON_UNSUPPORTED_HTTP_METHOD */, `This is a "${method}" request, "withPolling()" is only supported for GET, HEAD, OPTIONS requests and GQL queries.`);
2824
+ };
2825
+ const withAutoRefreshUsedOnUnsupportedHttpMethod = (method) => {
2826
+ return new RuntimeError(102 /* RuntimeErrorCode.WITH_AUTO_REFRESH_USED_ON_UNSUPPORTED_HTTP_METHOD */, `This is a "${method}" request, "withAutoRefresh()" is only supported for GET, HEAD, OPTIONS requests and GQL queries.`);
2827
+ };
2828
+ const withAutoRefreshUsedInManualQuery = () => {
2829
+ return new RuntimeError(103 /* RuntimeErrorCode.WITH_AUTO_REFRESH_USED_IN_MANUAL_QUERY */, `"withAutoRefresh()" has been used inside a query that has "onlyManualExecution" set to true.` +
2830
+ ` If this is intentional, set "ignoreOnlyManualExecution" to true inside the auto refresh config.`);
2831
+ };
2832
+ const cookieLoginTriedButCookieDisabled = () => {
2833
+ return new RuntimeError(200 /* RuntimeErrorCode.COOKIE_LOGIN_TRIED_BUT_COOKIE_DISABLED */, `Cookie login has been tried, but the cookie is disabled.`);
2834
+ };
2835
+ const enableCookieCalledWithoutCookieConfig = () => {
2836
+ return new RuntimeError(201 /* RuntimeErrorCode.ENABLE_COOKIE_CALLED_WITHOUT_COOKIE_CONFIG */, `enableCookie() has been called but there is no cookie config. Please set it during the auth provider creation.`);
2837
+ };
2838
+ const disableCookieCalledWithoutCookieConfig = () => {
2839
+ return new RuntimeError(202 /* RuntimeErrorCode.DISABLE_COOKIE_CALLED_WITHOUT_COOKIE_CONFIG */, `disableCookie() has been called but there is no cookie config. Please set it during the auth provider creation.`);
2840
+ };
2841
+ const loginCalledWithoutConfig = () => {
2842
+ return new RuntimeError(203 /* RuntimeErrorCode.LOGIN_CALLED_WITHOUT_CONFIG */, `login() has been called without a config. Please set it during the auth provider creation.`);
2843
+ };
2844
+ const loginWithTokenCalledWithoutConfig = () => {
2845
+ return new RuntimeError(204 /* RuntimeErrorCode.LOGIN_WITH_TOKEN_CALLED_WITHOUT_CONFIG */, `loginWithToken() has been called without a config. Please set it during the auth provider creation.`);
2846
+ };
2847
+ const refreshTokenCalledWithoutConfig = () => {
2848
+ return new RuntimeError(205 /* RuntimeErrorCode.REFRESH_TOKEN_CALLED_WITHOUT_CONFIG */, `refreshToken() has been called without a config. Please set it during the auth provider creation.`);
2849
+ };
2850
+ const selectRoleCalledWithoutConfig = () => {
2851
+ return new RuntimeError(206 /* RuntimeErrorCode.SELECT_ROLE_CALLED_WITHOUT_CONFIG */, `selectRole() has been called without a config. Please set it during the auth provider creation.`);
2852
+ };
2853
+ const defaultResponseTransformerResponseNotObject = (currentType) => {
2854
+ return new RuntimeError(207 /* RuntimeErrorCode.DEFAULT_RESPONSE_TRANSFORMER_RESPONSE_NOT_OBJECT */, `The default response transformer expects the response to be an object, but it is a "${currentType}".`);
2855
+ };
2856
+ const defaultResponseTransformerResponseNotContainingAccessToken = () => {
2857
+ return new RuntimeError(208 /* RuntimeErrorCode.DEFAULT_RESPONSE_TRANSFORMER_RESPONSE_NOT_CONTAINING_ACCESS_TOKEN */, `The default response transformer expects the response to contain an "accessToken" property.`);
2858
+ };
2859
+ const defaultResponseTransformerResponseNotContainingRefreshToken = () => {
2860
+ return new RuntimeError(209 /* RuntimeErrorCode.DEFAULT_RESPONSE_TRANSFORMER_RESPONSE_NOT_CONTAINING_REFRESH_TOKEN */, `The default response transformer expects the response to contain a "refreshToken" property.`);
2861
+ };
2862
+ const unableToDecryptBearerToken = (token) => {
2863
+ return new RuntimeError(210 /* RuntimeErrorCode.UNABLE_TO_DECRYPT_BEARER_TOKEN */, `The bearer token could not be decrypted: ${token}`);
2864
+ };
2865
+ const bearerExpiresInPropertyNotNumber = (expiresIn) => {
2866
+ return new RuntimeError(211 /* RuntimeErrorCode.BEARER_EXPIRES_IN_PROPERTY_NOT_NUMBER */, `The expires in property is not a number: ${expiresIn}`);
2867
+ };
2868
+
2869
+ /* eslint-disable @typescript-eslint/no-empty-function */
2870
+ const defaultResponseTransformer = (response) => {
2871
+ if (!isObject(response)) {
2872
+ throw defaultResponseTransformerResponseNotObject(typeof response);
2873
+ }
2874
+ if (!('accessToken' in response)) {
2875
+ throw defaultResponseTransformerResponseNotContainingAccessToken();
2876
+ }
2877
+ if (!('refreshToken' in response)) {
2878
+ throw defaultResponseTransformerResponseNotContainingRefreshToken();
2879
+ }
2880
+ return response;
2881
+ };
2882
+ const FIVE_MINUTES = 5 * 60 * 1000;
2883
+ const createAuthProviderQuery = (config, authProviderConfig) => {
2884
+ const query = config.queryCreator();
2885
+ const triggeredInternally = signal(false);
2886
+ const tokens = computed(() => {
2887
+ const res = query.response();
2888
+ if (!res)
2889
+ return null;
2890
+ const transformed = config.responseTransformer?.(res) ?? defaultResponseTransformer(res);
2891
+ const bearerValue = decryptBearer(transformed.accessToken);
2892
+ if (!bearerValue)
2893
+ throw unableToDecryptBearerToken(transformed.accessToken);
2894
+ return {
2895
+ bearer: bearerValue,
2896
+ tokens: transformed,
2897
+ };
2898
+ });
2899
+ const expiresIn = computed(() => {
2900
+ const res = tokens();
2901
+ if (!res)
2902
+ return null;
2903
+ const expiresIn = res.bearer[authProviderConfig.expiresInPropertyName ?? 'exp'];
2904
+ const refreshBuffer = authProviderConfig.refreshBuffer ?? FIVE_MINUTES;
2905
+ if (typeof expiresIn !== 'number') {
2906
+ throw bearerExpiresInPropertyNotNumber(expiresIn);
2907
+ }
2908
+ // const dummyRemainingTime = (query.lastTimeExecutedAt() ?? 0) + 5000 - new Date().getTime();
2909
+ const remainingTime = new Date(expiresIn * 1000).getTime() - refreshBuffer - new Date().getTime();
2910
+ return remainingTime;
2911
+ });
2912
+ const execute = (newArgs, options) => {
2913
+ query.execute(newArgs);
2914
+ triggeredInternally.set(options?.triggeredInternally ?? false);
2915
+ };
2916
+ return {
2917
+ execute,
2918
+ query,
2919
+ tokens,
2920
+ expiresIn,
2921
+ triggeredInternally: triggeredInternally.asReadonly(),
2922
+ };
2923
+ };
2924
+ const createBearerAuthProvider = (options) => {
2925
+ const cookieEnabled = signal(options.cookie === undefined ? false : (options.cookie.enabled ?? true));
2926
+ const cookieOptions = {
2927
+ expiresInDays: 30,
2928
+ name: 'etAuth',
2929
+ path: '/',
2930
+ sameSite: 'lax',
2931
+ domain: getDomain() ?? 'localhost',
2932
+ refreshArgsTransformer: (token) => ({ body: { token } }),
2933
+ ...(options.cookie ?? {}),
2934
+ };
2935
+ const loginQuery = options.login ? createAuthProviderQuery(options.login, options) : null;
2936
+ const tokenLoginQuery = options.tokenLogin ? createAuthProviderQuery(options.tokenLogin, options) : null;
2937
+ const tokenRefreshQuery = options.tokenRefresh ? createAuthProviderQuery(options.tokenRefresh, options) : null;
2938
+ const selectRoleQuery = options.selectRole ? createAuthProviderQuery(options.selectRole, options) : null;
2939
+ const queries = [
2940
+ { type: 'login', query: loginQuery },
2941
+ { type: 'tokenLogin', query: tokenLoginQuery },
2942
+ { type: 'tokenRefresh', query: tokenRefreshQuery },
2943
+ { type: 'selectRole', query: selectRoleQuery },
2944
+ ];
2945
+ const latestExecutedQuery = computed(() => {
2946
+ const relevantQueries = queries.filter((q) => q.query && q.query.query.lastTimeExecutedAt() !== null);
2947
+ return findMostRecentQuery(relevantQueries);
2948
+ });
2949
+ const tokens = computed(() => {
2950
+ const query = latestExecutedQuery();
2951
+ return query?.query?.tokens()?.tokens ?? null;
2952
+ });
2953
+ toObservable(computed(() => {
2954
+ const query = latestExecutedQuery();
2955
+ const expiresIn = query?.query?.expiresIn() ?? null;
2956
+ const tokens = query?.query?.tokens() ?? null;
2957
+ return { expiresIn, tokens, query };
2958
+ }))
2959
+ .pipe(switchMap((res) => {
2960
+ if (!res.tokens || res.expiresIn === null || !options.tokenRefresh)
2961
+ return of(null);
2962
+ const expIn = res.expiresIn;
2963
+ const tokens = res.tokens;
2964
+ if (!expIn || !tokens)
2965
+ return of(null);
2966
+ return timer(expIn).pipe(tap(() => refreshToken({
2967
+ ...cookieOptions.refreshArgsTransformer(tokens.tokens.refreshToken),
2968
+ }, { triggeredInternally: true })));
2969
+ }), takeUntilDestroyed())
2970
+ .subscribe();
2971
+ const latestNonInternalQuery = signal(null);
2972
+ effect(() => {
2973
+ const relevantQueries = queries.filter((q) => q.query && !q.query.triggeredInternally() && q.query.query.lastTimeExecutedAt() !== null);
2974
+ const lastQuery = findMostRecentQuery(relevantQueries);
2975
+ untracked(() => {
2976
+ if (!lastQuery || !lastQuery.query?.query)
2977
+ return;
2978
+ latestNonInternalQuery.set({
2979
+ type: lastQuery.type,
2980
+ ...lastQuery.query.query.createSnapshot(),
2981
+ });
2982
+ });
2983
+ });
2984
+ // Cookie writing
2985
+ effect(() => {
2986
+ const isCookieEnabled = cookieEnabled();
2987
+ const res = latestExecutedQuery();
2988
+ const error = res?.query?.query.error();
2989
+ if (!isCookieEnabled || (error && error.status === 401)) {
2990
+ deleteCookie$1();
2991
+ return;
2992
+ }
2993
+ if (!res?.query)
2994
+ return;
2995
+ const { tokens } = res.query;
2996
+ const rt = tokens()?.tokens.refreshToken;
2997
+ if (!rt)
2998
+ return;
2999
+ writeCookie(rt);
3000
+ });
3001
+ const login = (args) => {
3002
+ if (!loginQuery) {
3003
+ throw loginCalledWithoutConfig();
3004
+ }
3005
+ loginQuery.execute(args);
3006
+ return loginQuery.query.createSnapshot();
3007
+ };
3008
+ const loginWithToken = (args) => {
3009
+ if (!tokenLoginQuery) {
3010
+ throw loginWithTokenCalledWithoutConfig();
3011
+ }
3012
+ tokenLoginQuery.execute(args);
3013
+ return tokenLoginQuery.query.createSnapshot();
3014
+ };
3015
+ const refreshToken = (args, options) => {
3016
+ if (!tokenRefreshQuery) {
3017
+ throw refreshTokenCalledWithoutConfig();
3018
+ }
3019
+ tokenRefreshQuery.execute(args, { triggeredInternally: options?.triggeredInternally });
3020
+ return tokenRefreshQuery.query.createSnapshot();
3021
+ };
3022
+ const selectRole = (args) => {
3023
+ if (!selectRoleQuery) {
3024
+ throw selectRoleCalledWithoutConfig();
3025
+ }
3026
+ selectRoleQuery.execute(args);
3027
+ return selectRoleQuery.query.createSnapshot();
3028
+ };
3029
+ const logout = () => {
3030
+ deleteCookie$1();
3031
+ loginQuery?.query.execute.reset();
3032
+ tokenLoginQuery?.query.execute.reset();
3033
+ tokenRefreshQuery?.query.execute.reset();
3034
+ selectRoleQuery?.query.execute.reset();
3035
+ latestNonInternalQuery.set(null);
3036
+ };
3037
+ const enableCookie = () => {
3038
+ if (isDevMode() && !options.cookie) {
3039
+ throw enableCookieCalledWithoutCookieConfig();
3040
+ }
3041
+ cookieEnabled.set(true);
3042
+ };
3043
+ const disableCookie = () => {
3044
+ if (isDevMode() && !options.cookie) {
3045
+ throw disableCookieCalledWithoutCookieConfig();
3046
+ }
3047
+ cookieEnabled.set(false);
3048
+ deleteCookie$1();
3049
+ };
3050
+ const tryLoginWithCookie = () => {
3051
+ const isCookieEnabled = cookieEnabled();
3052
+ if (!isCookieEnabled) {
3053
+ if (isDevMode()) {
3054
+ throw cookieLoginTriedButCookieDisabled();
3055
+ }
3056
+ return false;
3057
+ }
3058
+ const cookie = getCookie(cookieOptions.name);
3059
+ if (!cookie) {
3060
+ return false;
3061
+ }
3062
+ refreshToken(cookieOptions.refreshArgsTransformer(cookie));
3063
+ return true;
3064
+ };
3065
+ const writeCookie = (refreshToken) => {
3066
+ const { name, expiresInDays, domain, path, sameSite } = cookieOptions;
3067
+ setCookie(name, refreshToken, expiresInDays, domain, path, sameSite);
3068
+ };
3069
+ const deleteCookie$1 = () => {
3070
+ const { name, path, domain } = cookieOptions;
3071
+ deleteCookie(name, path, domain);
3072
+ };
3073
+ const findMostRecentQuery = (queriesToSearch) => {
3074
+ return queriesToSearch.reduce((acc, curr) => {
3075
+ if (!acc)
3076
+ return curr;
3077
+ const accExp = acc.query?.query.lastTimeExecutedAt() ?? null;
3078
+ const currExp = curr.query?.query.lastTimeExecutedAt() ?? null;
3079
+ if (currExp === null || accExp === null)
3080
+ return acc;
3081
+ return accExp > currExp ? acc : curr;
3082
+ }, null);
3083
+ };
3084
+ const bearerAuthProvider = {
3085
+ login,
3086
+ loginWithToken,
3087
+ refreshToken,
3088
+ selectRole,
3089
+ logout,
3090
+ enableCookie,
3091
+ disableCookie,
3092
+ tryLoginWithCookie,
3093
+ latestExecutedQuery: latestNonInternalQuery.asReadonly(),
3094
+ tokens,
3095
+ };
3096
+ if (cookieEnabled()) {
3097
+ tryLoginWithCookie();
3098
+ }
3099
+ return bearerAuthProvider;
3100
+ };
3101
+ const provideBearerAuthProvider = (config) => {
3102
+ return {
3103
+ provide: config.token,
3104
+ useFactory: () => createBearerAuthProvider(config),
3105
+ };
3106
+ };
3107
+
3108
+ const createBearerAuthProviderConfig = (options) => {
3109
+ const token = new InjectionToken(`BearerAuthProvider_${options.name}`);
3110
+ const bearerAuthProviderConfig = {
3111
+ name: options.name,
3112
+ queryClientRef: options.queryClientRef,
3113
+ token,
3114
+ cookie: options.cookie,
3115
+ expiresInPropertyName: options.expiresInPropertyName ?? 'exp',
3116
+ refreshBuffer: options.refreshBuffer ?? 300000,
3117
+ refreshOnUnauthorizedResponse: options.refreshOnUnauthorizedResponse ?? true,
3118
+ login: options.login,
3119
+ selectRole: options.selectRole,
3120
+ tokenLogin: options.tokenLogin,
3121
+ tokenRefresh: options.tokenRefresh,
3122
+ };
3123
+ return bearerAuthProviderConfig;
3124
+ };
3125
+
3126
+ /* eslint-disable @typescript-eslint/no-empty-function */
3127
+ /**
3128
+ * Returning this inside e.g. a withComputedArgs feature will reset the query args to null.
3129
+ * This will also pause polling and auto refresh until new args are set.
3130
+ */
3131
+ const QUERY_ARGS_RESET = Symbol('QUERY_ARGS_RESET');
3132
+ const QUERY_EFFECT_ERROR_MESSAGE = 'Effect triggered too often. This is probably due to a circular dependency inside the query.';
3133
+ /** A angular effect that will throw an error in dev mode if it is called too often. This indicates a circular dependency inside the effect. */
3134
+ const queryEffect = (fn, errorMessage, options) => {
3135
+ let lastTriggerTs = 0;
3136
+ let illegalWrites = 0;
3137
+ effect(() => {
3138
+ if (isDevMode()) {
3139
+ const now = performance.now();
3140
+ if (now - lastTriggerTs < 100) {
3141
+ illegalWrites++;
3142
+ if (illegalWrites > 5) {
3143
+ throw new Error(errorMessage);
3144
+ }
3145
+ }
3146
+ lastTriggerTs = now;
3147
+ }
3148
+ fn();
3149
+ }, options);
3150
+ };
3151
+ const shouldAutoExecuteQuery = (method) => {
3152
+ return method === 'GET' || method === 'HEAD' || method === 'OPTIONS';
3153
+ };
3154
+ const extractExpiresInSeconds = (headers) => {
3155
+ const cacheControl = headers.get('cache-control');
3156
+ const age = headers.get('age');
3157
+ const expires = headers.get('expires');
3158
+ // In seconds
3159
+ let expiresIn = null;
3160
+ let maxAge = null;
3161
+ if (cacheControl?.includes('no-cache')) {
3162
+ return null;
3163
+ }
3164
+ if (cacheControl?.includes('max-age')) {
3165
+ const m = cacheControl.split('max-age=')[1];
3166
+ if (m) {
3167
+ maxAge = parseInt(m);
3168
+ }
3169
+ }
3170
+ else if (cacheControl?.includes('s-maxage')) {
3171
+ const m = cacheControl.split('s-maxage=')[1];
3172
+ if (m) {
3173
+ maxAge = parseInt(m);
3174
+ }
3175
+ }
3176
+ if (maxAge && age) {
3177
+ const ageSeconds = parseInt(age);
3178
+ expiresIn = maxAge - ageSeconds;
3179
+ }
3180
+ else if (maxAge) {
3181
+ expiresIn = maxAge / 2; // We assume the response is half way to its expiration
3182
+ }
3183
+ else if (expires) {
3184
+ // Used by some apis to tell the response will never expire
3185
+ // In this case we let the response expire after 1 hour
3186
+ if (expires === '-1') {
3187
+ expiresIn = 3600;
3188
+ }
3189
+ else {
3190
+ const expiresDate = new Date(expires);
3191
+ // check if the date is valid
3192
+ if (expiresDate.toString() !== 'Invalid Date') {
3193
+ expiresIn = Math.floor((expiresDate.getTime() - Date.now()) / 1000);
3194
+ }
3195
+ }
3196
+ }
3197
+ return expiresIn;
3198
+ };
3199
+ const shouldRetryRequest = (options) => {
3200
+ const { retryCount, error } = options;
3201
+ const defaultRetryDelay = 1000 + 1000 * retryCount;
3202
+ if (retryCount > 3) {
3203
+ return { retry: false };
3204
+ }
3205
+ if (!(error instanceof HttpErrorResponse)) {
3206
+ return { retry: false };
3207
+ }
3208
+ const { status, error: detail, headers } = error;
3209
+ // Retry on 5xx errors
3210
+ if (status >= 500) {
3211
+ // Don't retry if a requested page is out of range
3212
+ if (isSymfonyPagerfantaOutOfRangeError(detail)) {
3213
+ return { retry: false };
3214
+ }
3215
+ return { retry: true, delay: defaultRetryDelay };
3216
+ }
3217
+ // Retry on 408 or 425 errors
3218
+ if (status === HttpStatusCode.RequestTimeout || status === HttpStatusCode.TooEarly) {
3219
+ return { retry: true, delay: defaultRetryDelay };
3220
+ }
3221
+ // Retry on 429 errors
3222
+ if (status === HttpStatusCode.TooManyRequests) {
3223
+ const retryAfter = headers.get('retry-after') || headers.get('x-retry-after');
3224
+ if (retryAfter) {
3225
+ const delay = parseInt(retryAfter) * 1000;
3226
+ return { retry: true, delay: Number.isNaN(delay) ? defaultRetryDelay : delay };
3227
+ }
3228
+ return { retry: true, delay: defaultRetryDelay };
3229
+ }
3230
+ // Code 0 usually means the internet connection is down. We retry in this case.
3231
+ // It could also be a CORS issue but that should not be the case in production.
3232
+ if (status === 0) {
3233
+ return { retry: true, delay: defaultRetryDelay };
3234
+ }
3235
+ return { retry: false };
3236
+ };
3237
+ const getQueryFeatureUsage = (options) => {
3238
+ const { creator, creatorInternals, features, queryConfig } = options;
3239
+ const hasWithArgsFeature = features.some((f) => f.type == "withArgs" /* QueryFeatureType.WithArgs */);
3240
+ const shouldAutoExecuteMethod = shouldAutoExecuteQuery(creatorInternals.method);
3241
+ const shouldAutoExecute = shouldAutoExecuteMethod && !queryConfig.onlyManualExecution;
3242
+ const hasRouteFunction = typeof creator.route === 'function';
3243
+ if (hasRouteFunction && !hasWithArgsFeature) {
3244
+ throw withArgsQueryFeatureMissingButRouteIsFunction();
3245
+ }
3246
+ const featureFnContext = {
3247
+ hasWithArgsFeature,
3248
+ shouldAutoExecuteMethod,
3249
+ shouldAutoExecute,
3250
+ hasRouteFunction,
3251
+ };
3252
+ return featureFnContext;
3253
+ };
3254
+ const applyQueryFeatures = (options, context) => {
3255
+ const featureTypes = new Set();
3256
+ for (const feature of options.features) {
3257
+ if (featureTypes.has(feature.type)) {
3258
+ throw queryFeatureUsedMultipleTimes(feature.type);
3259
+ }
3260
+ featureTypes.add(feature.type);
3261
+ feature.fn(context);
3262
+ }
3263
+ };
3264
+ const maybeExecute = (options) => {
3265
+ if (options.flags.shouldAutoExecute && !options.flags.hasRouteFunction && !options.flags.hasWithArgsFeature) {
3266
+ options.execute();
3267
+ }
3268
+ };
3269
+
3270
+ /* eslint-disable @typescript-eslint/no-empty-function */
3271
+ const SPEED_BUFFER_TIME_IN_MS = 2000;
3272
+ const createHttpRequest = (options) => {
3273
+ let currentStreamSubscription = Subscription.EMPTY;
3274
+ const currentEvent = signal(null);
3275
+ const loading = signal(null);
3276
+ const error = signal(null);
3277
+ const response = signal(null);
3278
+ const lastLoadEventTime = signal(0);
3279
+ const lastLoadEventAmount = signal(0);
3280
+ const lastExecuteTime = signal(0);
3281
+ const expiresIn = signal(null);
3282
+ const isStale = computed(() => {
3283
+ const expiresInTs = expiresIn();
3284
+ return expiresInTs === null || expiresInTs < Date.now();
3285
+ });
3286
+ const stream = options.httpClient
3287
+ .request(options.method, options.fullPath, {
3288
+ observe: 'events',
3289
+ body: options.body,
3290
+ reportProgress: options.reportProgress,
3291
+ withCredentials: options.withCredentials,
3292
+ transferCache: options.transferCache,
3293
+ responseType: options.responseType || 'json',
3294
+ context: options.context,
3295
+ headers: options.headers,
3296
+ })
3297
+ .pipe(tap((event) => updateState(event)), retry({
3298
+ delay: (error, retryCount) => {
3299
+ const retryOptions = { error, retryCount };
3300
+ const retryResult = options.retryFn?.(retryOptions) || shouldRetryRequest(retryOptions);
3301
+ if (!retryResult.retry) {
3302
+ return throwError(() => error);
3303
+ }
3304
+ return timer(retryResult.delay);
3305
+ },
3306
+ }), catchError((e) => {
3307
+ updateErrorState(e);
3308
+ return throwError(() => e);
3309
+ }));
3310
+ const execute = () => {
3311
+ if (loading() || !isStale()) {
3312
+ // Do not execute if there is already a request in progress or the request is not stale
3313
+ return false;
3314
+ }
3315
+ currentStreamSubscription.unsubscribe();
3316
+ lastExecuteTime.set(Date.now());
3317
+ lastLoadEventTime.set(lastExecuteTime());
3318
+ loading.set({
3319
+ executeTime: lastExecuteTime(),
3320
+ progress: null,
3321
+ });
3322
+ error.set(null);
3323
+ expiresIn.set(null);
3324
+ currentStreamSubscription = stream.subscribe();
3325
+ return true;
3326
+ };
3327
+ const destroy = () => {
3328
+ if (currentStreamSubscription.closed) {
3329
+ return false;
3330
+ }
3331
+ currentStreamSubscription.unsubscribe();
3332
+ return true;
3333
+ };
3334
+ const updateState = (event) => {
3335
+ currentEvent.set(event);
3336
+ switch (event.type) {
3337
+ case HttpEventType.Response:
3338
+ {
3339
+ loading.set(null);
3340
+ response.set(event.body);
3341
+ const expiresInSeconds = options.cacheAdapter
3342
+ ? options.cacheAdapter(event.headers)
3343
+ : extractExpiresInSeconds(event.headers);
3344
+ const expiresInTimestamp = buildTimestampFromSeconds(expiresInSeconds);
3345
+ expiresIn.set(expiresInTimestamp);
3346
+ }
3347
+ break;
3348
+ case HttpEventType.UploadProgress:
3349
+ case HttpEventType.DownloadProgress:
3350
+ {
3351
+ updateLoadingState(event);
3352
+ }
3353
+ break;
3354
+ case HttpEventType.Sent:
3355
+ case HttpEventType.ResponseHeader:
3356
+ case HttpEventType.User:
3357
+ {
3358
+ // we don't care about these events
3359
+ }
3360
+ break;
3361
+ }
3362
+ };
3363
+ const updateErrorState = (errorResponse) => {
3364
+ let err = errorResponse instanceof HttpErrorResponse ? errorResponse : null;
3365
+ if (!err) {
3366
+ err = new HttpErrorResponse({
3367
+ error: errorResponse,
3368
+ status: 0,
3369
+ statusText: 'Unknown Error',
3370
+ });
3371
+ }
3372
+ error.set(err);
3373
+ loading.set(null);
3374
+ currentEvent.set({ type: 'error', error: err });
3375
+ };
3376
+ const updateLoadingState = (event) => {
3377
+ if (event.total === undefined) {
3378
+ return;
3379
+ }
3380
+ const progress = {
3381
+ total: event.total,
3382
+ loaded: event.loaded,
3383
+ percentage: (event.loaded / event.total) * 100,
3384
+ speed: null,
3385
+ remainingTime: null,
3386
+ };
3387
+ const state = {
3388
+ executeTime: lastExecuteTime(),
3389
+ progress,
3390
+ };
3391
+ const currentTime = Date.now();
3392
+ const elapsedTimeSinceLastEvent = currentTime - lastLoadEventTime();
3393
+ const elapsedTimeSinceLastExecute = currentTime - lastExecuteTime();
3394
+ const loadedAmount = event.loaded - lastLoadEventAmount();
3395
+ // We only want to calculate speed and remaining time after 2 seconds of the execution
3396
+ // This is to avoid showing incorrect speed and remaining time when the request is very fast
3397
+ if (elapsedTimeSinceLastExecute > SPEED_BUFFER_TIME_IN_MS) {
3398
+ const speed = (loadedAmount / elapsedTimeSinceLastEvent) * 1000;
3399
+ progress.speed = speed * 1000;
3400
+ progress.remainingTime = Math.round((event.total - event.loaded) / speed) * 1000;
3401
+ }
3402
+ lastLoadEventTime.set(currentTime);
3403
+ lastLoadEventAmount.set(event.loaded);
3404
+ loading.set(state);
3405
+ };
3406
+ const httpRequest = {
3407
+ execute,
3408
+ destroy,
3409
+ loading: loading.asReadonly(),
3410
+ error: error.asReadonly(),
3411
+ response: response.asReadonly(),
3412
+ currentEvent: currentEvent.asReadonly(),
3413
+ isStale,
3414
+ };
3415
+ return httpRequest;
3416
+ };
3417
+
3418
+ /* eslint-disable @typescript-eslint/no-empty-function */
3419
+ const setupQueryDependencies = (options) => {
3420
+ const destroyRef = inject(DestroyRef);
3421
+ const client = inject(options.clientConfig.token);
3422
+ const injector = inject(Injector);
3423
+ const dependencies = {
3424
+ destroyRef,
3425
+ client,
3426
+ injector,
3427
+ };
3428
+ return dependencies;
3429
+ };
3430
+
3431
+ const resetExecuteState = (options) => {
3432
+ const { executeState, executeOptions: opts } = options;
3433
+ const { deps, state } = opts;
3434
+ const { effectRefs, previousKey } = executeState;
3435
+ deps.client.repository.unbind(previousKey, deps.destroyRef);
3436
+ effectRefs.forEach((ref) => ref.destroy());
3437
+ effectRefs.length = 0;
3438
+ state.args.set(null);
3439
+ state.error.set(null);
3440
+ state.latestHttpEvent.set(null);
3441
+ state.loading.set(null);
3442
+ state.response.set(null);
3443
+ state.lastTimeExecutedAt.set(null);
3444
+ };
3445
+ const setupQueryExecuteState = () => {
3446
+ return {
3447
+ effectRefs: [],
3448
+ previousKey: false,
3449
+ };
3450
+ };
3451
+ const queryExecute = (options) => {
3452
+ const { executeOptions, args, executeState } = options;
3453
+ const { deps, state, creator, creatorInternals, queryConfig } = executeOptions;
3454
+ const { key, request } = deps.client.repository.request({
3455
+ method: creatorInternals.method,
3456
+ route: creator.route,
3457
+ reportProgress: creator.reportProgress,
3458
+ withCredentials: creator.withCredentials,
3459
+ transferCache: creator.transferCache,
3460
+ responseType: creator.responseType || 'json',
3461
+ pathParams: args?.pathParams,
3462
+ queryParams: args?.queryParams,
3463
+ body: args?.body,
3464
+ destroyRef: deps.destroyRef,
3465
+ key: queryConfig.key,
3466
+ headers: args?.headers,
3467
+ });
3468
+ executeState.previousKey = key;
3469
+ runInInjectionContext(deps.injector, () => {
3470
+ const responseRef = syncSignal(request.response, state.response);
3471
+ const loadingRef = syncSignal(request.loading, state.loading);
3472
+ const errorRef = syncSignal(request.error, state.error);
3473
+ const latestHttpEventRef = syncSignal(request.currentEvent, state.latestHttpEvent);
3474
+ executeState.effectRefs.push(responseRef, loadingRef, errorRef, latestHttpEventRef);
3475
+ });
3476
+ state.lastTimeExecutedAt.set(Date.now());
3477
+ };
3478
+ const cleanupPreviousExecute = (options) => {
3479
+ const { executeOptions, executeState } = options;
3480
+ const { deps } = executeOptions;
3481
+ deps.client.repository.unbind(executeState.previousKey, deps.destroyRef);
3482
+ executeState.effectRefs.forEach((ref) => ref.destroy());
3483
+ executeState.effectRefs.length = 0;
3484
+ };
3485
+
3486
+ const createExecuteFn = (options) => {
3487
+ const executeState = setupQueryExecuteState();
3488
+ const reset = () => resetExecuteState({ executeState, executeOptions: options });
3489
+ const exec = (args = options.state.args()) => {
3490
+ cleanupPreviousExecute({ executeOptions: options, executeState, args });
3491
+ queryExecute({ executeOptions: options, executeState, args });
3492
+ };
3493
+ exec['reset'] = reset;
3494
+ return exec;
3495
+ };
3496
+
3497
+ /* eslint-disable @typescript-eslint/no-empty-function */
3498
+ const setupQueryState = (options) => {
3499
+ const response = signal(null);
3500
+ const args = signal(null);
3501
+ const latestHttpEvent = signal(null);
3502
+ const error = signal(null);
3503
+ const loading = signal(null);
3504
+ const lastTimeExecutedAt = signal(null);
3505
+ const state = {
3506
+ response,
3507
+ args,
3508
+ latestHttpEvent,
3509
+ loading,
3510
+ error,
3511
+ lastTimeExecutedAt,
3512
+ };
3513
+ return state;
3514
+ };
3515
+
3516
+ const createQuerySnapshotFn = (options) => {
3517
+ const { state, deps } = options;
3518
+ const snapshotFn = () => {
3519
+ const snapshotState = setupQueryState({});
3520
+ const isAlive = signal(true);
3521
+ const killEffectRef = effect(() => {
3522
+ const currentLoading = state.loading();
3523
+ const currentError = state.error();
3524
+ const currentResponse = state.response();
3525
+ const currentArgs = state.args();
3526
+ const currentLatestHttpEvent = state.latestHttpEvent();
3527
+ const currentLastTimeExecutedAt = state.lastTimeExecutedAt();
3528
+ untracked(() => {
3529
+ snapshotState.args.set(currentArgs);
3530
+ snapshotState.error.set(currentError);
3531
+ snapshotState.lastTimeExecutedAt.set(currentLastTimeExecutedAt);
3532
+ snapshotState.latestHttpEvent.set(currentLatestHttpEvent);
3533
+ snapshotState.loading.set(currentLoading);
3534
+ snapshotState.response.set(currentResponse);
3535
+ if (currentLoading)
3536
+ return;
3537
+ if (!currentResponse && !currentError)
3538
+ return;
3539
+ // kill the effect once loading is done and we either have a response or an error
3540
+ killEffectRef.destroy();
3541
+ isAlive.set(false);
3542
+ });
3543
+ }, { injector: deps.injector });
3544
+ const snapshot = {
3545
+ args: snapshotState.args.asReadonly(),
3546
+ response: snapshotState.response.asReadonly(),
3547
+ latestHttpEvent: snapshotState.latestHttpEvent.asReadonly(),
3548
+ loading: snapshotState.loading.asReadonly(),
3549
+ error: snapshotState.error.asReadonly(),
3550
+ lastTimeExecutedAt: snapshotState.lastTimeExecutedAt.asReadonly(),
3551
+ isAlive: isAlive.asReadonly(),
3552
+ };
3553
+ return snapshot;
3554
+ };
3555
+ return snapshotFn;
3556
+ };
3557
+
3558
+ /* eslint-disable @typescript-eslint/no-explicit-any */
3559
+ /* eslint-disable @typescript-eslint/no-empty-function */
3560
+ const createQuery = (options) => {
3561
+ const deps = setupQueryDependencies({ clientConfig: options.creatorInternals.client });
3562
+ const state = setupQueryState({});
3563
+ const { creator, creatorInternals, queryConfig } = options;
3564
+ const flags = getQueryFeatureUsage(options);
3565
+ const execute = createExecuteFn({ deps, state, creator, creatorInternals, queryConfig: options.queryConfig });
3566
+ const createSnapshot = createQuerySnapshotFn({ state, deps });
3567
+ const featureFnContext = {
3568
+ state,
3569
+ queryConfig,
3570
+ creatorConfig: creator,
3571
+ creatorInternals,
3572
+ execute,
3573
+ flags,
3574
+ };
3575
+ applyQueryFeatures(options, featureFnContext);
3576
+ maybeExecute({ execute, flags });
3577
+ const query = {
3578
+ execute,
3579
+ args: state.args.asReadonly(),
3580
+ response: state.response.asReadonly(),
3581
+ latestHttpEvent: state.latestHttpEvent.asReadonly(),
3582
+ loading: state.loading.asReadonly(),
3583
+ error: state.error.asReadonly(),
3584
+ lastTimeExecutedAt: state.lastTimeExecutedAt.asReadonly(),
3585
+ createSnapshot,
3586
+ };
3587
+ return query;
3588
+ };
3589
+
3590
+ /* eslint-disable @typescript-eslint/no-explicit-any */
3591
+ /* eslint-disable @typescript-eslint/no-empty-function */
3592
+ const createQueryRepository = (config) => {
3593
+ const httpClient = inject(HttpClient);
3594
+ const cache = new Map();
3595
+ const request = (options) => {
3596
+ const shouldCache = shouldCacheQuery(options.method);
3597
+ const route = buildRoute({
3598
+ base: config.baseUrl,
3599
+ route: options.route,
3600
+ pathParams: options.pathParams,
3601
+ queryParams: options.queryParams,
3602
+ queryParamConfig: config.queryString,
3603
+ });
3604
+ const key = shouldCache &&
3605
+ buildQueryCacheKey(`${options.key ? options.key + '_' : ''}${route}`, {
3606
+ body: options.body,
3607
+ queryParams: options.queryParams,
3608
+ pathParams: options.pathParams,
3609
+ // TODO: remaining props
3610
+ });
3611
+ if (shouldCache && key) {
3612
+ const cacheEntry = cache.get(key);
3613
+ if (cacheEntry) {
3614
+ bind(key, options.destroyRef, cacheEntry.request);
3615
+ if (!options.skipExecution)
3616
+ cacheEntry.request.execute();
3617
+ return { key, request: cacheEntry.request };
3618
+ }
3619
+ }
3620
+ const request = createHttpRequest({
3621
+ fullPath: route,
3622
+ body: options.body,
3623
+ reportProgress: options.reportProgress,
3624
+ withCredentials: options.withCredentials,
3625
+ transferCache: options.transferCache,
3626
+ responseType: options.responseType || 'json',
3627
+ method: options.method,
3628
+ headers: options.headers,
3629
+ httpClient,
3630
+ cacheAdapter: config.cacheAdapter,
3631
+ retryFn: config.retryFn,
3632
+ });
3633
+ if (!options.skipExecution)
3634
+ request.execute();
3635
+ if (shouldCache && key) {
3636
+ bind(key, options.destroyRef, request);
3637
+ }
3638
+ return { key, request };
3639
+ };
3640
+ const unbind = (key, destroyRef) => {
3641
+ if (!key)
3642
+ return;
3643
+ const cacheEntry = cache.get(key);
3644
+ if (!cacheEntry)
3645
+ return;
3646
+ cacheEntry.consumers.delete(destroyRef);
3647
+ if (cacheEntry.consumers.size === 0) {
3648
+ cacheEntry.request.destroy();
3649
+ cache.delete(key);
3650
+ }
3651
+ };
3652
+ const bind = (key, destroyRef, request) => {
3653
+ if (!key)
3654
+ return;
3655
+ const destroyListener = destroyRef.onDestroy(() => unbind(key, destroyRef));
3656
+ const cacheEntry = cache.get(key);
3657
+ if (cacheEntry) {
3658
+ cacheEntry.consumers.set(destroyRef, destroyListener);
3659
+ }
3660
+ else {
3661
+ const consumers = new Map([]);
3662
+ consumers.set(destroyRef, destroyListener);
3663
+ cache.set(key, {
3664
+ consumers,
3665
+ request,
3666
+ });
3667
+ }
3668
+ };
3669
+ const repository = {
3670
+ request,
3671
+ unbind,
3672
+ };
3673
+ return repository;
3674
+ };
3675
+
3676
+ /* eslint-disable @typescript-eslint/no-empty-function */
3677
+ const createQueryClient = (config) => {
3678
+ const repository = createQueryRepository(config);
3679
+ const client = {
3680
+ repository,
3681
+ };
3682
+ return client;
3683
+ };
3684
+ const provideQueryClient = (config) => {
3685
+ return {
3686
+ provide: config.token,
3687
+ useFactory: () => createQueryClient(config),
3688
+ };
3689
+ };
3690
+
3691
+ /* eslint-disable @typescript-eslint/no-empty-function */
3692
+ const createQueryClientConfig = (options) => {
3693
+ const token = new InjectionToken(`QueryClient_${options.name}`);
3694
+ const clientConfig = {
3695
+ baseUrl: options.baseUrl,
3696
+ token,
3697
+ name: options.name,
3698
+ queryString: options.queryString,
3699
+ };
3700
+ return clientConfig;
3701
+ };
3702
+
3703
+ const splitQueryConfig = (args) => {
3704
+ let queryConfig = {};
3705
+ let features = [];
3706
+ const first = args[0];
3707
+ if (first) {
3708
+ if ('type' in first) {
3709
+ features = args;
3710
+ }
3711
+ else {
3712
+ [queryConfig, ...features] = args;
3713
+ }
3714
+ }
3715
+ return { features, queryConfig };
3716
+ };
3717
+ const createQueryCreator = (options, internals) => {
3718
+ function queryCreator(...args) {
3719
+ const { features, queryConfig } = splitQueryConfig(args);
3720
+ return createQuery({
3721
+ creator: options,
3722
+ creatorInternals: internals,
3723
+ features,
3724
+ queryConfig,
3725
+ });
3726
+ }
3727
+ return queryCreator;
3728
+ };
3729
+
3730
+ const AUTH_HEADER = 'Authorization';
3731
+ const createSecureExecuteFn = (options) => {
3732
+ const executeState = setupQueryExecuteState();
3733
+ const authProvider = inject(options.creatorInternals.authProvider.token);
3734
+ let authQuerySubscription = Subscription.EMPTY;
3735
+ const reset = () => {
3736
+ authQuerySubscription.unsubscribe();
3737
+ authQuerySubscription = Subscription.EMPTY;
3738
+ resetExecuteState({ executeState, executeOptions: options });
3739
+ };
3740
+ const error = (query) => {
3741
+ const state = options.state;
3742
+ state.error.set(query.error());
3743
+ state.loading.set(null);
3744
+ state.response.set(null);
3745
+ state.latestHttpEvent.set(null);
3746
+ state.args.set(null);
3747
+ };
3748
+ const authAndExec = (args) => {
3749
+ const tokens = authProvider.tokens();
3750
+ let headers = args?.headers || new HttpHeaders();
3751
+ if (!tokens) {
3752
+ throw new Error('Tokens are not available inside authAndExec');
3753
+ }
3754
+ if (!headers.has(AUTH_HEADER)) {
3755
+ headers = headers.set(AUTH_HEADER, `Bearer ${tokens.accessToken}`);
3756
+ }
3757
+ const updatedArgs = { ...(args ?? {}), headers };
3758
+ queryExecute({
3759
+ executeOptions: options,
3760
+ executeState,
3761
+ args: updatedArgs,
3762
+ });
3763
+ };
3764
+ const exec = (args = options.state.args()) => {
3765
+ authQuerySubscription.unsubscribe();
3766
+ authQuerySubscription = Subscription.EMPTY;
3767
+ cleanupPreviousExecute({ executeOptions: options, executeState, args });
3768
+ const authQuery = authProvider.latestExecutedQuery();
3769
+ if (!authQuery || authQuery.loading()) {
3770
+ options.state.loading.set({ executeTime: Date.now(), progress: null });
3771
+ authQuerySubscription = toObservable(authProvider.latestExecutedQuery, { injector: options.deps.injector })
3772
+ .pipe(switchMap((query) => {
3773
+ if (!query)
3774
+ return of(null);
3775
+ return toObservable(query.isAlive, { injector: options.deps.injector }).pipe(tap((isAlive) => {
3776
+ if (isAlive)
3777
+ return;
3778
+ if (query.error()) {
3779
+ error(query);
3780
+ }
3781
+ else if (query.response()) {
3782
+ authAndExec(args);
3783
+ }
3784
+ }));
3785
+ }))
3786
+ .subscribe();
3787
+ }
3788
+ else if (authQuery.response()) {
3789
+ authAndExec(args);
3790
+ }
3791
+ else if (authQuery.error()) {
3792
+ error(authQuery);
3793
+ }
3794
+ else {
3795
+ throw new Error('Invalid state ocurred inside createSecureExecuteFn');
3796
+ }
3797
+ };
3798
+ exec['reset'] = reset;
3799
+ return exec;
3800
+ };
3801
+
3802
+ const createSecureQuery = (options) => {
3803
+ const deps = setupQueryDependencies({ clientConfig: options.creatorInternals.client });
3804
+ const state = setupQueryState({});
3805
+ const { creator, creatorInternals, queryConfig } = options;
3806
+ const flags = getQueryFeatureUsage(options);
3807
+ const execute = createSecureExecuteFn({
3808
+ deps,
3809
+ state,
3810
+ creator,
3811
+ creatorInternals,
3812
+ queryConfig: options.queryConfig,
3813
+ });
3814
+ const createSnapshot = createQuerySnapshotFn({ state, deps });
3815
+ const featureFnContext = {
3816
+ state,
3817
+ queryConfig,
3818
+ creatorConfig: creator,
3819
+ creatorInternals,
3820
+ execute,
3821
+ flags,
3822
+ };
3823
+ applyQueryFeatures(options, featureFnContext);
3824
+ maybeExecute({ execute, flags });
3825
+ const query = {
3826
+ execute,
3827
+ args: state.args.asReadonly(),
3828
+ response: state.response.asReadonly(),
3829
+ latestHttpEvent: state.latestHttpEvent.asReadonly(),
3830
+ loading: state.loading.asReadonly(),
3831
+ error: state.error.asReadonly(),
3832
+ lastTimeExecutedAt: state.lastTimeExecutedAt.asReadonly(),
3833
+ createSnapshot,
3834
+ };
3835
+ return query;
3836
+ };
3837
+
3838
+ const createSecureQueryCreator = (options, internals) => {
3839
+ function queryCreator(...args) {
3840
+ const { features, queryConfig } = splitQueryConfig(args);
3841
+ return createSecureQuery({
3842
+ creator: options,
3843
+ creatorInternals: internals,
3844
+ features,
3845
+ queryConfig,
3846
+ });
3847
+ }
3848
+ return queryCreator;
3849
+ };
3850
+
3851
+ const createGetQuery = (client) => {
3852
+ return (creatorOptions) => createQueryCreator(creatorOptions, { method: 'GET', client });
3853
+ };
3854
+ const createSecureGetQuery = (client, authProvider) => {
3855
+ return (creatorOptions) => createSecureQueryCreator(creatorOptions, { method: 'GET', client, authProvider });
3856
+ };
3857
+ const createPostQuery = (client) => {
3858
+ return (creatorOptions) => createQueryCreator(creatorOptions, { method: 'POST', client });
3859
+ };
3860
+ const createSecurePostQuery = (client, authProvider) => {
3861
+ return (creatorOptions) => createSecureQueryCreator(creatorOptions, { method: 'POST', client, authProvider });
3862
+ };
3863
+ const createPutQuery = (client) => {
3864
+ return (creatorOptions) => createQueryCreator(creatorOptions, { method: 'PUT', client });
3865
+ };
3866
+ const createSecurePutQuery = (client, authProvider) => {
3867
+ return (creatorOptions) => createSecureQueryCreator(creatorOptions, { method: 'PUT', client, authProvider });
3868
+ };
3869
+ const createDeleteQuery = (client) => {
3870
+ return (creatorOptions) => createQueryCreator(creatorOptions, { method: 'DELETE', client });
3871
+ };
3872
+ const createSecureDeleteQuery = (client, authProvider) => {
3873
+ return (creatorOptions) => createSecureQueryCreator(creatorOptions, { method: 'DELETE', client, authProvider });
3874
+ };
3875
+ const createPatchQuery = (client) => {
3876
+ return (creatorOptions) => createQueryCreator(creatorOptions, { method: 'PATCH', client });
3877
+ };
3878
+ const createSecurePatchQuery = (client, authProvider) => {
3879
+ return (creatorOptions) => createSecureQueryCreator(creatorOptions, { method: 'PATCH', client, authProvider });
3880
+ };
3881
+
3882
+ /* eslint-disable @typescript-eslint/no-empty-function */
3883
+ const createQueryFeature = (config) => {
3884
+ return config;
3885
+ };
3886
+ const withArgs = (args) => {
3887
+ return createQueryFeature({
3888
+ type: "withArgs" /* QueryFeatureType.WithArgs */,
3889
+ fn: (context) => {
3890
+ const currArgs = computed(() => args());
3891
+ queryEffect(() => {
3892
+ const currArgsNow = currArgs();
3893
+ if (currArgsNow === null)
3894
+ return;
3895
+ untracked(() => {
3896
+ if (currArgsNow === QUERY_ARGS_RESET) {
3897
+ context.state.args.set(null);
3898
+ return;
3899
+ }
3900
+ context.state.args.set(currArgsNow);
3901
+ if (context.flags.shouldAutoExecute)
3902
+ context.execute(currArgsNow);
3903
+ });
3904
+ }, QUERY_EFFECT_ERROR_MESSAGE);
3905
+ },
3906
+ });
3907
+ };
3908
+ const withPolling = (options) => {
3909
+ return createQueryFeature({
3910
+ type: "withPolling" /* QueryFeatureType.WithPolling */,
3911
+ fn: (context) => {
3912
+ if (!context.flags.shouldAutoExecuteMethod) {
3913
+ throw withPollingUsedOnUnsupportedHttpMethod(context.creatorInternals.method);
3914
+ }
3915
+ let intervalId = null;
3916
+ queryEffect(() => {
3917
+ const args = context.state.args();
3918
+ untracked(() => {
3919
+ if (intervalId !== null)
3920
+ clearInterval(intervalId);
3921
+ if (args === null)
3922
+ return;
3923
+ if (options.executeInitially) {
3924
+ context.execute(args);
3925
+ }
3926
+ intervalId = window.setInterval(() => {
3927
+ context.execute(args);
3928
+ }, options.interval);
3929
+ });
3930
+ }, QUERY_EFFECT_ERROR_MESSAGE);
3931
+ inject(DestroyRef).onDestroy(() => intervalId !== null && clearInterval(intervalId));
3932
+ },
3933
+ });
3934
+ };
3935
+ const withLogging = (options) => {
3936
+ return createQueryFeature({
3937
+ type: "withLogging" /* QueryFeatureType.WithLogging */,
3938
+ fn: (context) => {
3939
+ effect(() => {
3940
+ const event = context.state.latestHttpEvent();
3941
+ if (event === null)
3942
+ return;
3943
+ untracked(() => {
3944
+ options.logFn(event);
3945
+ });
3946
+ });
3947
+ },
3948
+ });
3949
+ };
3950
+ const withErrorHandling = (options) => {
3951
+ return createQueryFeature({
3952
+ type: "withErrorHandling" /* QueryFeatureType.WithErrorHandling */,
3953
+ fn: (context) => {
3954
+ effect(() => {
3955
+ const error = context.state.error();
3956
+ if (error === null)
3957
+ return;
3958
+ untracked(() => {
3959
+ options.handler(error);
3960
+ });
3961
+ });
3962
+ },
3963
+ });
3964
+ };
3965
+ const withSuccessHandling = (options) => {
3966
+ return createQueryFeature({
3967
+ type: "withSuccessHandling" /* QueryFeatureType.WithSuccessHandling */,
3968
+ fn: (context) => {
3969
+ effect(() => {
3970
+ const response = context.state.response();
3971
+ if (response === null)
3972
+ return;
3973
+ untracked(() => {
3974
+ options.handler(response);
3975
+ });
3976
+ });
3977
+ },
3978
+ });
3979
+ };
3980
+ const withAutoRefresh = (options) => {
3981
+ return createQueryFeature({
3982
+ type: "withAutoRefresh" /* QueryFeatureType.WithAutoRefresh */,
3983
+ fn: (context) => {
3984
+ if (!context.flags.shouldAutoExecuteMethod) {
3985
+ throw withAutoRefreshUsedOnUnsupportedHttpMethod(context.creatorInternals.method);
3986
+ }
3987
+ if (context.queryConfig.onlyManualExecution && !options.ignoreOnlyManualExecution) {
3988
+ throw withAutoRefreshUsedOnUnsupportedHttpMethod(context.creatorInternals.method);
3989
+ }
3990
+ queryEffect(() => {
3991
+ for (const signal of options.signalChanges) {
3992
+ signal();
3993
+ }
3994
+ untracked(() => {
3995
+ const args = context.state.args();
3996
+ if (args === null)
3997
+ return;
3998
+ context.execute(args);
3999
+ });
4000
+ }, QUERY_EFFECT_ERROR_MESSAGE);
4001
+ },
4002
+ });
4003
+ };
4004
+
4005
+ var index = /*#__PURE__*/Object.freeze({
4006
+ __proto__: null,
4007
+ QUERY_ARGS_RESET: QUERY_ARGS_RESET,
4008
+ QUERY_EFFECT_ERROR_MESSAGE: QUERY_EFFECT_ERROR_MESSAGE,
4009
+ SPEED_BUFFER_TIME_IN_MS: SPEED_BUFFER_TIME_IN_MS,
4010
+ applyQueryFeatures: applyQueryFeatures,
4011
+ bearerExpiresInPropertyNotNumber: bearerExpiresInPropertyNotNumber,
4012
+ cleanupPreviousExecute: cleanupPreviousExecute,
4013
+ cookieLoginTriedButCookieDisabled: cookieLoginTriedButCookieDisabled,
4014
+ createBearerAuthProvider: createBearerAuthProvider,
4015
+ createBearerAuthProviderConfig: createBearerAuthProviderConfig,
4016
+ createDeleteQuery: createDeleteQuery,
4017
+ createExecuteFn: createExecuteFn,
4018
+ createGetQuery: createGetQuery,
4019
+ createHttpRequest: createHttpRequest,
4020
+ createPatchQuery: createPatchQuery,
4021
+ createPostQuery: createPostQuery,
4022
+ createPutQuery: createPutQuery,
4023
+ createQuery: createQuery,
4024
+ createQueryClient: createQueryClient,
4025
+ createQueryClientConfig: createQueryClientConfig,
4026
+ createQueryCreator: createQueryCreator,
4027
+ createQueryRepository: createQueryRepository,
4028
+ createQuerySnapshotFn: createQuerySnapshotFn,
4029
+ createSecureDeleteQuery: createSecureDeleteQuery,
4030
+ createSecureExecuteFn: createSecureExecuteFn,
4031
+ createSecureGetQuery: createSecureGetQuery,
4032
+ createSecurePatchQuery: createSecurePatchQuery,
4033
+ createSecurePostQuery: createSecurePostQuery,
4034
+ createSecurePutQuery: createSecurePutQuery,
4035
+ createSecureQuery: createSecureQuery,
4036
+ createSecureQueryCreator: createSecureQueryCreator,
4037
+ defaultResponseTransformerResponseNotContainingAccessToken: defaultResponseTransformerResponseNotContainingAccessToken,
4038
+ defaultResponseTransformerResponseNotContainingRefreshToken: defaultResponseTransformerResponseNotContainingRefreshToken,
4039
+ defaultResponseTransformerResponseNotObject: defaultResponseTransformerResponseNotObject,
4040
+ disableCookieCalledWithoutCookieConfig: disableCookieCalledWithoutCookieConfig,
4041
+ enableCookieCalledWithoutCookieConfig: enableCookieCalledWithoutCookieConfig,
4042
+ extractExpiresInSeconds: extractExpiresInSeconds,
4043
+ getQueryFeatureUsage: getQueryFeatureUsage,
4044
+ loginCalledWithoutConfig: loginCalledWithoutConfig,
4045
+ loginWithTokenCalledWithoutConfig: loginWithTokenCalledWithoutConfig,
4046
+ maybeExecute: maybeExecute,
4047
+ provideBearerAuthProvider: provideBearerAuthProvider,
4048
+ provideQueryClient: provideQueryClient,
4049
+ queryEffect: queryEffect,
4050
+ queryExecute: queryExecute,
4051
+ queryFeatureUsedMultipleTimes: queryFeatureUsedMultipleTimes,
4052
+ refreshTokenCalledWithoutConfig: refreshTokenCalledWithoutConfig,
4053
+ resetExecuteState: resetExecuteState,
4054
+ selectRoleCalledWithoutConfig: selectRoleCalledWithoutConfig,
4055
+ setupQueryDependencies: setupQueryDependencies,
4056
+ setupQueryExecuteState: setupQueryExecuteState,
4057
+ setupQueryState: setupQueryState,
4058
+ shouldAutoExecuteQuery: shouldAutoExecuteQuery,
4059
+ shouldRetryRequest: shouldRetryRequest,
4060
+ splitQueryConfig: splitQueryConfig,
4061
+ unableToDecryptBearerToken: unableToDecryptBearerToken,
4062
+ withArgs: withArgs,
4063
+ withArgsQueryFeatureMissingButRouteIsFunction: withArgsQueryFeatureMissingButRouteIsFunction,
4064
+ withAutoRefresh: withAutoRefresh,
4065
+ withAutoRefreshUsedInManualQuery: withAutoRefreshUsedInManualQuery,
4066
+ withAutoRefreshUsedOnUnsupportedHttpMethod: withAutoRefreshUsedOnUnsupportedHttpMethod,
4067
+ withErrorHandling: withErrorHandling,
4068
+ withLogging: withLogging,
4069
+ withPolling: withPolling,
4070
+ withPollingUsedOnUnsupportedHttpMethod: withPollingUsedOnUnsupportedHttpMethod,
4071
+ withSuccessHandling: withSuccessHandling
4072
+ });
4073
+
2813
4074
  const transformToString = (value) => {
2814
4075
  if (typeof value === 'string') {
2815
4076
  return value;
@@ -2946,11 +4207,12 @@ class QueryForm {
2946
4207
  this._router = inject(Router);
2947
4208
  this._activatedRoute = inject(ActivatedRoute);
2948
4209
  this._defaultValues = this._extractDefaultValues();
2949
- this._routerStateService = inject(RouterStateService);
2950
4210
  this._zone = inject(NgZone);
2951
4211
  this._didValueChanges$ = new Subject();
2952
4212
  this._isObserving = false;
2953
4213
  this._skipNextResets = false;
4214
+ this._queryParamChanges$ = toObservable(injectQueryParamChanges());
4215
+ this._queryParams = injectQueryParams();
2954
4216
  /**
2955
4217
  * The angular form group that contains all the fields.
2956
4218
  *
@@ -2997,6 +4259,7 @@ class QueryForm {
2997
4259
  })
2998
4260
  .filter((v) => v === false).length));
2999
4261
  assertInInjectionContext(QueryForm);
4262
+ inject(DestroyRef).onDestroy(() => this._cleanup());
3000
4263
  }
3001
4264
  observe(options) {
3002
4265
  if (this._isObserving) {
@@ -3008,7 +4271,7 @@ class QueryForm {
3008
4271
  this._isObserving = true;
3009
4272
  if (options?.syncOnNavigation !== false) {
3010
4273
  const didChanges = this.setFormValueFromUrlQueryParams({
3011
- queryParams: this._routerStateService.queryParams,
4274
+ queryParams: this._queryParams(),
3012
4275
  });
3013
4276
  if (didChanges) {
3014
4277
  this._handleFormChange(true);
@@ -3073,7 +4336,7 @@ class QueryForm {
3073
4336
  }), takeUntil(this._destroy$), takeUntil(this._unobserveTrigger$))
3074
4337
  .subscribe();
3075
4338
  if (options?.syncOnNavigation !== false) {
3076
- this._routerStateService.queryParamChanges$
4339
+ this._queryParamChanges$
3077
4340
  .pipe(takeUntil(this._destroy$), takeUntil(this._unobserveTrigger$), tap((changes) => {
3078
4341
  const didValueChanges = this.setFormValueFromUrlQueryParams({ queryParams: changes });
3079
4342
  if (didValueChanges) {
@@ -3119,6 +4382,7 @@ class QueryForm {
3119
4382
  }
3120
4383
  unobserve() {
3121
4384
  this._unobserveTrigger$.next(true);
4385
+ this._cleanup();
3122
4386
  }
3123
4387
  setFormValueFromUrlQueryParams(options) {
3124
4388
  let didValueChanges = false;
@@ -3256,10 +4520,12 @@ class QueryForm {
3256
4520
  }
3257
4521
  }
3258
4522
  this._zone.run(() => {
3259
- this._router.navigate([], {
3260
- queryParams,
3261
- replaceUrl,
3262
- queryParamsHandling: 'merge',
4523
+ queueMicrotask(() => {
4524
+ this._router.navigate([], {
4525
+ queryParams,
4526
+ replaceUrl,
4527
+ queryParamsHandling: 'merge',
4528
+ });
3263
4529
  });
3264
4530
  });
3265
4531
  }
@@ -3277,6 +4543,22 @@ class QueryForm {
3277
4543
  }
3278
4544
  this._currentFormValue$.next(newVal);
3279
4545
  }
4546
+ _cleanup() {
4547
+ const queryParamKeys = Object.keys(this._fields);
4548
+ const queryParams = queryParamKeys.reduce((acc, key) => {
4549
+ acc[this._transformKeyToQueryParam(key)] = undefined;
4550
+ return acc;
4551
+ }, {});
4552
+ this._zone.run(() => {
4553
+ queueMicrotask(() => {
4554
+ this._router.navigate([], {
4555
+ queryParams,
4556
+ replaceUrl: true,
4557
+ queryParamsHandling: 'merge',
4558
+ });
4559
+ });
4560
+ });
4561
+ }
3280
4562
  }
3281
4563
 
3282
4564
  // Burst cache
@@ -3285,5 +4567,5 @@ class QueryForm {
3285
4567
  * Generated bundle index. Do not edit.
3286
4568
  */
3287
4569
 
3288
- export { BasicAuthProvider, BearerAuthProvider, CustomHeaderAuthProvider, EntityStore, INFINITY_QUERY_TOKEN, InfinityQuery, InfinityQueryDirective, InfinityQueryTriggerDirective, QUERY_CLIENT_DEVTOOLS_TOKEN, Query, QueryClient, QueryCreator, QueryDevtoolsComponent, QueryDirective, QueryError, QueryField, QueryForm, QueryShortNamePipe, QueryStore, addQueryContainerHandling, buildErrorMessage, buildQueryCacheKey, buildQueryString, buildRoute, buildTimestampFromSeconds, castQueryCreatorTypes, computeQueryAuthHeader, computeQueryBody, computeQueryHeaders, computeQueryMethod, computeQueryQueryParams, createInfinityQueryConfig, createQueryCollection, createQueryCollectionSignal, createQueryCollectionSubject, decryptBearer, deepFreeze, def, detectContentTypeHeader, extractExpiresInSeconds, extractQuery, filterFailure, filterNull, filterQueryStates, filterSuccess, forEachHeader, getDefaultHeaders, getResponseUrl, gql, hasHeader, ignoreAutoRefresh, insertFrom, invalidBaseRouteError, invalidBodyError, invalidRouteError, isAutoRefresh, isBasicAuthProvider, isBearerAuthProvider, isClassValidatorError, isCustomHeaderAuthProvider, isEmptyString, isGqlQueryConfig, isNaN$1 as isNaN, isQuery, isQueryCollection, isQueryStateCancelled, isQueryStateFailure, isQueryStateLoading, isQueryStatePrepared, isQueryStateSuccess, isRequestError, isSymfonyError, isSymfonyFormViolationListError, isSymfonyListError, isSymfonyPagerfantaOutOfRangeError, mapToPaginated, mergeHeaders, paginatedEntityValueUpdater, parseAllXhrResponseHeaders, pathParamsMissingInRouteFunctionError, provideQueryClientForDevtools, queryArrayComputed, queryComputed, queryComputedTillTruthy, queryStateAlreadyHasKeyError, queryStateCannotTransformError, queryStateDoesNotContainKeyError, queryStateErrorSignal, queryStateLoadingSignal, queryStateResponseSignal, queryStateSignal, removeFrom, request, resetPageOnError, serializeBody, shouldCacheQuery, shouldRetryRequest, skipPaginationPageParamCalculator, switchQueryCollectionState, switchQueryState, takeUntilResponse, toQuerySignal, toQuerySubject, transformGql, transformMethod, transformToBoolean, transformToBooleanArray, transformToDate, transformToDateArray, transformToNumber, transformToNumberArray, transformToSort, transformToSortQueryParam, transformToString, transformToStringArray };
4570
+ export { BasicAuthProvider, BearerAuthProvider, CustomHeaderAuthProvider, EntityStore, index as ExperimentalQuery, INFINITY_QUERY_TOKEN, InfinityQuery, InfinityQueryDirective, InfinityQueryTriggerDirective, QUERY_CLIENT_DEVTOOLS_TOKEN, Query, QueryClient, QueryCreator, QueryDevtoolsComponent, QueryDirective, QueryError, QueryField, QueryForm, QueryShortNamePipe, QueryStore, addQueryContainerHandling, buildErrorMessage, buildQueryCacheKey, buildQueryString, buildRoute, buildTimestampFromSeconds, castQueryCreatorTypes, computeQueryAuthHeader, computeQueryBody, computeQueryHeaders, computeQueryMethod, computeQueryQueryParams, createInfinityQueryConfig, createQueryCollection, createQueryCollectionSignal, createQueryCollectionSubject, decryptBearer, deepFreeze, def, detectContentTypeHeader, extractExpiresInSeconds$1 as extractExpiresInSeconds, extractQuery, filterFailure, filterNull, filterQueryStates, filterSuccess, forEachHeader, getDefaultHeaders, getResponseUrl, gql, hasHeader, ignoreAutoRefresh, insertFrom, invalidBaseRouteError, invalidBodyError, invalidRouteError, isAutoRefresh, isBasicAuthProvider, isBearerAuthProvider, isClassValidatorError, isCustomHeaderAuthProvider, isEmptyString, isGqlQueryConfig, isNaN$1 as isNaN, isQuery, isQueryCollection, isQueryStateCancelled, isQueryStateFailure, isQueryStateLoading, isQueryStatePrepared, isQueryStateSuccess, isRequestError, isSymfonyError, isSymfonyFormViolationListError, isSymfonyListError, isSymfonyPagerfantaOutOfRangeError, mapToPaginated, mergeHeaders, paginatedEntityValueUpdater, parseAllXhrResponseHeaders, pathParamsMissingInRouteFunctionError, provideQueryClientForDevtools, queryArrayComputed, queryComputed, queryComputedTillTruthy, queryStateAlreadyHasKeyError, queryStateCannotTransformError, queryStateDoesNotContainKeyError, queryStateErrorSignal, queryStateLoadingSignal, queryStateResponseSignal, queryStateSignal, removeFrom, request, resetPageOnError, serializeBody, shouldCacheQuery, shouldRetryRequest$1 as shouldRetryRequest, skipPaginationPageParamCalculator, switchQueryCollectionState, switchQueryState, takeUntilResponse, toQuerySignal, toQuerySubject, transformGql, transformMethod, transformToBoolean, transformToBooleanArray, transformToDate, transformToDateArray, transformToNumber, transformToNumberArray, transformToSort, transformToSortQueryParam, transformToString, transformToStringArray };
3289
4571
  //# sourceMappingURL=ethlete-query.mjs.map