@ethlete/query 6.0.0-next.17 → 6.0.0-next.19

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,5 @@
1
1
  import * as i0 from '@angular/core';
2
- import { isDevMode, DestroyRef, InjectionToken, inject, Injector, EnvironmentInjector, ErrorHandler, createEnvironmentInjector, effect, untracked, signal, linkedSignal, computed, runInInjectionContext, assertInInjectionContext, ChangeDetectorRef, ViewContainerRef, TemplateRef, Input, Directive, ElementRef, input, Pipe, ViewEncapsulation, Component, resource, DOCUMENT, NgZone } from '@angular/core';
2
+ import { signal, isDevMode, makeEnvironmentProviders, DestroyRef, InjectionToken, inject, Injector, EnvironmentInjector, ElementRef, ErrorHandler, createEnvironmentInjector, effect, untracked, linkedSignal, computed, runInInjectionContext, assertInInjectionContext, ChangeDetectorRef, ViewContainerRef, TemplateRef, Input, Directive, input, Pipe, ViewEncapsulation, Component, resource, DOCUMENT, NgZone } from '@angular/core';
3
3
  import { createStaticProvider, RuntimeError, clamp, createDestroy, computedTillTruthy, getCookie, setCookie, deleteCookie, createProvider, nextFrame, randomId, createRootProvider, isObject, injectRoute, getDomain, injectQueryParamChanges, injectQueryParams, clone, equal, ET_PROPERTY_REMOVED, previousSignalValue } from '@ethlete/core';
4
4
  import { filter, Subject, Subscription, Observable, tap, retry, throwError, timer, catchError, takeUntil, startWith, pairwise, switchMap, of, BehaviorSubject, fromEvent, take, ReplaySubject, map, shareReplay, interval, skip, takeWhile, combineLatest, EMPTY, withLatestFrom, debounceTime, firstValueFrom, merge, throttleTime } from 'rxjs';
5
5
  import { toObservable, takeUntilDestroyed, toSignal } from '@angular/core/rxjs-interop';
@@ -12,6 +12,126 @@ import { validateAsync } from '@angular/forms/signals';
12
12
  import { Router, ActivatedRoute } from '@angular/router';
13
13
  import { io } from 'socket.io-client';
14
14
 
15
+ const noop = () => undefined;
16
+ let devtoolsEnabled = false;
17
+ /**
18
+ * Whether {@link provideQueryDevtools} has been called. When `false`, every `register*` call is a
19
+ * no-op so the devtools instrumentation retains no references and adds no overhead in production.
20
+ * @internal
21
+ */
22
+ const isQueryDevtoolsEnabled = () => devtoolsEnabled;
23
+ const entries = signal([], /* @ts-ignore */
24
+ ...(ngDevMode ? [{ debugName: "entries" }] : /* istanbul ignore next */ []));
25
+ /**
26
+ * The reactive list of every registered devtools entry, consumed by the `<et-query-devtools>` UI.
27
+ */
28
+ const queryDevtoolsEntries = entries.asReadonly();
29
+ // Per-descriptor counter used to derive stable, reload-deterministic ids. Reset on page load (module
30
+ // re-eval), so the same queries created in the same order get the same ids across reloads — which is
31
+ // what lets the devtools restore the selected query after a reload.
32
+ const idCounters = new Map();
33
+ const descriptorOf = (entry) => {
34
+ const { kind, meta } = entry;
35
+ if (kind === 'query')
36
+ return `query|${meta.clientName ?? ''}|${meta.method ?? ''}|${meta.route ?? ''}`;
37
+ if (kind === 'auth-provider')
38
+ return `auth-provider|${meta.name ?? ''}`;
39
+ if (kind === 'ws-client')
40
+ return `ws-client|${meta.name ?? ''}`;
41
+ return kind;
42
+ };
43
+ /**
44
+ * Registers an entry with the devtools registry. Returns an unregister callback. A no-op (returning
45
+ * a no-op callback) unless {@link provideQueryDevtools} has been called.
46
+ *
47
+ * Ids are derived deterministically from a stable descriptor + a per-descriptor sequence number, so
48
+ * they survive a page reload (letting the UI restore the selected entry) instead of being random.
49
+ * @internal
50
+ */
51
+ const registerQueryDevtoolsEntry = (entry) => {
52
+ if (!devtoolsEnabled)
53
+ return noop;
54
+ let id = entry.id;
55
+ if (!id) {
56
+ const descriptor = descriptorOf(entry);
57
+ const seq = idCounters.get(descriptor) ?? 0;
58
+ idCounters.set(descriptor, seq + 1);
59
+ id = `${descriptor}#${seq}`;
60
+ }
61
+ const fullEntry = { ...entry, id, createdAt: Date.now() };
62
+ entries.update((list) => [...list, fullEntry]);
63
+ return () => entries.update((list) => list.filter((e) => e.id !== fullEntry.id));
64
+ };
65
+ let suppressStackRegistration = false;
66
+ /**
67
+ * Suppresses devtools registration for the next {@link createQueryStack} call. Used by
68
+ * `createPagedQueryStack` so its backing stack is not registered as a separate `query-stack` entry.
69
+ * @internal
70
+ */
71
+ const suppressNextQueryStackDevtools = () => {
72
+ suppressStackRegistration = true;
73
+ };
74
+ /**
75
+ * Reads and clears the suppress-next-stack flag. Always call this from `createQueryStack` (even when
76
+ * devtools are disabled) so a suppression request never leaks into a later stack.
77
+ * @internal
78
+ */
79
+ const consumeSuppressQueryStackDevtools = () => {
80
+ const value = suppressStackRegistration;
81
+ suppressStackRegistration = false;
82
+ return value;
83
+ };
84
+ /**
85
+ * Stringifies a query creator route. Function routes are invoked with an empty args object and any
86
+ * resulting `undefined` path segments are rendered as `:param`, matching the legacy devtools.
87
+ * @internal
88
+ */
89
+ const stringifyQueryRoute = (route) => {
90
+ if (route === undefined || route === null)
91
+ return '';
92
+ try {
93
+ if (typeof route === 'function') {
94
+ return route({}).replace(/undefined/g, ':param');
95
+ }
96
+ return String(route);
97
+ }
98
+ catch {
99
+ return typeof route === 'function' ? '(dynamic route)' : String(route);
100
+ }
101
+ };
102
+ /**
103
+ * Extracts the human readable client name from a query client tuple. The client's DI token is named
104
+ * `QueryClient_<name>`, so we strip the prefix to recover the original name.
105
+ * @internal
106
+ */
107
+ const getQueryClientName = (client) => {
108
+ const token = client[2];
109
+ const desc = token?.toString?.() ?? '';
110
+ return desc.replace('InjectionToken ', '').replace('QueryClient_', '') || 'unknown';
111
+ };
112
+ /**
113
+ * Enables the `@ethlete/query` devtools. Add this to your application providers (e.g. in
114
+ * `bootstrapApplication`) to make query clients, queries, stacks, sequences and auth providers
115
+ * appear in the `<et-query-devtools>` panel.
116
+ *
117
+ * When omitted, all devtools instrumentation is a no-op — no references are retained and there is no
118
+ * runtime overhead — so it is safe to leave out of production builds.
119
+ *
120
+ * @example
121
+ * ```ts
122
+ * bootstrapApplication(AppComponent, {
123
+ * providers: [provideQueryDevtools()],
124
+ * });
125
+ * ```
126
+ */
127
+ const provideQueryDevtools = () => {
128
+ devtoolsEnabled = true;
129
+ if (!isDevMode()) {
130
+ console.warn('You are using the Query Devtools in production mode. This increases the size of your bundle and should only be used for development purposes.');
131
+ }
132
+ return makeEnvironmentProviders([]);
133
+ };
134
+
15
135
  const getOpName = /(query|mutation) ?([\w\d-_]+)? ?\(.*?\)? \{/;
16
136
  const transformGql = (str) => {
17
137
  const normalizedStr = Array.isArray(str) ? str.join('') : str;
@@ -133,6 +253,7 @@ const setupQueryDependencies = (options) => {
133
253
  injector: undefined, // Will be set after injector creation
134
254
  ngErrorHandler: hostInjector.get(ErrorHandler),
135
255
  httpClient: hostInjector.get(HttpClient),
256
+ hostElement: hostInjector.get(ElementRef, null, { optional: true })?.nativeElement ?? null,
136
257
  };
137
258
  const queryContext = {
138
259
  deps: dependencies,
@@ -195,6 +316,8 @@ const QueryRuntimeErrorCode = {
195
316
  INVALID_STATE_INSIDE_SECURE_EXECUTE_FACTORY: 701,
196
317
  // Query Execution
197
318
  CIRCULAR_QUERY_DEPENDENCY: 800,
319
+ // Query Sequence
320
+ QUERY_SEQUENCE_ALREADY_RUNNING: 900,
198
321
  };
199
322
  const queryFeatureUsedMultipleTimes = (type) => {
200
323
  return new RuntimeError(QueryRuntimeErrorCode.QUERY_FEATURE_USED_MULTIPLE_TIMES, `The query feature "${type}()" was used multiple times.`);
@@ -263,6 +386,9 @@ const invalidStateInsideSecureExecuteFactory = () => {
263
386
  const circularQueryDependency = () => {
264
387
  return new RuntimeError(QueryRuntimeErrorCode.CIRCULAR_QUERY_DEPENDENCY, `Query was executed more than 5 times in less than 100ms. This is usually a sign of a circular dependency.`);
265
388
  };
389
+ const querySequenceAlreadyRunning = () => {
390
+ return new RuntimeError(QueryRuntimeErrorCode.QUERY_SEQUENCE_ALREADY_RUNNING, `run() was called on a query sequence that is already running. Wait for the current run to settle before starting another.`);
391
+ };
266
392
 
267
393
  /**
268
394
  * Returning this inside a withArgs feature will reset the query args to null.
@@ -652,6 +778,8 @@ const createQueryObject = (options) => {
652
778
  const { state, execute, deps } = options;
653
779
  const destroy = () => deps.injector.destroy();
654
780
  const setResponse = (response) => state.rawResponse.set(response);
781
+ const setLoading = (loading) => state.loading.set(loading);
782
+ const setError = (error) => state.error.set(error);
655
783
  const createSnapshot = createQuerySnapshotFn({ state, execute, deps });
656
784
  // Pre-wrap all public signals once so both `query` and `roQuery` share the same instances.
657
785
  const wrappedArgs = wrapAsObservableSignal(state.args.asReadonly(), deps.injector);
@@ -696,6 +824,8 @@ const createQueryObject = (options) => {
696
824
  subtle: {
697
825
  destroy,
698
826
  setResponse,
827
+ setLoading,
828
+ setError,
699
829
  request: wrappedRequest,
700
830
  destroyRef: deps.scopeDestroyRef,
701
831
  injector: deps.injector,
@@ -729,7 +859,28 @@ const createBaseQuery = (options) => {
729
859
  };
730
860
  applyQueryFeatures(options.features, featureFnContext);
731
861
  maybeExecute({ execute, flags });
732
- return createQueryObject({ state, execute, deps });
862
+ const query = createQueryObject({ state, execute, deps });
863
+ if (isQueryDevtoolsEnabled()) {
864
+ const unregister = registerQueryDevtoolsEntry({
865
+ kind: 'query',
866
+ handle: query,
867
+ meta: {
868
+ clientName: getQueryClientName(client),
869
+ clientBaseUrl: deps.client.baseUrl,
870
+ route: stringifyQueryRoute(options.creatorInternals.route ??
871
+ options.creator?.route),
872
+ method: flags.method,
873
+ featureTypes: options.features.map((f) => f.type),
874
+ queryConfig: options.queryConfig,
875
+ creator: options.creator,
876
+ repository: deps.client.repository,
877
+ element: deps.hostElement,
878
+ gqlQuery: options.creatorInternals.query,
879
+ },
880
+ });
881
+ deps.destroyRef.onDestroy(unregister);
882
+ }
883
+ return query;
733
884
  });
734
885
  };
735
886
 
@@ -1267,7 +1418,7 @@ const request = (config) => {
1267
1418
  body = text;
1268
1419
  }
1269
1420
  }
1270
- catch (error) {
1421
+ catch {
1271
1422
  // Ignore the error.
1272
1423
  }
1273
1424
  }
@@ -1713,6 +1864,8 @@ const createHttpRequest = (options) => {
1713
1864
  loading.set(state);
1714
1865
  };
1715
1866
  const httpRequest = {
1867
+ method: options.method,
1868
+ url: options.fullPath,
1716
1869
  execute,
1717
1870
  destroy,
1718
1871
  loading: loading.asReadonly(),
@@ -1721,6 +1874,7 @@ const createHttpRequest = (options) => {
1721
1874
  currentEvent: currentEvent.asReadonly(),
1722
1875
  events$: event$.asObservable(),
1723
1876
  isStale,
1877
+ expiresAt: expiresIn.asReadonly(),
1724
1878
  };
1725
1879
  return httpRequest;
1726
1880
  };
@@ -1881,6 +2035,17 @@ const createQueryStack = (options) => {
1881
2035
  runWithArgs,
1882
2036
  },
1883
2037
  };
2038
+ const skipDevtools = consumeSuppressQueryStackDevtools();
2039
+ if (isQueryDevtoolsEnabled() && !skipDevtools) {
2040
+ const unregister = registerQueryDevtoolsEntry({
2041
+ kind: 'query-stack',
2042
+ handle: stack,
2043
+ meta: {
2044
+ featureTypes: features.map((f) => f.type),
2045
+ },
2046
+ });
2047
+ inject(DestroyRef).onDestroy(unregister);
2048
+ }
1884
2049
  return stack;
1885
2050
  };
1886
2051
 
@@ -1953,6 +2118,7 @@ const createPagedQueryStack = (options) => {
1953
2118
  ...(ngDevMode ? [{ debugName: "resetTrigger" }] : /* istanbul ignore next */ []));
1954
2119
  const pageDirection = signal('next', /* @ts-ignore */
1955
2120
  ...(ngDevMode ? [{ debugName: "pageDirection" }] : /* istanbul ignore next */ []));
2121
+ suppressNextQueryStackDevtools();
1956
2122
  const stack = createQueryStack({
1957
2123
  args: () => null,
1958
2124
  queryCreator,
@@ -2160,6 +2326,16 @@ const createPagedQueryStack = (options) => {
2160
2326
  reset,
2161
2327
  execute,
2162
2328
  };
2329
+ if (isQueryDevtoolsEnabled()) {
2330
+ const unregister = registerQueryDevtoolsEntry({
2331
+ kind: 'paged-query-stack',
2332
+ handle: pagedQuery,
2333
+ meta: {
2334
+ featureTypes: features?.map((f) => f.type),
2335
+ },
2336
+ });
2337
+ inject(DestroyRef).onDestroy(unregister);
2338
+ }
2163
2339
  return pagedQuery;
2164
2340
  };
2165
2341
 
@@ -3355,13 +3531,17 @@ const isQueryCollection = (query) => {
3355
3531
  const createQueryCollection = (
3356
3532
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
3357
3533
  queryMap) => new BehaviorSubject(null);
3358
- const createQueryCollectionSubject = (queryMap, config) => {
3534
+ const createQueryCollectionSubject = (
3535
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
3536
+ queryMap, config) => {
3359
3537
  assertInInjectionContext(createQueryCollectionSubject);
3360
3538
  const subject = new BehaviorSubject(null);
3361
3539
  addQueryContainerHandling(subject.pipe(map((s) => s?.query ?? null)), () => subject.getValue()?.query ?? null, config);
3362
3540
  return subject;
3363
3541
  };
3364
- const createQueryCollectionSignal = (queryMap, config) => {
3542
+ const createQueryCollectionSignal = (
3543
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
3544
+ queryMap, config) => {
3365
3545
  assertInInjectionContext(createQueryCollectionSignal);
3366
3546
  const _signal = signal(null, /* @ts-ignore */
3367
3547
  ...(ngDevMode ? [{ debugName: "_signal" }] : /* istanbul ignore next */ []));
@@ -4308,7 +4488,7 @@ class InfinityQueryDirective {
4308
4488
  get data$() {
4309
4489
  return this._data$.asObservable();
4310
4490
  }
4311
- static ngTemplateContextGuard(dir, ctx) {
4491
+ static ngTemplateContextGuard(_dir, _ctx) {
4312
4492
  return true;
4313
4493
  }
4314
4494
  constructor() {
@@ -4410,13 +4590,13 @@ class InfinityQueryDirective {
4410
4590
  this._viewContext.currentQuery = null;
4411
4591
  this._data$.next([]);
4412
4592
  }
4413
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: InfinityQueryDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
4414
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.0.5", type: InfinityQueryDirective, isStandalone: true, selector: "[etInfinityQuery]", inputs: { infinityQuery: ["etInfinityQuery", "infinityQuery"] }, providers: [
4593
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: InfinityQueryDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
4594
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.0.7", type: InfinityQueryDirective, isStandalone: true, selector: "[etInfinityQuery]", inputs: { infinityQuery: ["etInfinityQuery", "infinityQuery"] }, providers: [
4415
4595
  { provide: INFINITY_QUERY_TOKEN, useExisting: InfinityQueryDirective },
4416
4596
  provideInfinityQueryResponseDelay(),
4417
4597
  ], exportAs: ["etInfinityQuery"], ngImport: i0 }); }
4418
4598
  }
4419
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: InfinityQueryDirective, decorators: [{
4599
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: InfinityQueryDirective, decorators: [{
4420
4600
  type: Directive,
4421
4601
  args: [{
4422
4602
  selector: '[etInfinityQuery]',
@@ -4476,10 +4656,10 @@ class InfinityQueryTriggerDirective {
4476
4656
  });
4477
4657
  this._observer.observe(this._elementRef.nativeElement);
4478
4658
  }
4479
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: InfinityQueryTriggerDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
4480
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.0.5", type: InfinityQueryTriggerDirective, isStandalone: true, selector: "[etInfinityQueryTrigger], et-infinity-query-trigger", inputs: { scrollContainerSelector: { classPropertyName: "scrollContainerSelector", publicName: "scrollContainerSelector", isSignal: true, isRequired: false, transformFunction: null }, infinityQueryOverride: { classPropertyName: "infinityQueryOverride", publicName: "infinityQueryOverride", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0 }); }
4659
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: InfinityQueryTriggerDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
4660
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.0.7", type: InfinityQueryTriggerDirective, isStandalone: true, selector: "[etInfinityQueryTrigger], et-infinity-query-trigger", inputs: { scrollContainerSelector: { classPropertyName: "scrollContainerSelector", publicName: "scrollContainerSelector", isSignal: true, isRequired: false, transformFunction: null }, infinityQueryOverride: { classPropertyName: "infinityQueryOverride", publicName: "infinityQueryOverride", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0 }); }
4481
4661
  }
4482
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: InfinityQueryTriggerDirective, decorators: [{
4662
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: InfinityQueryTriggerDirective, decorators: [{
4483
4663
  type: Directive,
4484
4664
  args: [{
4485
4665
  selector: '[etInfinityQueryTrigger], et-infinity-query-trigger',
@@ -4487,7 +4667,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImpor
4487
4667
  }], propDecorators: { scrollContainerSelector: [{ type: i0.Input, args: [{ isSignal: true, alias: "scrollContainerSelector", required: false }] }], infinityQueryOverride: [{ type: i0.Input, args: [{ isSignal: true, alias: "infinityQueryOverride", required: false }] }] } });
4488
4668
 
4489
4669
  class QueryDirective {
4490
- static ngTemplateContextGuard(dir, ctx) {
4670
+ static ngTemplateContextGuard(_dir, _ctx) {
4491
4671
  return true;
4492
4672
  }
4493
4673
  constructor() {
@@ -4565,10 +4745,10 @@ class QueryDirective {
4565
4745
  });
4566
4746
  });
4567
4747
  }
4568
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: QueryDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
4569
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.0.5", type: QueryDirective, isStandalone: true, selector: "[etQuery]", inputs: { query: { classPropertyName: "query", publicName: "etQuery", isSignal: true, isRequired: true, transformFunction: null }, cache: { classPropertyName: "cache", publicName: "etQueryCache", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0 }); }
4748
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: QueryDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
4749
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.0.7", type: QueryDirective, isStandalone: true, selector: "[etQuery]", inputs: { query: { classPropertyName: "query", publicName: "etQuery", isSignal: true, isRequired: true, transformFunction: null }, cache: { classPropertyName: "cache", publicName: "etQueryCache", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0 }); }
4570
4750
  }
4571
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: QueryDirective, decorators: [{
4751
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: QueryDirective, decorators: [{
4572
4752
  type: Directive,
4573
4753
  args: [{
4574
4754
  selector: '[etQuery]',
@@ -4589,10 +4769,10 @@ class QueryShortNamePipe {
4589
4769
  }
4590
4770
  return route;
4591
4771
  }
4592
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: QueryShortNamePipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
4593
- static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "22.0.5", ngImport: i0, type: QueryShortNamePipe, isStandalone: true, name: "queryShortName" }); }
4772
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: QueryShortNamePipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
4773
+ static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "22.0.7", ngImport: i0, type: QueryShortNamePipe, isStandalone: true, name: "queryShortName" }); }
4594
4774
  }
4595
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: QueryShortNamePipe, decorators: [{
4775
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: QueryShortNamePipe, decorators: [{
4596
4776
  type: Pipe,
4597
4777
  args: [{ name: 'queryShortName' }]
4598
4778
  }] });
@@ -4639,15 +4819,13 @@ class QueryDevtoolsComponent {
4639
4819
  this.selectedQueryId = signal(null, /* @ts-ignore */
4640
4820
  ...(ngDevMode ? [{ debugName: "selectedQueryId" }] : /* istanbul ignore next */ []));
4641
4821
  this.selectedClientConfig = computed(() => {
4642
- if (this.queryClientConfigs.length === 1) {
4643
- return this.queryClientConfigs[0];
4644
- }
4645
- const index = this.selectedClientId() ?? 0;
4646
- const cfg = this.queryClientConfigs[index];
4647
- if (!cfg) {
4648
- return this.queryClientConfigs[0];
4822
+ const configs = this.queryClientConfigs;
4823
+ const index = configs.length === 1 ? 0 : (this.selectedClientId() ?? 0);
4824
+ const config = configs[index] ?? configs[0];
4825
+ if (!config) {
4826
+ throw new Error('QueryDevtools: no query client configs registered');
4649
4827
  }
4650
- return cfg;
4828
+ return config;
4651
4829
  }, /* @ts-ignore */
4652
4830
  ...(ngDevMode ? [{ debugName: "selectedClientConfig" }] : /* istanbul ignore next */ []));
4653
4831
  this.queryStore = computed(() => {
@@ -4900,10 +5078,10 @@ class QueryDevtoolsComponent {
4900
5078
  clearQueryHistory() {
4901
5079
  this.queryHistory$.next([]);
4902
5080
  }
4903
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: QueryDevtoolsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
4904
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.5", type: QueryDevtoolsComponent, isStandalone: true, selector: "et-query-devtools", host: { classAttribute: "et-query-devtools" }, ngImport: i0, template: "@if (!isOpen()) {\n <button (click)=\"toggleOpen()\" class=\"et-query-devtools-open-btn et-qd-chip\">Query Devtools</button>\n}\n\n@if (isOpen()) {\n <div\n [class.et-query-devtools-container--transparent]=\"isTranslucent()\"\n class=\"et-query-devtools-container et-query-devtools-container--snap-{{ snapLayout() }}\"\n >\n <header class=\"et-qd-header\">\n <h3 class=\"et-qd-header__title\">Query Devtools</h3>\n\n <div class=\"et-qd-header__select\">\n <label for=\"et-query-client-instance\">Client instance</label>\n <select [formControl]=\"selectedClientIdCtrl\" id=\"et-query-client-instance\">\n @for (clientConfig of queryClientConfigs; track trackByClient(i, clientConfig); let i = $index) {\n <option [value]=\"i\">\n {{ clientConfig.displayName ?? clientConfig.client.config.baseRoute }}\n </option>\n }\n </select>\n </div>\n\n <button (click)=\"toggleOpen()\" class=\"et-qd-btn et-qd-btn-secondary\">Close</button>\n </header>\n\n <div class=\"et-qd-sub-header\">\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': !isTranslucent() }\"\n (click)=\"toggleTranslucent()\"\n class=\"et-qd-chip et-qd-translucent-clickable\"\n >\n Translucent\n </button>\n <div class=\"et-qd-sub-header__divider\"></div>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': snapLayout() !== 'full' }\"\n (click)=\"selectSnapLayout('full')\"\n class=\"et-qd-chip\"\n >\n Fullscreen\n </button>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': snapLayout() !== 'top' }\"\n (click)=\"selectSnapLayout('top')\"\n class=\"et-qd-chip\"\n >\n Top\n </button>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': snapLayout() !== 'bottom' }\"\n (click)=\"selectSnapLayout('bottom')\"\n class=\"et-qd-chip\"\n >\n Bottom\n </button>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': snapLayout() !== 'left' }\"\n (click)=\"selectSnapLayout('left')\"\n class=\"et-qd-chip\"\n >\n Left\n </button>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': snapLayout() !== 'right' }\"\n (click)=\"selectSnapLayout('right')\"\n class=\"et-qd-chip\"\n >\n Right\n </button>\n </div>\n\n @if (selectedClientConfig(); as cfg) {\n <div class=\"et-qd-client\">\n <p class=\"et-qd-client__title\">{{ cfg.displayName ?? cfg.client.config.baseRoute }}</p>\n\n <div class=\"et-qd-client__actions\">\n <button (click)=\"cfg.client._store.refreshQueriesInUse()\" class=\"et-qd-chip\">Refresh all</button>\n <button (click)=\"cfg.client._store.refreshQueriesInUse({ ignoreCacheValidity: true })\" class=\"et-qd-chip\">\n Refresh all (ignore caches)\n </button>\n <button\n (click)=\"cfg.client._store.refreshQueriesInUse({ ignoreCacheValidity: true, purgeUnused: true })\"\n class=\"et-qd-chip\"\n >\n Refresh all (ignore caches & purge unused)\n </button>\n </div>\n </div>\n }\n\n @if (selectedClientConfig(); as cfg) {\n <div class=\"et-qd-queries\">\n <p class=\"et-qd-queries__title\">Inspector</p>\n <div class=\"et-qd-queries__actions\">\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': queryListMode() !== 'live' || viewMode() !== 'query' }\"\n (click)=\"selectQueryListMode('live'); selectViewMode('query')\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Live Queries ({{ queries()?.length ?? 0 }})\n </button>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': queryListMode() !== 'history' || viewMode() !== 'query' }\"\n (click)=\"selectQueryListMode('history'); selectViewMode('query')\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Query History ({{ (queryHistory$ | async)?.length ?? 0 }}/50)\n </button>\n @if (queryListMode() === 'history' && viewMode() === 'query') {\n <div class=\"et-qd-queries__divider\"></div>\n <button (click)=\"clearQueryHistory()\" class=\"et-qd-chip et-qd-chip-bordered\">Clear history</button>\n }\n\n <div class=\"et-qd-queries__divider\"></div>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': viewMode() !== 'authProvider' }\"\n (click)=\"selectViewMode('authProvider')\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Auth Provider\n </button>\n </div>\n\n @if (viewMode() === 'query') {\n <div class=\"et-qd-queries__browser\">\n @if (queryListMode() === 'live') {\n <ul class=\"et-qd-queries__browser-list\">\n @for (query of queries(); track trackByQuery($index, query)) {\n <li>\n <button\n [class.et-qd-query--active]=\"selectedQuery()?._id === query._id\"\n (click)=\"selectQuery(query)\"\n >\n <span> {{ query._queryConfig.method }}</span>\n <span> {{ query | queryShortName }}</span>\n </button>\n </li>\n }\n </ul>\n }\n @if (queryListMode() === 'history') {\n <ul class=\"et-qd-queries__browser-list\">\n @for (query of queryHistory$ | async; track trackByQuery($index, query)) {\n <li>\n <button\n [class.et-qd-query--active]=\"selectedQuery()?._id === query._id\"\n (click)=\"selectQuery(query)\"\n >\n <span> {{ query._queryConfig.method }}</span>\n <span> {{ query | queryShortName }}</span>\n </button>\n </li>\n }\n </ul>\n }\n <div class=\"et-qd-queries__browser-detail\">\n @if (selectedQuery(); as query) {\n <p class=\"et-qd-queries__browser-detail__title\">\n {{ query._queryConfig.method }} {{ query._routeWithParams }}\n </p>\n\n <div class=\"et-qd-queries__actions\">\n <button (click)=\"query.execute()\" class=\"et-qd-chip et-qd-chip-bordered\">Execute</button>\n <button (click)=\"query.execute({ skipCache: true })\" class=\"et-qd-chip et-qd-chip-bordered\">\n Execute (ignore cache)\n </button>\n\n <button (click)=\"query.abort()\" class=\"et-qd-chip et-qd-chip-bordered\">Abort</button>\n <div class=\"et-qd-queries__divider\"></div>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': !query.isPolling }\"\n (click)=\"query.poll({ interval: 5000, takeUntil: _destroy$ })\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Poll\n </button>\n\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': query.isPolling }\"\n (click)=\"query.stopPolling()\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Stop polling\n </button>\n @if (query.isPolling || query._isPollingPaused) {\n <button (click)=\"query.pausePolling()\" class=\"et-qd-chip et-qd-chip-secondary et-qd-chip-bordered\">\n Pause polling\n </button>\n <button (click)=\"query.resumePolling()\" class=\"et-qd-chip et-qd-chip-secondary et-qd-chip-bordered\">\n Resume polling\n </button>\n }\n </div>\n\n <div class=\"et-qd-list\">\n <div class=\"et-qd-list-item\">\n <p>State type</p>\n <pre>{{ query.rawState.type }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Dependents</p>\n <pre>{{ query._dependents | json }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Is expired</p>\n <pre>{{ query.isExpired }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Is in use</p>\n <pre>{{ query.isInUse }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Subscriber count</p>\n <pre>{{ query._subscriberCount }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Is polling</p>\n <pre>{{ query.isPolling }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Is polling paused</p>\n <pre>{{ query._isPollingPaused }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Enable smart polling</p>\n <pre>{{ query._enableSmartPolling }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Query store key</p>\n <pre>{{ query._queryStoreKey }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Arguments</p>\n\n <div>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': !showArguments() }\"\n (click)=\"toggleShowArguments()\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Toggle\n </button>\n </div>\n @if (showArguments()) {\n <pre>{{ query._arguments | json }}</pre>\n }\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>State</p>\n <p><i> Warning, this will cause a subscription if shown!</i></p>\n <div>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': !showResponse() }\"\n (click)=\"toggleShowResponse()\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Toggle\n </button>\n </div>\n @if (showResponse()) {\n <pre>{{ query.state$ | async | json }}</pre>\n }\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Raw state</p>\n <p><i> The query state unaffected by entity stores</i></p>\n\n <div>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': !showRawResponse() }\"\n (click)=\"toggleShowRawResponse()\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Toggle\n </button>\n </div>\n @if (showRawResponse()) {\n <pre>{{ query.rawState | json }}</pre>\n }\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Query config</p>\n\n <div>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': !showQueryConfig() }\"\n (click)=\"toggleShowQueryConfig()\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Toggle\n </button>\n </div>\n @if (showQueryConfig()) {\n <pre>{{ stringifiedQueryConfig() | json }}</pre>\n }\n </div>\n\n @if (!!query._queryConfig.entity) {\n <div class=\"et-qd-list-item\">\n <p>Entity store value</p>\n\n <div>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': !showEntityStoreValue() }\"\n (click)=\"toggleShowEntityStoreValue()\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Toggle\n </button>\n </div>\n @if (showEntityStoreValue()) {\n <pre>{{ selectedQueryEntityStoreValue$ | async | json }}</pre>\n }\n </div>\n }\n </div>\n }\n </div>\n </div>\n } @else if (viewMode() === 'authProvider') {\n <div class=\"et-qd-auth-provider__viewer\">\n @if (authProviderDetails(); as details) {\n <div class=\"et-qd-list\">\n <div class=\"et-qd-list-item\">\n <p>Type</p>\n <pre>{{ details.type }}</pre>\n </div>\n <div class=\"et-qd-list-item\">\n <p>Header value</p>\n <pre>{{ details.header() | json }}</pre>\n </div>\n <div class=\"et-qd-list-item\">\n <p>Config</p>\n <pre>{{ details.config | json }}</pre>\n </div>\n\n @if (details.type === 'BearerAuthProvider') {\n <div class=\"et-qd-list-item\">\n <p>Tokens</p>\n <pre>{{ details.provider.tokens$ | async | json }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Should refresh on unauthorized response</p>\n <pre>{{ details.provider.shouldRefreshOnUnauthorizedResponse }}</pre>\n </div>\n\n <ng-container\n *etQuery=\"\n details.provider.currentRefreshQuery$ | async as response;\n loading as loading;\n error as error;\n query as query\n \"\n >\n <div class=\"et-qd-list-item\">\n <p>Refresh query response</p>\n\n <div>\n <button (click)=\"details.provider._refreshQuery()\" class=\"et-qd-chip et-qd-chip-bordered\">\n Refresh\n </button>\n </div>\n <pre>{{ response | json }}</pre>\n </div>\n <div class=\"et-qd-list-item\">\n <p>Refresh query loading</p>\n <pre>{{ loading }}</pre>\n </div>\n <div class=\"et-qd-list-item\">\n <p>Refresh query error</p>\n <pre>{{ error ?? 'null' }}</pre>\n </div>\n <div class=\"et-qd-list-item\">\n <p>State</p>\n <pre>{{ $safeNavigationMigration(query?.state$) | async | json }}</pre>\n </div>\n </ng-container>\n }\n </div>\n } @else {\n <p>No auth provider set</p>\n }\n </div>\n }\n </div>\n }\n </div>\n}\n", styles: [":host{position:fixed;top:0;z-index:1000000;font-size:14px;color:#fff}.et-query-devtools-container{position:fixed;inset:0;background-color:#25292e;z-index:10000;overflow:auto;font-family:monospace;display:grid;grid-template-rows:auto auto auto minmax(0,1fr)}.et-query-devtools-container.et-query-devtools-container--transparent{opacity:.25;pointer-events:none}.et-query-devtools-container.et-query-devtools-container--transparent .et-query-devtools-translucent-btn{pointer-events:all}.et-query-devtools-container.et-query-devtools-container--snap-left{inset-inline-start:0;inset-block-start:0;inset-block-end:0;width:50%;border-right:1px solid rgb(37,41,46)}.et-query-devtools-container.et-query-devtools-container--snap-right{inset-inline-start:unset;inset-inline-end:0;inset-block-start:0;inset-block-end:0;width:50%;border-left:1px solid rgb(37,41,46)}.et-query-devtools-container.et-query-devtools-container--snap-top{inset-inline-start:0;inset-block-start:0;inset-inline-end:0;height:50%;border-bottom:1px solid rgb(37,41,46)}.et-query-devtools-container.et-query-devtools-container--snap-bottom{inset-inline-start:0;inset-block-start:unset;inset-block-end:0;inset-inline-end:0;height:50%;border-top:1px solid rgb(37,41,46)}button.et-query-devtools-open-btn{position:fixed;inset-inline-end:20px;inset-block-end:0;z-index:9999;font-family:monospace;border-radius:3px 3px 0 0;line-height:14px;font-size:12px}.et-qd-header{background-color:#00ffa1;padding:12px;display:grid;grid-template-columns:1fr auto auto;gap:12px;align-items:center}.et-qd-header__title{color:#25292e;margin:0;font-size:22px}.et-qd-header__select{display:grid;background-color:#25292e;border-radius:10px;overflow:hidden}.et-qd-header__select select{width:250px;color:#fff;padding:3px 10px 2px;border:none;background-color:#25292e;font-family:monospace}.et-qd-header__select label{padding:3px 10px;color:#25292e;font-size:12px;font-weight:700;color:#fff;border-bottom:1px solid gray}.et-qd-sub-header{background-color:#00b371;padding:12px;display:flex;gap:12px;flex-wrap:wrap}.et-qd-sub-header__divider{width:1px;background-color:#25292e}.et-qd-btn{background-color:#00ffa1;color:#25292e;border:none;padding:12px;cursor:pointer;font-size:14px;font-weight:700;text-align:center;text-decoration:none;display:inline-block;width:100%;transition:all .3s ease-in-out;font-family:monospace;border-radius:10px}.et-qd-btn:hover{background-color:#00cc81}.et-qd-btn.et-qd-btn-secondary{background-color:#25292e;color:#00ffa1}.et-qd-btn.et-qd-btn-secondary:hover{background-color:#3c424a}.et-qd-chip{background-color:#00ffa1;color:#25292e;border:none;padding:4px 9px;cursor:pointer;font-size:12px;font-weight:700;text-align:center;text-decoration:none;display:inline-block;transition:all .3s ease-in-out;font-family:monospace;border-radius:10px}.et-qd-chip:hover{background-color:#00cc81}.et-qd-chip.et-qd-chip-secondary{background-color:#25292e;color:#00ffa1}.et-qd-chip.et-qd-chip-secondary:hover{background-color:#3c424a}.et-qd-chip.et-qd-chip-bordered{border:1px solid rgb(0,255,161)}.et-qd-translucent-clickable{pointer-events:all}.et-qd-client{border-bottom:1px solid rgb(59.734939759,66.1927710843,74.265060241);padding:12px}.et-qd-client__title{margin:0;font-size:14px;color:#fff;font-weight:700}.et-qd-client__actions{display:flex;gap:12px;margin-top:12px}.et-qd-queries{padding:12px;display:grid;grid-template-rows:auto auto minmax(0,1fr)}.et-qd-queries__actions{display:flex;gap:12px;margin-top:12px;margin-bottom:16px}.et-qd-queries__title{margin:0;font-size:14px;color:#fff;font-weight:700}.et-qd-queries__divider{width:1px;background-color:#3c424a}.et-qd-queries__browser{display:grid;grid-template-columns:1fr minmax(0,3fr);margin-left:-12px;margin-right:-12px;border-top:1px solid rgb(59.734939759,66.1927710843,74.265060241);margin-bottom:-12px}.et-qd-queries__browser-list{border-right:1px solid rgb(59.734939759,66.1927710843,74.265060241);list-style:none;padding:0;margin:0;display:grid;grid-auto-flow:row;grid-auto-rows:55px;overflow-y:auto;overflow-x:hidden}.et-qd-queries__browser-list li{margin:0}.et-qd-queries__browser-list li button{all:unset;font-family:monospace;box-sizing:border-box;width:100%;border:none;border-bottom:1px solid rgb(59.734939759,66.1927710843,74.265060241);background-color:#25292e;color:#fff;text-align:left;padding:12px;height:100%;transition:all .3s ease-in-out;cursor:pointer;display:grid;grid-template-columns:auto minmax(0,1fr);gap:2px;display:block}.et-qd-queries__browser-list li button span{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.et-qd-queries__browser-list li button span:first-of-type{font-weight:700}.et-qd-queries__browser-list li button:hover,.et-qd-queries__browser-list li button.et-qd-query--active{background-color:#30363c}.et-qd-queries__browser-detail{padding:12px;overflow-y:auto;overflow-x:hidden}.et-qd-queries__browser-detail__title{margin:0;font-size:14px;color:#fff;font-weight:700}.et-qd-auth-provider__viewer{border-top:1px solid rgb(59.734939759,66.1927710843,74.265060241);margin-left:-12px;margin-right:-12px;margin-bottom:-12px;padding:12px;overflow-y:auto;overflow-x:hidden}.et-qd-list{display:grid;gap:12px}.et-qd-list-item{display:grid}.et-qd-list-item p{font-weight:700;margin:0;padding-bottom:8px}.et-qd-list-item p+p{margin-top:-8px}.et-qd-list-item div+pre{margin-top:8px}.et-qd-list-item pre{margin:0;padding:4px;background-color:#0e1012;border-radius:4px;max-height:450px;overflow:auto}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.SelectControlValueAccessor, selector: "select:not([multiple]):not([ngNoCva])[formControlName],select:not([multiple]):not([ngNoCva])[formControl],select:not([multiple]):not([ngNoCva])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: QueryDirective, selector: "[etQuery]", inputs: ["etQuery", "etQueryCache"] }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "pipe", type: JsonPipe, name: "json" }, { kind: "pipe", type: QueryShortNamePipe, name: "queryShortName" }], encapsulation: i0.ViewEncapsulation.ShadowDom }); }
5081
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: QueryDevtoolsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
5082
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.7", 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>{{ $safeNavigationMigration(query?.state$) | async | json }}</pre>\n </div>\n </ng-container>\n }\n </div>\n } @else {\n <p>No auth provider set</p>\n }\n </div>\n }\n </div>\n }\n </div>\n}\n", styles: [":host{position:fixed;top:0;z-index:1000000;font-size:14px;color:#fff}.et-query-devtools-container{position:fixed;inset:0;background-color:#25292e;z-index:10000;overflow:auto;font-family:monospace;display:grid;grid-template-rows:auto auto auto minmax(0,1fr)}.et-query-devtools-container.et-query-devtools-container--transparent{opacity:.25;pointer-events:none}.et-query-devtools-container.et-query-devtools-container--transparent .et-query-devtools-translucent-btn{pointer-events:all}.et-query-devtools-container.et-query-devtools-container--snap-left{inset-inline-start:0;inset-block-start:0;inset-block-end:0;width:50%;border-right:1px solid rgb(37,41,46)}.et-query-devtools-container.et-query-devtools-container--snap-right{inset-inline-start:unset;inset-inline-end:0;inset-block-start:0;inset-block-end:0;width:50%;border-left:1px solid rgb(37,41,46)}.et-query-devtools-container.et-query-devtools-container--snap-top{inset-inline-start:0;inset-block-start:0;inset-inline-end:0;height:50%;border-bottom:1px solid rgb(37,41,46)}.et-query-devtools-container.et-query-devtools-container--snap-bottom{inset-inline-start:0;inset-block-start:unset;inset-block-end:0;inset-inline-end:0;height:50%;border-top:1px solid rgb(37,41,46)}button.et-query-devtools-open-btn{position:fixed;inset-inline-end:20px;inset-block-end:0;z-index:9999;font-family:monospace;border-radius:3px 3px 0 0;line-height:14px;font-size:12px}.et-qd-header{background-color:#00ffa1;padding:12px;display:grid;grid-template-columns:1fr auto auto;gap:12px;align-items:center}.et-qd-header__title{color:#25292e;margin:0;font-size:22px}.et-qd-header__select{display:grid;background-color:#25292e;border-radius:10px;overflow:hidden}.et-qd-header__select select{width:250px;color:#fff;padding:3px 10px 2px;border:none;background-color:#25292e;font-family:monospace}.et-qd-header__select label{padding:3px 10px;color:#25292e;font-size:12px;font-weight:700;color:#fff;border-bottom:1px solid gray}.et-qd-sub-header{background-color:#00b371;padding:12px;display:flex;gap:12px;flex-wrap:wrap}.et-qd-sub-header__divider{width:1px;background-color:#25292e}.et-qd-btn{background-color:#00ffa1;color:#25292e;border:none;padding:12px;cursor:pointer;font-size:14px;font-weight:700;text-align:center;text-decoration:none;display:inline-block;width:100%;transition:all .3s ease-in-out;font-family:monospace;border-radius:10px}.et-qd-btn:hover{background-color:#00cc81}.et-qd-btn.et-qd-btn-secondary{background-color:#25292e;color:#00ffa1}.et-qd-btn.et-qd-btn-secondary:hover{background-color:#3c424a}.et-qd-chip{background-color:#00ffa1;color:#25292e;border:none;padding:4px 9px;cursor:pointer;font-size:12px;font-weight:700;text-align:center;text-decoration:none;display:inline-block;transition:all .3s ease-in-out;font-family:monospace;border-radius:10px}.et-qd-chip:hover{background-color:#00cc81}.et-qd-chip.et-qd-chip-secondary{background-color:#25292e;color:#00ffa1}.et-qd-chip.et-qd-chip-secondary:hover{background-color:#3c424a}.et-qd-chip.et-qd-chip-bordered{border:1px solid rgb(0,255,161)}.et-qd-translucent-clickable{pointer-events:all}.et-qd-client{border-bottom:1px solid rgb(59.734939759,66.1927710843,74.265060241);padding:12px}.et-qd-client__title{margin:0;font-size:14px;color:#fff;font-weight:700}.et-qd-client__actions{display:flex;gap:12px;margin-top:12px}.et-qd-queries{padding:12px;display:grid;grid-template-rows:auto auto minmax(0,1fr)}.et-qd-queries__actions{display:flex;gap:12px;margin-top:12px;margin-bottom:16px}.et-qd-queries__title{margin:0;font-size:14px;color:#fff;font-weight:700}.et-qd-queries__divider{width:1px;background-color:#3c424a}.et-qd-queries__browser{display:grid;grid-template-columns:1fr minmax(0,3fr);margin-left:-12px;margin-right:-12px;border-top:1px solid rgb(59.734939759,66.1927710843,74.265060241);margin-bottom:-12px}.et-qd-queries__browser-list{border-right:1px solid rgb(59.734939759,66.1927710843,74.265060241);list-style:none;padding:0;margin:0;display:grid;grid-auto-flow:row;grid-auto-rows:55px;overflow-y:auto;overflow-x:hidden}.et-qd-queries__browser-list li{margin:0}.et-qd-queries__browser-list li button{all:unset;font-family:monospace;box-sizing:border-box;width:100%;border:none;border-bottom:1px solid rgb(59.734939759,66.1927710843,74.265060241);background-color:#25292e;color:#fff;text-align:left;padding:12px;height:100%;transition:all .3s ease-in-out;cursor:pointer;display:grid;grid-template-columns:auto minmax(0,1fr);gap:2px;display:block}.et-qd-queries__browser-list li button span{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.et-qd-queries__browser-list li button span:first-of-type{font-weight:700}.et-qd-queries__browser-list li button:hover,.et-qd-queries__browser-list li button.et-qd-query--active{background-color:#30363c}.et-qd-queries__browser-detail{padding:12px;overflow-y:auto;overflow-x:hidden}.et-qd-queries__browser-detail__title{margin:0;font-size:14px;color:#fff;font-weight:700}.et-qd-auth-provider__viewer{border-top:1px solid rgb(59.734939759,66.1927710843,74.265060241);margin-left:-12px;margin-right:-12px;margin-bottom:-12px;padding:12px;overflow-y:auto;overflow-x:hidden}.et-qd-list{display:grid;gap:12px}.et-qd-list-item{display:grid}.et-qd-list-item p{font-weight:700;margin:0;padding-bottom:8px}.et-qd-list-item p+p{margin-top:-8px}.et-qd-list-item div+pre{margin-top:8px}.et-qd-list-item pre{margin:0;padding:4px;background-color:#0e1012;border-radius:4px;max-height:450px;overflow:auto}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.SelectControlValueAccessor, selector: "select:not([multiple]):not([ngNoCva])[formControlName],select:not([multiple]):not([ngNoCva])[formControl],select:not([multiple]):not([ngNoCva])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: QueryDirective, selector: "[etQuery]", inputs: ["etQuery", "etQueryCache"] }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "pipe", type: JsonPipe, name: "json" }, { kind: "pipe", type: QueryShortNamePipe, name: "queryShortName" }], encapsulation: i0.ViewEncapsulation.ShadowDom }); }
4905
5083
  }
4906
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: QueryDevtoolsComponent, decorators: [{
5084
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: QueryDevtoolsComponent, decorators: [{
4907
5085
  type: Component,
4908
5086
  args: [{ selector: 'et-query-devtools', encapsulation: ViewEncapsulation.ShadowDom, host: {
4909
5087
  class: 'et-query-devtools',
@@ -5278,6 +5456,11 @@ const generateUuid = () => randomId();
5278
5456
  const createQueryRepository = (config) => {
5279
5457
  const cache = new Map();
5280
5458
  const eventsSubject = new Subject();
5459
+ // Bumped on every cache mutation so the devtools cache view can react. Cheap enough to keep
5460
+ // unconditional — it is a single integer signal with no readers unless the devtools are open.
5461
+ const cacheVersion = signal(0, /* @ts-ignore */
5462
+ ...(ngDevMode ? [{ debugName: "cacheVersion" }] : /* istanbul ignore next */ []));
5463
+ const bumpCacheVersion = () => cacheVersion.update((v) => v + 1);
5281
5464
  const request = (options) => {
5282
5465
  const { args, creatorOptions, runQueryOptions } = options;
5283
5466
  const shouldCache = creatorOptions?.subtle?.useQueryRepositoryCache === false
@@ -5342,6 +5525,7 @@ const createQueryRepository = (config) => {
5342
5525
  cacheEntry.eventSubscription?.unsubscribe();
5343
5526
  cache.delete(key);
5344
5527
  }
5528
+ bumpCacheVersion();
5345
5529
  return true;
5346
5530
  };
5347
5531
  const unbindAllSecure = () => {
@@ -5354,6 +5538,7 @@ const createQueryRepository = (config) => {
5354
5538
  cache.delete(key);
5355
5539
  }
5356
5540
  }
5541
+ bumpCacheVersion();
5357
5542
  };
5358
5543
  const bind = (key, consumerDestroyRef, request, isSecure, allowReuse) => {
5359
5544
  const destroyListener = consumerDestroyRef.onDestroy(() => unbind(key, consumerDestroyRef));
@@ -5384,12 +5569,33 @@ const createQueryRepository = (config) => {
5384
5569
  eventSubscription,
5385
5570
  });
5386
5571
  }
5572
+ bumpCacheVersion();
5573
+ };
5574
+ const cacheEntries = () => Array.from(cache.entries()).map(([key, entry]) => ({
5575
+ key,
5576
+ isSecure: entry.isSecure,
5577
+ consumerCount: entry.consumers.size,
5578
+ request: entry.request,
5579
+ }));
5580
+ const evict = (key) => {
5581
+ const entry = cache.get(key);
5582
+ if (!entry)
5583
+ return;
5584
+ entry.request.destroy();
5585
+ entry.eventSubscription?.unsubscribe();
5586
+ cache.delete(key);
5587
+ bumpCacheVersion();
5387
5588
  };
5388
5589
  const repository = {
5389
5590
  request,
5390
5591
  unbind,
5391
5592
  unbindAllSecure,
5392
5593
  events$: eventsSubject.asObservable(),
5594
+ subtle: {
5595
+ cacheEntries,
5596
+ cacheVersion: cacheVersion.asReadonly(),
5597
+ evict,
5598
+ },
5393
5599
  };
5394
5600
  return repository;
5395
5601
  };
@@ -5404,6 +5610,7 @@ const createQueryClient = (options) => createRootProvider(() => {
5404
5610
  });
5405
5611
  const client = {
5406
5612
  repository,
5613
+ baseUrl: options.baseUrl,
5407
5614
  };
5408
5615
  return client;
5409
5616
  }, {
@@ -5490,6 +5697,123 @@ const executeUntilSettled = async (query, executeArgs) => {
5490
5697
  return snapshot;
5491
5698
  };
5492
5699
 
5700
+ /* eslint-disable @typescript-eslint/no-explicit-any */
5701
+ const createSequenceState = () => ({
5702
+ status: signal('idle'),
5703
+ running: signal(false),
5704
+ currentStep: signal(0),
5705
+ error: signal(null),
5706
+ failedAt: signal(null),
5707
+ snapshots: signal([]),
5708
+ stepArgs: signal([]),
5709
+ responses: signal([]),
5710
+ });
5711
+ const buildSequence = (steps, state, devtoolsHandle) => {
5712
+ const run = async () => {
5713
+ if (state.running())
5714
+ throw querySequenceAlreadyRunning();
5715
+ state.status.set('running');
5716
+ state.running.set(true);
5717
+ state.currentStep.set(0);
5718
+ state.error.set(null);
5719
+ state.failedAt.set(null);
5720
+ state.snapshots.set([]);
5721
+ state.stepArgs.set([]);
5722
+ state.responses.set([]);
5723
+ const snapshots = [];
5724
+ const stepArgs = [];
5725
+ const responses = [];
5726
+ let previousResponse = undefined;
5727
+ for (const [i, step] of steps.entries()) {
5728
+ state.currentStep.set(i + 1);
5729
+ const { args } = step.produceArgs(previousResponse, responses);
5730
+ stepArgs.push(args);
5731
+ state.stepArgs.set([...stepArgs]);
5732
+ const snapshot = await executeUntilSettled(step.query, { args });
5733
+ snapshots.push(snapshot);
5734
+ state.snapshots.set([...snapshots]);
5735
+ const error = snapshot.error();
5736
+ if (error) {
5737
+ state.status.set('error');
5738
+ state.error.set(error);
5739
+ state.failedAt.set(i);
5740
+ state.running.set(false);
5741
+ return { ok: false, failedAt: i, error, snapshots };
5742
+ }
5743
+ const response = snapshot.response();
5744
+ responses.push(response);
5745
+ state.responses.set([...responses]);
5746
+ previousResponse = response;
5747
+ }
5748
+ state.status.set('success');
5749
+ state.running.set(false);
5750
+ return { ok: true, responses: responses, snapshots };
5751
+ };
5752
+ const sequence = {
5753
+ then: (query, mapArgs) => buildSequence([
5754
+ ...steps,
5755
+ { query, produceArgs: (previousResponse, responses) => mapArgs(previousResponse, responses) },
5756
+ ], state, devtoolsHandle),
5757
+ status: state.status.asReadonly(),
5758
+ running: state.running.asReadonly(),
5759
+ currentStep: state.currentStep.asReadonly(),
5760
+ total: steps.length,
5761
+ queries: steps.map((s) => s.query),
5762
+ error: state.error.asReadonly(),
5763
+ failedAt: state.failedAt.asReadonly(),
5764
+ snapshots: state.snapshots.asReadonly(),
5765
+ stepArgs: state.stepArgs.asReadonly(),
5766
+ responses: state.responses.asReadonly(),
5767
+ run,
5768
+ };
5769
+ if (devtoolsHandle)
5770
+ devtoolsHandle.current = sequence;
5771
+ return sequence;
5772
+ };
5773
+ /**
5774
+ * Starts an imperative waterfall of dependent queries. Chain the remaining steps with `.then()`
5775
+ * and trigger it with `.run()` — see {@link QuerySequence}.
5776
+ *
5777
+ * The seed step's `args` are produced lazily (at `run()` time), so the sequence can safely live as
5778
+ * a component field while still reading current signal values on each run.
5779
+ *
5780
+ * @example
5781
+ * ```ts
5782
+ * readonly checkout = querySequence(this.createOrder, () => ({ args: { body: this.order() } }))
5783
+ * .then(this.createPayment, (order) => ({ args: { body: { orderId: order.id } } }))
5784
+ * .then(this.confirmOrder, (payment, [order]) => ({
5785
+ * args: { pathParams: { paymentId: payment.id }, body: { orderRef: order.id } },
5786
+ * }));
5787
+ *
5788
+ * async submit() {
5789
+ * const result = await this.checkout.run();
5790
+ * if (!result.ok) return this.handle(result.error);
5791
+ * const [order, payment, confirmation] = result.responses;
5792
+ * }
5793
+ * ```
5794
+ */
5795
+ const querySequence = (query, seedArgs) => {
5796
+ const devtoolsHandle = isQueryDevtoolsEnabled()
5797
+ ? { current: null }
5798
+ : undefined;
5799
+ const seed = buildSequence([{ query, produceArgs: () => seedArgs() }], createSequenceState(), devtoolsHandle);
5800
+ if (devtoolsHandle) {
5801
+ const unregister = registerQueryDevtoolsEntry({
5802
+ kind: 'query-sequence',
5803
+ handle: devtoolsHandle,
5804
+ meta: {},
5805
+ });
5806
+ // Sequences have no destroy hook; tie cleanup to the creating scope when there is one.
5807
+ try {
5808
+ inject(DestroyRef).onDestroy(unregister);
5809
+ }
5810
+ catch {
5811
+ // Created outside an injection context — the entry lives for the app's lifetime.
5812
+ }
5813
+ }
5814
+ return seed;
5815
+ };
5816
+
5493
5817
  /**
5494
5818
  * Binds a query-backed async validator to a signal-forms field, adapting an `@ethlete/query` v3
5495
5819
  * query into what `validateAsync` consumes. The query runs through the query client — so bearer
@@ -6119,7 +6443,7 @@ const createBearerAuthProviderImpl = (config) => {
6119
6443
  };
6120
6444
  const features = setupFeatures(config.features, featureSetupContext);
6121
6445
  setupMultiTabSyncIfEnabled(config, accessToken, refreshToken, queryClient);
6122
- return {
6446
+ const provider = {
6123
6447
  queries,
6124
6448
  features: features,
6125
6449
  accessToken: accessToken.asReadonly(),
@@ -6132,6 +6456,20 @@ const createBearerAuthProviderImpl = (config) => {
6132
6456
  logout,
6133
6457
  afterTokenRefresh$,
6134
6458
  };
6459
+ if (isQueryDevtoolsEnabled()) {
6460
+ const unregister = registerQueryDevtoolsEntry({
6461
+ kind: 'auth-provider',
6462
+ handle: provider,
6463
+ meta: {
6464
+ name: config.name,
6465
+ clientName: getQueryClientName(config.queryClientRef),
6466
+ clientBaseUrl: queryClient.baseUrl,
6467
+ repository: queryClient.repository,
6468
+ },
6469
+ });
6470
+ destroyRef.onDestroy(unregister);
6471
+ }
6472
+ return provider;
6135
6473
  };
6136
6474
  const createBearerAuthProvider = (config) => createRootProvider(() => createBearerAuthProviderImpl(config), { name: `BearerAuthProvider_${config.name}` });
6137
6475
 
@@ -6817,10 +7155,10 @@ class ParseHttpErrorCodeToTitleDePipe {
6817
7155
  constructor() {
6818
7156
  this.transform = parseHttpErrorCodeToTitleDe;
6819
7157
  }
6820
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: ParseHttpErrorCodeToTitleDePipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
6821
- static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "22.0.5", ngImport: i0, type: ParseHttpErrorCodeToTitleDePipe, isStandalone: true, name: "parseHttpErrorCodeToTitleDe" }); }
7158
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: ParseHttpErrorCodeToTitleDePipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
7159
+ static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "22.0.7", ngImport: i0, type: ParseHttpErrorCodeToTitleDePipe, isStandalone: true, name: "parseHttpErrorCodeToTitleDe" }); }
6822
7160
  }
6823
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: ParseHttpErrorCodeToTitleDePipe, decorators: [{
7161
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: ParseHttpErrorCodeToTitleDePipe, decorators: [{
6824
7162
  type: Pipe,
6825
7163
  args: [{
6826
7164
  name: 'parseHttpErrorCodeToTitleDe',
@@ -6830,10 +7168,10 @@ class ParseHttpErrorCodeToMessageDePipe {
6830
7168
  constructor() {
6831
7169
  this.transform = parseHttpErrorCodeToMessageDe;
6832
7170
  }
6833
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: ParseHttpErrorCodeToMessageDePipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
6834
- static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "22.0.5", ngImport: i0, type: ParseHttpErrorCodeToMessageDePipe, isStandalone: true, name: "parseHttpErrorCodeToMessageDe" }); }
7171
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: ParseHttpErrorCodeToMessageDePipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
7172
+ static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "22.0.7", ngImport: i0, type: ParseHttpErrorCodeToMessageDePipe, isStandalone: true, name: "parseHttpErrorCodeToMessageDe" }); }
6835
7173
  }
6836
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: ParseHttpErrorCodeToMessageDePipe, decorators: [{
7174
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: ParseHttpErrorCodeToMessageDePipe, decorators: [{
6837
7175
  type: Pipe,
6838
7176
  args: [{
6839
7177
  name: 'parseHttpErrorCodeToMessageDe',
@@ -7017,10 +7355,10 @@ class ParseHttpErrorCodeToTitleEnPipe {
7017
7355
  constructor() {
7018
7356
  this.transform = parseHttpErrorCodeToTitleEn;
7019
7357
  }
7020
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: ParseHttpErrorCodeToTitleEnPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
7021
- static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "22.0.5", ngImport: i0, type: ParseHttpErrorCodeToTitleEnPipe, isStandalone: true, name: "parseHttpErrorCodeToTitleEn" }); }
7358
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: ParseHttpErrorCodeToTitleEnPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
7359
+ static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "22.0.7", ngImport: i0, type: ParseHttpErrorCodeToTitleEnPipe, isStandalone: true, name: "parseHttpErrorCodeToTitleEn" }); }
7022
7360
  }
7023
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: ParseHttpErrorCodeToTitleEnPipe, decorators: [{
7361
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: ParseHttpErrorCodeToTitleEnPipe, decorators: [{
7024
7362
  type: Pipe,
7025
7363
  args: [{
7026
7364
  name: 'parseHttpErrorCodeToTitleEn',
@@ -7030,10 +7368,10 @@ class ParseHttpErrorCodeToMessageEnPipe {
7030
7368
  constructor() {
7031
7369
  this.transform = parseHttpErrorCodeToMessageEn;
7032
7370
  }
7033
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: ParseHttpErrorCodeToMessageEnPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
7034
- static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "22.0.5", ngImport: i0, type: ParseHttpErrorCodeToMessageEnPipe, isStandalone: true, name: "parseHttpErrorCodeToMessageEn" }); }
7371
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: ParseHttpErrorCodeToMessageEnPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
7372
+ static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "22.0.7", ngImport: i0, type: ParseHttpErrorCodeToMessageEnPipe, isStandalone: true, name: "parseHttpErrorCodeToMessageEn" }); }
7035
7373
  }
7036
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: ParseHttpErrorCodeToMessageEnPipe, decorators: [{
7374
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: ParseHttpErrorCodeToMessageEnPipe, decorators: [{
7037
7375
  type: Pipe,
7038
7376
  args: [{
7039
7377
  name: 'parseHttpErrorCodeToMessageEn',
@@ -7695,6 +8033,7 @@ const messageMalformed = () => {
7695
8033
  return new RuntimeError(WebSocketRuntimeErrorCode.MESSAGE_MALFORMED, 'A message has been received but it is malformed (cannot be parsed as JSON).');
7696
8034
  };
7697
8035
 
8036
+ const MAX_DEVTOOLS_MESSAGES = 100;
7698
8037
  const createWebSocketClient = (options) => {
7699
8038
  return createRootProvider(() => {
7700
8039
  const socket = io(options.url, {
@@ -7705,6 +8044,17 @@ const createWebSocketClient = (options) => {
7705
8044
  const rooms = new Map();
7706
8045
  const isConnected = signal(false, /* @ts-ignore */
7707
8046
  ...(ngDevMode ? [{ debugName: "isConnected" }] : /* istanbul ignore next */ []));
8047
+ // Devtools instrumentation (no-op unless provideQueryDevtools() was called).
8048
+ const devtoolsEnabled = isQueryDevtoolsEnabled();
8049
+ const devtoolsRooms = signal([], /* @ts-ignore */
8050
+ ...(ngDevMode ? [{ debugName: "devtoolsRooms" }] : /* istanbul ignore next */ []));
8051
+ const devtoolsMessages = signal([], /* @ts-ignore */
8052
+ ...(ngDevMode ? [{ debugName: "devtoolsMessages" }] : /* istanbul ignore next */ []));
8053
+ let devtoolsMessageId = 0;
8054
+ const syncDevtoolsRooms = () => {
8055
+ if (devtoolsEnabled)
8056
+ devtoolsRooms.set([...rooms.keys()]);
8057
+ };
7708
8058
  const joinRoom = (room) => {
7709
8059
  const roomFn = typeof room === 'function' ? room : () => room;
7710
8060
  const pre = previousSignalValue(computed(() => roomFn()));
@@ -7721,6 +8071,7 @@ const createWebSocketClient = (options) => {
7721
8071
  latestMessage: message,
7722
8072
  };
7723
8073
  rooms.set(name, newRoom);
8074
+ syncDevtoolsRooms();
7724
8075
  return newRoom;
7725
8076
  };
7726
8077
  effect(() => {
@@ -7757,6 +8108,7 @@ const createWebSocketClient = (options) => {
7757
8108
  }
7758
8109
  socket.emit('leave-room', room);
7759
8110
  rooms.delete(room);
8111
+ syncDevtoolsRooms();
7760
8112
  };
7761
8113
  const setupWebSocketConnectionListener = () => {
7762
8114
  socket.on('connect', () => {
@@ -7771,6 +8123,16 @@ const createWebSocketClient = (options) => {
7771
8123
  socket.onAny((data) => {
7772
8124
  try {
7773
8125
  const json = JSON.parse(data);
8126
+ if (devtoolsEnabled) {
8127
+ const message = {
8128
+ id: devtoolsMessageId++,
8129
+ timestamp: Date.now(),
8130
+ room: json.room,
8131
+ event: json.event,
8132
+ data: json.data,
8133
+ };
8134
+ devtoolsMessages.update((log) => [message, ...log].slice(0, MAX_DEVTOOLS_MESSAGES));
8135
+ }
7774
8136
  const room = rooms.get(json.room);
7775
8137
  if (room)
7776
8138
  room.latestMessage.set(json);
@@ -7793,6 +8155,19 @@ const createWebSocketClient = (options) => {
7793
8155
  leaveRoom,
7794
8156
  },
7795
8157
  };
8158
+ if (devtoolsEnabled) {
8159
+ const handle = {
8160
+ connected: isConnected.asReadonly(),
8161
+ rooms: devtoolsRooms.asReadonly(),
8162
+ messages: devtoolsMessages.asReadonly(),
8163
+ };
8164
+ const unregister = registerQueryDevtoolsEntry({
8165
+ kind: 'ws-client',
8166
+ handle,
8167
+ meta: { name: options.name, url: options.url },
8168
+ });
8169
+ inject(DestroyRef).onDestroy(unregister);
8170
+ }
7796
8171
  return client;
7797
8172
  }, {
7798
8173
  name: `WebSocketClient_${options.name}`,
@@ -7803,5 +8178,5 @@ const createWebSocketClient = (options) => {
7803
8178
  * Generated bundle index. Do not edit.
7804
8179
  */
7805
8180
 
7806
- export { BasicAuthProvider, BearerAuthFeatureType, BooleanArrayQueryField, CLEAR_QUERY_ARGS, CustomHeaderAuthProvider, DateArrayQueryField, DateQueryField, EntityStore, INFINITY_QUERY_TOKEN, InfinityQuery, InfinityQueryDirective, InfinityQueryTriggerDirective, LegacyQuery, LegacyQueryCreator, NumberArrayQueryField, ParseHttpErrorCodeToMessageDePipe, ParseHttpErrorCodeToMessageEnPipe, ParseHttpErrorCodeToTitleDePipe, ParseHttpErrorCodeToTitleEnPipe, QUERY_CLIENT_DEVTOOLS_TOKEN, QueryDevtoolsComponent, QueryDirective, QueryError, QueryFeatureType, QueryField, QueryForm, QueryRuntimeErrorCode, QueryShortNamePipe, QueryStore, SERVER_ERROR_KIND, SERVER_VIOLATION_ERROR_KIND, SPEED_BUFFER_TIME_IN_MS, SearchQueryField, SortQueryField, StringArrayQueryField, V2BearerAuthProvider, V2Query, V2QueryClient, V2QueryCreator, addQueryContainerHandling, applyQueryFeatures, authExtractTokensResponseMissingAccessToken, authExtractTokensResponseMissingRefreshToken, authExtractTokensResponseNotObject, authProviderFeatureUsedMultipleTimes, buildErrorMessage, buildQueryCacheKey, buildQueryString, buildRoute, buildTimestampFromSeconds, castQueryCreatorTypes, circularQueryDependency, circularQueryDependencyChecker, computeQueryAuthHeader, computeQueryBody, computeQueryHeaders, computeQueryMethod, computeQueryQueryParams, contentfulGqlLikePaginationAdapter, createBaseQuery, createBaseQueryCreator, createBearerAuthProvider, createDeleteQuery, createExecuteFn, createGetQuery, createGqlExecuteFn, createGqlMutationViaGet, createGqlMutationViaPost, createGqlQuery, createGqlQueryCreator, createGqlQueryViaGet, createGqlQueryViaPost, createHttpRequest, createInfinityQueryConfig, createLegacyQueryCreator, createPagedQueryStack, createPatchQuery, createPersistentAuthFeature, createPostQuery, createPutQuery, createQuery, createQueryClient, createQueryCollection, createQueryCollectionSignal, createQueryCollectionSubject, createQueryContext, createQueryCreator, createQueryErrorResponse, createQueryFeature, createQueryObject, createQueryRepository, createQuerySnapshotFn, createQueryStack, createSecureDeleteQuery, createSecureExecuteFactory, createSecureExecuteFn, createSecureGetQuery, createSecureGqlExecuteFn, createSecureGqlMutationViaGet, createSecureGqlMutationViaPost, createSecureGqlQuery, createSecureGqlQueryCreator, createSecureGqlQueryViaGet, createSecureGqlQueryViaPost, createSecurePatchQuery, createSecurePostQuery, createSecurePutQuery, createSecureQuery, createSecureQueryCreator, createTrackingFeature, createWebSocketClient, decryptBearer, deepFreeze, def, detectContentTypeHeader, dynLikePaginationAdapter, effectComputed, ethletePaginationAdapter, executeUntilSettled, extractExpiresInSeconds, extractFormViolations, extractQuery, fakePaginationAdapter, filterFailure, filterNull, filterQueryStates, filterSuccess, forEachHeader, getDefaultHeaders, getQueryFeatureUsage, getResponseUrl, ggLikePaginationAdapter, gql, gqlDataPropertyMissingInResponse, hasHeader, ignoreAutoRefresh, injectInfinityQueryResponseDelay, injectQueryContext, insertFrom, invalidBaseRouteError, invalidBodyError, invalidRouteError, invalidStateInsideSecureExecuteFactory, isAutoRefresh, isBasicAuthProvider, isBearerAuthProvider, isClassValidatorError, isCreateGqlQueryOptions, isCustomHeaderAuthProvider, isEmptyString, isGqlQueryConfig, isLegacyQuery, isNaN$1 as isNaN, isQuery, isQueryCollection, isQueryErrorResponse, isQueryStateCancelled, isQueryStateFailure, isQueryStateLoading, isQueryStatePrepared, isQueryStateSuccess, isRequestError, isSymfonyError, isSymfonyFormViolationListError, isSymfonyListError, isSymfonyPagerfantaOutOfRangeError, mapToPaginated, mapViolationsToFormErrors, maybeExecute, mergeHeaders, nestedEffect, pagedQueryStackNextPageCalledWithoutPreviousPage, pagedQueryStackPageBiggerThanTotalPages, pagedQueryStackPreviousPageCalledButAlreadyAtFirstPage, paginatedEntityValueUpdater, parseAllXhrResponseHeaders, parseHttpErrorCodeToMessageDe, parseHttpErrorCodeToMessageEn, parseHttpErrorCodeToTitleDe, parseHttpErrorCodeToTitleEn, pathParamsMissingInRouteFunctionError, provideInfinityQueryResponseDelay, provideQueryClientForDevtools, queryArrayComputed, queryComputed, queryComputedTillTruthy, queryExecute, queryFeatureUsedMultipleTimes, queryStackTotalQueriesAndExpectedQueriesMismatch, queryStackWithArgsUsed, queryStackWithResponseUpdateUsed, queryStateAlreadyHasKeyError, queryStateCannotTransformError, queryStateDoesNotContainKeyError, queryStateErrorSignal, queryStateLoadingSignal, queryStateResponseSignal, queryStateSignal, removeFrom, request, resetExecuteState, resetPageOnError, serializeBody, setupQueryDependencies, setupQueryExecuteState, setupQueryState, shouldAutoExecuteGqlQuery, shouldAutoExecuteQuery, shouldCacheQuery, shouldRetryRequest, silenceMissingWithArgsFeatureErrorUsedButWithArgsPresent, skipPaginationPageParamCalculator, splitQueryConfig, switchQueryCollectionState, switchQueryState, takeUntilResponse, toQuerySignal, toQuerySubject, tokensNotAvailableInsideAuthAndExec, transformArrayResponse, transformExecStateToQueryState, transformGql, transformMethod, transformPaginatedResponse, transformToBoolean, transformToBooleanArray, transformToDate, transformToDateArray, transformToNumber, transformToNumberArray, transformToSort, transformToSortQueryParam, transformToString, transformToStringArray, uncacheableRequestHasAllowCacheParam, uncacheableRequestHasCacheKeyParam, v2BuildQueryCacheKey, v2ExtractExpiresInSeconds, v2ShouldCacheQuery, v2ShouldRetryRequest, validateWithQuery, validateWithV2Query, withArgs, withArgsQueryFeatureMissingButRouteIsFunction, withAuthenticationQuery, withAutoRefresh, withAutoRefreshUsedInManualQuery, withAutoRefreshUsedOnUnsupportedHttpMethod, withErrorHandling, withInactivityLogout, withLogging, withPersistentAuth, withPolling, withPollingUsedOnUnsupportedHttpMethod, withRefreshQuery, withResponseUpdate, withSuccessHandling, withTokenExpirationWarning, withTokenRevocation, withTracking, wrapAsObservableSignal };
8181
+ export { BasicAuthProvider, BearerAuthFeatureType, BooleanArrayQueryField, CLEAR_QUERY_ARGS, CustomHeaderAuthProvider, DateArrayQueryField, DateQueryField, EntityStore, INFINITY_QUERY_TOKEN, InfinityQuery, InfinityQueryDirective, InfinityQueryTriggerDirective, LegacyQuery, LegacyQueryCreator, NumberArrayQueryField, ParseHttpErrorCodeToMessageDePipe, ParseHttpErrorCodeToMessageEnPipe, ParseHttpErrorCodeToTitleDePipe, ParseHttpErrorCodeToTitleEnPipe, QUERY_CLIENT_DEVTOOLS_TOKEN, QueryDevtoolsComponent, QueryDirective, QueryError, QueryFeatureType, QueryField, QueryForm, QueryRuntimeErrorCode, QueryShortNamePipe, QueryStore, SERVER_ERROR_KIND, SERVER_VIOLATION_ERROR_KIND, SPEED_BUFFER_TIME_IN_MS, SearchQueryField, SortQueryField, StringArrayQueryField, V2BearerAuthProvider, V2Query, V2QueryClient, V2QueryCreator, addQueryContainerHandling, applyQueryFeatures, authExtractTokensResponseMissingAccessToken, authExtractTokensResponseMissingRefreshToken, authExtractTokensResponseNotObject, authProviderFeatureUsedMultipleTimes, buildErrorMessage, buildQueryCacheKey, buildQueryString, buildRoute, buildTimestampFromSeconds, castQueryCreatorTypes, circularQueryDependency, circularQueryDependencyChecker, computeQueryAuthHeader, computeQueryBody, computeQueryHeaders, computeQueryMethod, computeQueryQueryParams, consumeSuppressQueryStackDevtools, contentfulGqlLikePaginationAdapter, createBaseQuery, createBaseQueryCreator, createBearerAuthProvider, createDeleteQuery, createExecuteFn, createGetQuery, createGqlExecuteFn, createGqlMutationViaGet, createGqlMutationViaPost, createGqlQuery, createGqlQueryCreator, createGqlQueryViaGet, createGqlQueryViaPost, createHttpRequest, createInfinityQueryConfig, createLegacyQueryCreator, createPagedQueryStack, createPatchQuery, createPersistentAuthFeature, createPostQuery, createPutQuery, createQuery, createQueryClient, createQueryCollection, createQueryCollectionSignal, createQueryCollectionSubject, createQueryContext, createQueryCreator, createQueryErrorResponse, createQueryFeature, createQueryObject, createQueryRepository, createQuerySnapshotFn, createQueryStack, createSecureDeleteQuery, createSecureExecuteFactory, createSecureExecuteFn, createSecureGetQuery, createSecureGqlExecuteFn, createSecureGqlMutationViaGet, createSecureGqlMutationViaPost, createSecureGqlQuery, createSecureGqlQueryCreator, createSecureGqlQueryViaGet, createSecureGqlQueryViaPost, createSecurePatchQuery, createSecurePostQuery, createSecurePutQuery, createSecureQuery, createSecureQueryCreator, createTrackingFeature, createWebSocketClient, decryptBearer, deepFreeze, def, detectContentTypeHeader, dynLikePaginationAdapter, effectComputed, ethletePaginationAdapter, executeUntilSettled, extractExpiresInSeconds, extractFormViolations, extractQuery, fakePaginationAdapter, filterFailure, filterNull, filterQueryStates, filterSuccess, forEachHeader, getDefaultHeaders, getQueryClientName, getQueryFeatureUsage, getResponseUrl, ggLikePaginationAdapter, gql, gqlDataPropertyMissingInResponse, hasHeader, ignoreAutoRefresh, injectInfinityQueryResponseDelay, injectQueryContext, insertFrom, invalidBaseRouteError, invalidBodyError, invalidRouteError, invalidStateInsideSecureExecuteFactory, isAutoRefresh, isBasicAuthProvider, isBearerAuthProvider, isClassValidatorError, isCreateGqlQueryOptions, isCustomHeaderAuthProvider, isEmptyString, isGqlQueryConfig, isLegacyQuery, isNaN$1 as isNaN, isQuery, isQueryCollection, isQueryDevtoolsEnabled, isQueryErrorResponse, isQueryStateCancelled, isQueryStateFailure, isQueryStateLoading, isQueryStatePrepared, isQueryStateSuccess, isRequestError, isSymfonyError, isSymfonyFormViolationListError, isSymfonyListError, isSymfonyPagerfantaOutOfRangeError, mapToPaginated, mapViolationsToFormErrors, maybeExecute, mergeHeaders, nestedEffect, pagedQueryStackNextPageCalledWithoutPreviousPage, pagedQueryStackPageBiggerThanTotalPages, pagedQueryStackPreviousPageCalledButAlreadyAtFirstPage, paginatedEntityValueUpdater, parseAllXhrResponseHeaders, parseHttpErrorCodeToMessageDe, parseHttpErrorCodeToMessageEn, parseHttpErrorCodeToTitleDe, parseHttpErrorCodeToTitleEn, pathParamsMissingInRouteFunctionError, provideInfinityQueryResponseDelay, provideQueryClientForDevtools, provideQueryDevtools, queryArrayComputed, queryComputed, queryComputedTillTruthy, queryDevtoolsEntries, queryExecute, queryFeatureUsedMultipleTimes, querySequence, querySequenceAlreadyRunning, queryStackTotalQueriesAndExpectedQueriesMismatch, queryStackWithArgsUsed, queryStackWithResponseUpdateUsed, queryStateAlreadyHasKeyError, queryStateCannotTransformError, queryStateDoesNotContainKeyError, queryStateErrorSignal, queryStateLoadingSignal, queryStateResponseSignal, queryStateSignal, registerQueryDevtoolsEntry, removeFrom, request, resetExecuteState, resetPageOnError, serializeBody, setupQueryDependencies, setupQueryExecuteState, setupQueryState, shouldAutoExecuteGqlQuery, shouldAutoExecuteQuery, shouldCacheQuery, shouldRetryRequest, silenceMissingWithArgsFeatureErrorUsedButWithArgsPresent, skipPaginationPageParamCalculator, splitQueryConfig, stringifyQueryRoute, suppressNextQueryStackDevtools, switchQueryCollectionState, switchQueryState, takeUntilResponse, toQuerySignal, toQuerySubject, tokensNotAvailableInsideAuthAndExec, transformArrayResponse, transformExecStateToQueryState, transformGql, transformMethod, transformPaginatedResponse, transformToBoolean, transformToBooleanArray, transformToDate, transformToDateArray, transformToNumber, transformToNumberArray, transformToSort, transformToSortQueryParam, transformToString, transformToStringArray, uncacheableRequestHasAllowCacheParam, uncacheableRequestHasCacheKeyParam, v2BuildQueryCacheKey, v2ExtractExpiresInSeconds, v2ShouldCacheQuery, v2ShouldRetryRequest, validateWithQuery, validateWithV2Query, withArgs, withArgsQueryFeatureMissingButRouteIsFunction, withAuthenticationQuery, withAutoRefresh, withAutoRefreshUsedInManualQuery, withAutoRefreshUsedOnUnsupportedHttpMethod, withErrorHandling, withInactivityLogout, withLogging, withPersistentAuth, withPolling, withPollingUsedOnUnsupportedHttpMethod, withRefreshQuery, withResponseUpdate, withSuccessHandling, withTokenExpirationWarning, withTokenRevocation, withTracking, wrapAsObservableSignal };
7807
8182
  //# sourceMappingURL=ethlete-query.mjs.map