@ethlete/query 6.0.0-next.33 → 6.0.0-next.34

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.
@@ -2,7 +2,7 @@ import * as i0 from '@angular/core';
2
2
  import { inject, computed, DestroyRef, InjectionToken, Injector, EnvironmentInjector, ElementRef, ErrorHandler, createEnvironmentInjector, effect, untracked, signal, linkedSignal, runInInjectionContext, isDevMode, PLATFORM_ID, resource, DOCUMENT, VERSION, makeEnvironmentProviders, assertInInjectionContext, provideEnvironmentInitializer, ChangeDetectorRef, ViewContainerRef, TemplateRef, Input, Directive, input, Pipe, ViewEncapsulation, Component, NgZone } from '@angular/core';
3
3
  import { toObservable, takeUntilDestroyed, toSignal } from '@angular/core/rxjs-interop';
4
4
  import { UrlTree, Router, RedirectCommand, ActivatedRoute } from '@angular/router';
5
- import { filter, take, map, defer, from, Subject, Subscription, throwError, of, timer, switchMap, tap, retry, catchError, EMPTY, takeWhile, merge, firstValueFrom, concatMap, fromEvent, throttleTime, interval, combineLatest, Observable, takeUntil, startWith, pairwise, BehaviorSubject, ReplaySubject, shareReplay, skip, withLatestFrom, debounceTime } from 'rxjs';
5
+ import { filter, take, map, defer, from, Subject, Subscription, throwError, of, timer, switchMap, tap, retry, catchError, merge, EMPTY, takeWhile, firstValueFrom, concatMap, fromEvent, throttleTime, interval, combineLatest, Observable, takeUntil, startWith, pairwise, BehaviorSubject, ReplaySubject, shareReplay, skip, withLatestFrom, debounceTime } from 'rxjs';
6
6
  import { defineStaticProvider, RuntimeError, clamp, randomId, defineRootProvider, isObject, injectUnsavedChangesCoordinator, injectRoute, getCookie, getDomain, deleteCookie, setCookie, CORE_VERSION, createDestroy, computedTillTruthy, defineProvider, toProvideFn, toInjectFn, nextFrame, injectQueryParams, injectQueryParamChanges, clone, equal, ET_PROPERTY_REMOVED, previousSignalValue } from '@ethlete/core';
7
7
  import { HttpClient, HttpEventType, HttpErrorResponse, HttpResponse, HttpHeaders, HttpStatusCode } from '@angular/common/http';
8
8
  import { getActiveConsumer, setActiveConsumer } from '@angular/core/primitives/signals';
@@ -265,6 +265,24 @@ const resolveQueryDevtoolsMock = (target) => mockResolver?.(target) ?? null;
265
265
  * @internal
266
266
  */
267
267
  const resolveQueryDevtoolsFault = (target) => faultResolver?.(target) ?? null;
268
+ let tokenPayloadPatcher = null;
269
+ /**
270
+ * Installs the access-token payload patcher. Called by `provideQueryDevtools()`; nothing else may call it.
271
+ * @internal
272
+ */
273
+ const setQueryDevtoolsTokenPayloadPatcher = (fn) => {
274
+ tokenPayloadPatcher = fn;
275
+ };
276
+ /**
277
+ * A decoded access token as the devtools want it seen, which today means with an overridden lifetime
278
+ * applied. Returns the payload as decoded unless `provideQueryDevtools()` installed a patcher.
279
+ *
280
+ * Auth code must reach the override through this rather than importing the registry it lives in: a
281
+ * static import would pin that module into every bundle that builds an auth provider, and a runtime
282
+ * guard at the call site does not undo that.
283
+ * @internal
284
+ */
285
+ const patchQueryDevtoolsTokenPayload = (options) => (tokenPayloadPatcher ? tokenPayloadPatcher(options) : options.payload);
268
286
  let suppressStackRegistration = false;
269
287
  /**
270
288
  * Suppresses devtools registration for the next {@link createQueryStack} call. Used by
@@ -1630,6 +1648,7 @@ const SPEED_BUFFER_TIME_IN_MS = 2000;
1630
1648
  const MOCKED_STATUS_TEXT = 'Served by the query devtools';
1631
1649
  const createHttpRequest = (options) => {
1632
1650
  let currentStreamSubscription = Subscription.EMPTY;
1651
+ let lastSentHeaders;
1633
1652
  const { args, clientOptions, dependencies } = options;
1634
1653
  const currentEvent = signal(null, /* @ts-ignore */
1635
1654
  ...(ngDevMode ? [{ debugName: "currentEvent" }] : /* istanbul ignore next */ []));
@@ -1751,6 +1770,7 @@ const createHttpRequest = (options) => {
1751
1770
  });
1752
1771
  const createStream = () => {
1753
1772
  const headers = resolveHeaders();
1773
+ lastSentHeaders = headers;
1754
1774
  const source$ = isQueryDevtoolsRequestInterceptionEnabled() ? sendWithFaults(headers) : send(headers);
1755
1775
  return source$.pipe(tap((event) => updateState(event)), retry({
1756
1776
  delay: (error, retryCount) => {
@@ -1923,6 +1943,7 @@ const createHttpRequest = (options) => {
1923
1943
  applyPersistedResponse,
1924
1944
  lastPersistedResponseAt: lastPersistedResponseAt.asReadonly(),
1925
1945
  resolveHeaders,
1946
+ lastSentHeaders: () => lastSentHeaders,
1926
1947
  attempts: attempts.asReadonly(),
1927
1948
  retryState: retryState.asReadonly(),
1928
1949
  lastDurationMs: lastDurationMs.asReadonly(),
@@ -3863,6 +3884,7 @@ const createSecureExecuteFactory = (options) => {
3863
3884
  let lastExecuteArgs;
3864
3885
  /** The access token the last request went out with - what the 401 retry below compares against. */
3865
3886
  let lastRequestedWithToken = null;
3887
+ const error$ = toObservable(options.state.error, { injector: options.deps.injector });
3866
3888
  const reset = () => {
3867
3889
  authQuerySubscription.unsubscribe();
3868
3890
  authQuerySubscription = Subscription.EMPTY;
@@ -3973,7 +3995,13 @@ const createSecureExecuteFactory = (options) => {
3973
3995
  // another refresh - an endless refresh/retry loop for as long as the server keeps handing out
3974
3996
  // tokens it rejects. A refresh that did not change the access token is therefore not a reason to
3975
3997
  // retry; the subscription stays open, so a later one that does change it still is.
3976
- tokenRefreshSubscription = options.authProvider.afterTokenRefresh$
3998
+ //
3999
+ // The error landing is a trigger of its own: a refresh can complete before this query's 401 has
4000
+ // even come back (which is also why that 401 must not start another refresh - see
4001
+ // withRefreshQuery's 401 handling), and the refresh emission alone would find no error to act
4002
+ // on. Emissions of the error this execution armed with are not landings, only replays.
4003
+ const errorAtArm = options.state.error();
4004
+ tokenRefreshSubscription = merge(options.authProvider.afterTokenRefresh$, error$.pipe(filter((landedError) => landedError !== errorAtArm)))
3977
4005
  .pipe(filter(() => {
3978
4006
  const currentError = options.state.error();
3979
4007
  return currentError?.code === 401 && options.authProvider.accessToken() !== lastRequestedWithToken;
@@ -4655,7 +4683,12 @@ const createBearerAuthProviderImpl = (config) => {
4655
4683
  if (!token)
4656
4684
  return null;
4657
4685
  try {
4658
- return config.bearerDecryptFn?.(token) ?? decryptBearer(token);
4686
+ const decoded = config.bearerDecryptFn?.(token) ?? decryptBearer(token);
4687
+ return patchQueryDevtoolsTokenPayload({
4688
+ payload: decoded,
4689
+ providerName: config.name,
4690
+ expiresInPropertyName: 'exp',
4691
+ });
4659
4692
  }
4660
4693
  catch (error) {
4661
4694
  if (isDevMode()) {
@@ -4728,6 +4761,7 @@ const createBearerAuthProviderImpl = (config) => {
4728
4761
  sessionEndCause: sessionEndCause.asReadonly(),
4729
4762
  });
4730
4763
  const querySetupContext = {
4764
+ name: config.name,
4731
4765
  accessToken,
4732
4766
  refreshToken,
4733
4767
  bearerDecryptFn: config.bearerDecryptFn,
@@ -4808,6 +4842,12 @@ const rescheduleDelayMs = 5000;
4808
4842
  * declining is either not the leader or busy issuing tokens; either way a 401 still forces a refresh.
4809
4843
  */
4810
4844
  const maxRescheduleAttempts = 5;
4845
+ /**
4846
+ * How many 401-driven refreshes may run back to back before they fall back to `minRefreshInterval`.
4847
+ * Every refresh in such a streak means the token the previous one issued was rejected too, so an
4848
+ * unbounded streak is a refresh loop, not recovery. A secure request succeeding ends the streak.
4849
+ */
4850
+ const maxUnauthorizedRefreshStreak = 3;
4811
4851
  const withAuthenticationQuery = (key, config, setup) => ({
4812
4852
  _type: 'authQuery',
4813
4853
  key,
@@ -4850,6 +4890,8 @@ const withRefreshQuery = (key, config) => {
4850
4890
  const minRefreshInterval = config.minRefreshInterval ?? 30000; // 30 seconds default
4851
4891
  const refreshIfExpired = config.refreshIfExpired ?? true;
4852
4892
  let lastRefreshTime = 0;
4893
+ let lastUnauthorizedRefreshTime = 0;
4894
+ let unauthorizedRefreshStreak = 0;
4853
4895
  // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
4854
4896
  const refreshQuery = () => context.queries[key];
4855
4897
  const executeRefresh = (reason) => {
@@ -4873,6 +4915,15 @@ const withRefreshQuery = (key, config) => {
4873
4915
  return 'throttled';
4874
4916
  lastRefreshTime = now;
4875
4917
  }
4918
+ else {
4919
+ const now = Date.now();
4920
+ if (unauthorizedRefreshStreak >= maxUnauthorizedRefreshStreak &&
4921
+ now - lastUnauthorizedRefreshTime < minRefreshInterval) {
4922
+ return 'throttled';
4923
+ }
4924
+ unauthorizedRefreshStreak++;
4925
+ lastUnauthorizedRefreshTime = now;
4926
+ }
4876
4927
  refreshQuery().execute(buildArgs(currentRefreshToken), { triggeredBy: 'token-refresh' });
4877
4928
  return 'executed';
4878
4929
  };
@@ -4907,7 +4958,12 @@ const withRefreshQuery = (key, config) => {
4907
4958
  /** When this access token is due to be refreshed, or `null` if it cannot be scheduled at all. */
4908
4959
  const scheduledRefreshDelay = (token) => {
4909
4960
  try {
4910
- const bearerDataValue = context.bearerDecryptFn ? context.bearerDecryptFn(token) : decryptBearer(token);
4961
+ const decoded = context.bearerDecryptFn ? context.bearerDecryptFn(token) : decryptBearer(token);
4962
+ const bearerDataValue = patchQueryDevtoolsTokenPayload({
4963
+ payload: decoded,
4964
+ providerName: context.name,
4965
+ expiresInPropertyName,
4966
+ });
4911
4967
  const expiresIn = bearerDataValue?.[expiresInPropertyName];
4912
4968
  if (typeof expiresIn !== 'number') {
4913
4969
  if (isDevMode()) {
@@ -4939,13 +4995,17 @@ const withRefreshQuery = (key, config) => {
4939
4995
  const retryInMs = retryScheduledIn(executeRefresh('scheduled'));
4940
4996
  return retryInMs === null || attemptsLeft <= 0 ? EMPTY : scheduledRefresh(retryInMs, attemptsLeft - 1);
4941
4997
  }));
4942
- toObservable(context.accessToken)
4943
- .pipe(switchMap((token) => {
4944
- if (!token)
4945
- return EMPTY;
4946
- const dueInMs = scheduledRefreshDelay(token);
4947
- return dueInMs === null ? EMPTY : scheduledRefresh(dueInMs, maxRescheduleAttempts);
4948
- }), takeUntilDestroyed())
4998
+ // The delay is read in a computed rather than in the `switchMap` so that a devtools-armed token
4999
+ // lifetime re-arms the schedule: the override is a signal, and only a reactive read of it moves the
5000
+ // timer before the next token arrives. The wrapper object keeps every recomputation an emission, so
5001
+ // two tokens that happen to be due at the same moment still restart the timer.
5002
+ const nextScheduledRefresh = computed(() => {
5003
+ const token = context.accessToken();
5004
+ return { dueInMs: token ? scheduledRefreshDelay(token) : null };
5005
+ }, /* @ts-ignore */
5006
+ ...(ngDevMode ? [{ debugName: "nextScheduledRefresh" }] : /* istanbul ignore next */ []));
5007
+ toObservable(nextScheduledRefresh)
5008
+ .pipe(switchMap(({ dueInMs }) => (dueInMs === null ? EMPTY : scheduledRefresh(dueInMs, maxRescheduleAttempts))), takeUntilDestroyed())
4949
5009
  .subscribe();
4950
5010
  context.refreshCoordination?.requests$.pipe(takeUntilDestroyed()).subscribe(() => executeRefresh('unauthorized'));
4951
5011
  const onRefreshFailure = config.onRefreshFailure ??
@@ -4965,18 +5025,22 @@ const withRefreshQuery = (key, config) => {
4965
5025
  // Auto-retry on 401: Listen to repository events and trigger refresh on 401 errors
4966
5026
  const autoRetryOn401 = config.autoRetryOn401 ?? true;
4967
5027
  if (autoRetryOn401) {
4968
- context.repository.events$
4969
- .pipe(filter((event) => {
4970
- // Only handle 401 errors for secure queries
4971
- if (event.type !== 'request-error')
4972
- return false;
4973
- if (!event.isSecure)
4974
- return false;
4975
- if (event.error?.status !== 401)
4976
- return false;
4977
- return true;
4978
- }), takeUntilDestroyed())
4979
- .subscribe(() => {
5028
+ context.repository.events$.pipe(takeUntilDestroyed()).subscribe((event) => {
5029
+ if (event.type === 'request-success' && event.isSecure) {
5030
+ unauthorizedRefreshStreak = 0;
5031
+ return;
5032
+ }
5033
+ if (event.type !== 'request-error' || !event.isSecure || event.error?.status !== 401)
5034
+ return;
5035
+ // A 401 from a request that went out with an older access token asks for a refresh that
5036
+ // already happened - the query re-runs itself with the current token (see
5037
+ // createSecureExecuteFactory). Refreshing again here would spend the refresh token that
5038
+ // pair came with, invalidating the tokens every other in-flight request is using; their
5039
+ // 401s would each do the same, keeping the loop alive for as long as queries are in flight.
5040
+ const sentAuthorization = event.request.subtle.lastSentHeaders()?.get('Authorization');
5041
+ const currentToken = context.accessToken();
5042
+ if (sentAuthorization && currentToken && sentAuthorization !== `Bearer ${currentToken}`)
5043
+ return;
4980
5044
  executeRefresh('unauthorized');
4981
5045
  });
4982
5046
  }
@@ -5811,124 +5875,13 @@ const queryDevtoolsAbout = () => ({
5811
5875
  app,
5812
5876
  });
5813
5877
 
5814
- /** The neutral fault: nothing armed. */
5815
- const EMPTY_QUERY_DEVTOOLS_FAULT = {
5816
- latencyMs: 0,
5817
- failNext: 0,
5818
- failRate: 0,
5819
- status: 503,
5820
- };
5821
- /**
5822
- * Statuses worth injecting, and whether the SDK's default retry policy retries them. A picker built from
5823
- * this cannot arm a 500 and then leave you wondering why no retry fired.
5824
- * @see runDefaultQueryRetry
5825
- */
5826
- const QUERY_DEVTOOLS_FAULT_STATUSES = [
5827
- { status: 0, label: 'Network error', retryable: true },
5828
- { status: 400, label: 'Bad Request', retryable: false },
5829
- { status: 401, label: 'Unauthorized', retryable: false },
5830
- { status: 403, label: 'Forbidden', retryable: false },
5831
- { status: 404, label: 'Not Found', retryable: false },
5832
- { status: 408, label: 'Request Timeout', retryable: true },
5833
- { status: 429, label: 'Too Many Requests', retryable: true },
5834
- { status: 500, label: 'Internal Server Error', retryable: false },
5835
- { status: 502, label: 'Bad Gateway', retryable: true },
5836
- { status: 503, label: 'Service Unavailable', retryable: true },
5837
- ];
5838
- const faults = /* @__PURE__ */ signal({}, /* @ts-ignore */
5839
- ...(ngDevMode ? [{ debugName: "faults" }] : /* istanbul ignore next */ []));
5840
- /**
5841
- * The faults armed per client name, consumed by the `<et-query-devtools>` UI. Clients with nothing armed
5842
- * are absent rather than present with an {@link EMPTY_QUERY_DEVTOOLS_FAULT}.
5843
- */
5844
- const queryDevtoolsFaults = /* @__PURE__ */ faults.asReadonly();
5845
- /** Whether anything at all is armed on a fault. */
5846
- const isQueryDevtoolsFaultArmed = (fault) => fault.latencyMs > 0 || fault.failNext > 0 || fault.failRate > 0;
5847
- /**
5848
- * Arms (or updates) the fault of one client. Only the given fields change; the rest keep their current
5849
- * value. A client whose resulting fault has nothing armed is dropped from {@link queryDevtoolsFaults}.
5850
- *
5851
- * Part of the devtools contract consumed by `<et-query-devtools>`; a fault is a debugging tool, not
5852
- * something an application should arm on itself.
5853
- */
5854
- const setQueryDevtoolsFault = (options) => {
5855
- const { clientName, patch } = options;
5856
- faults.update((current) => {
5857
- const next = { ...(current[clientName] ?? EMPTY_QUERY_DEVTOOLS_FAULT), ...patch };
5858
- if (!isQueryDevtoolsFaultArmed(next)) {
5859
- const { [clientName]: _removed, ...rest } = current;
5860
- return rest;
5861
- }
5862
- return { ...current, [clientName]: next };
5863
- });
5864
- };
5865
- /**
5866
- * Disarms every fault of one client, or of all clients when no name is given.
5867
- *
5868
- * @see setQueryDevtoolsFault
5869
- */
5870
- const clearQueryDevtoolsFaults = (clientName) => faults.update((current) => {
5871
- if (clientName === undefined)
5872
- return {};
5873
- const { [clientName]: _removed, ...rest } = current;
5874
- return rest;
5875
- });
5876
- /**
5877
- * Resolves what to do with one upcoming attempt, consuming a `failNext` budget in the process - so this
5878
- * must be called once per attempt and never speculatively.
5879
- *
5880
- * Installed as the fault resolver by `provideQueryDevtools()`; nothing else may call it.
5881
- * @internal
5882
- */
5883
- const resolveQueryDevtoolsFaultForAttempt = (target) => {
5884
- const fault = faults()[target.clientName];
5885
- if (!fault || !isQueryDevtoolsFaultArmed(fault))
5886
- return null;
5887
- let shouldFail = false;
5888
- if (fault.failNext > 0) {
5889
- shouldFail = true;
5890
- setQueryDevtoolsFault({ clientName: target.clientName, patch: { failNext: fault.failNext - 1 } });
5891
- }
5892
- else if (fault.failRate > 0) {
5893
- shouldFail = Math.random() * 100 < fault.failRate;
5894
- }
5895
- return {
5896
- latencyMs: fault.latencyMs,
5897
- status: shouldFail ? fault.status : null,
5898
- };
5899
- };
5900
-
5901
- /**
5902
- * Records which query forms feed one query's args, so the devtools can answer "which query does this
5903
- * form drive?" from the reads themselves rather than from a naming convention.
5904
- * @internal
5905
- */
5906
- const createQueryDevtoolsFormLinks = () => {
5907
- const ids = signal([], /* @ts-ignore */
5908
- ...(ngDevMode ? [{ debugName: "ids" }] : /* istanbul ignore next */ []));
5909
- return {
5910
- ids: ids.asReadonly(),
5911
- track: (build) => {
5912
- const collected = collectQueryFormLinks(build);
5913
- // Args are built inside a reactive computation, which may not write to a signal - `untracked`
5914
- // lifts that restriction, and skipping the write unless something is new keeps the panel from
5915
- // being notified on every evaluation.
5916
- untracked(() => {
5917
- const known = ids();
5918
- const added = collected.ids.filter((id) => !known.includes(id));
5919
- if (added.length)
5920
- ids.set([...known, ...added]);
5921
- });
5922
- return collected.value;
5923
- },
5924
- };
5925
- };
5926
-
5927
5878
  const DEFAULTS = {
5928
5879
  viewState: 'session',
5929
5880
  pins: 'local',
5930
5881
  overrides: 'none',
5931
5882
  mocks: 'local',
5883
+ armedMocks: 'none',
5884
+ armedFaults: 'none',
5932
5885
  maxEvents: 100,
5933
5886
  maxDroppedCacheEntries: 20,
5934
5887
  responseHistory: null,
@@ -6031,6 +5984,8 @@ const sanitize = (value) => ({
6031
5984
  pins: asScope(value?.pins, DEFAULTS.pins),
6032
5985
  overrides: asScope(value?.overrides, DEFAULTS.overrides),
6033
5986
  mocks: asScope(value?.mocks, DEFAULTS.mocks),
5987
+ armedMocks: asScope(value?.armedMocks, DEFAULTS.armedMocks),
5988
+ armedFaults: asScope(value?.armedFaults, DEFAULTS.armedFaults),
6034
5989
  maxEvents: asCount(value?.maxEvents, LIMITS.maxEvents, DEFAULTS.maxEvents),
6035
5990
  maxDroppedCacheEntries: asCount(value?.maxDroppedCacheEntries, LIMITS.maxDroppedCacheEntries, DEFAULTS.maxDroppedCacheEntries),
6036
5991
  responseHistory: asOptionalCount(value?.responseHistory, LIMITS.responseHistory),
@@ -6059,23 +6014,213 @@ const setQueryDevtoolsSettings = (patch) => {
6059
6014
  writeQueryDevtoolsStore('local', SETTINGS_KEY, next);
6060
6015
  };
6061
6016
 
6017
+ /** The neutral fault: nothing armed. */
6018
+ const EMPTY_QUERY_DEVTOOLS_FAULT = {
6019
+ latencyMs: 0,
6020
+ failNext: 0,
6021
+ failRate: 0,
6022
+ status: 503,
6023
+ };
6062
6024
  /**
6063
- * The designed library. Whether a mock is **armed** is deliberately not part of it - see
6025
+ * Statuses worth injecting, and whether the SDK's default retry policy retries them. A picker built from
6026
+ * this cannot arm a 500 and then leave you wondering why no retry fired.
6027
+ * @see runDefaultQueryRetry
6028
+ */
6029
+ const QUERY_DEVTOOLS_FAULT_STATUSES = [
6030
+ { status: 0, label: 'Network error', retryable: true },
6031
+ { status: 400, label: 'Bad Request', retryable: false },
6032
+ { status: 401, label: 'Unauthorized', retryable: false },
6033
+ { status: 403, label: 'Forbidden', retryable: false },
6034
+ { status: 404, label: 'Not Found', retryable: false },
6035
+ { status: 408, label: 'Request Timeout', retryable: true },
6036
+ { status: 429, label: 'Too Many Requests', retryable: true },
6037
+ { status: 500, label: 'Internal Server Error', retryable: false },
6038
+ { status: 502, label: 'Bad Gateway', retryable: true },
6039
+ { status: 503, label: 'Service Unavailable', retryable: true },
6040
+ ];
6041
+ const STORAGE_KEY$2 = 'ethlete:query:devtools:faults:v1';
6042
+ const faults = /* @__PURE__ */ signal({}, /* @ts-ignore */
6043
+ ...(ngDevMode ? [{ debugName: "faults" }] : /* istanbul ignore next */ []));
6044
+ const restored$1 = /* @__PURE__ */ signal(false, /* @ts-ignore */
6045
+ ...(ngDevMode ? [{ debugName: "restored" }] : /* istanbul ignore next */ []));
6046
+ const scope$2 = () => queryDevtoolsSettings().armedFaults;
6047
+ /**
6048
+ * The faults armed per client name, consumed by the `<et-query-devtools>` UI. Clients with nothing armed
6049
+ * are absent rather than present with an {@link EMPTY_QUERY_DEVTOOLS_FAULT}.
6050
+ */
6051
+ const queryDevtoolsFaults = /* @__PURE__ */ faults.asReadonly();
6052
+ /**
6053
+ * Whether what is armed right now came back from a previous page load rather than being armed by hand.
6054
+ * The panel's armed bar says so, because injected failures nobody remembers arming look exactly like a
6055
+ * broken API.
6056
+ */
6057
+ const queryDevtoolsFaultsRestored = /* @__PURE__ */ restored$1.asReadonly();
6058
+ const write$1 = () => {
6059
+ if (scope$2() === 'none') {
6060
+ clearQueryDevtoolsStore(STORAGE_KEY$2);
6061
+ return;
6062
+ }
6063
+ writeQueryDevtoolsStore(scope$2(), STORAGE_KEY$2, faults());
6064
+ };
6065
+ const asFault = (value) => {
6066
+ const fault = value;
6067
+ if (!fault || typeof fault !== 'object')
6068
+ return null;
6069
+ const next = {
6070
+ latencyMs: Number(fault.latencyMs) || 0,
6071
+ failNext: Number(fault.failNext) || 0,
6072
+ failRate: Number(fault.failRate) || 0,
6073
+ status: Number.isFinite(Number(fault.status)) ? Number(fault.status) : EMPTY_QUERY_DEVTOOLS_FAULT.status,
6074
+ };
6075
+ return isQueryDevtoolsFaultArmed(next) ? next : null;
6076
+ };
6077
+ /**
6078
+ * Reads the armed faults back, when the `armedFaults` setting asks for them. Called by
6079
+ * `provideQueryDevtools()` after the settings it takes its scope from; nothing else may call it.
6080
+ * @internal
6081
+ */
6082
+ const initQueryDevtoolsFaults = () => {
6083
+ const stored = readQueryDevtoolsStore(scope$2(), STORAGE_KEY$2);
6084
+ const inherited = {};
6085
+ for (const [clientName, value] of Object.entries(stored ?? {})) {
6086
+ const fault = asFault(value);
6087
+ if (fault)
6088
+ inherited[clientName] = fault;
6089
+ }
6090
+ faults.set(inherited);
6091
+ restored$1.set(Object.keys(inherited).length > 0);
6092
+ };
6093
+ /**
6094
+ * Where the armed faults are kept. Switching to a scope that keeps them stores whatever is armed right
6095
+ * now; switching to `none` empties the store and leaves this page's faults exactly where they are.
6096
+ */
6097
+ const setQueryDevtoolsFaultsScope = (next) => {
6098
+ if (next === scope$2())
6099
+ return;
6100
+ // Off both stores first: whichever the previous scope was, its copy must not outlive the change.
6101
+ clearQueryDevtoolsStore(STORAGE_KEY$2);
6102
+ setQueryDevtoolsSettings({ armedFaults: next });
6103
+ write$1();
6104
+ };
6105
+ /** Whether anything at all is armed on a fault. */
6106
+ const isQueryDevtoolsFaultArmed = (fault) => fault.latencyMs > 0 || fault.failNext > 0 || fault.failRate > 0;
6107
+ const patchFault = (options) => {
6108
+ const { clientName, patch } = options;
6109
+ faults.update((current) => {
6110
+ const next = { ...(current[clientName] ?? EMPTY_QUERY_DEVTOOLS_FAULT), ...patch };
6111
+ if (!isQueryDevtoolsFaultArmed(next)) {
6112
+ const { [clientName]: _removed, ...rest } = current;
6113
+ return rest;
6114
+ }
6115
+ return { ...current, [clientName]: next };
6116
+ });
6117
+ write$1();
6118
+ };
6119
+ /**
6120
+ * Arms (or updates) the fault of one client. Only the given fields change; the rest keep their current
6121
+ * value. A client whose resulting fault has nothing armed is dropped from {@link queryDevtoolsFaults}.
6122
+ *
6123
+ * Part of the devtools contract consumed by `<et-query-devtools>`; a fault is a debugging tool, not
6124
+ * something an application should arm on itself.
6125
+ */
6126
+ const setQueryDevtoolsFault = (options) => {
6127
+ patchFault(options);
6128
+ restored$1.set(false);
6129
+ };
6130
+ /**
6131
+ * Disarms every fault of one client, or of all clients when no name is given.
6132
+ *
6133
+ * @see setQueryDevtoolsFault
6134
+ */
6135
+ const clearQueryDevtoolsFaults = (clientName) => {
6136
+ faults.update((current) => {
6137
+ if (clientName === undefined)
6138
+ return {};
6139
+ const { [clientName]: _removed, ...rest } = current;
6140
+ return rest;
6141
+ });
6142
+ restored$1.set(false);
6143
+ write$1();
6144
+ };
6145
+ /**
6146
+ * Resolves what to do with one upcoming attempt, consuming a `failNext` budget in the process - so this
6147
+ * must be called once per attempt and never speculatively.
6148
+ *
6149
+ * Installed as the fault resolver by `provideQueryDevtools()`; nothing else may call it.
6150
+ * @internal
6151
+ */
6152
+ const resolveQueryDevtoolsFaultForAttempt = (target) => {
6153
+ const fault = faults()[target.clientName];
6154
+ if (!fault || !isQueryDevtoolsFaultArmed(fault))
6155
+ return null;
6156
+ let shouldFail = false;
6157
+ if (fault.failNext > 0) {
6158
+ shouldFail = true;
6159
+ // Not the public setter: spending the budget is the armed fault doing its job, not someone re-arming
6160
+ // it, so it must not clear what the panel's bar says about where the fault came from.
6161
+ patchFault({ clientName: target.clientName, patch: { failNext: fault.failNext - 1 } });
6162
+ }
6163
+ else if (fault.failRate > 0) {
6164
+ shouldFail = Math.random() * 100 < fault.failRate;
6165
+ }
6166
+ return {
6167
+ latencyMs: fault.latencyMs,
6168
+ status: shouldFail ? fault.status : null,
6169
+ };
6170
+ };
6171
+
6172
+ /**
6173
+ * Records which query forms feed one query's args, so the devtools can answer "which query does this
6174
+ * form drive?" from the reads themselves rather than from a naming convention.
6175
+ * @internal
6176
+ */
6177
+ const createQueryDevtoolsFormLinks = () => {
6178
+ const ids = signal([], /* @ts-ignore */
6179
+ ...(ngDevMode ? [{ debugName: "ids" }] : /* istanbul ignore next */ []));
6180
+ return {
6181
+ ids: ids.asReadonly(),
6182
+ track: (build) => {
6183
+ const collected = collectQueryFormLinks(build);
6184
+ // Args are built inside a reactive computation, which may not write to a signal - `untracked`
6185
+ // lifts that restriction, and skipping the write unless something is new keeps the panel from
6186
+ // being notified on every evaluation.
6187
+ untracked(() => {
6188
+ const known = ids();
6189
+ const added = collected.ids.filter((id) => !known.includes(id));
6190
+ if (added.length)
6191
+ ids.set([...known, ...added]);
6192
+ });
6193
+ return collected.value;
6194
+ },
6195
+ };
6196
+ };
6197
+
6198
+ /**
6199
+ * The designed library. Which of them is **armed** is a separate store under a separate scope - see
6064
6200
  * {@link queryDevtoolsArmedMocks}.
6065
6201
  */
6066
6202
  const STORAGE_KEY$1 = 'ethlete:query:devtools:mocks:v1';
6203
+ const ARMED_STORAGE_KEY = 'ethlete:query:devtools:mocks:armed:v1';
6067
6204
  const mocks = /* @__PURE__ */ signal([], /* @ts-ignore */
6068
6205
  ...(ngDevMode ? [{ debugName: "mocks" }] : /* istanbul ignore next */ []));
6069
6206
  const armed = /* @__PURE__ */ signal(/* @__PURE__ */ new Set(), /* @ts-ignore */
6070
6207
  ...(ngDevMode ? [{ debugName: "armed" }] : /* istanbul ignore next */ []));
6208
+ const armedRestored = /* @__PURE__ */ signal(false, /* @ts-ignore */
6209
+ ...(ngDevMode ? [{ debugName: "armedRestored" }] : /* istanbul ignore next */ []));
6071
6210
  const scope$1 = () => queryDevtoolsSettings().mocks;
6211
+ const armedScope = () => queryDevtoolsSettings().armedMocks;
6072
6212
  /** The designed mocks, armed or not. Persisted, because losing an hour of authoring is unacceptable. */
6073
6213
  const queryDevtoolsMocks = /* @__PURE__ */ mocks.asReadonly();
6074
6214
  /**
6075
- * The ids currently being served. **Never persisted, at any scope**: an app that silently serves designed
6076
- * data tomorrow morning is worse than losing which mocks were armed, so arming is per page load.
6215
+ * The ids currently being served. Not kept across page loads unless the `armedMocks` setting asks for it -
6216
+ * an app that silently serves designed data tomorrow morning is worse than losing which mocks were armed.
6077
6217
  */
6078
6218
  const queryDevtoolsArmedMocks = /* @__PURE__ */ armed.asReadonly();
6219
+ /**
6220
+ * Whether what is armed right now came back from a previous page load rather than being armed by hand.
6221
+ * The panel's armed bar says so, because mocks nobody remembers arming look exactly like a broken API.
6222
+ */
6223
+ const queryDevtoolsArmedMocksRestored = /* @__PURE__ */ armedRestored.asReadonly();
6079
6224
  /**
6080
6225
  * The identity of a designed mock: one per client, method, route **and** declared query. The query is part
6081
6226
  * of it so `/posts?page=1` and `/posts?page=2` can hold different bodies.
@@ -6088,6 +6233,19 @@ const write = () => {
6088
6233
  }
6089
6234
  writeQueryDevtoolsStore(scope$1(), STORAGE_KEY$1, mocks());
6090
6235
  };
6236
+ const writeArmed = () => {
6237
+ if (armedScope() === 'none') {
6238
+ clearQueryDevtoolsStore(ARMED_STORAGE_KEY);
6239
+ return;
6240
+ }
6241
+ writeQueryDevtoolsStore(armedScope(), ARMED_STORAGE_KEY, [...armed()]);
6242
+ };
6243
+ /** Every change made by hand goes through here, so none of them can leave the store or the bar behind. */
6244
+ const setArmed = (next) => {
6245
+ armed.set(next);
6246
+ armedRestored.set(false);
6247
+ writeArmed();
6248
+ };
6091
6249
  const isMock = (value) => {
6092
6250
  const mock = value;
6093
6251
  return (!!mock &&
@@ -6106,7 +6264,15 @@ const initQueryDevtoolsMocks = () => {
6106
6264
  const stored = readQueryDevtoolsStore(scope$1(), STORAGE_KEY$1);
6107
6265
  // `query` was added after the first version of the store, so an entry written before it still loads.
6108
6266
  mocks.set(Array.isArray(stored) ? stored.filter(isMock).map((mock) => ({ ...mock, query: mock.query ?? '' })) : []);
6109
- armed.set(new Set());
6267
+ const kept = readQueryDevtoolsStore(armedScope(), ARMED_STORAGE_KEY);
6268
+ const library = new Set(mocks().map((mock) => mock.id));
6269
+ // An id the library no longer holds would arm nothing, so it is dropped rather than kept waiting for a
6270
+ // mock that may never be designed again.
6271
+ const inherited = Array.isArray(kept)
6272
+ ? kept.filter((id) => typeof id === 'string' && library.has(id))
6273
+ : [];
6274
+ armed.set(new Set(inherited));
6275
+ armedRestored.set(inherited.length > 0);
6110
6276
  };
6111
6277
  /** The path of a request URL, without its origin or query string - what a pattern is matched against. */
6112
6278
  const queryDevtoolsRequestPath = (url) => {
@@ -6163,24 +6329,39 @@ const deleteQueryDevtoolsMock = (id) => {
6163
6329
  };
6164
6330
  /** Starts or stops serving one designed mock. Arming a mock that is not in the library does nothing. */
6165
6331
  const armQueryDevtoolsMock = (id, isArmed) => {
6166
- armed.update((current) => {
6167
- if (isArmed && !mocks().some((mock) => mock.id === id))
6168
- return current;
6169
- const next = new Set(current);
6170
- if (isArmed)
6171
- next.add(id);
6172
- else
6173
- next.delete(id);
6174
- return next;
6175
- });
6176
- };
6332
+ if (isArmed && !mocks().some((mock) => mock.id === id))
6333
+ return;
6334
+ const next = new Set(armed());
6335
+ if (isArmed)
6336
+ next.add(id);
6337
+ else
6338
+ next.delete(id);
6339
+ setArmed(next);
6340
+ };
6341
+ /** Starts serving every mock in the library - the counterpart of {@link clearQueryDevtoolsArmedMocks}. */
6342
+ const armAllQueryDevtoolsMocks = () => setArmed(new Set(mocks().map((mock) => mock.id)));
6177
6343
  /** Stops serving every mock, leaving the library alone - the armed bar's one-click way out. */
6178
- const clearQueryDevtoolsArmedMocks = () => armed.set(new Set());
6344
+ const clearQueryDevtoolsArmedMocks = () => setArmed(new Set());
6345
+ /**
6346
+ * Where the armed set is kept. Switching to a scope that keeps it stores whatever is armed right now, so
6347
+ * the choice reads as "keep these"; switching to `none` empties the store and leaves this page serving
6348
+ * exactly what it was already serving.
6349
+ */
6350
+ const setQueryDevtoolsArmedMocksScope = (next) => {
6351
+ if (next === armedScope())
6352
+ return;
6353
+ // Off both stores first: whichever the previous scope was, its copy must not outlive the change.
6354
+ clearQueryDevtoolsStore(ARMED_STORAGE_KEY);
6355
+ setQueryDevtoolsSettings({ armedMocks: next });
6356
+ writeArmed();
6357
+ };
6179
6358
  /** Empties the designed library and disarms everything - the panel's "Reset devtools". */
6180
6359
  const clearQueryDevtoolsMockStore = () => {
6181
6360
  mocks.set([]);
6182
6361
  armed.set(new Set());
6362
+ armedRestored.set(false);
6183
6363
  clearQueryDevtoolsStore(STORAGE_KEY$1);
6364
+ clearQueryDevtoolsStore(ARMED_STORAGE_KEY);
6184
6365
  };
6185
6366
  const declaredParamCount = (mock) => (mock.query ? [...new URLSearchParams(mock.query)].length : 0);
6186
6367
  /**
@@ -6916,7 +7097,7 @@ const armQueryDevtoolsOverrideTransfer = (recorder, ops) => {
6916
7097
 
6917
7098
  // Generated from package.json by tools/scripts/generate-version.js - do not edit.
6918
7099
  /** The version of `@ethlete/query` this build was cut from. */
6919
- const QUERY_VERSION = '6.0.0-next.33';
7100
+ const QUERY_VERSION = '6.0.0-next.34';
6920
7101
 
6921
7102
  /** How deep a schema is expanded before a nested branch is given up on. */
6922
7103
  const MAX_DEPTH = 12;
@@ -7248,6 +7429,89 @@ const seedQueryDevtoolsSchemaBody = (name) => {
7248
7429
  return null;
7249
7430
  return seedFrom(schema, name);
7250
7431
  };
7432
+ /** Where a schema was collected from, so the same name arriving from two pointers is caught. */
7433
+ const originOf = (label, pointer) => pointer ?? `named:${label}`;
7434
+ /**
7435
+ * Copies a schema, pointing every local `$ref` at `#/components/schemas/<name>` and queueing that name -
7436
+ * so a document assembled from these resolves against its own `components`, whether the description kept
7437
+ * its schemas under `components.schemas`, `definitions` or `$defs`.
7438
+ */
7439
+ const rewriteRefs = (value, queue) => {
7440
+ if (Array.isArray(value))
7441
+ return value.map((entry) => rewriteRefs(entry, queue));
7442
+ if (!isRecord(value))
7443
+ return value;
7444
+ const result = {};
7445
+ for (const [key, entry] of Object.entries(value)) {
7446
+ if (key === '$ref' && typeof entry === 'string') {
7447
+ if (!entry.startsWith('#/')) {
7448
+ result[key] = entry;
7449
+ continue;
7450
+ }
7451
+ const label = refLabel(entry);
7452
+ queue({ label, pointer: entry });
7453
+ result[key] = `#/components/schemas/${label}`;
7454
+ continue;
7455
+ }
7456
+ result[key] = rewriteRefs(entry, queue);
7457
+ }
7458
+ return result;
7459
+ };
7460
+ /**
7461
+ * Collects the named schemas a set of routes was designed against, ready to be handed back as the
7462
+ * `components.schemas` of an exported document - so a route seeded from `MatchView` can reference
7463
+ * `MatchView` instead of an anonymous shape inferred from one body.
7464
+ *
7465
+ * Part of the devtools contract. **Not part of the general public contract.**
7466
+ */
7467
+ const collectQueryDevtoolsSchemaComponents = (names) => {
7468
+ const declared = namedSchemas();
7469
+ const schemas = {};
7470
+ const notes = new Set();
7471
+ const origins = new Map();
7472
+ const pending = names.map((label) => ({ label, pointer: null }));
7473
+ while (pending.length) {
7474
+ const request = pending.shift();
7475
+ const origin = originOf(request.label, request.pointer);
7476
+ const seen = origins.get(request.label);
7477
+ if (seen !== undefined) {
7478
+ if (seen !== origin) {
7479
+ notes.add(`Two different schemas are both called ${request.label} - only the one from ${seen} was kept.`);
7480
+ }
7481
+ continue;
7482
+ }
7483
+ const schema = request.pointer === null ? declared[request.label] : resolveRef(request.pointer);
7484
+ if (schema === undefined) {
7485
+ if (request.pointer !== null) {
7486
+ notes.add(`${request.pointer} could not be resolved, so ${request.label} is missing from the export.`);
7487
+ }
7488
+ continue;
7489
+ }
7490
+ origins.set(request.label, origin);
7491
+ schemas[request.label] = rewriteRefs(schema, (next) => pending.push(next));
7492
+ }
7493
+ for (const schema of Object.values(schemas)) {
7494
+ collectRemoteRefs(schema, notes);
7495
+ }
7496
+ return { schemas, notes: [...notes] };
7497
+ };
7498
+ /** A `$ref` to another file is left as it was written, so a document says where it stops resolving. */
7499
+ const collectRemoteRefs = (value, notes) => {
7500
+ if (Array.isArray(value)) {
7501
+ for (const entry of value)
7502
+ collectRemoteRefs(entry, notes);
7503
+ return;
7504
+ }
7505
+ if (!isRecord(value))
7506
+ return;
7507
+ for (const [key, entry] of Object.entries(value)) {
7508
+ if (key === '$ref' && typeof entry === 'string' && !entry.startsWith('#/')) {
7509
+ notes.add(`${entry} points outside the description - it was exported unchanged and will not resolve.`);
7510
+ continue;
7511
+ }
7512
+ collectRemoteRefs(entry, notes);
7513
+ }
7514
+ };
7251
7515
  const segmentsOf = (pattern) => pattern.split('/').filter(Boolean);
7252
7516
  /** `/matches/{id}` and `/matches/:id` describe the same route; a mock's pattern is written the second way. */
7253
7517
  const toColonPattern = (path) => path.replace(/\{([^}]+)\}/g, ':$1');
@@ -7662,6 +7926,90 @@ const sumQueryDevtoolsStats = (handles) => {
7662
7926
  return total;
7663
7927
  };
7664
7928
 
7929
+ /**
7930
+ * The longest lifetime an armed override may claim, in seconds (7 days). Anything beyond it is never
7931
+ * refreshed at all, which is what arming nothing already does.
7932
+ */
7933
+ const QUERY_DEVTOOLS_TOKEN_TTL_LIMIT = 604800;
7934
+ /** The claims an overridden lifetime is measured from, in the order they are tried. */
7935
+ const ANCHOR_CLAIMS = ['iat', 'nbf'];
7936
+ const ttls = /* @__PURE__ */ signal({}, /* @ts-ignore */
7937
+ ...(ngDevMode ? [{ debugName: "ttls" }] : /* istanbul ignore next */ []));
7938
+ /**
7939
+ * The access-token lifetime armed per auth provider name, in seconds, consumed by the
7940
+ * `<et-query-devtools>` panel. A provider on its token's real lifetime is absent rather than present
7941
+ * with it.
7942
+ */
7943
+ const queryDevtoolsTokenTtls = /* @__PURE__ */ ttls.asReadonly();
7944
+ const tokenTtlAnchor = (options) => {
7945
+ const { payload, expiresInPropertyName } = options;
7946
+ if (!payload || typeof payload[expiresInPropertyName] !== 'number')
7947
+ return null;
7948
+ for (const claim of ANCHOR_CLAIMS) {
7949
+ const value = payload[claim];
7950
+ if (typeof value === 'number')
7951
+ return value;
7952
+ }
7953
+ return null;
7954
+ };
7955
+ /**
7956
+ * Whether an overridden lifetime can be applied to a decoded access token at all. It needs the claim
7957
+ * carrying the expiry - so a lifetime is never invented for a token that declares none - plus `iat` or
7958
+ * `nbf` to measure the new lifetime from.
7959
+ */
7960
+ const canOverrideQueryDevtoolsTokenTtl = (options) => tokenTtlAnchor({ payload: options.payload, expiresInPropertyName: options.expiresInPropertyName ?? 'exp' }) !== null;
7961
+ /**
7962
+ * Presents one auth provider's access token as living `seconds` from the moment it was issued, rather
7963
+ * than as long as it says it does. Everything that reads the expiry sees the shortened lifetime - the
7964
+ * proactive refresh schedule, `withBearerAuthTokenExpirationWarning`, and the panel's own countdown -
7965
+ * so arming 60 seconds makes a real refresh happen a minute after each token is issued, and keeps
7966
+ * happening for every token that refresh brings back.
7967
+ *
7968
+ * It is a lifetime, not a remaining time: `0` presents the current token as long expired, which is what
7969
+ * makes a refresh happen at once. Nothing is persisted, so a reload leaves every provider on its real
7970
+ * lifetime.
7971
+ *
7972
+ * Part of the devtools contract consumed by `<et-query-devtools>`; a token's lifetime is not something
7973
+ * an application should override on itself.
7974
+ */
7975
+ const setQueryDevtoolsTokenTtl = (options) => {
7976
+ const { providerName, seconds } = options;
7977
+ const clamped = Math.min(Math.max(Math.trunc(seconds) || 0, 0), QUERY_DEVTOOLS_TOKEN_TTL_LIMIT);
7978
+ ttls.update((current) => ({ ...current, [providerName]: clamped }));
7979
+ };
7980
+ /**
7981
+ * Puts one provider back on its token's real lifetime, or every provider when no name is given.
7982
+ *
7983
+ * @see setQueryDevtoolsTokenTtl
7984
+ */
7985
+ const clearQueryDevtoolsTokenTtl = (providerName) => {
7986
+ ttls.update((current) => {
7987
+ if (providerName === undefined)
7988
+ return {};
7989
+ const { [providerName]: _removed, ...rest } = current;
7990
+ return rest;
7991
+ });
7992
+ };
7993
+ /**
7994
+ * The decoded access token as the devtools want it seen: the claim carrying the expiry rewritten to the
7995
+ * armed lifetime, measured from `iat`. Returns `payload` untouched when nothing is armed for the
7996
+ * provider, or when the token cannot carry the override - see {@link canOverrideQueryDevtoolsTokenTtl}.
7997
+ *
7998
+ * Installed as the token payload patcher by `provideQueryDevtools()`, and called directly by the panel
7999
+ * for its own countdown.
8000
+ */
8001
+ const applyQueryDevtoolsTokenTtl = (options) => {
8002
+ const { payload, providerName, expiresInPropertyName = 'exp' } = options;
8003
+ const seconds = ttls()[providerName];
8004
+ if (seconds === undefined || !payload || typeof payload !== 'object')
8005
+ return payload;
8006
+ const record = payload;
8007
+ const anchor = tokenTtlAnchor({ payload: record, expiresInPropertyName });
8008
+ if (anchor === null)
8009
+ return payload;
8010
+ return { ...record, [expiresInPropertyName]: anchor + seconds };
8011
+ };
8012
+
7665
8013
  /**
7666
8014
  * How many destroyed queries the registry keeps. A tombstone holds the last response body it captured,
7667
8015
  * so the list is capped for the same reason the repository caps its unused entries.
@@ -7942,6 +8290,7 @@ const provideQueryDevtools = (options) => {
7942
8290
  setQueryDevtoolsAppInfo(options?.about);
7943
8291
  initQueryDevtoolsOverridePersistence();
7944
8292
  initQueryDevtoolsMocks();
8293
+ initQueryDevtoolsFaults();
7945
8294
  setQueryDevtoolsSchemaLoader(options?.schema);
7946
8295
  setQueryDevtoolsRegistrar(registerEntry);
7947
8296
  setQueryDevtoolsStatsFactory(createQueryDevtoolsStats);
@@ -7949,6 +8298,7 @@ const provideQueryDevtools = (options) => {
7949
8298
  setQueryDevtoolsOverridesFactory(createQueryDevtoolsOverrides);
7950
8299
  setQueryDevtoolsFaultResolver(resolveQueryDevtoolsFaultForAttempt);
7951
8300
  setQueryDevtoolsMockResolver(resolveQueryDevtoolsMockForAttempt);
8301
+ setQueryDevtoolsTokenPayloadPatcher(applyQueryDevtoolsTokenTtl);
7952
8302
  if (!isDevMode()) {
7953
8303
  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.');
7954
8304
  }
@@ -13489,5 +13839,5 @@ const createWebSocketClient = (options) => {
13489
13839
  * Generated bundle index. Do not edit.
13490
13840
  */
13491
13841
 
13492
- export { BasicAuthProvider, BearerAuthFeatureType, BooleanArrayQueryField, CLEAR_QUERY_ARGS, CustomHeaderAuthProvider, DEFAULT_KEEP_UNUSED_FOR, DEFAULT_QUERY_PERSISTENCE_MAX_AGE, DEFAULT_QUERY_PERSISTENCE_MAX_ENTRIES, DEFAULT_QUERY_PERSISTENCE_VERSION, DEFAULT_QUERY_PERSISTENCE_WRITE_DELAY, DateArrayQueryField, DateQueryField, EMPTY_QUERY_DEVTOOLS_FAULT, EntityStore, IGNORED_FILTER_COUNT_FIELDS, INFINITY_QUERY_TOKEN, InfinityQuery, InfinityQueryDirective, InfinityQueryTriggerDirective, LegacyQuery, LegacyQueryCreator, MAX_QUERY_DEVTOOLS_TOMBSTONES, MAX_UNUSED_ENTRIES, NumberArrayQueryField, ParseHttpErrorCodeToMessageDePipe, ParseHttpErrorCodeToMessageEnPipe, ParseHttpErrorCodeToTitleDePipe, ParseHttpErrorCodeToTitleEnPipe, QUERY_CLIENT_DEVTOOLS_TOKEN, QUERY_DEVTOOLS_FAULT_STATUSES, QUERY_PERSISTENCE_STORE_VERSION, QUERY_SYNC_PROTOCOL_VERSION, QUERY_VERSION, QueryClientFeatureType, QueryDevtoolsComponent, QueryDirective, 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, applyQueryDevtoolsOverrides, applyQueryFeatures, armQueryDevtoolsMock, armQueryDevtoolsOverrideTransfer, authExtractTokensResponseMissingAccessToken, authExtractTokensResponseMissingRefreshToken, authExtractTokensResponseNotObject, authProviderFeatureUsedMultipleTimes, booleanArrayQueryField, buildQueryCacheKey, buildQueryString, buildRoute, buildTimestampFromSeconds, castQueryCreatorTypes, circularQueryDependency, circularQueryDependencyChecker, clearQueryDevtoolsArmedMocks, clearQueryDevtoolsFaults, clearQueryDevtoolsMockStore, clearQueryDevtoolsOverrideStore, clearQueryDevtoolsStore, clearQueryDevtoolsTombstones, clearRestoredQueryDevtoolsOverrides, collectLeafPaths, collectQueryFormLinks, computeQueryAuthHeader, computeQueryBody, computeQueryHeaders, computeQueryMethod, computeQueryQueryParams, consumeSuppressQueryStackDevtools, contentfulGqlLikePaginationAdapter, countUnresolvedQueryDevtoolsOverrides, createAuthGuard, createBaseQuery, createBaseQueryCreator, createBearerAuthProvider, createDeleteQuery, createExecuteFn, createGetQuery, createGqlExecuteFn, createGqlMutationViaGet, createGqlMutationViaPost, createGqlQuery, createGqlQueryCreator, createGqlQueryViaGet, createGqlQueryViaPost, createHttpRequest, createIndexedDbQueryPersistenceAdapter, createInfinityQueryConfig, createLegacyQueryCreator, createNoopQueryPersistenceAdapter, createPagedQueryStack, createPatchQuery, createPersistentAuthFeature, createPostQuery, createPutQuery, createQuery, createQueryClient, createQueryCollection, createQueryCollectionSignal, createQueryCollectionSubject, createQueryContext, createQueryCreator, createQueryDevtoolsFormLinks, createQueryDevtoolsFormLinksRecorder, createQueryDevtoolsOverrides, createQueryDevtoolsOverridesRecorder, createQueryDevtoolsStats, createQueryDevtoolsStatsRecorder, createQueryErrorResponse, createQueryFeature, createQueryInvalidationFilter, createQueryKeyLockManager, createQueryObject, createQueryPersistenceEngine, createQueryRepository, createQuerySnapshotFn, createQueryStack, createQuerySyncEngine, createQuerySyncTransport, createSecureDeleteQuery, createSecureExecuteFactory, createSecureExecuteFn, createSecureGetQuery, createSecureGqlExecuteFn, createSecureGqlMutationViaGet, createSecureGqlMutationViaPost, createSecureGqlQuery, createSecureGqlQueryCreator, createSecureGqlQueryViaGet, createSecureGqlQueryViaPost, createSecurePatchQuery, createSecurePostQuery, createSecurePutQuery, createSecureQuery, createSecureQueryCreator, createTrackingFeature, createWebSocketClient, dateArrayQueryField, dateQueryField, decryptBearer, deepFreeze, def, defineQueryForm, deleteQueryDevtoolsMock, describeQueryDevtoolsFeatures, detectContentTypeHeader, detectPaginationShape, dynLikePaginationAdapter, effectComputed, emptyQueryArgs, ethletePaginationAdapter, executeUntilSettled, extractExpiresInSeconds, extractFormViolations, extractHtmlErrorMessage, extractQuery, fakePaginationAdapter, filterFailure, filterNull, filterQueryStates, filterSuccess, forEachHeader, formatQueryDevtoolsDuration, generateQueryDevtoolsNumberPreset, generateQueryDevtoolsStringPreset, getBearerAuthProviderName, getDefaultHeaders, getQueryClientName, getQueryFeatureUsage, getResponseUrl, ggLikePaginationAdapter, gql, gqlDataPropertyMissingInResponse, hasHeader, hasQueryDevtoolsOverridesAtPath, htmlErrorPayload, htmlQueryErrorParser, ignoreAutoRefresh, initQueryDevtoolsMocks, initQueryDevtoolsOverridePersistence, initQueryDevtoolsSettings, injectInfinityQueryResponseDelay, injectQueryContext, insertFrom, invalidBaseRouteError, invalidBodyError, invalidRouteError, invalidStateInsideSecureExecuteFactory, isAutoRefresh, isBasicAuthProvider, isBearerAuthProvider, isClassValidatorError, isCreateGqlQueryOptions, isCustomHeaderAuthProvider, isDateShapedLeaf, isEmptyString, isGqlQueryConfig, isHtmlErrorPayload, isLegacyQuery, isNaN$1 as isNaN, isPageOutOfRangeError, isQuery, isQueryCollection, isQueryDevtoolsEnabled, isQueryDevtoolsFaultArmed, isQueryDevtoolsRequestInterceptionEnabled, isQueryErrorResponse, isQueryStateCancelled, isQueryStateFailure, isQueryStateLoading, isQueryStatePrepared, isQueryStateSuccess, isRequestError, isSymfonyError, isSymfonyFormViolationListError, isSymfonyListError, isSymfonyPagerfantaOutOfRangeError, isUnderInvalidatedUrl, legacyPrepareFallbackInjector, legacyPrepareWithoutInjectionContext, loadQueryDevtoolsSchema, mapToPaginated, mapViolationsToFormErrors, matchesQueryDevtoolsMockPattern, matchesQueryDevtoolsMockQuery, maybeExecute, measureQueryDevtoolsPayload, mergeHeaders, nestedEffect, noteQueryFormRead, numberArrayQueryField, pagedQueryStackNextPageCalledWithoutPreviousPage, pagedQueryStackPageBiggerThanTotalPages, pagedQueryStackPreviousPageCalledButAlreadyAtFirstPage, paginatedEntityValueUpdater, parseAllXhrResponseHeaders, parseHttpErrorCodeToMessageDe, parseHttpErrorCodeToMessageEn, parseHttpErrorCodeToTitleDe, parseHttpErrorCodeToTitleEn, parseQueryDevtoolsOverrideTransfer, parseQueryRoute, pathParamsMissingInRouteFunctionError, provideInfinityQueryResponseDelay, provideLegacyPrepareFallback, provideQueryClientForDevtools, provideQueryDevtools, queryArrayComputed, queryClientFeatureUsedMultipleTimes, queryComputed, queryComputedTillTruthy, queryDevtoolsAbout, queryDevtoolsArmedMocks, queryDevtoolsEntries, queryDevtoolsFaults, queryDevtoolsFnDetail, queryDevtoolsMockId, queryDevtoolsMocks, queryDevtoolsOverridePersistence, queryDevtoolsRequestPath, queryDevtoolsResponseHistory, queryDevtoolsRestoredOverridesScope, queryDevtoolsSchemaNames, queryDevtoolsSchemaRoutes, queryDevtoolsSchemaState, queryDevtoolsSettings, queryDevtoolsStorage, queryErrorMessage, queryErrorMessages, queryExecute, queryFeatureUsedMultipleTimes, queryField, querySequence, querySequenceAlreadyRunning, queryStackTotalQueriesAndExpectedQueriesMismatch, queryStackWithArgsUsed, queryStackWithResponseUpdateUsed, queryStateAlreadyHasKeyError, queryStateCannotTransformError, queryStateDoesNotContainKeyError, queryStateErrorSignal, queryStateLoadingSignal, queryStateResponseSignal, queryStateSignal, readQueryDevtoolsStore, registerEthleteVersion, registerQueryDevtoolsEntry, registerQueryErrorParser, removeFrom, request, resetExecuteState, resetPageOnError, resolveInvalidationUrl, resolveQueryDevtoolsFault, resolveQueryDevtoolsFaultForAttempt, resolveQueryDevtoolsMock, resolveQueryDevtoolsMockForAttempt, restoredQueryDevtoolsOverrides, runDefaultQueryRetry, runQueryErrorParsers, saveQueryDevtoolsMock, searchQueryField, seedQueryDevtoolsSchemaBody, seedQueryDevtoolsSchemaRoute, serializeBody, serializeQueryDevtoolsOverrideTransfer, setDefaultQueryRetryFn, setQueryDevtoolsAppInfo, setQueryDevtoolsFault, setQueryDevtoolsFaultResolver, setQueryDevtoolsFormLinksFactory, setQueryDevtoolsMockResolver, setQueryDevtoolsOverridePersistence, setQueryDevtoolsOverridesFactory, setQueryDevtoolsOverridesScope, setQueryDevtoolsRegistrar, setQueryDevtoolsResponseHistory, setQueryDevtoolsSchemaLoader, setQueryDevtoolsSettings, setQueryDevtoolsStatsFactory, setupQueryDependencies, setupQueryExecuteState, setupQueryState, shouldAutoExecuteGqlQuery, shouldAutoExecuteQuery, shouldCacheQuery, shouldRetryRequest, silenceMissingWithArgsFeatureErrorUsedButWithArgsPresent, skipPaginationPageParamCalculator, smartDuplicateArrayItem, snapshotQueryDevtoolsHandle, sortQueryField, splitQueryConfig, stringArrayQueryField, stringifyQueryRouteParts, sumQueryDevtoolsStats, suppressNextQueryStackDevtools, switchQueryCollectionState, switchQueryState, symfonyQueryErrorParser, takeUntilResponse, toQuerySignal, toQuerySubject, tokensNotAvailableInsideAuthAndExec, tombstoneOf, transformArrayResponse, transformExecStateToQueryState, transformGql, transformMethod, transformPaginatedResponse, transformToBoolean, transformToBooleanArray, transformToDate, transformToDateArray, transformToNumber, transformToNumberArray, transformToSort, transformToSortQueryParam, transformToString, transformToStringArray, uncacheableRequestHasAllowCacheParam, uncacheableRequestHasCacheKeyParam, unwrapQuerySyncMessage, v2BuildQueryCacheKey, v2ExtractExpiresInSeconds, v2ShouldCacheQuery, v2ShouldRetryRequest, validateWithQuery, validateWithV2Query, withArgs, withArgsQueryFeatureMissingButRouteIsFunction, withAuthenticationQuery, withAutoRefresh, withAutoRefreshUsedInManualQuery, withAutoRefreshUsedOnUnsupportedHttpMethod, withBearerAuthMultiTabSync, withDefaultRetry, withErrorHandling, withEthleteApiErrors, withHtmlErrorParsing, withInactivityLogout, withLogging, withMultiTabSync, withPageResetOnError, withPersistentAuth, withPolling, withPollingUsedOnUnsupportedHttpMethod, withQueryDevtoolsOverridePersistence, withQueryPersistence, withRefreshQuery, withResponseUpdate, withSuccessHandling, withSymfonyErrors, withTokenExpirationWarning, withTokenRevocation, withTracking, wrapAsObservableSignal, wrapQuerySyncMessage, writeQueryDevtoolsStore };
13842
+ export { BasicAuthProvider, BearerAuthFeatureType, BooleanArrayQueryField, CLEAR_QUERY_ARGS, CustomHeaderAuthProvider, DEFAULT_KEEP_UNUSED_FOR, DEFAULT_QUERY_PERSISTENCE_MAX_AGE, DEFAULT_QUERY_PERSISTENCE_MAX_ENTRIES, DEFAULT_QUERY_PERSISTENCE_VERSION, DEFAULT_QUERY_PERSISTENCE_WRITE_DELAY, DateArrayQueryField, DateQueryField, EMPTY_QUERY_DEVTOOLS_FAULT, EntityStore, IGNORED_FILTER_COUNT_FIELDS, INFINITY_QUERY_TOKEN, InfinityQuery, InfinityQueryDirective, InfinityQueryTriggerDirective, LegacyQuery, LegacyQueryCreator, MAX_QUERY_DEVTOOLS_TOMBSTONES, MAX_UNUSED_ENTRIES, NumberArrayQueryField, ParseHttpErrorCodeToMessageDePipe, ParseHttpErrorCodeToMessageEnPipe, ParseHttpErrorCodeToTitleDePipe, ParseHttpErrorCodeToTitleEnPipe, QUERY_CLIENT_DEVTOOLS_TOKEN, QUERY_DEVTOOLS_FAULT_STATUSES, QUERY_DEVTOOLS_TOKEN_TTL_LIMIT, QUERY_PERSISTENCE_STORE_VERSION, QUERY_SYNC_PROTOCOL_VERSION, QUERY_VERSION, QueryClientFeatureType, QueryDevtoolsComponent, QueryDirective, 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, applyQueryDevtoolsOverrides, applyQueryDevtoolsTokenTtl, applyQueryFeatures, armAllQueryDevtoolsMocks, armQueryDevtoolsMock, armQueryDevtoolsOverrideTransfer, authExtractTokensResponseMissingAccessToken, authExtractTokensResponseMissingRefreshToken, authExtractTokensResponseNotObject, authProviderFeatureUsedMultipleTimes, booleanArrayQueryField, buildQueryCacheKey, buildQueryString, buildRoute, buildTimestampFromSeconds, canOverrideQueryDevtoolsTokenTtl, castQueryCreatorTypes, circularQueryDependency, circularQueryDependencyChecker, clearQueryDevtoolsArmedMocks, clearQueryDevtoolsFaults, clearQueryDevtoolsMockStore, clearQueryDevtoolsOverrideStore, clearQueryDevtoolsStore, clearQueryDevtoolsTokenTtl, clearQueryDevtoolsTombstones, clearRestoredQueryDevtoolsOverrides, collectLeafPaths, collectQueryDevtoolsSchemaComponents, collectQueryFormLinks, computeQueryAuthHeader, computeQueryBody, computeQueryHeaders, computeQueryMethod, computeQueryQueryParams, consumeSuppressQueryStackDevtools, contentfulGqlLikePaginationAdapter, countUnresolvedQueryDevtoolsOverrides, createAuthGuard, createBaseQuery, createBaseQueryCreator, createBearerAuthProvider, createDeleteQuery, createExecuteFn, createGetQuery, createGqlExecuteFn, createGqlMutationViaGet, createGqlMutationViaPost, createGqlQuery, createGqlQueryCreator, createGqlQueryViaGet, createGqlQueryViaPost, createHttpRequest, createIndexedDbQueryPersistenceAdapter, createInfinityQueryConfig, createLegacyQueryCreator, createNoopQueryPersistenceAdapter, createPagedQueryStack, createPatchQuery, createPersistentAuthFeature, createPostQuery, createPutQuery, createQuery, createQueryClient, createQueryCollection, createQueryCollectionSignal, createQueryCollectionSubject, createQueryContext, createQueryCreator, createQueryDevtoolsFormLinks, createQueryDevtoolsFormLinksRecorder, createQueryDevtoolsOverrides, createQueryDevtoolsOverridesRecorder, createQueryDevtoolsStats, createQueryDevtoolsStatsRecorder, createQueryErrorResponse, createQueryFeature, createQueryInvalidationFilter, createQueryKeyLockManager, createQueryObject, createQueryPersistenceEngine, createQueryRepository, createQuerySnapshotFn, createQueryStack, createQuerySyncEngine, createQuerySyncTransport, createSecureDeleteQuery, createSecureExecuteFactory, createSecureExecuteFn, createSecureGetQuery, createSecureGqlExecuteFn, createSecureGqlMutationViaGet, createSecureGqlMutationViaPost, createSecureGqlQuery, createSecureGqlQueryCreator, createSecureGqlQueryViaGet, createSecureGqlQueryViaPost, createSecurePatchQuery, createSecurePostQuery, createSecurePutQuery, createSecureQuery, createSecureQueryCreator, createTrackingFeature, createWebSocketClient, dateArrayQueryField, dateQueryField, decryptBearer, deepFreeze, def, defineQueryForm, deleteQueryDevtoolsMock, describeQueryDevtoolsFeatures, detectContentTypeHeader, detectPaginationShape, dynLikePaginationAdapter, effectComputed, emptyQueryArgs, ethletePaginationAdapter, executeUntilSettled, extractExpiresInSeconds, extractFormViolations, extractHtmlErrorMessage, extractQuery, fakePaginationAdapter, filterFailure, filterNull, filterQueryStates, filterSuccess, forEachHeader, formatQueryDevtoolsDuration, generateQueryDevtoolsNumberPreset, generateQueryDevtoolsStringPreset, getBearerAuthProviderName, getDefaultHeaders, getQueryClientName, getQueryFeatureUsage, getResponseUrl, ggLikePaginationAdapter, gql, gqlDataPropertyMissingInResponse, hasHeader, hasQueryDevtoolsOverridesAtPath, htmlErrorPayload, htmlQueryErrorParser, ignoreAutoRefresh, initQueryDevtoolsFaults, initQueryDevtoolsMocks, initQueryDevtoolsOverridePersistence, initQueryDevtoolsSettings, injectInfinityQueryResponseDelay, injectQueryContext, insertFrom, invalidBaseRouteError, invalidBodyError, invalidRouteError, invalidStateInsideSecureExecuteFactory, isAutoRefresh, isBasicAuthProvider, isBearerAuthProvider, isClassValidatorError, isCreateGqlQueryOptions, isCustomHeaderAuthProvider, isDateShapedLeaf, isEmptyString, isGqlQueryConfig, isHtmlErrorPayload, isLegacyQuery, isNaN$1 as isNaN, isPageOutOfRangeError, isQuery, isQueryCollection, isQueryDevtoolsEnabled, isQueryDevtoolsFaultArmed, isQueryDevtoolsRequestInterceptionEnabled, isQueryErrorResponse, isQueryStateCancelled, isQueryStateFailure, isQueryStateLoading, isQueryStatePrepared, isQueryStateSuccess, isRequestError, isSymfonyError, isSymfonyFormViolationListError, isSymfonyListError, isSymfonyPagerfantaOutOfRangeError, isUnderInvalidatedUrl, legacyPrepareFallbackInjector, legacyPrepareWithoutInjectionContext, loadQueryDevtoolsSchema, mapToPaginated, mapViolationsToFormErrors, matchesQueryDevtoolsMockPattern, matchesQueryDevtoolsMockQuery, maybeExecute, measureQueryDevtoolsPayload, mergeHeaders, nestedEffect, noteQueryFormRead, numberArrayQueryField, pagedQueryStackNextPageCalledWithoutPreviousPage, pagedQueryStackPageBiggerThanTotalPages, pagedQueryStackPreviousPageCalledButAlreadyAtFirstPage, paginatedEntityValueUpdater, parseAllXhrResponseHeaders, parseHttpErrorCodeToMessageDe, parseHttpErrorCodeToMessageEn, parseHttpErrorCodeToTitleDe, parseHttpErrorCodeToTitleEn, parseQueryDevtoolsOverrideTransfer, parseQueryRoute, patchQueryDevtoolsTokenPayload, pathParamsMissingInRouteFunctionError, provideInfinityQueryResponseDelay, provideLegacyPrepareFallback, provideQueryClientForDevtools, provideQueryDevtools, queryArrayComputed, queryClientFeatureUsedMultipleTimes, queryComputed, queryComputedTillTruthy, queryDevtoolsAbout, queryDevtoolsArmedMocks, queryDevtoolsArmedMocksRestored, queryDevtoolsEntries, queryDevtoolsFaults, queryDevtoolsFaultsRestored, queryDevtoolsFnDetail, queryDevtoolsMockId, queryDevtoolsMocks, queryDevtoolsOverridePersistence, queryDevtoolsRequestPath, queryDevtoolsResponseHistory, queryDevtoolsRestoredOverridesScope, queryDevtoolsSchemaNames, queryDevtoolsSchemaRoutes, queryDevtoolsSchemaState, queryDevtoolsSettings, queryDevtoolsStorage, queryDevtoolsTokenTtls, queryErrorMessage, queryErrorMessages, queryExecute, queryFeatureUsedMultipleTimes, queryField, querySequence, querySequenceAlreadyRunning, queryStackTotalQueriesAndExpectedQueriesMismatch, queryStackWithArgsUsed, queryStackWithResponseUpdateUsed, queryStateAlreadyHasKeyError, queryStateCannotTransformError, queryStateDoesNotContainKeyError, queryStateErrorSignal, queryStateLoadingSignal, queryStateResponseSignal, queryStateSignal, readQueryDevtoolsStore, registerEthleteVersion, registerQueryDevtoolsEntry, registerQueryErrorParser, removeFrom, request, resetExecuteState, resetPageOnError, resolveInvalidationUrl, resolveQueryDevtoolsFault, resolveQueryDevtoolsFaultForAttempt, resolveQueryDevtoolsMock, resolveQueryDevtoolsMockForAttempt, restoredQueryDevtoolsOverrides, runDefaultQueryRetry, runQueryErrorParsers, saveQueryDevtoolsMock, searchQueryField, seedQueryDevtoolsSchemaBody, seedQueryDevtoolsSchemaRoute, serializeBody, serializeQueryDevtoolsOverrideTransfer, setDefaultQueryRetryFn, setQueryDevtoolsAppInfo, setQueryDevtoolsArmedMocksScope, setQueryDevtoolsFault, setQueryDevtoolsFaultResolver, setQueryDevtoolsFaultsScope, setQueryDevtoolsFormLinksFactory, setQueryDevtoolsMockResolver, setQueryDevtoolsOverridePersistence, setQueryDevtoolsOverridesFactory, setQueryDevtoolsOverridesScope, setQueryDevtoolsRegistrar, setQueryDevtoolsResponseHistory, setQueryDevtoolsSchemaLoader, setQueryDevtoolsSettings, setQueryDevtoolsStatsFactory, setQueryDevtoolsTokenPayloadPatcher, setQueryDevtoolsTokenTtl, setupQueryDependencies, setupQueryExecuteState, setupQueryState, shouldAutoExecuteGqlQuery, shouldAutoExecuteQuery, shouldCacheQuery, shouldRetryRequest, silenceMissingWithArgsFeatureErrorUsedButWithArgsPresent, skipPaginationPageParamCalculator, smartDuplicateArrayItem, snapshotQueryDevtoolsHandle, sortQueryField, splitQueryConfig, stringArrayQueryField, stringifyQueryRouteParts, sumQueryDevtoolsStats, suppressNextQueryStackDevtools, switchQueryCollectionState, switchQueryState, symfonyQueryErrorParser, takeUntilResponse, toQuerySignal, toQuerySubject, tokensNotAvailableInsideAuthAndExec, tombstoneOf, transformArrayResponse, transformExecStateToQueryState, transformGql, transformMethod, transformPaginatedResponse, transformToBoolean, transformToBooleanArray, transformToDate, transformToDateArray, transformToNumber, transformToNumberArray, transformToSort, transformToSortQueryParam, transformToString, transformToStringArray, uncacheableRequestHasAllowCacheParam, uncacheableRequestHasCacheKeyParam, unwrapQuerySyncMessage, v2BuildQueryCacheKey, v2ExtractExpiresInSeconds, v2ShouldCacheQuery, v2ShouldRetryRequest, validateWithQuery, validateWithV2Query, withArgs, withArgsQueryFeatureMissingButRouteIsFunction, withAuthenticationQuery, withAutoRefresh, withAutoRefreshUsedInManualQuery, withAutoRefreshUsedOnUnsupportedHttpMethod, withBearerAuthMultiTabSync, withDefaultRetry, withErrorHandling, withEthleteApiErrors, withHtmlErrorParsing, withInactivityLogout, withLogging, withMultiTabSync, withPageResetOnError, withPersistentAuth, withPolling, withPollingUsedOnUnsupportedHttpMethod, withQueryDevtoolsOverridePersistence, withQueryPersistence, withRefreshQuery, withResponseUpdate, withSuccessHandling, withSymfonyErrors, withTokenExpirationWarning, withTokenRevocation, withTracking, wrapAsObservableSignal, wrapQuerySyncMessage, writeQueryDevtoolsStore };
13493
13843
  //# sourceMappingURL=ethlete-query.mjs.map