@ethlete/query 6.0.0-next.18 → 6.0.0-next.19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +18 -0
- package/fesm2022/ethlete-query.mjs +289 -8
- package/fesm2022/ethlete-query.mjs.map +1 -1
- package/package.json +1 -1
- package/types/ethlete-query.d.ts +163 -10
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,23 @@
|
|
|
1
1
|
# @ethlete/query
|
|
2
2
|
|
|
3
|
+
## 6.0.0-next.19
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [#3036](https://github.com/ethlete-io/ethdk/pull/3036) [`aa4bdde`](https://github.com/ethlete-io/ethdk/commit/aa4bdde586615ed13735ed9c970831b91323ebad) Thanks [@github-actions](https://github.com/apps/github-actions)! - Query devtools: add `provideQueryDevtools()` and a registry that instruments
|
|
8
|
+
queries, query stacks, paged query stacks, `querySequence`, bearer auth providers
|
|
9
|
+
and web socket clients so they can be inspected by `<et-query-devtools>` (from
|
|
10
|
+
`@ethlete/components`). Instrumentation is a no-op unless the provider is added,
|
|
11
|
+
so there is no overhead when it is omitted.
|
|
12
|
+
|
|
13
|
+
Supporting devtools APIs added: `querySequence` exposes a `stepArgs` signal (the
|
|
14
|
+
resolved input args of each step); the query repository gains
|
|
15
|
+
`subtle.cacheEntries()` / `subtle.cacheVersion` / `subtle.evict()`; queries gain
|
|
16
|
+
`subtle.setLoading()` / `subtle.setError()` (force UI states for testing);
|
|
17
|
+
`HttpRequest` exposes `method`, `url` and `expiresAt`; `QueryClient` exposes its
|
|
18
|
+
`baseUrl`; `QuerySequence` exposes its step `queries`; and web socket clients
|
|
19
|
+
expose a devtools handle (connection state, rooms, recent messages).
|
|
20
|
+
|
|
3
21
|
## 6.0.0-next.18
|
|
4
22
|
|
|
5
23
|
### Minor Changes
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { isDevMode, DestroyRef, InjectionToken, inject, Injector, EnvironmentInjector, ErrorHandler, createEnvironmentInjector, effect, untracked,
|
|
2
|
+
import { signal, isDevMode, makeEnvironmentProviders, DestroyRef, InjectionToken, inject, Injector, EnvironmentInjector, ElementRef, ErrorHandler, createEnvironmentInjector, effect, untracked, linkedSignal, computed, runInInjectionContext, assertInInjectionContext, ChangeDetectorRef, ViewContainerRef, TemplateRef, Input, Directive, input, Pipe, ViewEncapsulation, Component, resource, DOCUMENT, NgZone } from '@angular/core';
|
|
3
3
|
import { createStaticProvider, RuntimeError, clamp, createDestroy, computedTillTruthy, getCookie, setCookie, deleteCookie, createProvider, nextFrame, randomId, createRootProvider, isObject, injectRoute, getDomain, injectQueryParamChanges, injectQueryParams, clone, equal, ET_PROPERTY_REMOVED, previousSignalValue } from '@ethlete/core';
|
|
4
4
|
import { filter, Subject, Subscription, Observable, tap, retry, throwError, timer, catchError, takeUntil, startWith, pairwise, switchMap, of, BehaviorSubject, fromEvent, take, ReplaySubject, map, shareReplay, interval, skip, takeWhile, combineLatest, EMPTY, withLatestFrom, debounceTime, firstValueFrom, merge, throttleTime } from 'rxjs';
|
|
5
5
|
import { toObservable, takeUntilDestroyed, toSignal } from '@angular/core/rxjs-interop';
|
|
@@ -12,6 +12,126 @@ import { validateAsync } from '@angular/forms/signals';
|
|
|
12
12
|
import { Router, ActivatedRoute } from '@angular/router';
|
|
13
13
|
import { io } from 'socket.io-client';
|
|
14
14
|
|
|
15
|
+
const noop = () => undefined;
|
|
16
|
+
let devtoolsEnabled = false;
|
|
17
|
+
/**
|
|
18
|
+
* Whether {@link provideQueryDevtools} has been called. When `false`, every `register*` call is a
|
|
19
|
+
* no-op so the devtools instrumentation retains no references and adds no overhead in production.
|
|
20
|
+
* @internal
|
|
21
|
+
*/
|
|
22
|
+
const isQueryDevtoolsEnabled = () => devtoolsEnabled;
|
|
23
|
+
const entries = signal([], /* @ts-ignore */
|
|
24
|
+
...(ngDevMode ? [{ debugName: "entries" }] : /* istanbul ignore next */ []));
|
|
25
|
+
/**
|
|
26
|
+
* The reactive list of every registered devtools entry, consumed by the `<et-query-devtools>` UI.
|
|
27
|
+
*/
|
|
28
|
+
const queryDevtoolsEntries = entries.asReadonly();
|
|
29
|
+
// Per-descriptor counter used to derive stable, reload-deterministic ids. Reset on page load (module
|
|
30
|
+
// re-eval), so the same queries created in the same order get the same ids across reloads — which is
|
|
31
|
+
// what lets the devtools restore the selected query after a reload.
|
|
32
|
+
const idCounters = new Map();
|
|
33
|
+
const descriptorOf = (entry) => {
|
|
34
|
+
const { kind, meta } = entry;
|
|
35
|
+
if (kind === 'query')
|
|
36
|
+
return `query|${meta.clientName ?? ''}|${meta.method ?? ''}|${meta.route ?? ''}`;
|
|
37
|
+
if (kind === 'auth-provider')
|
|
38
|
+
return `auth-provider|${meta.name ?? ''}`;
|
|
39
|
+
if (kind === 'ws-client')
|
|
40
|
+
return `ws-client|${meta.name ?? ''}`;
|
|
41
|
+
return kind;
|
|
42
|
+
};
|
|
43
|
+
/**
|
|
44
|
+
* Registers an entry with the devtools registry. Returns an unregister callback. A no-op (returning
|
|
45
|
+
* a no-op callback) unless {@link provideQueryDevtools} has been called.
|
|
46
|
+
*
|
|
47
|
+
* Ids are derived deterministically from a stable descriptor + a per-descriptor sequence number, so
|
|
48
|
+
* they survive a page reload (letting the UI restore the selected entry) instead of being random.
|
|
49
|
+
* @internal
|
|
50
|
+
*/
|
|
51
|
+
const registerQueryDevtoolsEntry = (entry) => {
|
|
52
|
+
if (!devtoolsEnabled)
|
|
53
|
+
return noop;
|
|
54
|
+
let id = entry.id;
|
|
55
|
+
if (!id) {
|
|
56
|
+
const descriptor = descriptorOf(entry);
|
|
57
|
+
const seq = idCounters.get(descriptor) ?? 0;
|
|
58
|
+
idCounters.set(descriptor, seq + 1);
|
|
59
|
+
id = `${descriptor}#${seq}`;
|
|
60
|
+
}
|
|
61
|
+
const fullEntry = { ...entry, id, createdAt: Date.now() };
|
|
62
|
+
entries.update((list) => [...list, fullEntry]);
|
|
63
|
+
return () => entries.update((list) => list.filter((e) => e.id !== fullEntry.id));
|
|
64
|
+
};
|
|
65
|
+
let suppressStackRegistration = false;
|
|
66
|
+
/**
|
|
67
|
+
* Suppresses devtools registration for the next {@link createQueryStack} call. Used by
|
|
68
|
+
* `createPagedQueryStack` so its backing stack is not registered as a separate `query-stack` entry.
|
|
69
|
+
* @internal
|
|
70
|
+
*/
|
|
71
|
+
const suppressNextQueryStackDevtools = () => {
|
|
72
|
+
suppressStackRegistration = true;
|
|
73
|
+
};
|
|
74
|
+
/**
|
|
75
|
+
* Reads and clears the suppress-next-stack flag. Always call this from `createQueryStack` (even when
|
|
76
|
+
* devtools are disabled) so a suppression request never leaks into a later stack.
|
|
77
|
+
* @internal
|
|
78
|
+
*/
|
|
79
|
+
const consumeSuppressQueryStackDevtools = () => {
|
|
80
|
+
const value = suppressStackRegistration;
|
|
81
|
+
suppressStackRegistration = false;
|
|
82
|
+
return value;
|
|
83
|
+
};
|
|
84
|
+
/**
|
|
85
|
+
* Stringifies a query creator route. Function routes are invoked with an empty args object and any
|
|
86
|
+
* resulting `undefined` path segments are rendered as `:param`, matching the legacy devtools.
|
|
87
|
+
* @internal
|
|
88
|
+
*/
|
|
89
|
+
const stringifyQueryRoute = (route) => {
|
|
90
|
+
if (route === undefined || route === null)
|
|
91
|
+
return '';
|
|
92
|
+
try {
|
|
93
|
+
if (typeof route === 'function') {
|
|
94
|
+
return route({}).replace(/undefined/g, ':param');
|
|
95
|
+
}
|
|
96
|
+
return String(route);
|
|
97
|
+
}
|
|
98
|
+
catch {
|
|
99
|
+
return typeof route === 'function' ? '(dynamic route)' : String(route);
|
|
100
|
+
}
|
|
101
|
+
};
|
|
102
|
+
/**
|
|
103
|
+
* Extracts the human readable client name from a query client tuple. The client's DI token is named
|
|
104
|
+
* `QueryClient_<name>`, so we strip the prefix to recover the original name.
|
|
105
|
+
* @internal
|
|
106
|
+
*/
|
|
107
|
+
const getQueryClientName = (client) => {
|
|
108
|
+
const token = client[2];
|
|
109
|
+
const desc = token?.toString?.() ?? '';
|
|
110
|
+
return desc.replace('InjectionToken ', '').replace('QueryClient_', '') || 'unknown';
|
|
111
|
+
};
|
|
112
|
+
/**
|
|
113
|
+
* Enables the `@ethlete/query` devtools. Add this to your application providers (e.g. in
|
|
114
|
+
* `bootstrapApplication`) to make query clients, queries, stacks, sequences and auth providers
|
|
115
|
+
* appear in the `<et-query-devtools>` panel.
|
|
116
|
+
*
|
|
117
|
+
* When omitted, all devtools instrumentation is a no-op — no references are retained and there is no
|
|
118
|
+
* runtime overhead — so it is safe to leave out of production builds.
|
|
119
|
+
*
|
|
120
|
+
* @example
|
|
121
|
+
* ```ts
|
|
122
|
+
* bootstrapApplication(AppComponent, {
|
|
123
|
+
* providers: [provideQueryDevtools()],
|
|
124
|
+
* });
|
|
125
|
+
* ```
|
|
126
|
+
*/
|
|
127
|
+
const provideQueryDevtools = () => {
|
|
128
|
+
devtoolsEnabled = true;
|
|
129
|
+
if (!isDevMode()) {
|
|
130
|
+
console.warn('You are using the Query Devtools in production mode. This increases the size of your bundle and should only be used for development purposes.');
|
|
131
|
+
}
|
|
132
|
+
return makeEnvironmentProviders([]);
|
|
133
|
+
};
|
|
134
|
+
|
|
15
135
|
const getOpName = /(query|mutation) ?([\w\d-_]+)? ?\(.*?\)? \{/;
|
|
16
136
|
const transformGql = (str) => {
|
|
17
137
|
const normalizedStr = Array.isArray(str) ? str.join('') : str;
|
|
@@ -133,6 +253,7 @@ const setupQueryDependencies = (options) => {
|
|
|
133
253
|
injector: undefined, // Will be set after injector creation
|
|
134
254
|
ngErrorHandler: hostInjector.get(ErrorHandler),
|
|
135
255
|
httpClient: hostInjector.get(HttpClient),
|
|
256
|
+
hostElement: hostInjector.get(ElementRef, null, { optional: true })?.nativeElement ?? null,
|
|
136
257
|
};
|
|
137
258
|
const queryContext = {
|
|
138
259
|
deps: dependencies,
|
|
@@ -657,6 +778,8 @@ const createQueryObject = (options) => {
|
|
|
657
778
|
const { state, execute, deps } = options;
|
|
658
779
|
const destroy = () => deps.injector.destroy();
|
|
659
780
|
const setResponse = (response) => state.rawResponse.set(response);
|
|
781
|
+
const setLoading = (loading) => state.loading.set(loading);
|
|
782
|
+
const setError = (error) => state.error.set(error);
|
|
660
783
|
const createSnapshot = createQuerySnapshotFn({ state, execute, deps });
|
|
661
784
|
// Pre-wrap all public signals once so both `query` and `roQuery` share the same instances.
|
|
662
785
|
const wrappedArgs = wrapAsObservableSignal(state.args.asReadonly(), deps.injector);
|
|
@@ -701,6 +824,8 @@ const createQueryObject = (options) => {
|
|
|
701
824
|
subtle: {
|
|
702
825
|
destroy,
|
|
703
826
|
setResponse,
|
|
827
|
+
setLoading,
|
|
828
|
+
setError,
|
|
704
829
|
request: wrappedRequest,
|
|
705
830
|
destroyRef: deps.scopeDestroyRef,
|
|
706
831
|
injector: deps.injector,
|
|
@@ -734,7 +859,28 @@ const createBaseQuery = (options) => {
|
|
|
734
859
|
};
|
|
735
860
|
applyQueryFeatures(options.features, featureFnContext);
|
|
736
861
|
maybeExecute({ execute, flags });
|
|
737
|
-
|
|
862
|
+
const query = createQueryObject({ state, execute, deps });
|
|
863
|
+
if (isQueryDevtoolsEnabled()) {
|
|
864
|
+
const unregister = registerQueryDevtoolsEntry({
|
|
865
|
+
kind: 'query',
|
|
866
|
+
handle: query,
|
|
867
|
+
meta: {
|
|
868
|
+
clientName: getQueryClientName(client),
|
|
869
|
+
clientBaseUrl: deps.client.baseUrl,
|
|
870
|
+
route: stringifyQueryRoute(options.creatorInternals.route ??
|
|
871
|
+
options.creator?.route),
|
|
872
|
+
method: flags.method,
|
|
873
|
+
featureTypes: options.features.map((f) => f.type),
|
|
874
|
+
queryConfig: options.queryConfig,
|
|
875
|
+
creator: options.creator,
|
|
876
|
+
repository: deps.client.repository,
|
|
877
|
+
element: deps.hostElement,
|
|
878
|
+
gqlQuery: options.creatorInternals.query,
|
|
879
|
+
},
|
|
880
|
+
});
|
|
881
|
+
deps.destroyRef.onDestroy(unregister);
|
|
882
|
+
}
|
|
883
|
+
return query;
|
|
738
884
|
});
|
|
739
885
|
};
|
|
740
886
|
|
|
@@ -1718,6 +1864,8 @@ const createHttpRequest = (options) => {
|
|
|
1718
1864
|
loading.set(state);
|
|
1719
1865
|
};
|
|
1720
1866
|
const httpRequest = {
|
|
1867
|
+
method: options.method,
|
|
1868
|
+
url: options.fullPath,
|
|
1721
1869
|
execute,
|
|
1722
1870
|
destroy,
|
|
1723
1871
|
loading: loading.asReadonly(),
|
|
@@ -1726,6 +1874,7 @@ const createHttpRequest = (options) => {
|
|
|
1726
1874
|
currentEvent: currentEvent.asReadonly(),
|
|
1727
1875
|
events$: event$.asObservable(),
|
|
1728
1876
|
isStale,
|
|
1877
|
+
expiresAt: expiresIn.asReadonly(),
|
|
1729
1878
|
};
|
|
1730
1879
|
return httpRequest;
|
|
1731
1880
|
};
|
|
@@ -1886,6 +2035,17 @@ const createQueryStack = (options) => {
|
|
|
1886
2035
|
runWithArgs,
|
|
1887
2036
|
},
|
|
1888
2037
|
};
|
|
2038
|
+
const skipDevtools = consumeSuppressQueryStackDevtools();
|
|
2039
|
+
if (isQueryDevtoolsEnabled() && !skipDevtools) {
|
|
2040
|
+
const unregister = registerQueryDevtoolsEntry({
|
|
2041
|
+
kind: 'query-stack',
|
|
2042
|
+
handle: stack,
|
|
2043
|
+
meta: {
|
|
2044
|
+
featureTypes: features.map((f) => f.type),
|
|
2045
|
+
},
|
|
2046
|
+
});
|
|
2047
|
+
inject(DestroyRef).onDestroy(unregister);
|
|
2048
|
+
}
|
|
1889
2049
|
return stack;
|
|
1890
2050
|
};
|
|
1891
2051
|
|
|
@@ -1958,6 +2118,7 @@ const createPagedQueryStack = (options) => {
|
|
|
1958
2118
|
...(ngDevMode ? [{ debugName: "resetTrigger" }] : /* istanbul ignore next */ []));
|
|
1959
2119
|
const pageDirection = signal('next', /* @ts-ignore */
|
|
1960
2120
|
...(ngDevMode ? [{ debugName: "pageDirection" }] : /* istanbul ignore next */ []));
|
|
2121
|
+
suppressNextQueryStackDevtools();
|
|
1961
2122
|
const stack = createQueryStack({
|
|
1962
2123
|
args: () => null,
|
|
1963
2124
|
queryCreator,
|
|
@@ -2165,6 +2326,16 @@ const createPagedQueryStack = (options) => {
|
|
|
2165
2326
|
reset,
|
|
2166
2327
|
execute,
|
|
2167
2328
|
};
|
|
2329
|
+
if (isQueryDevtoolsEnabled()) {
|
|
2330
|
+
const unregister = registerQueryDevtoolsEntry({
|
|
2331
|
+
kind: 'paged-query-stack',
|
|
2332
|
+
handle: pagedQuery,
|
|
2333
|
+
meta: {
|
|
2334
|
+
featureTypes: features?.map((f) => f.type),
|
|
2335
|
+
},
|
|
2336
|
+
});
|
|
2337
|
+
inject(DestroyRef).onDestroy(unregister);
|
|
2338
|
+
}
|
|
2168
2339
|
return pagedQuery;
|
|
2169
2340
|
};
|
|
2170
2341
|
|
|
@@ -5285,6 +5456,11 @@ const generateUuid = () => randomId();
|
|
|
5285
5456
|
const createQueryRepository = (config) => {
|
|
5286
5457
|
const cache = new Map();
|
|
5287
5458
|
const eventsSubject = new Subject();
|
|
5459
|
+
// Bumped on every cache mutation so the devtools cache view can react. Cheap enough to keep
|
|
5460
|
+
// unconditional — it is a single integer signal with no readers unless the devtools are open.
|
|
5461
|
+
const cacheVersion = signal(0, /* @ts-ignore */
|
|
5462
|
+
...(ngDevMode ? [{ debugName: "cacheVersion" }] : /* istanbul ignore next */ []));
|
|
5463
|
+
const bumpCacheVersion = () => cacheVersion.update((v) => v + 1);
|
|
5288
5464
|
const request = (options) => {
|
|
5289
5465
|
const { args, creatorOptions, runQueryOptions } = options;
|
|
5290
5466
|
const shouldCache = creatorOptions?.subtle?.useQueryRepositoryCache === false
|
|
@@ -5349,6 +5525,7 @@ const createQueryRepository = (config) => {
|
|
|
5349
5525
|
cacheEntry.eventSubscription?.unsubscribe();
|
|
5350
5526
|
cache.delete(key);
|
|
5351
5527
|
}
|
|
5528
|
+
bumpCacheVersion();
|
|
5352
5529
|
return true;
|
|
5353
5530
|
};
|
|
5354
5531
|
const unbindAllSecure = () => {
|
|
@@ -5361,6 +5538,7 @@ const createQueryRepository = (config) => {
|
|
|
5361
5538
|
cache.delete(key);
|
|
5362
5539
|
}
|
|
5363
5540
|
}
|
|
5541
|
+
bumpCacheVersion();
|
|
5364
5542
|
};
|
|
5365
5543
|
const bind = (key, consumerDestroyRef, request, isSecure, allowReuse) => {
|
|
5366
5544
|
const destroyListener = consumerDestroyRef.onDestroy(() => unbind(key, consumerDestroyRef));
|
|
@@ -5391,12 +5569,33 @@ const createQueryRepository = (config) => {
|
|
|
5391
5569
|
eventSubscription,
|
|
5392
5570
|
});
|
|
5393
5571
|
}
|
|
5572
|
+
bumpCacheVersion();
|
|
5573
|
+
};
|
|
5574
|
+
const cacheEntries = () => Array.from(cache.entries()).map(([key, entry]) => ({
|
|
5575
|
+
key,
|
|
5576
|
+
isSecure: entry.isSecure,
|
|
5577
|
+
consumerCount: entry.consumers.size,
|
|
5578
|
+
request: entry.request,
|
|
5579
|
+
}));
|
|
5580
|
+
const evict = (key) => {
|
|
5581
|
+
const entry = cache.get(key);
|
|
5582
|
+
if (!entry)
|
|
5583
|
+
return;
|
|
5584
|
+
entry.request.destroy();
|
|
5585
|
+
entry.eventSubscription?.unsubscribe();
|
|
5586
|
+
cache.delete(key);
|
|
5587
|
+
bumpCacheVersion();
|
|
5394
5588
|
};
|
|
5395
5589
|
const repository = {
|
|
5396
5590
|
request,
|
|
5397
5591
|
unbind,
|
|
5398
5592
|
unbindAllSecure,
|
|
5399
5593
|
events$: eventsSubject.asObservable(),
|
|
5594
|
+
subtle: {
|
|
5595
|
+
cacheEntries,
|
|
5596
|
+
cacheVersion: cacheVersion.asReadonly(),
|
|
5597
|
+
evict,
|
|
5598
|
+
},
|
|
5400
5599
|
};
|
|
5401
5600
|
return repository;
|
|
5402
5601
|
};
|
|
@@ -5411,6 +5610,7 @@ const createQueryClient = (options) => createRootProvider(() => {
|
|
|
5411
5610
|
});
|
|
5412
5611
|
const client = {
|
|
5413
5612
|
repository,
|
|
5613
|
+
baseUrl: options.baseUrl,
|
|
5414
5614
|
};
|
|
5415
5615
|
return client;
|
|
5416
5616
|
}, {
|
|
@@ -5505,9 +5705,10 @@ const createSequenceState = () => ({
|
|
|
5505
5705
|
error: signal(null),
|
|
5506
5706
|
failedAt: signal(null),
|
|
5507
5707
|
snapshots: signal([]),
|
|
5708
|
+
stepArgs: signal([]),
|
|
5508
5709
|
responses: signal([]),
|
|
5509
5710
|
});
|
|
5510
|
-
const buildSequence = (steps, state) => {
|
|
5711
|
+
const buildSequence = (steps, state, devtoolsHandle) => {
|
|
5511
5712
|
const run = async () => {
|
|
5512
5713
|
if (state.running())
|
|
5513
5714
|
throw querySequenceAlreadyRunning();
|
|
@@ -5517,13 +5718,17 @@ const buildSequence = (steps, state) => {
|
|
|
5517
5718
|
state.error.set(null);
|
|
5518
5719
|
state.failedAt.set(null);
|
|
5519
5720
|
state.snapshots.set([]);
|
|
5721
|
+
state.stepArgs.set([]);
|
|
5520
5722
|
state.responses.set([]);
|
|
5521
5723
|
const snapshots = [];
|
|
5724
|
+
const stepArgs = [];
|
|
5522
5725
|
const responses = [];
|
|
5523
5726
|
let previousResponse = undefined;
|
|
5524
5727
|
for (const [i, step] of steps.entries()) {
|
|
5525
5728
|
state.currentStep.set(i + 1);
|
|
5526
5729
|
const { args } = step.produceArgs(previousResponse, responses);
|
|
5730
|
+
stepArgs.push(args);
|
|
5731
|
+
state.stepArgs.set([...stepArgs]);
|
|
5527
5732
|
const snapshot = await executeUntilSettled(step.query, { args });
|
|
5528
5733
|
snapshots.push(snapshot);
|
|
5529
5734
|
state.snapshots.set([...snapshots]);
|
|
@@ -5544,21 +5749,26 @@ const buildSequence = (steps, state) => {
|
|
|
5544
5749
|
state.running.set(false);
|
|
5545
5750
|
return { ok: true, responses: responses, snapshots };
|
|
5546
5751
|
};
|
|
5547
|
-
|
|
5752
|
+
const sequence = {
|
|
5548
5753
|
then: (query, mapArgs) => buildSequence([
|
|
5549
5754
|
...steps,
|
|
5550
5755
|
{ query, produceArgs: (previousResponse, responses) => mapArgs(previousResponse, responses) },
|
|
5551
|
-
], state),
|
|
5756
|
+
], state, devtoolsHandle),
|
|
5552
5757
|
status: state.status.asReadonly(),
|
|
5553
5758
|
running: state.running.asReadonly(),
|
|
5554
5759
|
currentStep: state.currentStep.asReadonly(),
|
|
5555
5760
|
total: steps.length,
|
|
5761
|
+
queries: steps.map((s) => s.query),
|
|
5556
5762
|
error: state.error.asReadonly(),
|
|
5557
5763
|
failedAt: state.failedAt.asReadonly(),
|
|
5558
5764
|
snapshots: state.snapshots.asReadonly(),
|
|
5765
|
+
stepArgs: state.stepArgs.asReadonly(),
|
|
5559
5766
|
responses: state.responses.asReadonly(),
|
|
5560
5767
|
run,
|
|
5561
5768
|
};
|
|
5769
|
+
if (devtoolsHandle)
|
|
5770
|
+
devtoolsHandle.current = sequence;
|
|
5771
|
+
return sequence;
|
|
5562
5772
|
};
|
|
5563
5773
|
/**
|
|
5564
5774
|
* Starts an imperative waterfall of dependent queries. Chain the remaining steps with `.then()`
|
|
@@ -5582,7 +5792,27 @@ const buildSequence = (steps, state) => {
|
|
|
5582
5792
|
* }
|
|
5583
5793
|
* ```
|
|
5584
5794
|
*/
|
|
5585
|
-
const querySequence = (query, seedArgs) =>
|
|
5795
|
+
const querySequence = (query, seedArgs) => {
|
|
5796
|
+
const devtoolsHandle = isQueryDevtoolsEnabled()
|
|
5797
|
+
? { current: null }
|
|
5798
|
+
: undefined;
|
|
5799
|
+
const seed = buildSequence([{ query, produceArgs: () => seedArgs() }], createSequenceState(), devtoolsHandle);
|
|
5800
|
+
if (devtoolsHandle) {
|
|
5801
|
+
const unregister = registerQueryDevtoolsEntry({
|
|
5802
|
+
kind: 'query-sequence',
|
|
5803
|
+
handle: devtoolsHandle,
|
|
5804
|
+
meta: {},
|
|
5805
|
+
});
|
|
5806
|
+
// Sequences have no destroy hook; tie cleanup to the creating scope when there is one.
|
|
5807
|
+
try {
|
|
5808
|
+
inject(DestroyRef).onDestroy(unregister);
|
|
5809
|
+
}
|
|
5810
|
+
catch {
|
|
5811
|
+
// Created outside an injection context — the entry lives for the app's lifetime.
|
|
5812
|
+
}
|
|
5813
|
+
}
|
|
5814
|
+
return seed;
|
|
5815
|
+
};
|
|
5586
5816
|
|
|
5587
5817
|
/**
|
|
5588
5818
|
* Binds a query-backed async validator to a signal-forms field, adapting an `@ethlete/query` v3
|
|
@@ -6213,7 +6443,7 @@ const createBearerAuthProviderImpl = (config) => {
|
|
|
6213
6443
|
};
|
|
6214
6444
|
const features = setupFeatures(config.features, featureSetupContext);
|
|
6215
6445
|
setupMultiTabSyncIfEnabled(config, accessToken, refreshToken, queryClient);
|
|
6216
|
-
|
|
6446
|
+
const provider = {
|
|
6217
6447
|
queries,
|
|
6218
6448
|
features: features,
|
|
6219
6449
|
accessToken: accessToken.asReadonly(),
|
|
@@ -6226,6 +6456,20 @@ const createBearerAuthProviderImpl = (config) => {
|
|
|
6226
6456
|
logout,
|
|
6227
6457
|
afterTokenRefresh$,
|
|
6228
6458
|
};
|
|
6459
|
+
if (isQueryDevtoolsEnabled()) {
|
|
6460
|
+
const unregister = registerQueryDevtoolsEntry({
|
|
6461
|
+
kind: 'auth-provider',
|
|
6462
|
+
handle: provider,
|
|
6463
|
+
meta: {
|
|
6464
|
+
name: config.name,
|
|
6465
|
+
clientName: getQueryClientName(config.queryClientRef),
|
|
6466
|
+
clientBaseUrl: queryClient.baseUrl,
|
|
6467
|
+
repository: queryClient.repository,
|
|
6468
|
+
},
|
|
6469
|
+
});
|
|
6470
|
+
destroyRef.onDestroy(unregister);
|
|
6471
|
+
}
|
|
6472
|
+
return provider;
|
|
6229
6473
|
};
|
|
6230
6474
|
const createBearerAuthProvider = (config) => createRootProvider(() => createBearerAuthProviderImpl(config), { name: `BearerAuthProvider_${config.name}` });
|
|
6231
6475
|
|
|
@@ -7789,6 +8033,7 @@ const messageMalformed = () => {
|
|
|
7789
8033
|
return new RuntimeError(WebSocketRuntimeErrorCode.MESSAGE_MALFORMED, 'A message has been received but it is malformed (cannot be parsed as JSON).');
|
|
7790
8034
|
};
|
|
7791
8035
|
|
|
8036
|
+
const MAX_DEVTOOLS_MESSAGES = 100;
|
|
7792
8037
|
const createWebSocketClient = (options) => {
|
|
7793
8038
|
return createRootProvider(() => {
|
|
7794
8039
|
const socket = io(options.url, {
|
|
@@ -7799,6 +8044,17 @@ const createWebSocketClient = (options) => {
|
|
|
7799
8044
|
const rooms = new Map();
|
|
7800
8045
|
const isConnected = signal(false, /* @ts-ignore */
|
|
7801
8046
|
...(ngDevMode ? [{ debugName: "isConnected" }] : /* istanbul ignore next */ []));
|
|
8047
|
+
// Devtools instrumentation (no-op unless provideQueryDevtools() was called).
|
|
8048
|
+
const devtoolsEnabled = isQueryDevtoolsEnabled();
|
|
8049
|
+
const devtoolsRooms = signal([], /* @ts-ignore */
|
|
8050
|
+
...(ngDevMode ? [{ debugName: "devtoolsRooms" }] : /* istanbul ignore next */ []));
|
|
8051
|
+
const devtoolsMessages = signal([], /* @ts-ignore */
|
|
8052
|
+
...(ngDevMode ? [{ debugName: "devtoolsMessages" }] : /* istanbul ignore next */ []));
|
|
8053
|
+
let devtoolsMessageId = 0;
|
|
8054
|
+
const syncDevtoolsRooms = () => {
|
|
8055
|
+
if (devtoolsEnabled)
|
|
8056
|
+
devtoolsRooms.set([...rooms.keys()]);
|
|
8057
|
+
};
|
|
7802
8058
|
const joinRoom = (room) => {
|
|
7803
8059
|
const roomFn = typeof room === 'function' ? room : () => room;
|
|
7804
8060
|
const pre = previousSignalValue(computed(() => roomFn()));
|
|
@@ -7815,6 +8071,7 @@ const createWebSocketClient = (options) => {
|
|
|
7815
8071
|
latestMessage: message,
|
|
7816
8072
|
};
|
|
7817
8073
|
rooms.set(name, newRoom);
|
|
8074
|
+
syncDevtoolsRooms();
|
|
7818
8075
|
return newRoom;
|
|
7819
8076
|
};
|
|
7820
8077
|
effect(() => {
|
|
@@ -7851,6 +8108,7 @@ const createWebSocketClient = (options) => {
|
|
|
7851
8108
|
}
|
|
7852
8109
|
socket.emit('leave-room', room);
|
|
7853
8110
|
rooms.delete(room);
|
|
8111
|
+
syncDevtoolsRooms();
|
|
7854
8112
|
};
|
|
7855
8113
|
const setupWebSocketConnectionListener = () => {
|
|
7856
8114
|
socket.on('connect', () => {
|
|
@@ -7865,6 +8123,16 @@ const createWebSocketClient = (options) => {
|
|
|
7865
8123
|
socket.onAny((data) => {
|
|
7866
8124
|
try {
|
|
7867
8125
|
const json = JSON.parse(data);
|
|
8126
|
+
if (devtoolsEnabled) {
|
|
8127
|
+
const message = {
|
|
8128
|
+
id: devtoolsMessageId++,
|
|
8129
|
+
timestamp: Date.now(),
|
|
8130
|
+
room: json.room,
|
|
8131
|
+
event: json.event,
|
|
8132
|
+
data: json.data,
|
|
8133
|
+
};
|
|
8134
|
+
devtoolsMessages.update((log) => [message, ...log].slice(0, MAX_DEVTOOLS_MESSAGES));
|
|
8135
|
+
}
|
|
7868
8136
|
const room = rooms.get(json.room);
|
|
7869
8137
|
if (room)
|
|
7870
8138
|
room.latestMessage.set(json);
|
|
@@ -7887,6 +8155,19 @@ const createWebSocketClient = (options) => {
|
|
|
7887
8155
|
leaveRoom,
|
|
7888
8156
|
},
|
|
7889
8157
|
};
|
|
8158
|
+
if (devtoolsEnabled) {
|
|
8159
|
+
const handle = {
|
|
8160
|
+
connected: isConnected.asReadonly(),
|
|
8161
|
+
rooms: devtoolsRooms.asReadonly(),
|
|
8162
|
+
messages: devtoolsMessages.asReadonly(),
|
|
8163
|
+
};
|
|
8164
|
+
const unregister = registerQueryDevtoolsEntry({
|
|
8165
|
+
kind: 'ws-client',
|
|
8166
|
+
handle,
|
|
8167
|
+
meta: { name: options.name, url: options.url },
|
|
8168
|
+
});
|
|
8169
|
+
inject(DestroyRef).onDestroy(unregister);
|
|
8170
|
+
}
|
|
7890
8171
|
return client;
|
|
7891
8172
|
}, {
|
|
7892
8173
|
name: `WebSocketClient_${options.name}`,
|
|
@@ -7897,5 +8178,5 @@ const createWebSocketClient = (options) => {
|
|
|
7897
8178
|
* Generated bundle index. Do not edit.
|
|
7898
8179
|
*/
|
|
7899
8180
|
|
|
7900
|
-
export { BasicAuthProvider, BearerAuthFeatureType, BooleanArrayQueryField, CLEAR_QUERY_ARGS, CustomHeaderAuthProvider, DateArrayQueryField, DateQueryField, EntityStore, INFINITY_QUERY_TOKEN, InfinityQuery, InfinityQueryDirective, InfinityQueryTriggerDirective, LegacyQuery, LegacyQueryCreator, NumberArrayQueryField, ParseHttpErrorCodeToMessageDePipe, ParseHttpErrorCodeToMessageEnPipe, ParseHttpErrorCodeToTitleDePipe, ParseHttpErrorCodeToTitleEnPipe, QUERY_CLIENT_DEVTOOLS_TOKEN, QueryDevtoolsComponent, QueryDirective, QueryError, QueryFeatureType, QueryField, QueryForm, QueryRuntimeErrorCode, QueryShortNamePipe, QueryStore, SERVER_ERROR_KIND, SERVER_VIOLATION_ERROR_KIND, SPEED_BUFFER_TIME_IN_MS, SearchQueryField, SortQueryField, StringArrayQueryField, V2BearerAuthProvider, V2Query, V2QueryClient, V2QueryCreator, addQueryContainerHandling, applyQueryFeatures, authExtractTokensResponseMissingAccessToken, authExtractTokensResponseMissingRefreshToken, authExtractTokensResponseNotObject, authProviderFeatureUsedMultipleTimes, buildErrorMessage, buildQueryCacheKey, buildQueryString, buildRoute, buildTimestampFromSeconds, castQueryCreatorTypes, circularQueryDependency, circularQueryDependencyChecker, computeQueryAuthHeader, computeQueryBody, computeQueryHeaders, computeQueryMethod, computeQueryQueryParams, contentfulGqlLikePaginationAdapter, createBaseQuery, createBaseQueryCreator, createBearerAuthProvider, createDeleteQuery, createExecuteFn, createGetQuery, createGqlExecuteFn, createGqlMutationViaGet, createGqlMutationViaPost, createGqlQuery, createGqlQueryCreator, createGqlQueryViaGet, createGqlQueryViaPost, createHttpRequest, createInfinityQueryConfig, createLegacyQueryCreator, createPagedQueryStack, createPatchQuery, createPersistentAuthFeature, createPostQuery, createPutQuery, createQuery, createQueryClient, createQueryCollection, createQueryCollectionSignal, createQueryCollectionSubject, createQueryContext, createQueryCreator, createQueryErrorResponse, createQueryFeature, createQueryObject, createQueryRepository, createQuerySnapshotFn, createQueryStack, createSecureDeleteQuery, createSecureExecuteFactory, createSecureExecuteFn, createSecureGetQuery, createSecureGqlExecuteFn, createSecureGqlMutationViaGet, createSecureGqlMutationViaPost, createSecureGqlQuery, createSecureGqlQueryCreator, createSecureGqlQueryViaGet, createSecureGqlQueryViaPost, createSecurePatchQuery, createSecurePostQuery, createSecurePutQuery, createSecureQuery, createSecureQueryCreator, createTrackingFeature, createWebSocketClient, decryptBearer, deepFreeze, def, detectContentTypeHeader, dynLikePaginationAdapter, effectComputed, ethletePaginationAdapter, executeUntilSettled, extractExpiresInSeconds, extractFormViolations, extractQuery, fakePaginationAdapter, filterFailure, filterNull, filterQueryStates, filterSuccess, forEachHeader, getDefaultHeaders, getQueryFeatureUsage, getResponseUrl, ggLikePaginationAdapter, gql, gqlDataPropertyMissingInResponse, hasHeader, ignoreAutoRefresh, injectInfinityQueryResponseDelay, injectQueryContext, insertFrom, invalidBaseRouteError, invalidBodyError, invalidRouteError, invalidStateInsideSecureExecuteFactory, isAutoRefresh, isBasicAuthProvider, isBearerAuthProvider, isClassValidatorError, isCreateGqlQueryOptions, isCustomHeaderAuthProvider, isEmptyString, isGqlQueryConfig, isLegacyQuery, isNaN$1 as isNaN, isQuery, isQueryCollection, isQueryErrorResponse, isQueryStateCancelled, isQueryStateFailure, isQueryStateLoading, isQueryStatePrepared, isQueryStateSuccess, isRequestError, isSymfonyError, isSymfonyFormViolationListError, isSymfonyListError, isSymfonyPagerfantaOutOfRangeError, mapToPaginated, mapViolationsToFormErrors, maybeExecute, mergeHeaders, nestedEffect, pagedQueryStackNextPageCalledWithoutPreviousPage, pagedQueryStackPageBiggerThanTotalPages, pagedQueryStackPreviousPageCalledButAlreadyAtFirstPage, paginatedEntityValueUpdater, parseAllXhrResponseHeaders, parseHttpErrorCodeToMessageDe, parseHttpErrorCodeToMessageEn, parseHttpErrorCodeToTitleDe, parseHttpErrorCodeToTitleEn, pathParamsMissingInRouteFunctionError, provideInfinityQueryResponseDelay, provideQueryClientForDevtools, queryArrayComputed, queryComputed, queryComputedTillTruthy, queryExecute, queryFeatureUsedMultipleTimes, querySequence, querySequenceAlreadyRunning, queryStackTotalQueriesAndExpectedQueriesMismatch, queryStackWithArgsUsed, queryStackWithResponseUpdateUsed, queryStateAlreadyHasKeyError, queryStateCannotTransformError, queryStateDoesNotContainKeyError, queryStateErrorSignal, queryStateLoadingSignal, queryStateResponseSignal, queryStateSignal, removeFrom, request, resetExecuteState, resetPageOnError, serializeBody, setupQueryDependencies, setupQueryExecuteState, setupQueryState, shouldAutoExecuteGqlQuery, shouldAutoExecuteQuery, shouldCacheQuery, shouldRetryRequest, silenceMissingWithArgsFeatureErrorUsedButWithArgsPresent, skipPaginationPageParamCalculator, splitQueryConfig, switchQueryCollectionState, switchQueryState, takeUntilResponse, toQuerySignal, toQuerySubject, tokensNotAvailableInsideAuthAndExec, transformArrayResponse, transformExecStateToQueryState, transformGql, transformMethod, transformPaginatedResponse, transformToBoolean, transformToBooleanArray, transformToDate, transformToDateArray, transformToNumber, transformToNumberArray, transformToSort, transformToSortQueryParam, transformToString, transformToStringArray, uncacheableRequestHasAllowCacheParam, uncacheableRequestHasCacheKeyParam, v2BuildQueryCacheKey, v2ExtractExpiresInSeconds, v2ShouldCacheQuery, v2ShouldRetryRequest, validateWithQuery, validateWithV2Query, withArgs, withArgsQueryFeatureMissingButRouteIsFunction, withAuthenticationQuery, withAutoRefresh, withAutoRefreshUsedInManualQuery, withAutoRefreshUsedOnUnsupportedHttpMethod, withErrorHandling, withInactivityLogout, withLogging, withPersistentAuth, withPolling, withPollingUsedOnUnsupportedHttpMethod, withRefreshQuery, withResponseUpdate, withSuccessHandling, withTokenExpirationWarning, withTokenRevocation, withTracking, wrapAsObservableSignal };
|
|
8181
|
+
export { BasicAuthProvider, BearerAuthFeatureType, BooleanArrayQueryField, CLEAR_QUERY_ARGS, CustomHeaderAuthProvider, DateArrayQueryField, DateQueryField, EntityStore, INFINITY_QUERY_TOKEN, InfinityQuery, InfinityQueryDirective, InfinityQueryTriggerDirective, LegacyQuery, LegacyQueryCreator, NumberArrayQueryField, ParseHttpErrorCodeToMessageDePipe, ParseHttpErrorCodeToMessageEnPipe, ParseHttpErrorCodeToTitleDePipe, ParseHttpErrorCodeToTitleEnPipe, QUERY_CLIENT_DEVTOOLS_TOKEN, QueryDevtoolsComponent, QueryDirective, QueryError, QueryFeatureType, QueryField, QueryForm, QueryRuntimeErrorCode, QueryShortNamePipe, QueryStore, SERVER_ERROR_KIND, SERVER_VIOLATION_ERROR_KIND, SPEED_BUFFER_TIME_IN_MS, SearchQueryField, SortQueryField, StringArrayQueryField, V2BearerAuthProvider, V2Query, V2QueryClient, V2QueryCreator, addQueryContainerHandling, applyQueryFeatures, authExtractTokensResponseMissingAccessToken, authExtractTokensResponseMissingRefreshToken, authExtractTokensResponseNotObject, authProviderFeatureUsedMultipleTimes, buildErrorMessage, buildQueryCacheKey, buildQueryString, buildRoute, buildTimestampFromSeconds, castQueryCreatorTypes, circularQueryDependency, circularQueryDependencyChecker, computeQueryAuthHeader, computeQueryBody, computeQueryHeaders, computeQueryMethod, computeQueryQueryParams, consumeSuppressQueryStackDevtools, contentfulGqlLikePaginationAdapter, createBaseQuery, createBaseQueryCreator, createBearerAuthProvider, createDeleteQuery, createExecuteFn, createGetQuery, createGqlExecuteFn, createGqlMutationViaGet, createGqlMutationViaPost, createGqlQuery, createGqlQueryCreator, createGqlQueryViaGet, createGqlQueryViaPost, createHttpRequest, createInfinityQueryConfig, createLegacyQueryCreator, createPagedQueryStack, createPatchQuery, createPersistentAuthFeature, createPostQuery, createPutQuery, createQuery, createQueryClient, createQueryCollection, createQueryCollectionSignal, createQueryCollectionSubject, createQueryContext, createQueryCreator, createQueryErrorResponse, createQueryFeature, createQueryObject, createQueryRepository, createQuerySnapshotFn, createQueryStack, createSecureDeleteQuery, createSecureExecuteFactory, createSecureExecuteFn, createSecureGetQuery, createSecureGqlExecuteFn, createSecureGqlMutationViaGet, createSecureGqlMutationViaPost, createSecureGqlQuery, createSecureGqlQueryCreator, createSecureGqlQueryViaGet, createSecureGqlQueryViaPost, createSecurePatchQuery, createSecurePostQuery, createSecurePutQuery, createSecureQuery, createSecureQueryCreator, createTrackingFeature, createWebSocketClient, decryptBearer, deepFreeze, def, detectContentTypeHeader, dynLikePaginationAdapter, effectComputed, ethletePaginationAdapter, executeUntilSettled, extractExpiresInSeconds, extractFormViolations, extractQuery, fakePaginationAdapter, filterFailure, filterNull, filterQueryStates, filterSuccess, forEachHeader, getDefaultHeaders, getQueryClientName, getQueryFeatureUsage, getResponseUrl, ggLikePaginationAdapter, gql, gqlDataPropertyMissingInResponse, hasHeader, ignoreAutoRefresh, injectInfinityQueryResponseDelay, injectQueryContext, insertFrom, invalidBaseRouteError, invalidBodyError, invalidRouteError, invalidStateInsideSecureExecuteFactory, isAutoRefresh, isBasicAuthProvider, isBearerAuthProvider, isClassValidatorError, isCreateGqlQueryOptions, isCustomHeaderAuthProvider, isEmptyString, isGqlQueryConfig, isLegacyQuery, isNaN$1 as isNaN, isQuery, isQueryCollection, isQueryDevtoolsEnabled, isQueryErrorResponse, isQueryStateCancelled, isQueryStateFailure, isQueryStateLoading, isQueryStatePrepared, isQueryStateSuccess, isRequestError, isSymfonyError, isSymfonyFormViolationListError, isSymfonyListError, isSymfonyPagerfantaOutOfRangeError, mapToPaginated, mapViolationsToFormErrors, maybeExecute, mergeHeaders, nestedEffect, pagedQueryStackNextPageCalledWithoutPreviousPage, pagedQueryStackPageBiggerThanTotalPages, pagedQueryStackPreviousPageCalledButAlreadyAtFirstPage, paginatedEntityValueUpdater, parseAllXhrResponseHeaders, parseHttpErrorCodeToMessageDe, parseHttpErrorCodeToMessageEn, parseHttpErrorCodeToTitleDe, parseHttpErrorCodeToTitleEn, pathParamsMissingInRouteFunctionError, provideInfinityQueryResponseDelay, provideQueryClientForDevtools, provideQueryDevtools, queryArrayComputed, queryComputed, queryComputedTillTruthy, queryDevtoolsEntries, queryExecute, queryFeatureUsedMultipleTimes, querySequence, querySequenceAlreadyRunning, queryStackTotalQueriesAndExpectedQueriesMismatch, queryStackWithArgsUsed, queryStackWithResponseUpdateUsed, queryStateAlreadyHasKeyError, queryStateCannotTransformError, queryStateDoesNotContainKeyError, queryStateErrorSignal, queryStateLoadingSignal, queryStateResponseSignal, queryStateSignal, registerQueryDevtoolsEntry, removeFrom, request, resetExecuteState, resetPageOnError, serializeBody, setupQueryDependencies, setupQueryExecuteState, setupQueryState, shouldAutoExecuteGqlQuery, shouldAutoExecuteQuery, shouldCacheQuery, shouldRetryRequest, silenceMissingWithArgsFeatureErrorUsedButWithArgsPresent, skipPaginationPageParamCalculator, splitQueryConfig, stringifyQueryRoute, suppressNextQueryStackDevtools, switchQueryCollectionState, switchQueryState, takeUntilResponse, toQuerySignal, toQuerySubject, tokensNotAvailableInsideAuthAndExec, transformArrayResponse, transformExecStateToQueryState, transformGql, transformMethod, transformPaginatedResponse, transformToBoolean, transformToBooleanArray, transformToDate, transformToDateArray, transformToNumber, transformToNumberArray, transformToSort, transformToSortQueryParam, transformToString, transformToStringArray, uncacheableRequestHasAllowCacheParam, uncacheableRequestHasCacheKeyParam, v2BuildQueryCacheKey, v2ExtractExpiresInSeconds, v2ShouldCacheQuery, v2ShouldRetryRequest, validateWithQuery, validateWithV2Query, withArgs, withArgsQueryFeatureMissingButRouteIsFunction, withAuthenticationQuery, withAutoRefresh, withAutoRefreshUsedInManualQuery, withAutoRefreshUsedOnUnsupportedHttpMethod, withErrorHandling, withInactivityLogout, withLogging, withPersistentAuth, withPolling, withPollingUsedOnUnsupportedHttpMethod, withRefreshQuery, withResponseUpdate, withSuccessHandling, withTokenExpirationWarning, withTokenRevocation, withTracking, wrapAsObservableSignal };
|
|
7901
8182
|
//# sourceMappingURL=ethlete-query.mjs.map
|