@ethlete/query 6.0.0-next.46 → 6.0.0-next.49
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.
- package/CHANGELOG.md +44 -0
- package/fesm2022/ethlete-query-testing.mjs +8 -0
- package/fesm2022/ethlete-query-testing.mjs.map +1 -1
- package/fesm2022/ethlete-query.mjs +475 -150
- package/fesm2022/ethlete-query.mjs.map +1 -1
- package/generators/migrate-query-opt-in-features/migration.js +13 -1
- package/generators/migrate-to-query-v3/auth-provider-scaffold.js +6 -4
- package/generators/migrate-to-query-v3/cleanup-migration.js +2 -42
- package/generators/migrate-to-query-v3/legacy-prepare-migration.js +9 -12
- package/generators/migrate-to-query-v3/legacy-query-creator-migration.js +81 -15
- package/generators/migrate-to-query-v3/migration-scope.js +0 -3
- package/generators/migrate-to-query-v3/query-client-migration.js +97 -47
- package/generators/migrate-to-query-v3/rename-symbols.js +19 -6
- package/generators/migrate-to-query-v3/shared.js +6 -2
- package/generators/prep-for-query-v3/migration.js +68 -11
- package/package.json +1 -1
- package/types/ethlete-query-testing.d.ts +2 -0
- package/types/ethlete-query.d.ts +250 -49
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { inject,
|
|
2
|
+
import { inject, ApplicationRef, untracked, effect, Injector, runInInjectionContext, DestroyRef, computed, InjectionToken, EnvironmentInjector, ElementRef, ErrorHandler, createEnvironmentInjector, signal, linkedSignal, isDevMode, PLATFORM_ID, resource, DOCUMENT, VERSION, provideEnvironmentInitializer, afterNextRender, makeEnvironmentProviders, assertInInjectionContext, ChangeDetectorRef, ViewContainerRef, TemplateRef, Input, Directive, input, Pipe, ViewEncapsulation, Component, NgZone } from '@angular/core';
|
|
3
3
|
import { UrlTree, Router, RedirectCommand, ActivatedRoute } from '@angular/router';
|
|
4
4
|
import { Observable, defer, from, filter, Subject, Subscription, throwError, of, timer, switchMap, tap, retry, catchError, EMPTY as EMPTY$1, take, takeUntil, finalize, mergeMap, toArray, map, race, NEVER, merge, takeWhile, firstValueFrom, concatMap, fromEvent, throttleTime, interval, startWith, pairwise, BehaviorSubject, combineLatest, ReplaySubject, distinctUntilChanged, shareReplay, withLatestFrom, debounceTime } from 'rxjs';
|
|
5
5
|
import { defineStaticProvider, RuntimeError, clamp, randomId, defineRootProvider, isObject, injectUnsavedChangesCoordinator, injectRoute, getCookie, setCookie, deleteCookie, CORE_VERSION, createDestroy, computedTillTruthy, defineProvider, toProvideFn, toInjectFn, nextFrame, injectQueryParams, injectQueryParamChanges, clone, equal, ET_PROPERTY_REMOVED, previousSignalValue } from '@ethlete/core';
|
|
6
|
-
import { HttpClient, HttpErrorResponse, HttpEventType,
|
|
6
|
+
import { HttpClient, HttpErrorResponse, HttpEventType, HttpHeaders, HttpResponse, HttpStatusCode } from '@angular/common/http';
|
|
7
7
|
import { toObservable, takeUntilDestroyed, toSignal } from '@angular/core/rxjs-interop';
|
|
8
8
|
import { getActiveConsumer, setActiveConsumer, SIGNAL } from '@angular/core/primitives/signals';
|
|
9
9
|
import { isPlatformBrowser, NgClass, AsyncPipe, JsonPipe } from '@angular/common';
|
|
@@ -13,6 +13,7 @@ import { FormControl, ReactiveFormsModule, FormGroup } from '@angular/forms';
|
|
|
13
13
|
|
|
14
14
|
const DEFAULT_RETURN_URL_PARAM = 'returnUrl';
|
|
15
15
|
const DEFAULT_URL = '/';
|
|
16
|
+
const DEFAULT_RESTORE_TIMEOUT_MS = 10000;
|
|
16
17
|
const resolveTarget = (router, target) => {
|
|
17
18
|
if (target instanceof UrlTree)
|
|
18
19
|
return target;
|
|
@@ -45,51 +46,137 @@ const readReturnUrl = (router, url, param) => {
|
|
|
45
46
|
* ];
|
|
46
47
|
* ```
|
|
47
48
|
*
|
|
48
|
-
* A guard pends while a session restore is in flight
|
|
49
|
-
* is about to exist, so a hard reload of a protected URL stays on
|
|
49
|
+
* A guard pends while a session restore is in flight, for up to `restoreTimeoutMs`, rather than
|
|
50
|
+
* redirecting against a session that is about to exist, so a hard reload of a protected URL stays on
|
|
51
|
+
* that URL.
|
|
50
52
|
*/
|
|
51
53
|
const createAuthGuard = (providerRef, config) => {
|
|
52
54
|
const param = config.returnUrlParam === false ? null : (config.returnUrlParam ?? DEFAULT_RETURN_URL_PARAM);
|
|
53
55
|
const behavior = config.navigationBehaviorOptions ?? { replaceUrl: true };
|
|
54
|
-
const
|
|
56
|
+
const restoreTimeoutMs = config.restoreTimeoutMs ?? DEFAULT_RESTORE_TIMEOUT_MS;
|
|
57
|
+
const sessionGuards = new Set();
|
|
58
|
+
const watchedRouters = new WeakSet();
|
|
59
|
+
const anonymousGuards = new Set();
|
|
60
|
+
const watchedStartRouters = new WeakSet();
|
|
61
|
+
const timedOutRestores = new WeakSet();
|
|
62
|
+
const loginRedirect = (router, returnUrl) => {
|
|
63
|
+
const loginTree = resolveTarget(router, config.loginUrl);
|
|
64
|
+
return param && returnUrl ? withQueryParam(loginTree, param, returnUrl) : loginTree;
|
|
65
|
+
};
|
|
66
|
+
const usesGuard = (route, guardSet) => {
|
|
67
|
+
const guards = [...(route.routeConfig?.canMatch ?? []), ...(route.routeConfig?.canActivate ?? [])];
|
|
68
|
+
return guards.some((guard) => guardSet.has(guard)) || route.children.some((child) => usesGuard(child, guardSet));
|
|
69
|
+
};
|
|
70
|
+
const watchSessionStart = (router, provider) => {
|
|
71
|
+
if (!config.redirectOnSessionStart || watchedStartRouters.has(router))
|
|
72
|
+
return;
|
|
73
|
+
watchedStartRouters.add(router);
|
|
74
|
+
const appRef = inject(ApplicationRef);
|
|
75
|
+
let wasAuthenticated = untracked(provider.sessionStatus) === 'authenticated';
|
|
76
|
+
effect(() => {
|
|
77
|
+
const isAuthenticated = provider.sessionStatus() === 'authenticated';
|
|
78
|
+
const started = isAuthenticated && !wasAuthenticated;
|
|
79
|
+
wasAuthenticated = isAuthenticated;
|
|
80
|
+
if (!started)
|
|
81
|
+
return;
|
|
82
|
+
untracked(() => {
|
|
83
|
+
if (!usesGuard(router.routerState.snapshot.root, anonymousGuards))
|
|
84
|
+
return;
|
|
85
|
+
const returnUrl = readReturnUrl(router, router.url, param);
|
|
86
|
+
void router.navigateByUrl(returnUrl ? router.parseUrl(returnUrl) : resolveTarget(router, config.defaultUrl ?? DEFAULT_URL), behavior);
|
|
87
|
+
});
|
|
88
|
+
}, { injector: appRef.injector });
|
|
89
|
+
};
|
|
90
|
+
const watchSessionEnd = (router, provider) => {
|
|
91
|
+
const causes = config.redirectOnSessionEnd;
|
|
92
|
+
if (!causes?.length || watchedRouters.has(router))
|
|
93
|
+
return;
|
|
94
|
+
watchedRouters.add(router);
|
|
95
|
+
const appRef = inject(ApplicationRef);
|
|
96
|
+
let handled = untracked(provider.executionState);
|
|
97
|
+
effect(() => {
|
|
98
|
+
const state = provider.executionState();
|
|
99
|
+
const cause = provider.sessionEndCause();
|
|
100
|
+
if (state === handled || state?.type !== 'logout')
|
|
101
|
+
return;
|
|
102
|
+
handled = state;
|
|
103
|
+
if (!cause || !causes.includes(cause))
|
|
104
|
+
return;
|
|
105
|
+
untracked(() => {
|
|
106
|
+
if (!usesGuard(router.routerState.snapshot.root, sessionGuards))
|
|
107
|
+
return;
|
|
108
|
+
void router.navigateByUrl(loginRedirect(router, cause === 'user' ? null : router.url), behavior);
|
|
109
|
+
});
|
|
110
|
+
}, { injector: appRef.injector });
|
|
111
|
+
};
|
|
112
|
+
const guardFor = (requiresSession, permission, options) => () => {
|
|
55
113
|
const router = inject(Router);
|
|
56
114
|
const injector = inject(Injector);
|
|
57
115
|
const provider = providerRef.inject();
|
|
116
|
+
if (requiresSession)
|
|
117
|
+
watchSessionEnd(router, provider);
|
|
118
|
+
else
|
|
119
|
+
watchSessionStart(router, provider);
|
|
58
120
|
// Captured before the wait below: once the session settles the router has moved on, and the URL
|
|
59
121
|
// the visitor actually asked for is no longer reachable from it.
|
|
60
122
|
const attemptedUrl = router.currentNavigation()?.extractedUrl.toString() ?? router.url;
|
|
123
|
+
// A restore a guard stopped waiting for is not waited for again, or the redirect to the login
|
|
124
|
+
// would wait out a second timeout on the login route's own guard.
|
|
61
125
|
const settled = () => {
|
|
62
126
|
const status = provider.sessionStatus();
|
|
63
|
-
|
|
127
|
+
if (status === 'unknown' || status === 'restoring')
|
|
128
|
+
return timedOutRestores.has(provider);
|
|
129
|
+
timedOutRestores.delete(provider);
|
|
130
|
+
return true;
|
|
64
131
|
};
|
|
65
132
|
const decide = () => {
|
|
66
133
|
const authenticated = provider.sessionStatus() === 'authenticated';
|
|
67
|
-
if (authenticated
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
const
|
|
71
|
-
return new RedirectCommand(
|
|
134
|
+
if (authenticated !== requiresSession) {
|
|
135
|
+
if (requiresSession)
|
|
136
|
+
return new RedirectCommand(loginRedirect(router, attemptedUrl), behavior);
|
|
137
|
+
const returnUrl = readReturnUrl(router, attemptedUrl, param);
|
|
138
|
+
return new RedirectCommand(returnUrl ? router.parseUrl(returnUrl) : resolveTarget(router, config.defaultUrl ?? DEFAULT_URL), behavior);
|
|
72
139
|
}
|
|
73
|
-
|
|
74
|
-
|
|
140
|
+
if (!permission || untracked(() => runInInjectionContext(injector, () => permission(provider))))
|
|
141
|
+
return true;
|
|
142
|
+
return new RedirectCommand(resolveTarget(router, options?.redirectTo ?? config.defaultUrl ?? DEFAULT_URL), behavior);
|
|
75
143
|
};
|
|
76
144
|
if (settled())
|
|
77
145
|
return decide();
|
|
78
146
|
return new Observable((subscriber) => {
|
|
79
|
-
const
|
|
80
|
-
if (!settled())
|
|
81
|
-
return;
|
|
147
|
+
const finish = () => {
|
|
82
148
|
subscriber.next(decide());
|
|
83
149
|
subscriber.complete();
|
|
150
|
+
};
|
|
151
|
+
const timeout = restoreTimeoutMs === false
|
|
152
|
+
? null
|
|
153
|
+
: setTimeout(() => {
|
|
154
|
+
timedOutRestores.add(provider);
|
|
155
|
+
finish();
|
|
156
|
+
}, restoreTimeoutMs);
|
|
157
|
+
const watcher = effect(() => {
|
|
158
|
+
if (settled())
|
|
159
|
+
untracked(finish);
|
|
84
160
|
}, { ...(ngDevMode ? { debugName: "watcher" } : /* istanbul ignore next */ {}), injector });
|
|
85
|
-
return () =>
|
|
161
|
+
return () => {
|
|
162
|
+
watcher.destroy();
|
|
163
|
+
if (timeout !== null)
|
|
164
|
+
clearTimeout(timeout);
|
|
165
|
+
};
|
|
86
166
|
});
|
|
87
167
|
};
|
|
88
|
-
const
|
|
168
|
+
const sessionGuard = (guard) => {
|
|
169
|
+
sessionGuards.add(guard);
|
|
170
|
+
return guard;
|
|
171
|
+
};
|
|
172
|
+
const requireSession = sessionGuard(guardFor(true));
|
|
89
173
|
const requireAnonymous = guardFor(false);
|
|
174
|
+
anonymousGuards.add(requireAnonymous);
|
|
90
175
|
return {
|
|
91
176
|
canMatch: requireSession,
|
|
92
177
|
canActivate: requireSession,
|
|
178
|
+
canMatchWith: (permission, options) => sessionGuard(guardFor(true, permission, options)),
|
|
179
|
+
canActivateWith: (permission, options) => sessionGuard(guardFor(true, permission, options)),
|
|
93
180
|
canMatchAnonymous: requireAnonymous,
|
|
94
181
|
canActivateAnonymous: requireAnonymous,
|
|
95
182
|
returnUrl: () => {
|
|
@@ -397,6 +484,7 @@ const createQueryContext = (context) => defineStaticProvider(context, {
|
|
|
397
484
|
/** @internal */
|
|
398
485
|
const injectQueryContext = () => inject(QUERY_CONTEXT_TOKEN);
|
|
399
486
|
|
|
487
|
+
/** @internal */
|
|
400
488
|
const setupQueryDependencies = (options) => {
|
|
401
489
|
const hostInjector = options.queryConfig?.injector ?? inject(Injector);
|
|
402
490
|
const environmentInjector = options.queryConfig?.injector?.get(EnvironmentInjector) ?? hostInjector.get(EnvironmentInjector);
|
|
@@ -469,7 +557,6 @@ const QueryRuntimeErrorCode = {
|
|
|
469
557
|
// Query Stack
|
|
470
558
|
QUERY_STACK_WITH_ARGS_USED: 500,
|
|
471
559
|
QUERY_STACK_WITH_RESPONSE_UPDATE_USED: 501,
|
|
472
|
-
QUERY_STACK_TOTAL_QUERIES_AND_EXPECTED_QUERIES_MISMATCH: 502,
|
|
473
560
|
// GQL
|
|
474
561
|
GQL_DATA_PROPERTY_MISSING_IN_RESPONSE: 600,
|
|
475
562
|
GQL_ERRORS_IN_RESPONSE: 601,
|
|
@@ -552,9 +639,6 @@ const queryStackWithArgsUsed = () => {
|
|
|
552
639
|
const queryStackWithResponseUpdateUsed = () => {
|
|
553
640
|
return new RuntimeError(QueryRuntimeErrorCode.QUERY_STACK_WITH_RESPONSE_UPDATE_USED, `withResponseUpdate() has been used in a query stack or a paged query stack. This is not supported.`);
|
|
554
641
|
};
|
|
555
|
-
const queryStackTotalQueriesAndExpectedQueriesMismatch = (totalQueries, expectedQueries) => {
|
|
556
|
-
return new RuntimeError(QueryRuntimeErrorCode.QUERY_STACK_TOTAL_QUERIES_AND_EXPECTED_QUERIES_MISMATCH, `The total queries "${totalQueries}" and the expected queries "${expectedQueries}" do not match. This usually happens if a query depends on the response of the previous query to calculate its pagination values. Set blockExecutionDuringLoading to true to prevent this.`);
|
|
557
|
-
};
|
|
558
642
|
const gqlDataPropertyMissingInResponse = () => {
|
|
559
643
|
return new RuntimeError(QueryRuntimeErrorCode.GQL_DATA_PROPERTY_MISSING_IN_RESPONSE, `The GraphQL response is missing the required "data" property. Please add a custom transformResponse param to the query creator to handle this response format.`);
|
|
560
644
|
};
|
|
@@ -700,6 +784,7 @@ const withArgs = (args) => {
|
|
|
700
784
|
},
|
|
701
785
|
});
|
|
702
786
|
};
|
|
787
|
+
const readPollingInterval = (interval) => typeof interval === 'function' ? interval() : interval;
|
|
703
788
|
/**
|
|
704
789
|
* A query feature that will automatically execute the query at a given interval.
|
|
705
790
|
* The interval will be cleared when the query is destroyed.
|
|
@@ -717,14 +802,21 @@ const withPolling = (options) => {
|
|
|
717
802
|
return createQueryFeature({
|
|
718
803
|
type: QueryFeatureType.WITH_POLLING,
|
|
719
804
|
devtools: () => [
|
|
720
|
-
{ label: 'interval', value: formatQueryDevtoolsDuration(options.interval) },
|
|
805
|
+
{ label: 'interval', value: formatQueryDevtoolsDuration(untracked(() => readPollingInterval(options.interval))) },
|
|
721
806
|
{ label: 'execute initially', value: options.executeInitially ? 'yes' : 'no' },
|
|
807
|
+
...(options.pauseWhileHidden ? [{ label: 'pause while hidden', value: 'yes' }] : []),
|
|
808
|
+
...(options.refetchOnFocus ? [{ label: 'refetch on focus', value: 'yes' }] : []),
|
|
809
|
+
...(options.refetchOnReconnect ? [{ label: 'refetch on reconnect', value: 'yes' }] : []),
|
|
722
810
|
],
|
|
723
811
|
fn: (context) => {
|
|
724
812
|
if (!context.flags.shouldAutoExecuteMethod) {
|
|
725
813
|
throw withPollingUsedOnUnsupportedHttpMethod(context.flags.method);
|
|
726
814
|
}
|
|
727
815
|
let intervalId = null;
|
|
816
|
+
let timeoutId = null;
|
|
817
|
+
let active = false;
|
|
818
|
+
let currentArgs = null;
|
|
819
|
+
let lastTickAt = 0;
|
|
728
820
|
const sync = context.deps.client.subtle.sync;
|
|
729
821
|
const lockManager = sync?.isPollingDedupeEnabled && context.flags.isMultiTabSyncEnabled ? sync.lockManager : null;
|
|
730
822
|
// Only ever set while dedup is active. A tick runs unless we know another tab is taking care of
|
|
@@ -757,28 +849,98 @@ const withPolling = (options) => {
|
|
|
757
849
|
hold?.release();
|
|
758
850
|
});
|
|
759
851
|
}
|
|
852
|
+
const currentInterval = () => untracked(() => readPollingInterval(options.interval));
|
|
853
|
+
const isPaused = () => options.pauseWhileHidden === true && document.hidden;
|
|
854
|
+
const stop = () => {
|
|
855
|
+
if (intervalId !== null)
|
|
856
|
+
clearInterval(intervalId);
|
|
857
|
+
if (timeoutId !== null)
|
|
858
|
+
clearTimeout(timeoutId);
|
|
859
|
+
intervalId = null;
|
|
860
|
+
timeoutId = null;
|
|
861
|
+
};
|
|
862
|
+
const tick = () => {
|
|
863
|
+
lastTickAt = Date.now();
|
|
864
|
+
// The interval keeps running while another tab is the holder, so leadership arriving
|
|
865
|
+
// mid-flight needs no restart and `executeInitially`/interval semantics stay identical.
|
|
866
|
+
if (hold && !hold.isHolder())
|
|
867
|
+
return;
|
|
868
|
+
context.execute({ args: currentArgs });
|
|
869
|
+
};
|
|
870
|
+
const schedule = (firstDelay) => {
|
|
871
|
+
stop();
|
|
872
|
+
if (!active || isPaused())
|
|
873
|
+
return;
|
|
874
|
+
const interval = currentInterval();
|
|
875
|
+
if (firstDelay >= interval) {
|
|
876
|
+
intervalId = window.setInterval(tick, interval);
|
|
877
|
+
return;
|
|
878
|
+
}
|
|
879
|
+
timeoutId = window.setTimeout(() => {
|
|
880
|
+
timeoutId = null;
|
|
881
|
+
tick();
|
|
882
|
+
intervalId = window.setInterval(tick, currentInterval());
|
|
883
|
+
}, Math.max(0, firstDelay));
|
|
884
|
+
};
|
|
885
|
+
const remainingDelay = () => lastTickAt + currentInterval() - Date.now();
|
|
760
886
|
nestedEffect(() => {
|
|
761
887
|
const args = context.state.args();
|
|
762
888
|
untracked(() => {
|
|
763
|
-
|
|
764
|
-
|
|
889
|
+
stop();
|
|
890
|
+
currentArgs = args;
|
|
765
891
|
// Don't start polling if the query doesn't have args.
|
|
766
892
|
// It should have args because a withArgs feature is present.
|
|
767
|
-
|
|
893
|
+
active = !(args === null && context.flags.hasWithArgsFeature);
|
|
894
|
+
if (!active)
|
|
768
895
|
return;
|
|
769
|
-
|
|
770
|
-
|
|
896
|
+
lastTickAt = Date.now();
|
|
897
|
+
if (options.executeInitially) {
|
|
898
|
+
if (isPaused())
|
|
899
|
+
lastTickAt -= currentInterval();
|
|
900
|
+
else if (!hold || hold.isHolder())
|
|
901
|
+
context.execute({ args });
|
|
771
902
|
}
|
|
772
|
-
|
|
773
|
-
// The interval keeps running while another tab is the holder, so leadership arriving
|
|
774
|
-
// mid-flight needs no restart and `executeInitially`/interval semantics stay identical.
|
|
775
|
-
if (hold && !hold.isHolder())
|
|
776
|
-
return;
|
|
777
|
-
context.execute({ args });
|
|
778
|
-
}, options.interval);
|
|
903
|
+
schedule(currentInterval());
|
|
779
904
|
});
|
|
780
905
|
}, { injector: context.deps.injector });
|
|
781
|
-
|
|
906
|
+
if (typeof options.interval === 'function') {
|
|
907
|
+
const interval = options.interval;
|
|
908
|
+
nestedEffect(() => {
|
|
909
|
+
interval();
|
|
910
|
+
untracked(() => {
|
|
911
|
+
if (intervalId === null && timeoutId === null)
|
|
912
|
+
return;
|
|
913
|
+
schedule(remainingDelay());
|
|
914
|
+
});
|
|
915
|
+
}, { injector: context.deps.injector });
|
|
916
|
+
}
|
|
917
|
+
const listen = (target, type, listener) => {
|
|
918
|
+
target.addEventListener(type, listener);
|
|
919
|
+
context.deps.destroyRef.onDestroy(() => target.removeEventListener(type, listener));
|
|
920
|
+
};
|
|
921
|
+
if (options.pauseWhileHidden) {
|
|
922
|
+
listen(document, 'visibilitychange', () => {
|
|
923
|
+
if (!active)
|
|
924
|
+
return;
|
|
925
|
+
if (document.hidden) {
|
|
926
|
+
stop();
|
|
927
|
+
}
|
|
928
|
+
else if (intervalId === null && timeoutId === null) {
|
|
929
|
+
schedule(remainingDelay());
|
|
930
|
+
}
|
|
931
|
+
});
|
|
932
|
+
}
|
|
933
|
+
const refetchNow = () => {
|
|
934
|
+
if (!active || isPaused())
|
|
935
|
+
return;
|
|
936
|
+
tick();
|
|
937
|
+
schedule(currentInterval());
|
|
938
|
+
};
|
|
939
|
+
if (options.refetchOnFocus)
|
|
940
|
+
listen(window, 'focus', refetchNow);
|
|
941
|
+
if (options.refetchOnReconnect)
|
|
942
|
+
listen(window, 'online', refetchNow);
|
|
943
|
+
context.deps.destroyRef.onDestroy(stop);
|
|
782
944
|
},
|
|
783
945
|
});
|
|
784
946
|
};
|
|
@@ -1068,6 +1230,74 @@ const setDefaultQueryRetryFn = (fn) => {
|
|
|
1068
1230
|
/** @internal */
|
|
1069
1231
|
const runDefaultQueryRetry = (options) => defaultRetryFn$1?.(options) ?? NO_RETRY;
|
|
1070
1232
|
|
|
1233
|
+
const DEFAULT_MAX_ATTEMPTS = 3;
|
|
1234
|
+
const DEFAULT_BASE_DELAY_MS = 1000;
|
|
1235
|
+
const DEFAULT_MAX_DELAY_MS = 30_000;
|
|
1236
|
+
const DEFAULT_JITTER = 0.25;
|
|
1237
|
+
// 500 is left out on purpose: an internal server error is a bug in the backend far more often than a
|
|
1238
|
+
// blip, and repeating the request that triggered it does not make it go away.
|
|
1239
|
+
const isRetryableByDefault = (status) => status === 0 || status === 408 || status === 425 || status === 429 || status >= 501;
|
|
1240
|
+
/**
|
|
1241
|
+
* Builds a retry policy: an exponentially backing off, jittered {@link ShouldRetryRequestFn} bounded by
|
|
1242
|
+
* an attempt ceiling. What {@link withDefaultRetry} installs - reach for this directly to hand a single
|
|
1243
|
+
* client or creator its own `retryFn`.
|
|
1244
|
+
*
|
|
1245
|
+
* @example
|
|
1246
|
+
* const flakyEndpointRetry = createDefaultRetryFn({ maxAttempts: 8, maxDelayMs: 10_000 });
|
|
1247
|
+
*
|
|
1248
|
+
* const getReport = myApiGet<GetReportArgs>('/report').clone({ retryFn: flakyEndpointRetry });
|
|
1249
|
+
*/
|
|
1250
|
+
const createDefaultRetryFn = (options = {}) => {
|
|
1251
|
+
const maxAttempts = options.maxAttempts ?? DEFAULT_MAX_ATTEMPTS;
|
|
1252
|
+
const baseDelayMs = options.baseDelayMs ?? DEFAULT_BASE_DELAY_MS;
|
|
1253
|
+
const maxDelayMs = options.maxDelayMs ?? DEFAULT_MAX_DELAY_MS;
|
|
1254
|
+
const jitter = clamp(options.jitter ?? DEFAULT_JITTER, 0, 1);
|
|
1255
|
+
const retryableStatusCodes = options.retryableStatusCodes;
|
|
1256
|
+
const retryNonIdempotent = options.retryNonIdempotent ?? false;
|
|
1257
|
+
const isRetryableStatus = (status) => retryableStatusCodes ? retryableStatusCodes.includes(status) : isRetryableByDefault(status);
|
|
1258
|
+
const backoff = (retryCount) => {
|
|
1259
|
+
const exponential = baseDelayMs * Math.pow(2, retryCount);
|
|
1260
|
+
const spread = jitter === 0 ? 1 : 1 + (Math.random() * 2 - 1) * jitter;
|
|
1261
|
+
return Math.round(clamp(exponential * spread, 0, maxDelayMs));
|
|
1262
|
+
};
|
|
1263
|
+
return ({ retryCount, error, idempotent }) => {
|
|
1264
|
+
// Not an HTTP failure at all, so nothing about it says a second attempt would go any better.
|
|
1265
|
+
if (!(error instanceof HttpErrorResponse))
|
|
1266
|
+
return { retry: false };
|
|
1267
|
+
if (!idempotent && !retryNonIdempotent)
|
|
1268
|
+
return { retry: false };
|
|
1269
|
+
if (maxAttempts > 0 && retryCount > maxAttempts)
|
|
1270
|
+
return { retry: false };
|
|
1271
|
+
const { status, error: detail, headers } = error;
|
|
1272
|
+
if (!isRetryableStatus(status))
|
|
1273
|
+
return { retry: false };
|
|
1274
|
+
// A page past the end of a Pagerfanta collection answers 5xx, and asking for it again keeps
|
|
1275
|
+
// answering 5xx - the request is wrong, not the server.
|
|
1276
|
+
if (status >= 501 && isSymfonyPagerfantaOutOfRangeError(detail))
|
|
1277
|
+
return { retry: false };
|
|
1278
|
+
if (status === 429) {
|
|
1279
|
+
const retryAfter = headers.get('retry-after') || headers.get('x-retry-after');
|
|
1280
|
+
const delay = retryAfter ? parseInt(retryAfter) * 1000 : NaN;
|
|
1281
|
+
// The server named a time, so it is used as named rather than jittered - only capped, since a
|
|
1282
|
+
// `retry-after` of an hour would otherwise arm a timer nobody is still around for.
|
|
1283
|
+
if (!Number.isNaN(delay))
|
|
1284
|
+
return { retry: true, delay: Math.min(delay, maxDelayMs) };
|
|
1285
|
+
}
|
|
1286
|
+
return { retry: true, delay: backoff(retryCount) };
|
|
1287
|
+
};
|
|
1288
|
+
};
|
|
1289
|
+
const defaultRetryFn = /* @__PURE__ */ createDefaultRetryFn();
|
|
1290
|
+
/**
|
|
1291
|
+
* The SDK's default retry policy, installed by {@link withDefaultRetry}: three retries with an
|
|
1292
|
+
* exponentially backing off, jittered delay, for a connection failure, a `408`, a `425`, a `429`
|
|
1293
|
+
* (honouring `retry-after`) and a 5xx above `500` - never for a `POST`, a `PATCH` or a GraphQL mutation.
|
|
1294
|
+
*
|
|
1295
|
+
* Pass {@link createDefaultRetryFn} options to {@link withDefaultRetry} to configure it.
|
|
1296
|
+
*/
|
|
1297
|
+
const shouldRetryRequest = (options) => defaultRetryFn(options instanceof HttpErrorResponse ? { retryCount: 0, error: options, method: null, idempotent: true } : options);
|
|
1298
|
+
/** Whether a request with this method may be sent again without changing the outcome - everything but `POST` and `PATCH`. */
|
|
1299
|
+
const isIdempotentQueryMethod = (method) => method !== 'POST' && method !== 'PATCH';
|
|
1300
|
+
|
|
1071
1301
|
const isQueryErrorResponse = (error) => {
|
|
1072
1302
|
return typeof error === 'object' && error !== null && 'raw' in error && 'retryState' in error && 'isList' in error;
|
|
1073
1303
|
};
|
|
@@ -1110,7 +1340,13 @@ const createQueryErrorResponse = (error, retry) => {
|
|
|
1110
1340
|
statusText: 'Unknown Error',
|
|
1111
1341
|
});
|
|
1112
1342
|
}
|
|
1113
|
-
const
|
|
1343
|
+
const method = retry?.method ?? null;
|
|
1344
|
+
const retryOptions = {
|
|
1345
|
+
retryCount: retry?.retryCount ?? 0,
|
|
1346
|
+
error: err,
|
|
1347
|
+
method,
|
|
1348
|
+
idempotent: retry?.idempotent ?? (method ? isIdempotentQueryMethod(method) : true),
|
|
1349
|
+
};
|
|
1114
1350
|
const retryState = typeof retry?.retryFn === 'function' ? retry.retryFn(retryOptions) : runDefaultQueryRetry(retryOptions);
|
|
1115
1351
|
const detail = err.error;
|
|
1116
1352
|
const errorList = [];
|
|
@@ -1574,6 +1810,14 @@ const createBaseQuery = (options) => {
|
|
|
1574
1810
|
});
|
|
1575
1811
|
};
|
|
1576
1812
|
|
|
1813
|
+
/** Resolves a {@link QueryHeadersInput} to `HttpHeaders`, or `undefined` when none is given. */
|
|
1814
|
+
const resolveQueryHeaders = (input) => {
|
|
1815
|
+
const headers = typeof input === 'function' ? input() : input;
|
|
1816
|
+
if (!headers)
|
|
1817
|
+
return undefined;
|
|
1818
|
+
return headers instanceof HttpHeaders ? headers : new HttpHeaders(headers);
|
|
1819
|
+
};
|
|
1820
|
+
|
|
1577
1821
|
const extractExpiresInSeconds = (headers) => {
|
|
1578
1822
|
const cacheControl = headers.get('cache-control');
|
|
1579
1823
|
const age = headers.get('age');
|
|
@@ -1629,7 +1873,7 @@ const sortObjectKeys = (_key, value) => {
|
|
|
1629
1873
|
* entries written by an older version are stored under.
|
|
1630
1874
|
*/
|
|
1631
1875
|
const buildQueryCacheKey = (route, args, method) => {
|
|
1632
|
-
const headers =
|
|
1876
|
+
const headers = resolveQueryHeaders(args?.headers);
|
|
1633
1877
|
const serializedHeaders = headers
|
|
1634
1878
|
?.keys()
|
|
1635
1879
|
.map((name) => name.toLowerCase())
|
|
@@ -1970,6 +2214,7 @@ const createHttpRequest = (options) => {
|
|
|
1970
2214
|
...(ngDevMode ? [{ debugName: "attempts" }] : /* istanbul ignore next */ []));
|
|
1971
2215
|
const retryState = signal(null, /* @ts-ignore */
|
|
1972
2216
|
...(ngDevMode ? [{ debugName: "retryState" }] : /* istanbul ignore next */ []));
|
|
2217
|
+
const idempotent = options.idempotent ?? isIdempotentQueryMethod(options.method);
|
|
1973
2218
|
const lastDurationMs = signal(null, /* @ts-ignore */
|
|
1974
2219
|
...(ngDevMode ? [{ debugName: "lastDurationMs" }] : /* istanbul ignore next */ []));
|
|
1975
2220
|
// Set at the top of every `sendWithFaults` attempt (including unfaulted ones), so it always reflects
|
|
@@ -1986,8 +2231,8 @@ const createHttpRequest = (options) => {
|
|
|
1986
2231
|
// Resolved per execution rather than once at creation, so a client whose headers are a function
|
|
1987
2232
|
// reading a signal (a preview token, a tenant id) sees the current value on every re-run.
|
|
1988
2233
|
const resolveHeaders = () => {
|
|
1989
|
-
const clientHeaders =
|
|
1990
|
-
const argHeaders =
|
|
2234
|
+
const clientHeaders = resolveQueryHeaders(options.clientHeaders);
|
|
2235
|
+
const argHeaders = resolveQueryHeaders(args?.headers);
|
|
1991
2236
|
if (!clientHeaders)
|
|
1992
2237
|
return argHeaders;
|
|
1993
2238
|
if (!argHeaders)
|
|
@@ -2073,7 +2318,7 @@ const createHttpRequest = (options) => {
|
|
|
2073
2318
|
const source$ = isQueryDevtoolsRequestInterceptionEnabled() ? sendWithFaults(headers) : send(headers);
|
|
2074
2319
|
return source$.pipe(tap((event) => updateState(event)), retry({
|
|
2075
2320
|
delay: (error, retryCount) => {
|
|
2076
|
-
const retryOptions = { error, retryCount };
|
|
2321
|
+
const retryOptions = { error, retryCount, method: options.method, idempotent };
|
|
2077
2322
|
const retryResult = options.retryFn?.(retryOptions) || runDefaultQueryRetry(retryOptions);
|
|
2078
2323
|
if (!retryResult.retry) {
|
|
2079
2324
|
return throwError(() => error);
|
|
@@ -2178,6 +2423,8 @@ const createHttpRequest = (options) => {
|
|
|
2178
2423
|
const errorRes = createQueryErrorResponse(errorResponse, {
|
|
2179
2424
|
retryCount: attempts(),
|
|
2180
2425
|
retryFn: options.retryFn,
|
|
2426
|
+
method: options.method,
|
|
2427
|
+
idempotent,
|
|
2181
2428
|
});
|
|
2182
2429
|
error.set(errorRes);
|
|
2183
2430
|
loading.set(null);
|
|
@@ -2643,13 +2890,6 @@ const createPagedQueryStack = (options) => {
|
|
|
2643
2890
|
const isOneMinusMinPagination = pageToLoad === currentMinPagination.currentPage - 1;
|
|
2644
2891
|
const isOnePlusMaxPagination = pageToLoad === currentMaxPagination.currentPage + 1;
|
|
2645
2892
|
if (!options.blockExecutionDuringLoading) {
|
|
2646
|
-
const totalQueries = stack.queries().length;
|
|
2647
|
-
const expectedQueries = Math.abs(loadedMaxPage() - loadedMinPage()) + 1;
|
|
2648
|
-
if (totalQueries !== expectedQueries) {
|
|
2649
|
-
if (isDevMode()) {
|
|
2650
|
-
throw queryStackTotalQueriesAndExpectedQueriesMismatch(totalQueries, expectedQueries);
|
|
2651
|
-
}
|
|
2652
|
-
}
|
|
2653
2893
|
return true;
|
|
2654
2894
|
}
|
|
2655
2895
|
return isOneMinusMinPagination || isOnePlusMaxPagination;
|
|
@@ -3777,69 +4017,6 @@ const symfonyQueryErrorParser = (detail) => {
|
|
|
3777
4017
|
return null;
|
|
3778
4018
|
};
|
|
3779
4019
|
|
|
3780
|
-
const DEFAULT_MAX_ATTEMPTS = 3;
|
|
3781
|
-
const DEFAULT_BASE_DELAY_MS = 1000;
|
|
3782
|
-
const DEFAULT_MAX_DELAY_MS = 30_000;
|
|
3783
|
-
const DEFAULT_JITTER = 0.25;
|
|
3784
|
-
// 500 is left out on purpose: an internal server error is a bug in the backend far more often than a
|
|
3785
|
-
// blip, and repeating the request that triggered it does not make it go away.
|
|
3786
|
-
const isRetryableByDefault = (status) => status === 0 || status === 408 || status === 425 || status === 429 || status >= 501;
|
|
3787
|
-
/**
|
|
3788
|
-
* Builds a retry policy: an exponentially backing off, jittered {@link ShouldRetryRequestFn} bounded by
|
|
3789
|
-
* an attempt ceiling. What {@link withDefaultRetry} installs - reach for this directly to hand a single
|
|
3790
|
-
* client or creator its own `retryFn`.
|
|
3791
|
-
*
|
|
3792
|
-
* @example
|
|
3793
|
-
* const flakyEndpointRetry = createDefaultRetryFn({ maxAttempts: 8, maxDelayMs: 10_000 });
|
|
3794
|
-
*
|
|
3795
|
-
* const getReport = myApiGet<GetReportArgs>('/report').clone({ retryFn: flakyEndpointRetry });
|
|
3796
|
-
*/
|
|
3797
|
-
const createDefaultRetryFn = (options = {}) => {
|
|
3798
|
-
const maxAttempts = options.maxAttempts ?? DEFAULT_MAX_ATTEMPTS;
|
|
3799
|
-
const baseDelayMs = options.baseDelayMs ?? DEFAULT_BASE_DELAY_MS;
|
|
3800
|
-
const maxDelayMs = options.maxDelayMs ?? DEFAULT_MAX_DELAY_MS;
|
|
3801
|
-
const jitter = clamp(options.jitter ?? DEFAULT_JITTER, 0, 1);
|
|
3802
|
-
const retryableStatusCodes = options.retryableStatusCodes;
|
|
3803
|
-
const isRetryableStatus = (status) => retryableStatusCodes ? retryableStatusCodes.includes(status) : isRetryableByDefault(status);
|
|
3804
|
-
const backoff = (retryCount) => {
|
|
3805
|
-
const exponential = baseDelayMs * Math.pow(2, retryCount);
|
|
3806
|
-
const spread = jitter === 0 ? 1 : 1 + (Math.random() * 2 - 1) * jitter;
|
|
3807
|
-
return Math.round(clamp(exponential * spread, 0, maxDelayMs));
|
|
3808
|
-
};
|
|
3809
|
-
return ({ retryCount, error }) => {
|
|
3810
|
-
// Not an HTTP failure at all, so nothing about it says a second attempt would go any better.
|
|
3811
|
-
if (!(error instanceof HttpErrorResponse))
|
|
3812
|
-
return { retry: false };
|
|
3813
|
-
if (maxAttempts > 0 && retryCount > maxAttempts)
|
|
3814
|
-
return { retry: false };
|
|
3815
|
-
const { status, error: detail, headers } = error;
|
|
3816
|
-
if (!isRetryableStatus(status))
|
|
3817
|
-
return { retry: false };
|
|
3818
|
-
// A page past the end of a Pagerfanta collection answers 5xx, and asking for it again keeps
|
|
3819
|
-
// answering 5xx - the request is wrong, not the server.
|
|
3820
|
-
if (status >= 501 && isSymfonyPagerfantaOutOfRangeError(detail))
|
|
3821
|
-
return { retry: false };
|
|
3822
|
-
if (status === 429) {
|
|
3823
|
-
const retryAfter = headers.get('retry-after') || headers.get('x-retry-after');
|
|
3824
|
-
const delay = retryAfter ? parseInt(retryAfter) * 1000 : NaN;
|
|
3825
|
-
// The server named a time, so it is used as named rather than jittered - only capped, since a
|
|
3826
|
-
// `retry-after` of an hour would otherwise arm a timer nobody is still around for.
|
|
3827
|
-
if (!Number.isNaN(delay))
|
|
3828
|
-
return { retry: true, delay: Math.min(delay, maxDelayMs) };
|
|
3829
|
-
}
|
|
3830
|
-
return { retry: true, delay: backoff(retryCount) };
|
|
3831
|
-
};
|
|
3832
|
-
};
|
|
3833
|
-
const defaultRetryFn = /* @__PURE__ */ createDefaultRetryFn();
|
|
3834
|
-
/**
|
|
3835
|
-
* The SDK's default retry policy, installed by {@link withDefaultRetry}: three retries with an
|
|
3836
|
-
* exponentially backing off, jittered delay, for a connection failure, a `408`, a `425`, a `429`
|
|
3837
|
-
* (honouring `retry-after`) and a 5xx above `500`.
|
|
3838
|
-
*
|
|
3839
|
-
* Pass {@link createDefaultRetryFn} options to {@link withDefaultRetry} to configure it.
|
|
3840
|
-
*/
|
|
3841
|
-
const shouldRetryRequest = (options) => defaultRetryFn(options instanceof HttpErrorResponse ? { retryCount: 0, error: options } : options);
|
|
3842
|
-
|
|
3843
4020
|
const noop$2 = () => undefined;
|
|
3844
4021
|
/** Shared because it never changes: without Web Locks, every hold is granted and never lost. */
|
|
3845
4022
|
const alwaysHolder = { isHolder: /* @__PURE__ */ signal(true).asReadonly(), release: noop$2 };
|
|
@@ -3926,6 +4103,7 @@ const createQueryKeyLockManager = (namespace) => {
|
|
|
3926
4103
|
return { hold, isSupported: true, keyStates: keyStates.asReadonly() };
|
|
3927
4104
|
};
|
|
3928
4105
|
|
|
4106
|
+
/** @internal */
|
|
3929
4107
|
const createQuerySyncEngine = (options) => {
|
|
3930
4108
|
const { config, repository, transport, lockManager } = options;
|
|
3931
4109
|
const syncResponses = config.syncResponses ?? true;
|
|
@@ -4259,7 +4437,8 @@ const withSymfonyErrors = () => () => {
|
|
|
4259
4437
|
/**
|
|
4260
4438
|
* Gives this client the SDK's default retry policy for every request that does not bring its own `retryFn`: a
|
|
4261
4439
|
* connection failure, a 5xx above 500, a 408/425 and a 429 (honouring `retry-after`) are retried three
|
|
4262
|
-
* times with an exponentially backing off, jittered delay - and a Pagerfanta out-of-range page never is.
|
|
4440
|
+
* times with an exponentially backing off, jittered delay - and a Pagerfanta out-of-range page never is. A `POST`,
|
|
4441
|
+
* a `PATCH` and a GraphQL mutation are never retried unless the options set `retryNonIdempotent`.
|
|
4263
4442
|
*
|
|
4264
4443
|
* The policy belongs to the client the feature is on, so another client of the same app is not
|
|
4265
4444
|
* affected. Without it nothing is retried automatically and `error.retryState` always reads
|
|
@@ -4397,6 +4576,7 @@ const createQueryRepository = (config) => {
|
|
|
4397
4576
|
clientHeaders: config.headers,
|
|
4398
4577
|
cacheAdapter: config.cacheAdapter,
|
|
4399
4578
|
retryFn: options.retryFn ?? config.retryFn,
|
|
4579
|
+
idempotent: options.isRefreshable ?? isIdempotentQueryMethod(options.method),
|
|
4400
4580
|
});
|
|
4401
4581
|
const executed = request.execute();
|
|
4402
4582
|
bind({
|
|
@@ -4749,7 +4929,7 @@ const createQueryClient = (options) => defineRootProvider(() => {
|
|
|
4749
4929
|
name: `QueryClient_${options.name}`,
|
|
4750
4930
|
});
|
|
4751
4931
|
|
|
4752
|
-
const AUTH_HEADER = 'Authorization';
|
|
4932
|
+
const AUTH_HEADER$1 = 'Authorization';
|
|
4753
4933
|
/**
|
|
4754
4934
|
* How long a request waits for the refresh of an expired access token before it sends the expired one
|
|
4755
4935
|
* anyway. Nothing guarantees the refresh arrives - the refresh token can be spent, and the request can
|
|
@@ -4819,12 +4999,12 @@ const createSecureExecuteFactory = (options) => {
|
|
|
4819
4999
|
const args = executeArgs.args;
|
|
4820
5000
|
const headerProvider = () => {
|
|
4821
5001
|
const accessToken = options.authProvider.accessToken();
|
|
4822
|
-
const baseHeaders =
|
|
5002
|
+
const baseHeaders = resolveQueryHeaders(args?.headers) ?? new HttpHeaders();
|
|
4823
5003
|
if (!accessToken) {
|
|
4824
5004
|
throw tokensNotAvailableInsideAuthAndExec();
|
|
4825
5005
|
}
|
|
4826
|
-
if (!baseHeaders.has(AUTH_HEADER)) {
|
|
4827
|
-
return baseHeaders.set(AUTH_HEADER, `Bearer ${accessToken}`);
|
|
5006
|
+
if (!baseHeaders.has(AUTH_HEADER$1)) {
|
|
5007
|
+
return baseHeaders.set(AUTH_HEADER$1, `Bearer ${accessToken}`);
|
|
4828
5008
|
}
|
|
4829
5009
|
return baseHeaders;
|
|
4830
5010
|
};
|
|
@@ -5809,6 +5989,7 @@ const createBearerAuthProviderImpl = (config) => {
|
|
|
5809
5989
|
activityCoordination: isLeader.activityCoordination,
|
|
5810
5990
|
afterTokenRefresh$,
|
|
5811
5991
|
queries: queries,
|
|
5992
|
+
queryBuilders: config.queries,
|
|
5812
5993
|
latestExecutedQuery: latestExecutedQuery.asReadonly(),
|
|
5813
5994
|
executionState,
|
|
5814
5995
|
sessionStatus: sessionStatus.asReadonly(),
|
|
@@ -5845,6 +6026,11 @@ const createBearerAuthProviderImpl = (config) => {
|
|
|
5845
6026
|
executionState: executionState.asReadonly(),
|
|
5846
6027
|
sessionStatus: sessionStatus.asReadonly(),
|
|
5847
6028
|
sessionEndCause: sessionEndCause.asReadonly(),
|
|
6029
|
+
session: computed(() => ({
|
|
6030
|
+
status: sessionStatus(),
|
|
6031
|
+
endCause: sessionEndCause(),
|
|
6032
|
+
executionState: executionState(),
|
|
6033
|
+
})),
|
|
5848
6034
|
setTokens,
|
|
5849
6035
|
logout,
|
|
5850
6036
|
afterTokenRefresh$,
|
|
@@ -5946,7 +6132,7 @@ const withAuthenticationQuery = (key, config, setup) => ({
|
|
|
5946
6132
|
const withRefreshQuery = (key, config) => {
|
|
5947
6133
|
const retryableStatusCodes = config.retryConfig?.retryableStatusCodes ?? [0, 408, 425, 429, 500, 502, 503, 504];
|
|
5948
6134
|
const maxRetryDelayMs = config.retryConfig?.maxRetryDelayMs ?? 30000; // 30 seconds
|
|
5949
|
-
const maxAttempts = config.retryConfig?.maxAttempts ??
|
|
6135
|
+
const maxAttempts = config.retryConfig?.maxAttempts ?? 8;
|
|
5950
6136
|
const refreshRetryFn = ({ error, retryCount }) => {
|
|
5951
6137
|
const { status } = error;
|
|
5952
6138
|
if (maxAttempts > 0 && retryCount > maxAttempts) {
|
|
@@ -7327,12 +7513,20 @@ const createPersistentAuthFeature = (config, context) => {
|
|
|
7327
7513
|
if (wasRejected && !context.isTabLocalSession())
|
|
7328
7514
|
removeCookie();
|
|
7329
7515
|
});
|
|
7516
|
+
const autoLoginBuilder = context.queryBuilders.find((builder) => builder.key === config.autoLogin.queryKey);
|
|
7517
|
+
const buildAutoLoginArgs = (token) => {
|
|
7518
|
+
if (config.autoLogin.buildArgs)
|
|
7519
|
+
return config.autoLogin.buildArgs(token);
|
|
7520
|
+
if (autoLoginBuilder?._type === 'tokenRefreshQuery')
|
|
7521
|
+
return autoLoginBuilder.buildArgs(token);
|
|
7522
|
+
return { body: { token } };
|
|
7523
|
+
};
|
|
7330
7524
|
const exchangeCookie = () => {
|
|
7331
7525
|
const storedToken = getCookie(cookieName);
|
|
7332
7526
|
if (!storedToken)
|
|
7333
7527
|
return;
|
|
7334
7528
|
const decryptedToken = decryptToken(storedToken);
|
|
7335
|
-
const args =
|
|
7529
|
+
const args = buildAutoLoginArgs(decryptedToken);
|
|
7336
7530
|
context.queries[config.autoLogin.queryKey].execute(args, { triggeredBy: 'persistent-auth' });
|
|
7337
7531
|
};
|
|
7338
7532
|
const tryLogin = () => {
|
|
@@ -7380,7 +7574,10 @@ const withTokenExpirationWarning = (config = {}) => {
|
|
|
7380
7574
|
return (context) => {
|
|
7381
7575
|
const warningThreshold = config.warningThreshold ?? 5 * 60 * 1000;
|
|
7382
7576
|
const checkInterval = config.checkInterval ?? 1000;
|
|
7383
|
-
const
|
|
7577
|
+
const refreshBuilder = context.queryBuilders.find((builder) => builder._type === 'tokenRefreshQuery');
|
|
7578
|
+
const expiresInPropertyName = config.expiresInPropertyName ??
|
|
7579
|
+
(refreshBuilder?._type === 'tokenRefreshQuery' ? refreshBuilder.config.expiresInPropertyName : undefined) ??
|
|
7580
|
+
'exp';
|
|
7384
7581
|
const expiresAt = computed(() => {
|
|
7385
7582
|
const decoded = context.bearerData();
|
|
7386
7583
|
if (!decoded)
|
|
@@ -7424,9 +7621,21 @@ const withTokenExpirationWarning = (config = {}) => {
|
|
|
7424
7621
|
};
|
|
7425
7622
|
};
|
|
7426
7623
|
|
|
7624
|
+
const AUTH_HEADER = 'Authorization';
|
|
7427
7625
|
const withTokenRevocation = (config) => {
|
|
7428
7626
|
return (context) => {
|
|
7429
7627
|
const revokeOnLogout = config.revokeOnLogout ?? true;
|
|
7628
|
+
const withBearerHeader = (args, accessToken) => {
|
|
7629
|
+
if (!config.bearer || !accessToken)
|
|
7630
|
+
return args;
|
|
7631
|
+
const argHeaders = args.headers;
|
|
7632
|
+
const headers = () => {
|
|
7633
|
+
const base = resolveQueryHeaders(argHeaders) ?? new HttpHeaders();
|
|
7634
|
+
return base.has(AUTH_HEADER) ? base : base.set(AUTH_HEADER, `Bearer ${accessToken}`);
|
|
7635
|
+
};
|
|
7636
|
+
return { ...args, headers };
|
|
7637
|
+
};
|
|
7638
|
+
const shouldRevokeFor = (cause) => !config.revokeOn || (cause !== null && config.revokeOn.includes(cause));
|
|
7430
7639
|
const enabled = signal(true, /* @ts-ignore */
|
|
7431
7640
|
...(ngDevMode ? [{ debugName: "enabled" }] : /* istanbul ignore next */ []));
|
|
7432
7641
|
let previousAccessToken = null;
|
|
@@ -7438,7 +7647,7 @@ const withTokenRevocation = (config) => {
|
|
|
7438
7647
|
if (!accessToken && !refreshToken) {
|
|
7439
7648
|
return null;
|
|
7440
7649
|
}
|
|
7441
|
-
const args = config.buildArgs({ accessToken, refreshToken });
|
|
7650
|
+
const args = withBearerHeader(config.buildArgs?.({ accessToken, refreshToken }) ?? {}, accessToken);
|
|
7442
7651
|
context.executionState.set({ type: 'revocation', state: 'loading' });
|
|
7443
7652
|
currentRevocationSnapshot = context.queries[config.queryKey].execute(args, {
|
|
7444
7653
|
triggeredBy: 'token-revocation',
|
|
@@ -7458,7 +7667,10 @@ const withTokenRevocation = (config) => {
|
|
|
7458
7667
|
effect(() => {
|
|
7459
7668
|
const currentToken = context.accessToken();
|
|
7460
7669
|
const currentRefreshToken = context.refreshToken();
|
|
7461
|
-
if (previousAccessToken &&
|
|
7670
|
+
if (previousAccessToken &&
|
|
7671
|
+
!currentToken &&
|
|
7672
|
+
enabled() &&
|
|
7673
|
+
shouldRevokeFor(untracked(context.sessionEndCause))) {
|
|
7462
7674
|
untracked(() => revokeWithTokens(previousAccessToken, previousRefreshToken));
|
|
7463
7675
|
}
|
|
7464
7676
|
previousAccessToken = currentToken;
|
|
@@ -7476,7 +7688,8 @@ const withTokenRevocation = (config) => {
|
|
|
7476
7688
|
instance,
|
|
7477
7689
|
devtools: () => [
|
|
7478
7690
|
{ label: 'query', value: config.queryKey },
|
|
7479
|
-
{ label: 'on logout', value: revokeOnLogout ? 'yes' : 'no' },
|
|
7691
|
+
{ label: 'on logout', value: revokeOnLogout ? (config.revokeOn?.join(', ') ?? 'yes') : 'no' },
|
|
7692
|
+
{ label: 'bearer', value: config.bearer ? 'yes' : 'no' },
|
|
7480
7693
|
],
|
|
7481
7694
|
};
|
|
7482
7695
|
};
|
|
@@ -8485,12 +8698,13 @@ const asScope = (value, fallback) => value === 'none' || value === 'session' ||
|
|
|
8485
8698
|
* Whether the session vault may be kept in `localStorage`. Only a development build may: the vault
|
|
8486
8699
|
* holds live access and refresh tokens plus the credentials somebody typed in, and a deployed
|
|
8487
8700
|
* application that mounts the panel for its debugging value must not leave those on the machine of
|
|
8488
|
-
* whoever opened it.
|
|
8701
|
+
* whoever opened it. Outside a development build a stored or default `local` reads back as `none`, so a
|
|
8702
|
+
* plain login keeps nothing; `session` stays on offer for whoever picks it in Settings.
|
|
8489
8703
|
*
|
|
8490
8704
|
* Part of the devtools contract. **Not part of the general public contract.**
|
|
8491
8705
|
*/
|
|
8492
8706
|
const queryDevtoolsAllowsLocalAuthSessions = () => isDevMode();
|
|
8493
|
-
const clampAuthSessions = (scope) => scope === 'local' && !queryDevtoolsAllowsLocalAuthSessions() ? '
|
|
8707
|
+
const clampAuthSessions = (scope) => scope === 'local' && !queryDevtoolsAllowsLocalAuthSessions() ? 'none' : scope;
|
|
8494
8708
|
const asCount = (value, limits, fallback) => {
|
|
8495
8709
|
const count = Math.floor(Number(value));
|
|
8496
8710
|
if (!Number.isFinite(count))
|
|
@@ -8695,11 +8909,15 @@ let listening = false;
|
|
|
8695
8909
|
* @internal
|
|
8696
8910
|
*/
|
|
8697
8911
|
const initQueryDevtoolsAuthSessions = (accounts) => {
|
|
8698
|
-
// Before the read below, which never looks at `localStorage` once the scope is clamped: a vault an
|
|
8699
|
-
// earlier version left there would otherwise sit on a deployed origin with nothing left to remove it.
|
|
8700
|
-
if (!queryDevtoolsAllowsLocalAuthSessions())
|
|
8701
|
-
queryDevtoolsStorage('local')?.removeItem(STORE_KEY);
|
|
8702
8912
|
const scope = queryDevtoolsSettings().authSessions;
|
|
8913
|
+
// The read below only looks at the store the scope names: a vault an earlier version or scope left in
|
|
8914
|
+
// another store would otherwise sit there, tokens and all, with nothing left to remove it.
|
|
8915
|
+
for (const other of ['local', 'session']) {
|
|
8916
|
+
if (other !== scope)
|
|
8917
|
+
queryDevtoolsStorage(other)?.removeItem(STORE_KEY);
|
|
8918
|
+
}
|
|
8919
|
+
if (scope === 'none')
|
|
8920
|
+
queryDevtoolsStorage('session')?.removeItem(ACTIVE_KEY);
|
|
8703
8921
|
declared.set(accounts ?? []);
|
|
8704
8922
|
store.set(sanitize(readQueryDevtoolsStore(scope, STORE_KEY)));
|
|
8705
8923
|
active.set(readQueryDevtoolsStore(scope === 'none' ? 'none' : 'session', ACTIVE_KEY) ?? {});
|
|
@@ -10294,7 +10512,7 @@ const armQueryDevtoolsOverrideTransfer = (recorder, ops) => {
|
|
|
10294
10512
|
|
|
10295
10513
|
// Generated from package.json by tools/scripts/generate-version.js - do not edit.
|
|
10296
10514
|
/** The version of `@ethlete/query` this build was cut from. */
|
|
10297
|
-
const QUERY_VERSION = '6.0.0-next.
|
|
10515
|
+
const QUERY_VERSION = '6.0.0-next.49';
|
|
10298
10516
|
|
|
10299
10517
|
/** How deep a schema is expanded before a nested branch is given up on. */
|
|
10300
10518
|
const MAX_DEPTH = 12;
|
|
@@ -10536,7 +10754,7 @@ const clampToBounds = (value, bounds) => {
|
|
|
10536
10754
|
const numberSample = (schema, ctx) => {
|
|
10537
10755
|
const bounds = boundsOf(schema);
|
|
10538
10756
|
if (ctx.style === 'placeholder')
|
|
10539
|
-
return bounds.min ??
|
|
10757
|
+
return bounds.min ?? 0;
|
|
10540
10758
|
if (ctx.style === 'realistic') {
|
|
10541
10759
|
return generateQueryDevtoolsSampleNumber({ ...bounds, fractional: typeOf(schema) === 'number' });
|
|
10542
10760
|
}
|
|
@@ -11691,6 +11909,7 @@ const gql = (strings, ...values) => {
|
|
|
11691
11909
|
return str;
|
|
11692
11910
|
};
|
|
11693
11911
|
|
|
11912
|
+
/** @internal */
|
|
11694
11913
|
const createGqlExecuteFn = (executeOptions) => {
|
|
11695
11914
|
const executeState = setupQueryExecuteState();
|
|
11696
11915
|
const circularChecker = circularQueryDependencyChecker();
|
|
@@ -11748,7 +11967,7 @@ const createGqlQuery = (options) => createBaseQuery({
|
|
|
11748
11967
|
executeFactory: createGqlExecuteFn,
|
|
11749
11968
|
});
|
|
11750
11969
|
|
|
11751
|
-
const
|
|
11970
|
+
const readGqlEnvelope = (rawResponse) => {
|
|
11752
11971
|
if (!rawResponse || typeof rawResponse !== 'object')
|
|
11753
11972
|
throw gqlDataPropertyMissingInResponse();
|
|
11754
11973
|
const data = 'data' in rawResponse ? rawResponse.data : undefined;
|
|
@@ -11757,8 +11976,14 @@ const unwrapGqlResponse = (rawResponse) => {
|
|
|
11757
11976
|
throw gqlErrorsInResponse(errors);
|
|
11758
11977
|
if (!('data' in rawResponse))
|
|
11759
11978
|
throw gqlDataPropertyMissingInResponse();
|
|
11760
|
-
return data;
|
|
11979
|
+
return { data, errors: Array.isArray(errors) ? errors : [] };
|
|
11761
11980
|
};
|
|
11981
|
+
const unwrapGqlResponse = (rawResponse) => readGqlEnvelope(rawResponse).data;
|
|
11982
|
+
/**
|
|
11983
|
+
* A GQL `transformResponse` that keeps the server's `errors` next to partial data. Declare the
|
|
11984
|
+
* args' `response` as `GqlDataWithErrors<TData>`; a response without data still fails with ET601.
|
|
11985
|
+
*/
|
|
11986
|
+
const unwrapGqlResponseWithErrors = (rawResponse) => readGqlEnvelope(rawResponse);
|
|
11762
11987
|
|
|
11763
11988
|
const createGqlQueryCreator = (options, internals) => createBaseQueryCreator({
|
|
11764
11989
|
options: {
|
|
@@ -11769,6 +11994,7 @@ const createGqlQueryCreator = (options, internals) => createBaseQueryCreator({
|
|
|
11769
11994
|
queryFactory: createGqlQuery,
|
|
11770
11995
|
});
|
|
11771
11996
|
|
|
11997
|
+
/** @internal */
|
|
11772
11998
|
const createSecureGqlExecuteFn = (executeOptions) => {
|
|
11773
11999
|
const authProvider = executeOptions.creatorInternals.authProvider.inject();
|
|
11774
12000
|
return createSecureExecuteFactory({
|
|
@@ -16887,6 +17113,36 @@ const normalizeLive = (fieldDefs, rawLive, defaults) => {
|
|
|
16887
17113
|
}
|
|
16888
17114
|
return live;
|
|
16889
17115
|
};
|
|
17116
|
+
const resolveStorage = (storage) => {
|
|
17117
|
+
if (typeof storage !== 'string')
|
|
17118
|
+
return storage;
|
|
17119
|
+
try {
|
|
17120
|
+
if (typeof globalThis.window === 'undefined')
|
|
17121
|
+
return null;
|
|
17122
|
+
return (storage === 'session' ? globalThis.sessionStorage : globalThis.localStorage) ?? null;
|
|
17123
|
+
}
|
|
17124
|
+
catch {
|
|
17125
|
+
return null;
|
|
17126
|
+
}
|
|
17127
|
+
};
|
|
17128
|
+
const readStoredParams = (persistence) => {
|
|
17129
|
+
try {
|
|
17130
|
+
const raw = resolveStorage(persistence.storage)?.getItem(persistence.key);
|
|
17131
|
+
const parsed = raw ? JSON.parse(raw) : null;
|
|
17132
|
+
return parsed && typeof parsed === 'object' && !Array.isArray(parsed) ? parsed : null;
|
|
17133
|
+
}
|
|
17134
|
+
catch {
|
|
17135
|
+
return null;
|
|
17136
|
+
}
|
|
17137
|
+
};
|
|
17138
|
+
const writeStoredParams = (persistence, params) => {
|
|
17139
|
+
try {
|
|
17140
|
+
resolveStorage(persistence.storage)?.setItem(persistence.key, JSON.stringify(params));
|
|
17141
|
+
}
|
|
17142
|
+
catch {
|
|
17143
|
+
return;
|
|
17144
|
+
}
|
|
17145
|
+
};
|
|
16890
17146
|
const computeFilterCount = (fields, value, defaults) => {
|
|
16891
17147
|
let count = 0;
|
|
16892
17148
|
for (const [key, def] of Object.entries(fields)) {
|
|
@@ -16984,6 +17240,11 @@ const createBranch = (fields, initial, injector) => {
|
|
|
16984
17240
|
model.set(clone(next));
|
|
16985
17241
|
}
|
|
16986
17242
|
};
|
|
17243
|
+
const write = (next, options) => {
|
|
17244
|
+
model.set(next);
|
|
17245
|
+
if (!options?.debounce)
|
|
17246
|
+
flush();
|
|
17247
|
+
};
|
|
16987
17248
|
effect(() => {
|
|
16988
17249
|
const live = normalizedLive();
|
|
16989
17250
|
untracked(() => {
|
|
@@ -17006,13 +17267,13 @@ const createBranch = (fields, initial, injector) => {
|
|
|
17006
17267
|
value: committed.asReadonly(),
|
|
17007
17268
|
liveValue: model.asReadonly(),
|
|
17008
17269
|
activeFilterCount: computed(() => computeFilterCount(fields, committed(), defaults)),
|
|
17009
|
-
setValue: (value) =>
|
|
17010
|
-
patchValue: (value
|
|
17011
|
-
resetFieldToDefault: (key
|
|
17012
|
-
resetAllFieldsToDefault: () => {
|
|
17270
|
+
setValue: (value, options) => write(clone(value), options),
|
|
17271
|
+
patchValue: (value, options) => write({ ...model(), ...value }, options),
|
|
17272
|
+
resetFieldToDefault: (key, options) => write({ ...model(), [key]: defaultFor(key) }, options),
|
|
17273
|
+
resetAllFieldsToDefault: (options) => {
|
|
17013
17274
|
for (const key of Object.keys(fields))
|
|
17014
17275
|
defaultFor(key);
|
|
17015
|
-
|
|
17276
|
+
write(clone(defaults), options);
|
|
17016
17277
|
},
|
|
17017
17278
|
};
|
|
17018
17279
|
};
|
|
@@ -17074,6 +17335,7 @@ const defineQueryForm = (config) => {
|
|
|
17074
17335
|
const skipResetsFor = new Set();
|
|
17075
17336
|
let skipNextResetsFor;
|
|
17076
17337
|
let urlWriteVersion = 0;
|
|
17338
|
+
let changesSeenAtObserve;
|
|
17077
17339
|
const urlNavigationMarker = {};
|
|
17078
17340
|
const pathOf = (tree) => router.serializeUrl(tree).split(/[?#]/)[0];
|
|
17079
17341
|
const fields = form(model);
|
|
@@ -17091,6 +17353,9 @@ const defineQueryForm = (config) => {
|
|
|
17091
17353
|
const writeDefault = def.appendDefaultValueToUrl === true;
|
|
17092
17354
|
if (!writeToUrl || (isDefault && !writeDefault))
|
|
17093
17355
|
return undefined;
|
|
17356
|
+
return serialize(key, def, value);
|
|
17357
|
+
};
|
|
17358
|
+
const serialize = (key, def, value) => {
|
|
17094
17359
|
if (def.valueToQueryParam)
|
|
17095
17360
|
return def.valueToQueryParam(value);
|
|
17096
17361
|
if (value === '' && defaults[key] === null)
|
|
@@ -17099,16 +17364,47 @@ const defineQueryForm = (config) => {
|
|
|
17099
17364
|
return ET_EMPTY_ARRAY_VALUE;
|
|
17100
17365
|
return value === null ? ET_NULL_VALUE : value;
|
|
17101
17366
|
};
|
|
17367
|
+
const persistedKeys = () => {
|
|
17368
|
+
const keys = observeOptions?.persistence?.fields ?? Object.keys(fieldDefs);
|
|
17369
|
+
return keys.filter((key) => key in fieldDefs);
|
|
17370
|
+
};
|
|
17371
|
+
const persist = () => {
|
|
17372
|
+
const persistence = observeOptions?.persistence;
|
|
17373
|
+
if (!persistence || !observing())
|
|
17374
|
+
return;
|
|
17375
|
+
const value = committed();
|
|
17376
|
+
const stored = {};
|
|
17377
|
+
for (const key of persistedKeys()) {
|
|
17378
|
+
if (equal(value[key], defaults[key]))
|
|
17379
|
+
continue;
|
|
17380
|
+
stored[key] = serialize(key, fieldDefs[key], value[key]);
|
|
17381
|
+
}
|
|
17382
|
+
writeStoredParams(persistence, stored);
|
|
17383
|
+
};
|
|
17384
|
+
const restoreFromStorage = (persistence, urlParams) => {
|
|
17385
|
+
const keys = persistedKeys();
|
|
17386
|
+
if (keys.some((key) => urlParams[paramKey(key)] !== undefined))
|
|
17387
|
+
return;
|
|
17388
|
+
const stored = readStoredParams(persistence);
|
|
17389
|
+
if (!stored)
|
|
17390
|
+
return;
|
|
17391
|
+
const params = {};
|
|
17392
|
+
for (const key of keys) {
|
|
17393
|
+
if (stored[key] !== undefined)
|
|
17394
|
+
params[paramKey(key)] = stored[key];
|
|
17395
|
+
}
|
|
17396
|
+
applyFromUrl(params, { base: model() });
|
|
17397
|
+
};
|
|
17102
17398
|
const deserialize = (def, raw) => {
|
|
17103
17399
|
if (!def.skipAutoTransform && raw === ET_NULL_VALUE)
|
|
17104
17400
|
return null;
|
|
17105
17401
|
if (!def.skipAutoTransform && raw === ET_EMPTY_ARRAY_VALUE)
|
|
17106
17402
|
return [];
|
|
17107
17403
|
if (def.queryParamToValue)
|
|
17108
|
-
return def.queryParamToValue(raw);
|
|
17404
|
+
return def.queryParamToValue(raw) ?? resolveDefault(def);
|
|
17109
17405
|
if (def.skipAutoTransform)
|
|
17110
17406
|
return raw;
|
|
17111
|
-
return autoCoerce(raw, resolveDefault(def));
|
|
17407
|
+
return autoCoerce(raw, resolveDefault(def)) ?? resolveDefault(def);
|
|
17112
17408
|
};
|
|
17113
17409
|
const clearTimer = () => {
|
|
17114
17410
|
if (pendingTimer !== null) {
|
|
@@ -17184,6 +17480,7 @@ const defineQueryForm = (config) => {
|
|
|
17184
17480
|
if (observing() && observeOptions?.writeToQueryParams !== false) {
|
|
17185
17481
|
writeToUrl(next);
|
|
17186
17482
|
}
|
|
17483
|
+
persist();
|
|
17187
17484
|
};
|
|
17188
17485
|
const onLiveChange = (live) => {
|
|
17189
17486
|
if (equal(live, committed())) {
|
|
@@ -17214,6 +17511,7 @@ const defineQueryForm = (config) => {
|
|
|
17214
17511
|
committed.set(clone(next));
|
|
17215
17512
|
// Feed the URL value into the live model & bound controls; the effect no-ops (model === committed).
|
|
17216
17513
|
model.set(clone(next));
|
|
17514
|
+
persist();
|
|
17217
17515
|
};
|
|
17218
17516
|
const applyFromUrl = (params, options) => {
|
|
17219
17517
|
const current = { ...(options?.base ?? committed()) };
|
|
@@ -17259,6 +17557,12 @@ const defineQueryForm = (config) => {
|
|
|
17259
17557
|
}
|
|
17260
17558
|
}
|
|
17261
17559
|
model.set(next);
|
|
17560
|
+
if (options?.debounce) {
|
|
17561
|
+
onLiveChange(next);
|
|
17562
|
+
}
|
|
17563
|
+
else {
|
|
17564
|
+
flush();
|
|
17565
|
+
}
|
|
17262
17566
|
};
|
|
17263
17567
|
const setValue = (value, options) => writeModel(clone(value), options);
|
|
17264
17568
|
const patchValue = (value, options) => writeModel({ ...model(), ...value }, options);
|
|
@@ -17289,6 +17593,10 @@ const defineQueryForm = (config) => {
|
|
|
17289
17593
|
}
|
|
17290
17594
|
observeOptions = options;
|
|
17291
17595
|
observing.set(true);
|
|
17596
|
+
changesSeenAtObserve = untracked(queryParamChanges);
|
|
17597
|
+
if (options?.persistence) {
|
|
17598
|
+
restoreFromStorage(options.persistence, route.snapshot.queryParams);
|
|
17599
|
+
}
|
|
17292
17600
|
if (options?.syncOnNavigation !== false) {
|
|
17293
17601
|
// A value written before `observe()` sits in the model only, so the URL merges onto the model
|
|
17294
17602
|
// here. Against `committed()` any single URL param would drop that value.
|
|
@@ -17304,6 +17612,7 @@ const defineQueryForm = (config) => {
|
|
|
17304
17612
|
if (options?.writeToQueryParams !== false && writesAnyParam) {
|
|
17305
17613
|
writeToUrl(committed());
|
|
17306
17614
|
}
|
|
17615
|
+
persist();
|
|
17307
17616
|
return queryForm;
|
|
17308
17617
|
},
|
|
17309
17618
|
unobserve: () => {
|
|
@@ -17336,6 +17645,10 @@ const defineQueryForm = (config) => {
|
|
|
17336
17645
|
untracked(() => {
|
|
17337
17646
|
if (!observing() || observeOptions?.syncOnNavigation === false)
|
|
17338
17647
|
return;
|
|
17648
|
+
// The changes are shared app-wide, so the diff present at `observe()` describes a navigation this
|
|
17649
|
+
// form never saw - applying its removals would wipe a restored or seeded value.
|
|
17650
|
+
if (changes === changesSeenAtObserve)
|
|
17651
|
+
return;
|
|
17339
17652
|
const info = router.lastSuccessfulNavigation()?.extras.info;
|
|
17340
17653
|
// Including the newest write: re-parsing the form's own output would coerce a committed
|
|
17341
17654
|
// string back to a number and drop the milliseconds of a committed Date.
|
|
@@ -17485,10 +17798,12 @@ const messageMalformed = () => {
|
|
|
17485
17798
|
const MAX_DEVTOOLS_MESSAGES = 100;
|
|
17486
17799
|
const createWebSocketClient = (options) => {
|
|
17487
17800
|
return defineRootProvider(() => {
|
|
17801
|
+
const auth = options.auth;
|
|
17488
17802
|
const socket = options.io(options.url, {
|
|
17489
|
-
withCredentials: true,
|
|
17803
|
+
withCredentials: options.withCredentials ?? true,
|
|
17490
17804
|
autoConnect: false,
|
|
17491
17805
|
transports: options.transports,
|
|
17806
|
+
auth: auth ? (cb) => cb(typeof auth === 'function' ? auth() : auth) : undefined,
|
|
17492
17807
|
});
|
|
17493
17808
|
const rooms = new Map();
|
|
17494
17809
|
const joinsDeliveredThisConnection = new Set();
|
|
@@ -17538,10 +17853,11 @@ const createWebSocketClient = (options) => {
|
|
|
17538
17853
|
}
|
|
17539
17854
|
emit({ event: 'join-room', data: name, room: name });
|
|
17540
17855
|
joinsDeliveredToClosedConnection.delete(name);
|
|
17541
|
-
const
|
|
17542
|
-
...(ngDevMode ? [{ debugName: "message" }] : /* istanbul ignore next */ []));
|
|
17856
|
+
const messages = new Subject();
|
|
17543
17857
|
const newRoom = {
|
|
17544
|
-
latestMessage:
|
|
17858
|
+
latestMessage: signal(null),
|
|
17859
|
+
messages,
|
|
17860
|
+
messages$: messages.asObservable(),
|
|
17545
17861
|
joinCount: 1,
|
|
17546
17862
|
};
|
|
17547
17863
|
rooms.set(name, newRoom);
|
|
@@ -17594,6 +17910,7 @@ const createWebSocketClient = (options) => {
|
|
|
17594
17910
|
emit({ event: 'leave-room', data: room, room });
|
|
17595
17911
|
rooms.delete(room);
|
|
17596
17912
|
syncDevtoolsRooms();
|
|
17913
|
+
joinedRoom.messages.complete();
|
|
17597
17914
|
};
|
|
17598
17915
|
const setupWebSocketConnectionListener = () => {
|
|
17599
17916
|
socket.onAnyOutgoing((eventName, room) => {
|
|
@@ -17627,6 +17944,7 @@ const createWebSocketClient = (options) => {
|
|
|
17627
17944
|
};
|
|
17628
17945
|
const setupWebSocketListener = () => {
|
|
17629
17946
|
socket.onAny((_eventName, ...args) => {
|
|
17947
|
+
let json;
|
|
17630
17948
|
try {
|
|
17631
17949
|
const data = args[0];
|
|
17632
17950
|
if (typeof data !== 'string')
|
|
@@ -17637,11 +17955,7 @@ const createWebSocketClient = (options) => {
|
|
|
17637
17955
|
typeof parsed.room !== 'string') {
|
|
17638
17956
|
throw messageMalformed();
|
|
17639
17957
|
}
|
|
17640
|
-
|
|
17641
|
-
recordDevtoolsMessage({ room: json.room, event: json.event, data: json.data, direction: 'in' });
|
|
17642
|
-
const room = rooms.get(json.room);
|
|
17643
|
-
if (room)
|
|
17644
|
-
room.latestMessage.set(json);
|
|
17958
|
+
json = parsed;
|
|
17645
17959
|
}
|
|
17646
17960
|
catch (error) {
|
|
17647
17961
|
if (!isDevMode())
|
|
@@ -17649,15 +17963,26 @@ const createWebSocketClient = (options) => {
|
|
|
17649
17963
|
console.error(error);
|
|
17650
17964
|
throw messageMalformed();
|
|
17651
17965
|
}
|
|
17966
|
+
recordDevtoolsMessage({ room: json.room, event: json.event, data: json.data, direction: 'in' });
|
|
17967
|
+
const room = rooms.get(json.room);
|
|
17968
|
+
if (!room)
|
|
17969
|
+
return;
|
|
17970
|
+
room.latestMessage.set(json);
|
|
17971
|
+
room.messages.next(json);
|
|
17652
17972
|
});
|
|
17653
17973
|
};
|
|
17654
|
-
inject(DestroyRef).onDestroy(() =>
|
|
17974
|
+
inject(DestroyRef).onDestroy(() => {
|
|
17975
|
+
socket.disconnect();
|
|
17976
|
+
for (const room of rooms.values())
|
|
17977
|
+
room.messages.complete();
|
|
17978
|
+
});
|
|
17655
17979
|
setupWebSocketConnectionListener();
|
|
17656
17980
|
setupWebSocketListener();
|
|
17657
17981
|
socket.connect();
|
|
17658
17982
|
const client = {
|
|
17659
17983
|
joinRoom,
|
|
17660
17984
|
isConnected: isConnected.asReadonly(),
|
|
17985
|
+
send: (message) => emit({ event: message.event, data: message.data }),
|
|
17661
17986
|
subtle: {
|
|
17662
17987
|
leaveRoom,
|
|
17663
17988
|
},
|
|
@@ -17686,5 +18011,5 @@ const createWebSocketClient = (options) => {
|
|
|
17686
18011
|
* Generated bundle index. Do not edit.
|
|
17687
18012
|
*/
|
|
17688
18013
|
|
|
17689
|
-
export { AuthBearerRefreshStrategy, BasicAuthProvider, BearerAuthFeatureType, BooleanArrayQueryField, 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_BATCH_TOMBSTONES, 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, QueryStateType, QueryStore, SERVER_ERROR_KIND, SERVER_VIOLATION_ERROR_KIND, SPEED_BUFFER_TIME_IN_MS, SearchQueryField, SortQueryField, StringArrayQueryField, V2BearerAuthProvider, V2Query, V2QueryClient, V2QueryCreator, addQueryContainerHandling, addQueryDevtoolsAuthAccount, applyQueryDevtoolsOverrides, applyQueryDevtoolsTokenTtl, applyQueryFeatures, armAllQueryDevtoolsMocks, armQueryDevtoolsMock, armQueryDevtoolsOverrideTransfer, authExtractTokensResponseMissingAccessToken, authExtractTokensResponseMissingRefreshToken, authExtractTokensResponseNotObject, authProviderFeatureUsedMultipleTimes, booleanArrayQueryField, buildQueryCacheKey, buildQueryString, buildRoute, buildTimestampFromSeconds, canOverrideQueryDevtoolsTokenTtl, castQueryCreatorTypes, circularQueryDependency, circularQueryDependencyChecker, clearQueryDevtoolsArmedMocks, clearQueryDevtoolsAuthCredentials, clearQueryDevtoolsAuthSessions, clearQueryDevtoolsFaults, clearQueryDevtoolsMockStore, clearQueryDevtoolsOverrideStore, clearQueryDevtoolsStore, clearQueryDevtoolsTokenTtl, clearQueryDevtoolsTombstones, clearRestoredQueryDevtoolsOverrides, collectLeafPaths, collectQueryDevtoolsSchemaComponents, collectQueryFormLinks, computeQueryAuthHeader, computeQueryBody, computeQueryHeaders, computeQueryMethod, computeQueryQueryParams, consumeSuppressQueryStackDevtools, contentfulGqlLikePaginationAdapter, countUnresolvedQueryDevtoolsOverrides, createAuthGuard, createBaseQuery, createBaseQueryCreator, createBearerAuthProvider, createDefaultRetryFn, createDeleteQuery, createExecuteFn, createGetQuery, createGqlExecuteFn, createGqlMutationViaGet, createGqlMutationViaPost, createGqlQuery, createGqlQueryCreator, createGqlQueryViaGet, createGqlQueryViaPost, createHeadQuery, createHttpRequest, createIndexedDbQueryPersistenceAdapter, createInfinityQueryConfig, createLegacyQueryCreator, createNoopQueryPersistenceAdapter, createOptionsQuery, createPagedQueryStack, createPatchQuery, createPersistentAuthFeature, createPostQuery, createPutQuery, createQuery, createQueryBatch, createQueryClient, createQueryCollection, createQueryCollectionSignal, createQueryCollectionSubject, createQueryContext, createQueryCreator, createQueryDevtoolsFormLinks, createQueryDevtoolsFormLinksRecorder, createQueryDevtoolsOverrides, createQueryDevtoolsOverridesRecorder, createQueryDevtoolsStats, createQueryDevtoolsStatsRecorder, createQueryErrorResponse, createQueryFeature, createQueryInvalidationFilter, createQueryKeyLockManager, createQueryObject, createQueryPersistenceEngine, createQueryRepository, createQuerySnapshotFn, createQueryStack, createQuerySubmission, createQuerySyncEngine, createQuerySyncTransport, createSecureDeleteQuery, createSecureExecuteFactory, createSecureExecuteFn, createSecureGetQuery, createSecureGqlExecuteFn, createSecureGqlMutationViaGet, createSecureGqlMutationViaPost, createSecureGqlQuery, createSecureGqlQueryCreator, createSecureGqlQueryViaGet, createSecureGqlQueryViaPost, createSecureHeadQuery, createSecureOptionsQuery, createSecurePatchQuery, createSecurePostQuery, createSecurePutQuery, createSecureQuery, createSecureQueryCreator, createTrackingFeature, createWebSocketClient, currentQueryDevtoolsBatch, 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, forgetQueryDevtoolsAuthSession, forgetQueryDevtoolsAuthSessionsFor, formatQueryDevtoolsDuration, generateQueryDevtoolsNumberPreset, generateQueryDevtoolsSampleNumber, generateQueryDevtoolsStringPreset, getBearerAuthProviderName, getDefaultHeaders, getQueryClientName, getQueryFeatureUsage, getResponseUrl, ggLikePaginationAdapter, gql, gqlDataPropertyMissingInResponse, gqlErrorsInResponse, gqlTransformerFor, hasHeader, hasQueryDevtoolsOverridesAtPath, htmlErrorPayload, htmlQueryErrorParser, ignoreAutoRefresh, initQueryDevtoolsAuthSessions, 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, isQueryDevtoolsRepositoryLive, isQueryDevtoolsRequestInterceptionEnabled, isQueryErrorResponse, isQueryStateCancelled, isQueryStateFailure, isQueryStateLoading, isQueryStatePrepared, isQueryStateSuccess, isRequestError, isSymfonyError, isSymfonyFormViolationListError, isSymfonyListError, isSymfonyPagerfantaOutOfRangeError, isUnderInvalidatedUrl, legacyPrepareFallbackInjector, legacyPrepareWithoutInjectionContext, loadQueryDevtoolsSchema, loginQueryDevtoolsAuthAccount, logoutQueryDevtoolsAuthSession, mapToPaginated, mapViolationsToFormErrors, matchesQueryDevtoolsMockPattern, matchesQueryDevtoolsMockQuery, maybeExecute, measureQueryDevtoolsPayload, mergeHeaders, nestedEffect, noteQueryFormRead, noteQueryFormReads, numberArrayQueryField, pagedQueryStackNextPageCalledWithoutPreviousPage, pagedQueryStackPageBiggerThanTotalPages, pagedQueryStackPreviousPageCalledButAlreadyAtFirstPage, paginatedEntityValueUpdater, parseAllXhrResponseHeaders, parseHttpErrorCodeToMessageDe, parseHttpErrorCodeToMessageEn, parseHttpErrorCodeToTitleDe, parseHttpErrorCodeToTitleEn, parseQueryDevtoolsOverrideTransfer, parseQueryRoute, patchQueryDevtoolsTokenPayload, pathParamsMissingInRouteFunctionError, provideInfinityQueryResponseDelay, provideLegacyPrepareFallback, provideQueryClientForDevtools, provideQueryDevtools, queryArrayComputed, queryBatchAlreadyRunning, queryBatchWithArgsUsed, queryClientFeatureUsedMultipleTimes, queryComputed, queryComputedTillTruthy, queryDevtoolsAbout, queryDevtoolsAllowsLocalAuthSessions, queryDevtoolsApiEnvIds, queryDevtoolsApiEnvIsProduction, queryDevtoolsApiEnvScope, queryDevtoolsApiEnvValues, queryDevtoolsApiEnvs, queryDevtoolsArmedMocks, queryDevtoolsArmedMocksRestored, queryDevtoolsAuthAccountsFor, queryDevtoolsAuthActive, queryDevtoolsAuthFieldsFor, queryDevtoolsAuthOtherScopeCount, queryDevtoolsAuthProviders, queryDevtoolsAuthSessions, queryDevtoolsAuthSessionsFor, queryDevtoolsAuthTabLocal, queryDevtoolsEntries, queryDevtoolsFaults, queryDevtoolsFaultsRestored, queryDevtoolsFnDetail, queryDevtoolsMockId, queryDevtoolsMocks, queryDevtoolsOverridePersistence, queryDevtoolsRequestPath, queryDevtoolsResponseHistory, queryDevtoolsRestoredOverridesScope, queryDevtoolsSchemaNames, queryDevtoolsSchemaRoutes, queryDevtoolsSchemaState, queryDevtoolsSettings, queryDevtoolsStorage, queryDevtoolsTokenTtls, queryErrorMessage, queryErrorMessages, queryExecute, queryExecutedAfterDestroyMessage, queryFeatureUsedMultipleTimes, queryField, querySequence, querySequenceAlreadyRunning, queryStackTotalQueriesAndExpectedQueriesMismatch, queryStackWithArgsUsed, queryStackWithResponseUpdateUsed, queryStateAlreadyHasKeyError, queryStateCannotTransformError, queryStateDoesNotContainKeyError, queryStateErrorSignal, queryStateLoadingSignal, queryStateResponseSignal, queryStateSignal, readQueryDevtoolsAuthSeed, readQueryDevtoolsAuthSeedFor, readQueryDevtoolsStore, registerEthleteVersion, registerLiveQueryDevtoolsRepository, registerQueryDevtoolsAuthProvider, registerQueryDevtoolsEntry, registerQueryErrorParser, releaseQueryDevtoolsOverridePersistence, removeFrom, removeQueryDevtoolsAuthAccount, renameQueryDevtoolsAuthSession, request, resetExecuteState, resetPageOnError, resolveInvalidationUrl, resolveQueryDevtoolsFault, resolveQueryDevtoolsFaultForAttempt, resolveQueryDevtoolsMock, resolveQueryDevtoolsMockForAttempt, restoredQueryDevtoolsOverrides, runDefaultQueryRetry, runInQueryDevtoolsBatch, runQueryErrorParsers, saveQueryDevtoolsMock, searchQueryField, seedQueryDevtoolsSchemaBody, seedQueryDevtoolsSchemaRoute, serializeBody, serializeQueryDevtoolsOverrideTransfer, setDefaultQueryRetryFn, setQueryDevtoolsApiEnv, setQueryDevtoolsApiEnvs, setQueryDevtoolsAppInfo, setQueryDevtoolsArmedMocksScope, setQueryDevtoolsAuthCredentials, setQueryDevtoolsAuthProviderRegistrar, setQueryDevtoolsAuthSeedReader, setQueryDevtoolsAuthTabLocal, setQueryDevtoolsFault, setQueryDevtoolsFaultResolver, setQueryDevtoolsFaultsScope, setQueryDevtoolsFormLinksFactory, setQueryDevtoolsMockResolver, setQueryDevtoolsOverridePersistence, setQueryDevtoolsOverridesFactory, setQueryDevtoolsOverridesScope, setQueryDevtoolsRegistrar, setQueryDevtoolsResponseHistory, setQueryDevtoolsSchemaLoader, setQueryDevtoolsSettings, setQueryDevtoolsStatsFactory, setQueryDevtoolsTokenPayloadPatcher, setQueryDevtoolsTokenTtl, setQueryDevtoolsUiMounted, setupQueryDependencies, setupQueryExecuteState, setupQueryState, shouldAutoExecuteGqlQuery, shouldAutoExecuteQuery, shouldCacheQuery, shouldRetryRequest, silenceMissingWithArgsFeatureErrorUsedButWithArgsPresent, skipPaginationPageParamCalculator, smartDuplicateArrayItem, snapshotQueryDevtoolsHandle, sortQueryField, splitQueryConfig, stringArrayQueryField, stringifyQueryRouteParts, sumQueryDevtoolsStats, suppressNextQueryStackDevtools, switchQueryCollectionState, switchQueryDevtoolsAuthSession, switchQueryState, symfonyQueryErrorParser, takeUntilResponse, toQuerySignal, toQuerySubject, tokensNotAvailableInsideAuthAndExec, tombstoneOf, trackQueryDevtoolsAuthProvider, 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, withLongPolling, withLongPollingUsedOnUnsupportedHttpMethod, withLongPollingUsedWithPolling, withMultiTabSync, withPageResetOnError, withPersistentAuth, withPolling, withPollingUsedOnUnsupportedHttpMethod, withQueryDevtoolsOverridePersistence, withQueryPersistence, withRefreshQuery, withResponseUpdate, withSuccessHandling, withSymfonyErrors, withTokenExpirationWarning, withTokenRevocation, withTracking, wrapAsObservableSignal, wrapQuerySyncMessage, writeQueryDevtoolsStore };
|
|
18014
|
+
export { AuthBearerRefreshStrategy, BasicAuthProvider, BearerAuthFeatureType, BooleanArrayQueryField, 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_BATCH_TOMBSTONES, 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, QueryStateType, QueryStore, SERVER_ERROR_KIND, SERVER_VIOLATION_ERROR_KIND, SPEED_BUFFER_TIME_IN_MS, SearchQueryField, SortQueryField, StringArrayQueryField, V2BearerAuthProvider, V2Query, V2QueryClient, V2QueryCreator, addQueryContainerHandling, addQueryDevtoolsAuthAccount, applyQueryDevtoolsOverrides, applyQueryDevtoolsTokenTtl, applyQueryFeatures, armAllQueryDevtoolsMocks, armQueryDevtoolsMock, armQueryDevtoolsOverrideTransfer, authExtractTokensResponseMissingAccessToken, authExtractTokensResponseMissingRefreshToken, authExtractTokensResponseNotObject, authProviderFeatureUsedMultipleTimes, booleanArrayQueryField, buildQueryCacheKey, buildQueryString, buildRoute, buildTimestampFromSeconds, canOverrideQueryDevtoolsTokenTtl, castQueryCreatorTypes, circularQueryDependency, circularQueryDependencyChecker, clearQueryDevtoolsArmedMocks, clearQueryDevtoolsAuthCredentials, clearQueryDevtoolsAuthSessions, clearQueryDevtoolsFaults, clearQueryDevtoolsMockStore, clearQueryDevtoolsOverrideStore, clearQueryDevtoolsStore, clearQueryDevtoolsTokenTtl, clearQueryDevtoolsTombstones, clearRestoredQueryDevtoolsOverrides, collectLeafPaths, collectQueryDevtoolsSchemaComponents, collectQueryFormLinks, computeQueryAuthHeader, computeQueryBody, computeQueryHeaders, computeQueryMethod, computeQueryQueryParams, consumeSuppressQueryStackDevtools, contentfulGqlLikePaginationAdapter, countUnresolvedQueryDevtoolsOverrides, createAuthGuard, createBaseQuery, createBaseQueryCreator, createBearerAuthProvider, createDefaultRetryFn, createDeleteQuery, createExecuteFn, createGetQuery, createGqlExecuteFn, createGqlMutationViaGet, createGqlMutationViaPost, createGqlQuery, createGqlQueryCreator, createGqlQueryViaGet, createGqlQueryViaPost, createHeadQuery, createHttpRequest, createIndexedDbQueryPersistenceAdapter, createInfinityQueryConfig, createLegacyQueryCreator, createNoopQueryPersistenceAdapter, createOptionsQuery, createPagedQueryStack, createPatchQuery, createPersistentAuthFeature, createPostQuery, createPutQuery, createQuery, createQueryBatch, createQueryClient, createQueryCollection, createQueryCollectionSignal, createQueryCollectionSubject, createQueryContext, createQueryCreator, createQueryDevtoolsFormLinks, createQueryDevtoolsFormLinksRecorder, createQueryDevtoolsOverrides, createQueryDevtoolsOverridesRecorder, createQueryDevtoolsStats, createQueryDevtoolsStatsRecorder, createQueryErrorResponse, createQueryFeature, createQueryInvalidationFilter, createQueryKeyLockManager, createQueryObject, createQueryPersistenceEngine, createQueryRepository, createQuerySnapshotFn, createQueryStack, createQuerySubmission, createQuerySyncEngine, createQuerySyncTransport, createSecureDeleteQuery, createSecureExecuteFactory, createSecureExecuteFn, createSecureGetQuery, createSecureGqlExecuteFn, createSecureGqlMutationViaGet, createSecureGqlMutationViaPost, createSecureGqlQuery, createSecureGqlQueryCreator, createSecureGqlQueryViaGet, createSecureGqlQueryViaPost, createSecureHeadQuery, createSecureOptionsQuery, createSecurePatchQuery, createSecurePostQuery, createSecurePutQuery, createSecureQuery, createSecureQueryCreator, createTrackingFeature, createWebSocketClient, currentQueryDevtoolsBatch, 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, forgetQueryDevtoolsAuthSession, forgetQueryDevtoolsAuthSessionsFor, formatQueryDevtoolsDuration, generateQueryDevtoolsNumberPreset, generateQueryDevtoolsSampleNumber, generateQueryDevtoolsStringPreset, getBearerAuthProviderName, getDefaultHeaders, getQueryClientName, getQueryFeatureUsage, getResponseUrl, ggLikePaginationAdapter, gql, gqlDataPropertyMissingInResponse, gqlErrorsInResponse, gqlTransformerFor, hasHeader, hasQueryDevtoolsOverridesAtPath, htmlErrorPayload, htmlQueryErrorParser, ignoreAutoRefresh, initQueryDevtoolsAuthSessions, initQueryDevtoolsFaults, initQueryDevtoolsMocks, initQueryDevtoolsOverridePersistence, initQueryDevtoolsSettings, injectInfinityQueryResponseDelay, injectQueryContext, insertFrom, invalidBaseRouteError, invalidBodyError, invalidRouteError, invalidStateInsideSecureExecuteFactory, isAutoRefresh, isBasicAuthProvider, isBearerAuthProvider, isClassValidatorError, isCreateGqlQueryOptions, isCustomHeaderAuthProvider, isDateShapedLeaf, isEmptyString, isGqlQueryConfig, isHtmlErrorPayload, isIdempotentQueryMethod, isLegacyQuery, isNaN$1 as isNaN, isPageOutOfRangeError, isQuery, isQueryCollection, isQueryDevtoolsEnabled, isQueryDevtoolsFaultArmed, isQueryDevtoolsRepositoryLive, isQueryDevtoolsRequestInterceptionEnabled, isQueryErrorResponse, isQueryStateCancelled, isQueryStateFailure, isQueryStateLoading, isQueryStatePrepared, isQueryStateSuccess, isRequestError, isSymfonyError, isSymfonyFormViolationListError, isSymfonyListError, isSymfonyPagerfantaOutOfRangeError, isUnderInvalidatedUrl, legacyPrepareFallbackInjector, legacyPrepareWithoutInjectionContext, loadQueryDevtoolsSchema, loginQueryDevtoolsAuthAccount, logoutQueryDevtoolsAuthSession, mapToPaginated, mapViolationsToFormErrors, matchesQueryDevtoolsMockPattern, matchesQueryDevtoolsMockQuery, maybeExecute, measureQueryDevtoolsPayload, mergeHeaders, nestedEffect, noteQueryFormRead, noteQueryFormReads, numberArrayQueryField, pagedQueryStackNextPageCalledWithoutPreviousPage, pagedQueryStackPageBiggerThanTotalPages, pagedQueryStackPreviousPageCalledButAlreadyAtFirstPage, paginatedEntityValueUpdater, parseAllXhrResponseHeaders, parseHttpErrorCodeToMessageDe, parseHttpErrorCodeToMessageEn, parseHttpErrorCodeToTitleDe, parseHttpErrorCodeToTitleEn, parseQueryDevtoolsOverrideTransfer, parseQueryRoute, patchQueryDevtoolsTokenPayload, pathParamsMissingInRouteFunctionError, provideInfinityQueryResponseDelay, provideLegacyPrepareFallback, provideQueryClientForDevtools, provideQueryDevtools, queryArrayComputed, queryBatchAlreadyRunning, queryBatchWithArgsUsed, queryClientFeatureUsedMultipleTimes, queryComputed, queryComputedTillTruthy, queryDevtoolsAbout, queryDevtoolsAllowsLocalAuthSessions, queryDevtoolsApiEnvIds, queryDevtoolsApiEnvIsProduction, queryDevtoolsApiEnvScope, queryDevtoolsApiEnvValues, queryDevtoolsApiEnvs, queryDevtoolsArmedMocks, queryDevtoolsArmedMocksRestored, queryDevtoolsAuthAccountsFor, queryDevtoolsAuthActive, queryDevtoolsAuthFieldsFor, queryDevtoolsAuthOtherScopeCount, queryDevtoolsAuthProviders, queryDevtoolsAuthSessions, queryDevtoolsAuthSessionsFor, queryDevtoolsAuthTabLocal, queryDevtoolsEntries, queryDevtoolsFaults, queryDevtoolsFaultsRestored, queryDevtoolsFnDetail, queryDevtoolsMockId, queryDevtoolsMocks, queryDevtoolsOverridePersistence, queryDevtoolsRequestPath, queryDevtoolsResponseHistory, queryDevtoolsRestoredOverridesScope, queryDevtoolsSchemaNames, queryDevtoolsSchemaRoutes, queryDevtoolsSchemaState, queryDevtoolsSettings, queryDevtoolsStorage, queryDevtoolsTokenTtls, queryErrorMessage, queryErrorMessages, queryExecute, queryExecutedAfterDestroyMessage, queryFeatureUsedMultipleTimes, queryField, querySequence, querySequenceAlreadyRunning, queryStackWithArgsUsed, queryStackWithResponseUpdateUsed, queryStateAlreadyHasKeyError, queryStateCannotTransformError, queryStateDoesNotContainKeyError, queryStateErrorSignal, queryStateLoadingSignal, queryStateResponseSignal, queryStateSignal, readQueryDevtoolsAuthSeed, readQueryDevtoolsAuthSeedFor, readQueryDevtoolsStore, registerEthleteVersion, registerLiveQueryDevtoolsRepository, registerQueryDevtoolsAuthProvider, registerQueryDevtoolsEntry, registerQueryErrorParser, releaseQueryDevtoolsOverridePersistence, removeFrom, removeQueryDevtoolsAuthAccount, renameQueryDevtoolsAuthSession, request, resetExecuteState, resetPageOnError, resolveInvalidationUrl, resolveQueryDevtoolsFault, resolveQueryDevtoolsFaultForAttempt, resolveQueryDevtoolsMock, resolveQueryDevtoolsMockForAttempt, resolveQueryHeaders, restoredQueryDevtoolsOverrides, runDefaultQueryRetry, runInQueryDevtoolsBatch, runQueryErrorParsers, saveQueryDevtoolsMock, searchQueryField, seedQueryDevtoolsSchemaBody, seedQueryDevtoolsSchemaRoute, serializeBody, serializeQueryDevtoolsOverrideTransfer, setDefaultQueryRetryFn, setQueryDevtoolsApiEnv, setQueryDevtoolsApiEnvs, setQueryDevtoolsAppInfo, setQueryDevtoolsArmedMocksScope, setQueryDevtoolsAuthCredentials, setQueryDevtoolsAuthProviderRegistrar, setQueryDevtoolsAuthSeedReader, setQueryDevtoolsAuthTabLocal, setQueryDevtoolsFault, setQueryDevtoolsFaultResolver, setQueryDevtoolsFaultsScope, setQueryDevtoolsFormLinksFactory, setQueryDevtoolsMockResolver, setQueryDevtoolsOverridePersistence, setQueryDevtoolsOverridesFactory, setQueryDevtoolsOverridesScope, setQueryDevtoolsRegistrar, setQueryDevtoolsResponseHistory, setQueryDevtoolsSchemaLoader, setQueryDevtoolsSettings, setQueryDevtoolsStatsFactory, setQueryDevtoolsTokenPayloadPatcher, setQueryDevtoolsTokenTtl, setQueryDevtoolsUiMounted, setupQueryDependencies, setupQueryExecuteState, setupQueryState, shouldAutoExecuteGqlQuery, shouldAutoExecuteQuery, shouldCacheQuery, shouldRetryRequest, silenceMissingWithArgsFeatureErrorUsedButWithArgsPresent, skipPaginationPageParamCalculator, smartDuplicateArrayItem, snapshotQueryDevtoolsHandle, sortQueryField, splitQueryConfig, stringArrayQueryField, stringifyQueryRouteParts, sumQueryDevtoolsStats, suppressNextQueryStackDevtools, switchQueryCollectionState, switchQueryDevtoolsAuthSession, switchQueryState, symfonyQueryErrorParser, takeUntilResponse, toQuerySignal, toQuerySubject, tokensNotAvailableInsideAuthAndExec, tombstoneOf, trackQueryDevtoolsAuthProvider, transformArrayResponse, transformExecStateToQueryState, transformGql, transformMethod, transformPaginatedResponse, transformToBoolean, transformToBooleanArray, transformToDate, transformToDateArray, transformToNumber, transformToNumberArray, transformToSort, transformToSortQueryParam, transformToString, transformToStringArray, uncacheableRequestHasAllowCacheParam, uncacheableRequestHasCacheKeyParam, unwrapGqlResponseWithErrors, unwrapQuerySyncMessage, v2BuildQueryCacheKey, v2ExtractExpiresInSeconds, v2ShouldCacheQuery, v2ShouldRetryRequest, validateWithQuery, validateWithV2Query, withArgs, withArgsQueryFeatureMissingButRouteIsFunction, withAuthenticationQuery, withAutoRefresh, withAutoRefreshUsedInManualQuery, withAutoRefreshUsedOnUnsupportedHttpMethod, withBearerAuthMultiTabSync, withDefaultRetry, withErrorHandling, withEthleteApiErrors, withHtmlErrorParsing, withInactivityLogout, withLogging, withLongPolling, withLongPollingUsedOnUnsupportedHttpMethod, withLongPollingUsedWithPolling, withMultiTabSync, withPageResetOnError, withPersistentAuth, withPolling, withPollingUsedOnUnsupportedHttpMethod, withQueryDevtoolsOverridePersistence, withQueryPersistence, withRefreshQuery, withResponseUpdate, withSuccessHandling, withSymfonyErrors, withTokenExpirationWarning, withTokenRevocation, withTracking, wrapAsObservableSignal, wrapQuerySyncMessage, writeQueryDevtoolsStore };
|
|
17690
18015
|
//# sourceMappingURL=ethlete-query.mjs.map
|