@ethlete/query 6.0.0-next.0 → 6.0.0-next.10
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 +93 -0
- package/fesm2022/ethlete-query.mjs +283 -171
- package/fesm2022/ethlete-query.mjs.map +1 -1
- package/generators/migrate-to-query-v3/cleanup-migration.js +242 -0
- package/generators/migrate-to-query-v3/legacy-prepare-migration.js +773 -0
- package/generators/migrate-to-query-v3/legacy-query-creator-migration.js +589 -0
- package/generators/migrate-to-query-v3/migration.js +16 -2928
- package/generators/migrate-to-query-v3/query-client-migration.js +477 -0
- package/generators/migrate-to-query-v3/report.js +136 -0
- package/generators/migrate-to-query-v3/shared.js +97 -0
- package/package.json +12 -11
- package/types/ethlete-query.d.ts +42 -8
|
@@ -3,7 +3,7 @@ import { isDevMode, DestroyRef, InjectionToken, inject, Injector, EnvironmentInj
|
|
|
3
3
|
import { createStaticProvider, RuntimeError, clamp, createDestroy, computedTillTruthy, getCookie, setCookie, deleteCookie, createProvider, nextFrame, createRootProvider, isObject, injectRoute, getDomain, injectQueryParamChanges, injectQueryParams, clone, equal, ET_PROPERTY_REMOVED, previousSignalValue } from '@ethlete/core';
|
|
4
4
|
import { Observable, Subscription, tap, retry, throwError, timer, catchError, takeUntil, startWith, pairwise, switchMap, of, BehaviorSubject, Subject, fromEvent, take, filter, ReplaySubject, map, shareReplay, interval, skip, takeWhile, combineLatest, EMPTY, withLatestFrom, debounceTime, merge, throttleTime } from 'rxjs';
|
|
5
5
|
import { toObservable, takeUntilDestroyed, toSignal } from '@angular/core/rxjs-interop';
|
|
6
|
-
import { HttpClient,
|
|
6
|
+
import { HttpClient, HttpEventType, HttpErrorResponse, HttpHeaders, HttpStatusCode } from '@angular/common/http';
|
|
7
7
|
import { getActiveConsumer, setActiveConsumer } from '@angular/core/primitives/signals';
|
|
8
8
|
import { NgClass, AsyncPipe, JsonPipe } from '@angular/common';
|
|
9
9
|
import * as i1 from '@angular/forms';
|
|
@@ -307,7 +307,7 @@ const withArgs = (args) => {
|
|
|
307
307
|
return createQueryFeature({
|
|
308
308
|
type: QueryFeatureType.WITH_ARGS,
|
|
309
309
|
fn: (context) => {
|
|
310
|
-
const currArgs = computed(() => args(), ...(ngDevMode ? [{ debugName: "currArgs" }] : []));
|
|
310
|
+
const currArgs = computed(() => args(), ...(ngDevMode ? [{ debugName: "currArgs" }] : /* istanbul ignore next */ []));
|
|
311
311
|
nestedEffect(() => {
|
|
312
312
|
const currArgsNow = currArgs();
|
|
313
313
|
if (currArgsNow === null)
|
|
@@ -399,11 +399,11 @@ const withSuccessHandling = (options) => {
|
|
|
399
399
|
type: QueryFeatureType.WITH_SUCCESS_HANDLING,
|
|
400
400
|
fn: (context) => {
|
|
401
401
|
nestedEffect(() => {
|
|
402
|
-
const
|
|
403
|
-
if (
|
|
402
|
+
const event = context.state.latestHttpEvent();
|
|
403
|
+
if (!event || event.type !== HttpEventType.Response)
|
|
404
404
|
return;
|
|
405
405
|
untracked(() => {
|
|
406
|
-
options.handler(response);
|
|
406
|
+
options.handler(context.state.response());
|
|
407
407
|
});
|
|
408
408
|
}, { injector: context.deps.injector });
|
|
409
409
|
},
|
|
@@ -458,20 +458,20 @@ const withResponseUpdate = (options) => {
|
|
|
458
458
|
};
|
|
459
459
|
|
|
460
460
|
const setupQueryState = (options) => {
|
|
461
|
-
const request = signal(null, ...(ngDevMode ? [{ debugName: "request" }] : []));
|
|
462
|
-
const rawResponse = linkedSignal(() => request()?.response() ?? null, ...(ngDevMode ? [{ debugName: "rawResponse" }] : []));
|
|
461
|
+
const request = signal(null, ...(ngDevMode ? [{ debugName: "request" }] : /* istanbul ignore next */ []));
|
|
462
|
+
const rawResponse = linkedSignal(() => request()?.response() ?? null, ...(ngDevMode ? [{ debugName: "rawResponse" }] : /* istanbul ignore next */ []));
|
|
463
463
|
const response = computed(() => {
|
|
464
464
|
const raw = rawResponse();
|
|
465
465
|
if (raw === null)
|
|
466
466
|
return null;
|
|
467
467
|
return options.transformResponse ? options.transformResponse(raw) : raw;
|
|
468
|
-
}, ...(ngDevMode ? [{ debugName: "response" }] : []));
|
|
469
|
-
const loading = linkedSignal(() => request()?.loading() ?? null, ...(ngDevMode ? [{ debugName: "loading" }] : []));
|
|
470
|
-
const error = linkedSignal(() => request()?.error() ?? null, ...(ngDevMode ? [{ debugName: "error" }] : []));
|
|
471
|
-
const latestHttpEvent = linkedSignal(() => request()?.currentEvent() ?? null, ...(ngDevMode ? [{ debugName: "latestHttpEvent" }] : []));
|
|
472
|
-
const args = signal(null, ...(ngDevMode ? [{ debugName: "args" }] : []));
|
|
473
|
-
const lastTimeExecutedAt = signal(null, ...(ngDevMode ? [{ debugName: "lastTimeExecutedAt" }] : []));
|
|
474
|
-
const lastTriggeredBy = signal(null, ...(ngDevMode ? [{ debugName: "lastTriggeredBy" }] : []));
|
|
468
|
+
}, ...(ngDevMode ? [{ debugName: "response" }] : /* istanbul ignore next */ []));
|
|
469
|
+
const loading = linkedSignal(() => request()?.loading() ?? null, ...(ngDevMode ? [{ debugName: "loading" }] : /* istanbul ignore next */ []));
|
|
470
|
+
const error = linkedSignal(() => request()?.error() ?? null, ...(ngDevMode ? [{ debugName: "error" }] : /* istanbul ignore next */ []));
|
|
471
|
+
const latestHttpEvent = linkedSignal(() => request()?.currentEvent() ?? null, ...(ngDevMode ? [{ debugName: "latestHttpEvent" }] : /* istanbul ignore next */ []));
|
|
472
|
+
const args = signal(null, ...(ngDevMode ? [{ debugName: "args" }] : /* istanbul ignore next */ []));
|
|
473
|
+
const lastTimeExecutedAt = signal(null, ...(ngDevMode ? [{ debugName: "lastTimeExecutedAt" }] : /* istanbul ignore next */ []));
|
|
474
|
+
const lastTriggeredBy = signal(null, ...(ngDevMode ? [{ debugName: "lastTriggeredBy" }] : /* istanbul ignore next */ []));
|
|
475
475
|
const executionState = computed(() => {
|
|
476
476
|
const currentResponse = response();
|
|
477
477
|
const currentError = error();
|
|
@@ -506,7 +506,7 @@ const setupQueryState = (options) => {
|
|
|
506
506
|
else {
|
|
507
507
|
return null;
|
|
508
508
|
}
|
|
509
|
-
}, ...(ngDevMode ? [{ debugName: "executionState" }] : []));
|
|
509
|
+
}, ...(ngDevMode ? [{ debugName: "executionState" }] : /* istanbul ignore next */ []));
|
|
510
510
|
const state = {
|
|
511
511
|
rawResponse,
|
|
512
512
|
response,
|
|
@@ -530,7 +530,7 @@ const createQuerySnapshotFn = (options) => {
|
|
|
530
530
|
const context = injectQueryContext();
|
|
531
531
|
const snapshotFn = () => {
|
|
532
532
|
const snapshotState = setupQueryState({});
|
|
533
|
-
const isAlive = signal(true, ...(ngDevMode ? [{ debugName: "isAlive" }] : []));
|
|
533
|
+
const isAlive = signal(true, ...(ngDevMode ? [{ debugName: "isAlive" }] : /* istanbul ignore next */ []));
|
|
534
534
|
const killEffectRef = effect(() => {
|
|
535
535
|
const currentLoading = state.loading();
|
|
536
536
|
const currentError = state.error();
|
|
@@ -549,13 +549,14 @@ const createQuerySnapshotFn = (options) => {
|
|
|
549
549
|
snapshotState.rawResponse.set(currentResponse);
|
|
550
550
|
if (currentLoading)
|
|
551
551
|
return;
|
|
552
|
-
|
|
552
|
+
const hasCompletedResponse = currentLatestHttpEvent?.type === HttpEventType.Response;
|
|
553
|
+
if (!hasCompletedResponse && !currentError)
|
|
553
554
|
return;
|
|
554
555
|
// kill the effect once loading is done and we either have a response or an error
|
|
555
556
|
killEffectRef.destroy();
|
|
556
557
|
isAlive.set(false);
|
|
557
558
|
});
|
|
558
|
-
}, { ...(ngDevMode ? { debugName: "killEffectRef" } : {}), injector: context.deps.injector });
|
|
559
|
+
}, { ...(ngDevMode ? { debugName: "killEffectRef" } : /* istanbul ignore next */ {}), injector: context.deps.injector });
|
|
559
560
|
const snapshot = {
|
|
560
561
|
args: wrapAsObservableSignal(snapshotState.args.asReadonly(), context.deps.injector),
|
|
561
562
|
response: wrapAsObservableSignal(snapshotState.response, context.deps.injector),
|
|
@@ -1538,18 +1539,18 @@ const SPEED_BUFFER_TIME_IN_MS = 2000;
|
|
|
1538
1539
|
const createHttpRequest = (options) => {
|
|
1539
1540
|
let currentStreamSubscription = Subscription.EMPTY;
|
|
1540
1541
|
const { args, clientOptions, dependencies } = options;
|
|
1541
|
-
const currentEvent = signal(null, ...(ngDevMode ? [{ debugName: "currentEvent" }] : []));
|
|
1542
|
-
const loading = signal(null, ...(ngDevMode ? [{ debugName: "loading" }] : []));
|
|
1543
|
-
const error = signal(null, ...(ngDevMode ? [{ debugName: "error" }] : []));
|
|
1544
|
-
const response = signal(null, ...(ngDevMode ? [{ debugName: "response" }] : []));
|
|
1545
|
-
const lastLoadEventTime = signal(0, ...(ngDevMode ? [{ debugName: "lastLoadEventTime" }] : []));
|
|
1546
|
-
const lastLoadEventAmount = signal(0, ...(ngDevMode ? [{ debugName: "lastLoadEventAmount" }] : []));
|
|
1547
|
-
const lastExecuteTime = signal(0, ...(ngDevMode ? [{ debugName: "lastExecuteTime" }] : []));
|
|
1548
|
-
const expiresIn = signal(null, ...(ngDevMode ? [{ debugName: "expiresIn" }] : []));
|
|
1542
|
+
const currentEvent = signal(null, ...(ngDevMode ? [{ debugName: "currentEvent" }] : /* istanbul ignore next */ []));
|
|
1543
|
+
const loading = signal(null, ...(ngDevMode ? [{ debugName: "loading" }] : /* istanbul ignore next */ []));
|
|
1544
|
+
const error = signal(null, ...(ngDevMode ? [{ debugName: "error" }] : /* istanbul ignore next */ []));
|
|
1545
|
+
const response = signal(null, ...(ngDevMode ? [{ debugName: "response" }] : /* istanbul ignore next */ []));
|
|
1546
|
+
const lastLoadEventTime = signal(0, ...(ngDevMode ? [{ debugName: "lastLoadEventTime" }] : /* istanbul ignore next */ []));
|
|
1547
|
+
const lastLoadEventAmount = signal(0, ...(ngDevMode ? [{ debugName: "lastLoadEventAmount" }] : /* istanbul ignore next */ []));
|
|
1548
|
+
const lastExecuteTime = signal(0, ...(ngDevMode ? [{ debugName: "lastExecuteTime" }] : /* istanbul ignore next */ []));
|
|
1549
|
+
const expiresIn = signal(null, ...(ngDevMode ? [{ debugName: "expiresIn" }] : /* istanbul ignore next */ []));
|
|
1549
1550
|
const isStale = computed(() => {
|
|
1550
1551
|
const expiresInTs = expiresIn();
|
|
1551
1552
|
return expiresInTs === null || expiresInTs < Date.now();
|
|
1552
|
-
}, ...(ngDevMode ? [{ debugName: "isStale" }] : []));
|
|
1553
|
+
}, ...(ngDevMode ? [{ debugName: "isStale" }] : /* istanbul ignore next */ []));
|
|
1553
1554
|
const createStream = () => {
|
|
1554
1555
|
const headers = typeof args?.headers === 'function' ? args.headers() : args?.headers;
|
|
1555
1556
|
return dependencies.httpClient
|
|
@@ -1607,7 +1608,6 @@ const createHttpRequest = (options) => {
|
|
|
1607
1608
|
return true;
|
|
1608
1609
|
};
|
|
1609
1610
|
const updateState = (event) => {
|
|
1610
|
-
currentEvent.set(event);
|
|
1611
1611
|
switch (event.type) {
|
|
1612
1612
|
case HttpEventType.Response:
|
|
1613
1613
|
{
|
|
@@ -1634,6 +1634,7 @@ const createHttpRequest = (options) => {
|
|
|
1634
1634
|
}
|
|
1635
1635
|
break;
|
|
1636
1636
|
}
|
|
1637
|
+
currentEvent.set(event);
|
|
1637
1638
|
};
|
|
1638
1639
|
const updateErrorState = (errorResponse) => {
|
|
1639
1640
|
const errorRes = createQueryErrorResponse(errorResponse);
|
|
@@ -1696,9 +1697,9 @@ const createQueryStack = (options) => {
|
|
|
1696
1697
|
return { queries, lastQuery };
|
|
1697
1698
|
}, transform, argsKeyFn, deduplicateArgs, maxQueries = Infinity, removeStrategy = 'oldest', } = options ?? {};
|
|
1698
1699
|
const injector = inject(Injector);
|
|
1699
|
-
const queries = signal([], ...(ngDevMode ? [{ debugName: "queries" }] : []));
|
|
1700
|
-
const lastQuery = signal(null, ...(ngDevMode ? [{ debugName: "lastQuery" }] : []));
|
|
1701
|
-
const firstQuery = computed(() => queries()[0] ?? null, ...(ngDevMode ? [{ debugName: "firstQuery" }] : []));
|
|
1700
|
+
const queries = signal([], ...(ngDevMode ? [{ debugName: "queries" }] : /* istanbul ignore next */ []));
|
|
1701
|
+
const lastQuery = signal(null, ...(ngDevMode ? [{ debugName: "lastQuery" }] : /* istanbul ignore next */ []));
|
|
1702
|
+
const firstQuery = computed(() => queries()[0] ?? null, ...(ngDevMode ? [{ debugName: "firstQuery" }] : /* istanbul ignore next */ []));
|
|
1702
1703
|
const hasWithArgsFeature = features.some((f) => f.type == QueryFeatureType.WITH_ARGS);
|
|
1703
1704
|
const hasWithOptimisticUpdateFeature = features.some((f) => f.type == QueryFeatureType.WITH_RESPONSE_UPDATE);
|
|
1704
1705
|
if (hasWithArgsFeature) {
|
|
@@ -1780,23 +1781,23 @@ const createQueryStack = (options) => {
|
|
|
1780
1781
|
untracked(() => clear());
|
|
1781
1782
|
});
|
|
1782
1783
|
effect(() => runWithArgs(args(dependencies?.())));
|
|
1783
|
-
const anyLoading = computed(() => queries().some((q) => q.loading()), ...(ngDevMode ? [{ debugName: "anyLoading" }] : []));
|
|
1784
|
-
const loadingCount = computed(() => queries().filter((q) => q.loading()).length, ...(ngDevMode ? [{ debugName: "loadingCount" }] : []));
|
|
1784
|
+
const anyLoading = computed(() => queries().some((q) => q.loading()), ...(ngDevMode ? [{ debugName: "anyLoading" }] : /* istanbul ignore next */ []));
|
|
1785
|
+
const loadingCount = computed(() => queries().filter((q) => q.loading()).length, ...(ngDevMode ? [{ debugName: "loadingCount" }] : /* istanbul ignore next */ []));
|
|
1785
1786
|
const allLoading = computed(() => {
|
|
1786
1787
|
const qs = queries();
|
|
1787
1788
|
return qs.length > 0 && qs.every((q) => q.loading());
|
|
1788
|
-
}, ...(ngDevMode ? [{ debugName: "allLoading" }] : []));
|
|
1789
|
+
}, ...(ngDevMode ? [{ debugName: "allLoading" }] : /* istanbul ignore next */ []));
|
|
1789
1790
|
const loadingProgress = computed(() => {
|
|
1790
1791
|
const total = queries().length;
|
|
1791
1792
|
const loaded = queries().filter((q) => !q.loading()).length;
|
|
1792
1793
|
return { loaded, total };
|
|
1793
|
-
}, ...(ngDevMode ? [{ debugName: "loadingProgress" }] : []));
|
|
1794
|
+
}, ...(ngDevMode ? [{ debugName: "loadingProgress" }] : /* istanbul ignore next */ []));
|
|
1794
1795
|
const anyError = computed(() => queries()
|
|
1795
1796
|
.map((q) => q.error())
|
|
1796
|
-
.find((e) => e !== null) ?? null, ...(ngDevMode ? [{ debugName: "anyError" }] : []));
|
|
1797
|
+
.find((e) => e !== null) ?? null, ...(ngDevMode ? [{ debugName: "anyError" }] : /* istanbul ignore next */ []));
|
|
1797
1798
|
const errors = computed(() => queries()
|
|
1798
1799
|
.map((q) => q.error())
|
|
1799
|
-
.filter((e) => e !== null), ...(ngDevMode ? [{ debugName: "errors" }] : []));
|
|
1800
|
+
.filter((e) => e !== null), ...(ngDevMode ? [{ debugName: "errors" }] : /* istanbul ignore next */ []));
|
|
1800
1801
|
const response = computed(() => {
|
|
1801
1802
|
const responses = queries().map((q) => q.response());
|
|
1802
1803
|
return transform?.(responses) ?? responses;
|
|
@@ -1891,12 +1892,12 @@ const fakePaginationAdapter = (totalHits = 10) => {
|
|
|
1891
1892
|
};
|
|
1892
1893
|
const createPagedQueryStack = (options) => {
|
|
1893
1894
|
const { responseNormalizer, queryCreator, features } = options;
|
|
1894
|
-
const currentPageArgs = signal(null, ...(ngDevMode ? [{ debugName: "currentPageArgs" }] : []));
|
|
1895
|
-
const initialPage = signal(options.initialPage ?? 1, ...(ngDevMode ? [{ debugName: "initialPage" }] : []));
|
|
1896
|
-
const loadedMinPage = signal(initialPage(), ...(ngDevMode ? [{ debugName: "loadedMinPage" }] : []));
|
|
1897
|
-
const loadedMaxPage = signal(initialPage(), ...(ngDevMode ? [{ debugName: "loadedMaxPage" }] : []));
|
|
1898
|
-
const
|
|
1899
|
-
const pageDirection = signal('next', ...(ngDevMode ? [{ debugName: "pageDirection" }] : []));
|
|
1895
|
+
const currentPageArgs = signal(null, ...(ngDevMode ? [{ debugName: "currentPageArgs" }] : /* istanbul ignore next */ []));
|
|
1896
|
+
const initialPage = signal(options.initialPage ?? 1, ...(ngDevMode ? [{ debugName: "initialPage" }] : /* istanbul ignore next */ []));
|
|
1897
|
+
const loadedMinPage = signal(initialPage(), ...(ngDevMode ? [{ debugName: "loadedMinPage" }] : /* istanbul ignore next */ []));
|
|
1898
|
+
const loadedMaxPage = signal(initialPage(), ...(ngDevMode ? [{ debugName: "loadedMaxPage" }] : /* istanbul ignore next */ []));
|
|
1899
|
+
const resetTrigger = signal(0, ...(ngDevMode ? [{ debugName: "resetTrigger" }] : /* istanbul ignore next */ []));
|
|
1900
|
+
const pageDirection = signal('next', ...(ngDevMode ? [{ debugName: "pageDirection" }] : /* istanbul ignore next */ []));
|
|
1900
1901
|
const stack = createQueryStack({
|
|
1901
1902
|
args: () => null,
|
|
1902
1903
|
queryCreator,
|
|
@@ -1919,7 +1920,7 @@ const createPagedQueryStack = (options) => {
|
|
|
1919
1920
|
transform: transformArrayResponse,
|
|
1920
1921
|
});
|
|
1921
1922
|
effect(() => {
|
|
1922
|
-
|
|
1923
|
+
resetTrigger();
|
|
1923
1924
|
const args = options.args(initialPage(), []);
|
|
1924
1925
|
untracked(() => {
|
|
1925
1926
|
stack.clear();
|
|
@@ -1935,22 +1936,22 @@ const createPagedQueryStack = (options) => {
|
|
|
1935
1936
|
if (!res)
|
|
1936
1937
|
return null;
|
|
1937
1938
|
return responseNormalizer(res, all);
|
|
1938
|
-
}, ...(ngDevMode ? [{ debugName: "maxPagination" }] : []));
|
|
1939
|
+
}, ...(ngDevMode ? [{ debugName: "maxPagination" }] : /* istanbul ignore next */ []));
|
|
1939
1940
|
const minPagination = computed(() => {
|
|
1940
1941
|
const res = stack.firstQuery()?.response();
|
|
1941
1942
|
const all = stack.response();
|
|
1942
1943
|
if (!res)
|
|
1943
1944
|
return null;
|
|
1944
1945
|
return responseNormalizer(res, all);
|
|
1945
|
-
}, ...(ngDevMode ? [{ debugName: "minPagination" }] : []));
|
|
1946
|
+
}, ...(ngDevMode ? [{ debugName: "minPagination" }] : /* istanbul ignore next */ []));
|
|
1946
1947
|
const isFirstPageLoaded = computed(() => {
|
|
1947
1948
|
const min = minPagination();
|
|
1948
1949
|
return min ? loadedMinPage() === min.currentPage : false;
|
|
1949
|
-
}, ...(ngDevMode ? [{ debugName: "isFirstPageLoaded" }] : []));
|
|
1950
|
+
}, ...(ngDevMode ? [{ debugName: "isFirstPageLoaded" }] : /* istanbul ignore next */ []));
|
|
1950
1951
|
const isLastPageLoaded = computed(() => {
|
|
1951
1952
|
const max = maxPagination();
|
|
1952
1953
|
return max ? loadedMaxPage() === max.totalPages : false;
|
|
1953
|
-
}, ...(ngDevMode ? [{ debugName: "isLastPageLoaded" }] : []));
|
|
1954
|
+
}, ...(ngDevMode ? [{ debugName: "isLastPageLoaded" }] : /* istanbul ignore next */ []));
|
|
1954
1955
|
const fetchPreviousPage = () => {
|
|
1955
1956
|
const page = loadedMinPage() - 1;
|
|
1956
1957
|
const allResponses = stack.response();
|
|
@@ -2019,25 +2020,25 @@ const createPagedQueryStack = (options) => {
|
|
|
2019
2020
|
const page = resetOptions?.initialPage ?? initialPage();
|
|
2020
2021
|
initialPage.set(page);
|
|
2021
2022
|
pageDirection.set('next');
|
|
2022
|
-
|
|
2023
|
+
resetTrigger.update((v) => v + 1);
|
|
2023
2024
|
};
|
|
2024
2025
|
const canFetchPreviousPage = computed(() => {
|
|
2025
2026
|
const currentMinPagination = minPagination();
|
|
2026
2027
|
if (!currentMinPagination)
|
|
2027
2028
|
return false;
|
|
2028
2029
|
return loadedMinPage() > 1;
|
|
2029
|
-
}, ...(ngDevMode ? [{ debugName: "canFetchPreviousPage" }] : []));
|
|
2030
|
+
}, ...(ngDevMode ? [{ debugName: "canFetchPreviousPage" }] : /* istanbul ignore next */ []));
|
|
2030
2031
|
const canFetchNextPage = computed(() => {
|
|
2031
2032
|
const currentMaxPagination = maxPagination();
|
|
2032
2033
|
return currentMaxPagination ? loadedMaxPage() < currentMaxPagination.totalPages : false;
|
|
2033
|
-
}, ...(ngDevMode ? [{ debugName: "canFetchNextPage" }] : []));
|
|
2034
|
+
}, ...(ngDevMode ? [{ debugName: "canFetchNextPage" }] : /* istanbul ignore next */ []));
|
|
2034
2035
|
const items = computed(() => {
|
|
2035
2036
|
const res = stack.response();
|
|
2036
2037
|
return res.map((r) => responseNormalizer(r, res).items).flat();
|
|
2037
|
-
}, ...(ngDevMode ? [{ debugName: "items" }] : []));
|
|
2038
|
+
}, ...(ngDevMode ? [{ debugName: "items" }] : /* istanbul ignore next */ []));
|
|
2038
2039
|
const isFirstLoad = computed(() => {
|
|
2039
2040
|
return stack.queries().length === 1 && !!stack.lastQuery()?.loading();
|
|
2040
|
-
}, ...(ngDevMode ? [{ debugName: "isFirstLoad" }] : []));
|
|
2041
|
+
}, ...(ngDevMode ? [{ debugName: "isFirstLoad" }] : /* istanbul ignore next */ []));
|
|
2041
2042
|
const execute = (options) => {
|
|
2042
2043
|
const whereFn = options?.where;
|
|
2043
2044
|
if (whereFn) {
|
|
@@ -2210,7 +2211,7 @@ function effectComputed(computation, injector) {
|
|
|
2210
2211
|
// Ignore errors in the initial computation
|
|
2211
2212
|
// Angular might throw an error if required inputs are read but not available yet
|
|
2212
2213
|
}
|
|
2213
|
-
const lastResult = signal(initialData, ...(ngDevMode ? [{ debugName: "lastResult" }] : []));
|
|
2214
|
+
const lastResult = signal(initialData, ...(ngDevMode ? [{ debugName: "lastResult" }] : /* istanbul ignore next */ []));
|
|
2214
2215
|
effect(() => {
|
|
2215
2216
|
const data = runInInjectionContext(injector, () => computation());
|
|
2216
2217
|
untracked(() => {
|
|
@@ -2261,7 +2262,7 @@ function queryStateSignal(source, options) {
|
|
|
2261
2262
|
})), {
|
|
2262
2263
|
initialValue: null,
|
|
2263
2264
|
});
|
|
2264
|
-
const rwSignal = linkedSignal(roSignal, ...(ngDevMode ? [{ debugName: "rwSignal" }] : []));
|
|
2265
|
+
const rwSignal = linkedSignal(roSignal, ...(ngDevMode ? [{ debugName: "rwSignal" }] : /* istanbul ignore next */ []));
|
|
2265
2266
|
return rwSignal;
|
|
2266
2267
|
}
|
|
2267
2268
|
function queryStateResponseSignal(source, options) {
|
|
@@ -2269,7 +2270,7 @@ function queryStateResponseSignal(source, options) {
|
|
|
2269
2270
|
const dataSignal = computed(() => {
|
|
2270
2271
|
const state = s();
|
|
2271
2272
|
return isQueryStateSuccess(state) ? state.response : null;
|
|
2272
|
-
}, ...(ngDevMode ? [{ debugName: "dataSignal" }] : []));
|
|
2273
|
+
}, ...(ngDevMode ? [{ debugName: "dataSignal" }] : /* istanbul ignore next */ []));
|
|
2273
2274
|
dataSignal['reset'] = () => {
|
|
2274
2275
|
s.set(null);
|
|
2275
2276
|
};
|
|
@@ -2352,7 +2353,7 @@ class V2QueryCreator {
|
|
|
2352
2353
|
};
|
|
2353
2354
|
this.createSignal = (initialValue, config) => {
|
|
2354
2355
|
assertInInjectionContext(this.createSignal);
|
|
2355
|
-
const _signal = signal(initialValue ?? null, ...(ngDevMode ? [{ debugName: "_signal" }] : []));
|
|
2356
|
+
const _signal = signal(initialValue ?? null, ...(ngDevMode ? [{ debugName: "_signal" }] : /* istanbul ignore next */ []));
|
|
2356
2357
|
addQueryContainerHandling(toObservable(_signal), () => _signal(), config);
|
|
2357
2358
|
return _signal;
|
|
2358
2359
|
};
|
|
@@ -2959,7 +2960,7 @@ class LegacyQuery {
|
|
|
2959
2960
|
});
|
|
2960
2961
|
}
|
|
2961
2962
|
});
|
|
2962
|
-
}, ...(ngDevMode ? [{ debugName: "storeSyncEffect" }] : []));
|
|
2963
|
+
}, ...(ngDevMode ? [{ debugName: "storeSyncEffect" }] : /* istanbul ignore next */ []));
|
|
2963
2964
|
/**
|
|
2964
2965
|
* @internal
|
|
2965
2966
|
*/
|
|
@@ -3112,7 +3113,7 @@ class LegacyQueryCreator {
|
|
|
3112
3113
|
legacyQuery.destroy();
|
|
3113
3114
|
destroyEffect.destroy();
|
|
3114
3115
|
}
|
|
3115
|
-
}, ...(ngDevMode ? [{ debugName: "destroyEffect" }] : []));
|
|
3116
|
+
}, ...(ngDevMode ? [{ debugName: "destroyEffect" }] : /* istanbul ignore next */ []));
|
|
3116
3117
|
}
|
|
3117
3118
|
return legacyQuery;
|
|
3118
3119
|
});
|
|
@@ -3124,7 +3125,7 @@ class LegacyQueryCreator {
|
|
|
3124
3125
|
return subject;
|
|
3125
3126
|
};
|
|
3126
3127
|
this.createSignal = (initialValue, config) => {
|
|
3127
|
-
const _signal = signal(initialValue ?? null, ...(ngDevMode ? [{ debugName: "_signal" }] : []));
|
|
3128
|
+
const _signal = signal(initialValue ?? null, ...(ngDevMode ? [{ debugName: "_signal" }] : /* istanbul ignore next */ []));
|
|
3128
3129
|
addQueryContainerHandling(toObservable(_signal), () => _signal(), config);
|
|
3129
3130
|
return _signal;
|
|
3130
3131
|
};
|
|
@@ -3271,7 +3272,7 @@ const createQueryCollectionSubject = (queryMap, config) => {
|
|
|
3271
3272
|
};
|
|
3272
3273
|
const createQueryCollectionSignal = (queryMap, config) => {
|
|
3273
3274
|
assertInInjectionContext(createQueryCollectionSignal);
|
|
3274
|
-
const _signal = signal(null, ...(ngDevMode ? [{ debugName: "_signal" }] : []));
|
|
3275
|
+
const _signal = signal(null, ...(ngDevMode ? [{ debugName: "_signal" }] : /* istanbul ignore next */ []));
|
|
3275
3276
|
addQueryContainerHandling(toObservable(_signal).pipe(map((s) => s?.query ?? null)), () => _signal()?.query ?? null, config);
|
|
3276
3277
|
return _signal;
|
|
3277
3278
|
};
|
|
@@ -4005,7 +4006,7 @@ class V2BearerAuthProvider {
|
|
|
4005
4006
|
}
|
|
4006
4007
|
|
|
4007
4008
|
const [provideInfinityQueryResponseDelay, injectInfinityQueryResponseDelay] = createProvider(() => {
|
|
4008
|
-
const enabled = signal(false, ...(ngDevMode ? [{ debugName: "enabled" }] : []));
|
|
4009
|
+
const enabled = signal(false, ...(ngDevMode ? [{ debugName: "enabled" }] : /* istanbul ignore next */ []));
|
|
4009
4010
|
const enabled$ = toObservable(enabled);
|
|
4010
4011
|
return {
|
|
4011
4012
|
enabled,
|
|
@@ -4316,13 +4317,13 @@ class InfinityQueryDirective {
|
|
|
4316
4317
|
this._viewContext.currentQuery = null;
|
|
4317
4318
|
this._data$.next([]);
|
|
4318
4319
|
}
|
|
4319
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
4320
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.
|
|
4320
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: InfinityQueryDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
4321
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.13", type: InfinityQueryDirective, isStandalone: true, selector: "[etInfinityQuery]", inputs: { infinityQuery: ["etInfinityQuery", "infinityQuery"] }, providers: [
|
|
4321
4322
|
{ provide: INFINITY_QUERY_TOKEN, useExisting: InfinityQueryDirective },
|
|
4322
4323
|
provideInfinityQueryResponseDelay(),
|
|
4323
4324
|
], exportAs: ["etInfinityQuery"], ngImport: i0 }); }
|
|
4324
4325
|
}
|
|
4325
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
4326
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: InfinityQueryDirective, decorators: [{
|
|
4326
4327
|
type: Directive,
|
|
4327
4328
|
args: [{
|
|
4328
4329
|
selector: '[etInfinityQuery]',
|
|
@@ -4344,10 +4345,10 @@ class InfinityQueryTriggerDirective {
|
|
|
4344
4345
|
this._destroy = new Subject();
|
|
4345
4346
|
this._observer = null;
|
|
4346
4347
|
this.click$ = fromEvent(this._elementRef.nativeElement, 'click');
|
|
4347
|
-
this.scrollContainerSelector = input(null, ...(ngDevMode ? [{ debugName: "scrollContainerSelector" }] : []));
|
|
4348
|
+
this.scrollContainerSelector = input(null, ...(ngDevMode ? [{ debugName: "scrollContainerSelector" }] : /* istanbul ignore next */ []));
|
|
4348
4349
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
4349
|
-
this.infinityQueryOverride = input(null, ...(ngDevMode ? [{ debugName: "infinityQueryOverride" }] : []));
|
|
4350
|
-
this.infinityQuery = computed(() => this.infinityQueryOverride() ?? this._infinityQuery, ...(ngDevMode ? [{ debugName: "infinityQuery" }] : []));
|
|
4350
|
+
this.infinityQueryOverride = input(null, ...(ngDevMode ? [{ debugName: "infinityQueryOverride" }] : /* istanbul ignore next */ []));
|
|
4351
|
+
this.infinityQuery = computed(() => this.infinityQueryOverride() ?? this._infinityQuery, ...(ngDevMode ? [{ debugName: "infinityQuery" }] : /* istanbul ignore next */ []));
|
|
4351
4352
|
}
|
|
4352
4353
|
ngOnInit() {
|
|
4353
4354
|
const isInteractive = this._elementRef.nativeElement.tagName === 'BUTTON';
|
|
@@ -4379,10 +4380,10 @@ class InfinityQueryTriggerDirective {
|
|
|
4379
4380
|
});
|
|
4380
4381
|
this._observer.observe(this._elementRef.nativeElement);
|
|
4381
4382
|
}
|
|
4382
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
4383
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.
|
|
4383
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: InfinityQueryTriggerDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
4384
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.13", type: InfinityQueryTriggerDirective, isStandalone: true, selector: "[etInfinityQueryTrigger], et-infinity-query-trigger", inputs: { scrollContainerSelector: { classPropertyName: "scrollContainerSelector", publicName: "scrollContainerSelector", isSignal: true, isRequired: false, transformFunction: null }, infinityQueryOverride: { classPropertyName: "infinityQueryOverride", publicName: "infinityQueryOverride", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0 }); }
|
|
4384
4385
|
}
|
|
4385
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
4386
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: InfinityQueryTriggerDirective, decorators: [{
|
|
4386
4387
|
type: Directive,
|
|
4387
4388
|
args: [{
|
|
4388
4389
|
selector: '[etInfinityQueryTrigger], et-infinity-query-trigger',
|
|
@@ -4406,8 +4407,8 @@ class QueryDirective {
|
|
|
4406
4407
|
scope: null,
|
|
4407
4408
|
query: null,
|
|
4408
4409
|
};
|
|
4409
|
-
this.query = input.required({ ...(ngDevMode ? { debugName: "query" } : {}), alias: 'etQuery' });
|
|
4410
|
-
this.cache = input(false, { ...(ngDevMode ? { debugName: "cache" } : {}), alias: 'etQueryCache' });
|
|
4410
|
+
this.query = input.required({ ...(ngDevMode ? { debugName: "query" } : /* istanbul ignore next */ {}), alias: 'etQuery' });
|
|
4411
|
+
this.cache = input(false, { ...(ngDevMode ? { debugName: "cache" } : /* istanbul ignore next */ {}), alias: 'etQueryCache' });
|
|
4411
4412
|
this.queryState = queryStateSignal(this.query);
|
|
4412
4413
|
inject(ViewContainerRef).createEmbeddedView(inject(TemplateRef), this._viewContext);
|
|
4413
4414
|
effect(() => {
|
|
@@ -4468,10 +4469,10 @@ class QueryDirective {
|
|
|
4468
4469
|
});
|
|
4469
4470
|
});
|
|
4470
4471
|
}
|
|
4471
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
4472
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.
|
|
4472
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: QueryDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
4473
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.13", type: QueryDirective, isStandalone: true, selector: "[etQuery]", inputs: { query: { classPropertyName: "query", publicName: "etQuery", isSignal: true, isRequired: true, transformFunction: null }, cache: { classPropertyName: "cache", publicName: "etQueryCache", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0 }); }
|
|
4473
4474
|
}
|
|
4474
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
4475
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: QueryDirective, decorators: [{
|
|
4475
4476
|
type: Directive,
|
|
4476
4477
|
args: [{
|
|
4477
4478
|
selector: '[etQuery]',
|
|
@@ -4492,10 +4493,10 @@ class QueryShortNamePipe {
|
|
|
4492
4493
|
}
|
|
4493
4494
|
return route;
|
|
4494
4495
|
}
|
|
4495
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
4496
|
-
static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.2.
|
|
4496
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: QueryShortNamePipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
|
|
4497
|
+
static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.2.13", ngImport: i0, type: QueryShortNamePipe, isStandalone: true, name: "queryShortName" }); }
|
|
4497
4498
|
}
|
|
4498
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
4499
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: QueryShortNamePipe, decorators: [{
|
|
4499
4500
|
type: Pipe,
|
|
4500
4501
|
args: [{ name: 'queryShortName' }]
|
|
4501
4502
|
}] });
|
|
@@ -4517,19 +4518,19 @@ class QueryDevtoolsComponent {
|
|
|
4517
4518
|
this._cdr = inject(ChangeDetectorRef);
|
|
4518
4519
|
this._destroy$ = createDestroy();
|
|
4519
4520
|
this.queryClientConfigs = inject(QUERY_CLIENT_DEVTOOLS_TOKEN);
|
|
4520
|
-
this.isOpen = signal(false, ...(ngDevMode ? [{ debugName: "isOpen" }] : []));
|
|
4521
|
-
this.isTranslucent = signal(false, ...(ngDevMode ? [{ debugName: "isTranslucent" }] : []));
|
|
4522
|
-
this.snapLayout = signal('full', ...(ngDevMode ? [{ debugName: "snapLayout" }] : []));
|
|
4523
|
-
this.queryListMode = signal('live', ...(ngDevMode ? [{ debugName: "queryListMode" }] : []));
|
|
4524
|
-
this.viewMode = signal('query', ...(ngDevMode ? [{ debugName: "viewMode" }] : []));
|
|
4525
|
-
this.showResponse = signal(false, ...(ngDevMode ? [{ debugName: "showResponse" }] : []));
|
|
4526
|
-
this.showRawResponse = signal(false, ...(ngDevMode ? [{ debugName: "showRawResponse" }] : []));
|
|
4527
|
-
this.showQueryConfig = signal(false, ...(ngDevMode ? [{ debugName: "showQueryConfig" }] : []));
|
|
4528
|
-
this.showEntityStoreValue = signal(false, ...(ngDevMode ? [{ debugName: "showEntityStoreValue" }] : []));
|
|
4529
|
-
this.showArguments = signal(false, ...(ngDevMode ? [{ debugName: "showArguments" }] : []));
|
|
4521
|
+
this.isOpen = signal(false, ...(ngDevMode ? [{ debugName: "isOpen" }] : /* istanbul ignore next */ []));
|
|
4522
|
+
this.isTranslucent = signal(false, ...(ngDevMode ? [{ debugName: "isTranslucent" }] : /* istanbul ignore next */ []));
|
|
4523
|
+
this.snapLayout = signal('full', ...(ngDevMode ? [{ debugName: "snapLayout" }] : /* istanbul ignore next */ []));
|
|
4524
|
+
this.queryListMode = signal('live', ...(ngDevMode ? [{ debugName: "queryListMode" }] : /* istanbul ignore next */ []));
|
|
4525
|
+
this.viewMode = signal('query', ...(ngDevMode ? [{ debugName: "viewMode" }] : /* istanbul ignore next */ []));
|
|
4526
|
+
this.showResponse = signal(false, ...(ngDevMode ? [{ debugName: "showResponse" }] : /* istanbul ignore next */ []));
|
|
4527
|
+
this.showRawResponse = signal(false, ...(ngDevMode ? [{ debugName: "showRawResponse" }] : /* istanbul ignore next */ []));
|
|
4528
|
+
this.showQueryConfig = signal(false, ...(ngDevMode ? [{ debugName: "showQueryConfig" }] : /* istanbul ignore next */ []));
|
|
4529
|
+
this.showEntityStoreValue = signal(false, ...(ngDevMode ? [{ debugName: "showEntityStoreValue" }] : /* istanbul ignore next */ []));
|
|
4530
|
+
this.showArguments = signal(false, ...(ngDevMode ? [{ debugName: "showArguments" }] : /* istanbul ignore next */ []));
|
|
4530
4531
|
this.selectedClientIdCtrl = new FormControl(0);
|
|
4531
4532
|
this.selectedClientId = toSignal(this.selectedClientIdCtrl.valueChanges.pipe(startWith(this.selectedClientIdCtrl.value)));
|
|
4532
|
-
this.selectedQueryId = signal(null, ...(ngDevMode ? [{ debugName: "selectedQueryId" }] : []));
|
|
4533
|
+
this.selectedQueryId = signal(null, ...(ngDevMode ? [{ debugName: "selectedQueryId" }] : /* istanbul ignore next */ []));
|
|
4533
4534
|
this.selectedClientConfig = computed(() => {
|
|
4534
4535
|
if (this.queryClientConfigs.length === 1) {
|
|
4535
4536
|
return this.queryClientConfigs[0];
|
|
@@ -4540,11 +4541,11 @@ class QueryDevtoolsComponent {
|
|
|
4540
4541
|
return this.queryClientConfigs[0];
|
|
4541
4542
|
}
|
|
4542
4543
|
return cfg;
|
|
4543
|
-
}, ...(ngDevMode ? [{ debugName: "selectedClientConfig" }] : []));
|
|
4544
|
+
}, ...(ngDevMode ? [{ debugName: "selectedClientConfig" }] : /* istanbul ignore next */ []));
|
|
4544
4545
|
this.queryStore = computed(() => {
|
|
4545
4546
|
const config = this.selectedClientConfig();
|
|
4546
4547
|
return config.client._store;
|
|
4547
|
-
}, ...(ngDevMode ? [{ debugName: "queryStore" }] : []));
|
|
4548
|
+
}, ...(ngDevMode ? [{ debugName: "queryStore" }] : /* istanbul ignore next */ []));
|
|
4548
4549
|
this.queryStore$ = toObservable(this.queryStore);
|
|
4549
4550
|
this._queries$ = new BehaviorSubject([]);
|
|
4550
4551
|
this.queries = toSignal(this._queries$);
|
|
@@ -4558,14 +4559,14 @@ class QueryDevtoolsComponent {
|
|
|
4558
4559
|
return this.queries()?.find((q) => q._id === id) ?? null;
|
|
4559
4560
|
}
|
|
4560
4561
|
return this.queryHistory$.getValue()?.find((q) => q._id === id) ?? null;
|
|
4561
|
-
}, ...(ngDevMode ? [{ debugName: "selectedQuery" }] : []));
|
|
4562
|
+
}, ...(ngDevMode ? [{ debugName: "selectedQuery" }] : /* istanbul ignore next */ []));
|
|
4562
4563
|
this.selectedQuery$ = toObservable(this.selectedQuery);
|
|
4563
4564
|
this.selectedQueryEntityStore = computed(() => {
|
|
4564
4565
|
const query = this.selectedQuery();
|
|
4565
4566
|
if (!query)
|
|
4566
4567
|
return null;
|
|
4567
4568
|
return query.store;
|
|
4568
|
-
}, ...(ngDevMode ? [{ debugName: "selectedQueryEntityStore" }] : []));
|
|
4569
|
+
}, ...(ngDevMode ? [{ debugName: "selectedQueryEntityStore" }] : /* istanbul ignore next */ []));
|
|
4569
4570
|
this.selectedQueryEntityStore$ = toObservable(this.selectedQueryEntityStore);
|
|
4570
4571
|
this.selectedQueryEntityStoreValue$ = this.selectedQueryEntityStore$.pipe(switchMap((s) => s?._change$.pipe(startWith(''), map(() => {
|
|
4571
4572
|
if (!s._dictionary)
|
|
@@ -4603,7 +4604,7 @@ class QueryDevtoolsComponent {
|
|
|
4603
4604
|
return {
|
|
4604
4605
|
...sharedCfg,
|
|
4605
4606
|
};
|
|
4606
|
-
}, ...(ngDevMode ? [{ debugName: "stringifiedQueryConfig" }] : []));
|
|
4607
|
+
}, ...(ngDevMode ? [{ debugName: "stringifiedQueryConfig" }] : /* istanbul ignore next */ []));
|
|
4607
4608
|
this.authProvider = toSignal(toObservable(this.selectedClientConfig).pipe(switchMap((c) => c.client.authProvider$)));
|
|
4608
4609
|
this.authProviderDetails = computed(() => {
|
|
4609
4610
|
const provider = this.authProvider();
|
|
@@ -4665,7 +4666,7 @@ class QueryDevtoolsComponent {
|
|
|
4665
4666
|
config: {},
|
|
4666
4667
|
};
|
|
4667
4668
|
}
|
|
4668
|
-
}, ...(ngDevMode ? [{ debugName: "authProviderDetails" }] : []));
|
|
4669
|
+
}, ...(ngDevMode ? [{ debugName: "authProviderDetails" }] : /* istanbul ignore next */ []));
|
|
4669
4670
|
this.trackByClient = (_, { client }) => client.config.baseRoute;
|
|
4670
4671
|
this.trackByQuery = (_, { _id }) => _id;
|
|
4671
4672
|
this.selectedClientIdCtrl.valueChanges
|
|
@@ -4786,10 +4787,10 @@ class QueryDevtoolsComponent {
|
|
|
4786
4787
|
clearQueryHistory() {
|
|
4787
4788
|
this.queryHistory$.next([]);
|
|
4788
4789
|
}
|
|
4789
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
4790
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.1", type: QueryDevtoolsComponent, isStandalone: true, selector: "et-query-devtools", host: { classAttribute: "et-query-devtools" }, ngImport: i0, template: "@if (!isOpen()) {\n <button (click)=\"toggleOpen()\" class=\"et-query-devtools-open-btn et-qd-chip\">Query Devtools</button>\n}\n\n@if (isOpen()) {\n <div\n [class.et-query-devtools-container--transparent]=\"isTranslucent()\"\n class=\"et-query-devtools-container et-query-devtools-container--snap-{{ snapLayout() }}\"\n >\n <header class=\"et-qd-header\">\n <h3 class=\"et-qd-header__title\">Query Devtools</h3>\n\n <div class=\"et-qd-header__select\">\n <label for=\"et-query-client-instance\">Client instance</label>\n <select [formControl]=\"selectedClientIdCtrl\" id=\"et-query-client-instance\">\n @for (clientConfig of queryClientConfigs; track trackByClient(i, clientConfig); let i = $index) {\n <option [value]=\"i\">\n {{ clientConfig.displayName ?? clientConfig.client.config.baseRoute }}\n </option>\n }\n </select>\n </div>\n\n <button (click)=\"toggleOpen()\" class=\"et-qd-btn et-qd-btn-secondary\">Close</button>\n </header>\n\n <div class=\"et-qd-sub-header\">\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': !isTranslucent() }\"\n (click)=\"toggleTranslucent()\"\n class=\"et-qd-chip et-qd-translucent-clickable\"\n >\n Translucent\n </button>\n <div class=\"et-qd-sub-header__divider\"></div>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': snapLayout() !== 'full' }\"\n (click)=\"selectSnapLayout('full')\"\n class=\"et-qd-chip\"\n >\n Fullscreen\n </button>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': snapLayout() !== 'top' }\"\n (click)=\"selectSnapLayout('top')\"\n class=\"et-qd-chip\"\n >\n Top\n </button>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': snapLayout() !== 'bottom' }\"\n (click)=\"selectSnapLayout('bottom')\"\n class=\"et-qd-chip\"\n >\n Bottom\n </button>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': snapLayout() !== 'left' }\"\n (click)=\"selectSnapLayout('left')\"\n class=\"et-qd-chip\"\n >\n Left\n </button>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': snapLayout() !== 'right' }\"\n (click)=\"selectSnapLayout('right')\"\n class=\"et-qd-chip\"\n >\n Right\n </button>\n </div>\n\n @if (selectedClientConfig(); as cfg) {\n <div class=\"et-qd-client\">\n <p class=\"et-qd-client__title\">{{ cfg.displayName ?? cfg.client.config.baseRoute }}</p>\n\n <div class=\"et-qd-client__actions\">\n <button (click)=\"cfg.client._store.refreshQueriesInUse()\" class=\"et-qd-chip\">Refresh all</button>\n <button (click)=\"cfg.client._store.refreshQueriesInUse({ ignoreCacheValidity: true })\" class=\"et-qd-chip\">\n Refresh all (ignore caches)\n </button>\n <button\n (click)=\"cfg.client._store.refreshQueriesInUse({ ignoreCacheValidity: true, purgeUnused: true })\"\n class=\"et-qd-chip\"\n >\n Refresh all (ignore caches & purge unused)\n </button>\n </div>\n </div>\n }\n\n @if (selectedClientConfig(); as cfg) {\n <div class=\"et-qd-queries\">\n <p class=\"et-qd-queries__title\">Inspector</p>\n <div class=\"et-qd-queries__actions\">\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': queryListMode() !== 'live' || viewMode() !== 'query' }\"\n (click)=\"selectQueryListMode('live'); selectViewMode('query')\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Live Queries ({{ queries()?.length ?? 0 }})\n </button>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': queryListMode() !== 'history' || viewMode() !== 'query' }\"\n (click)=\"selectQueryListMode('history'); selectViewMode('query')\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Query History ({{ (queryHistory$ | async)?.length ?? 0 }}/50)\n </button>\n @if (queryListMode() === 'history' && viewMode() === 'query') {\n <div class=\"et-qd-queries__divider\"></div>\n <button (click)=\"clearQueryHistory()\" class=\"et-qd-chip et-qd-chip-bordered\">Clear history</button>\n }\n\n <div class=\"et-qd-queries__divider\"></div>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': viewMode() !== 'authProvider' }\"\n (click)=\"selectViewMode('authProvider')\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Auth Provider\n </button>\n </div>\n\n @if (viewMode() === 'query') {\n <div class=\"et-qd-queries__browser\">\n @if (queryListMode() === 'live') {\n <ul class=\"et-qd-queries__browser-list\">\n @for (query of queries(); track trackByQuery($index, query)) {\n <li>\n <button\n [class.et-qd-query--active]=\"selectedQuery()?._id === query._id\"\n (click)=\"selectQuery(query)\"\n >\n <span> {{ query._queryConfig.method }}</span>\n <span> {{ query | queryShortName }}</span>\n </button>\n </li>\n }\n </ul>\n }\n @if (queryListMode() === 'history') {\n <ul class=\"et-qd-queries__browser-list\">\n @for (query of queryHistory$ | async; track trackByQuery($index, query)) {\n <li>\n <button\n [class.et-qd-query--active]=\"selectedQuery()?._id === query._id\"\n (click)=\"selectQuery(query)\"\n >\n <span> {{ query._queryConfig.method }}</span>\n <span> {{ query | queryShortName }}</span>\n </button>\n </li>\n }\n </ul>\n }\n <div class=\"et-qd-queries__browser-detail\">\n @if (selectedQuery(); as query) {\n <p class=\"et-qd-queries__browser-detail__title\">\n {{ query._queryConfig.method }} {{ query._routeWithParams }}\n </p>\n\n <div class=\"et-qd-queries__actions\">\n <button (click)=\"query.execute()\" class=\"et-qd-chip et-qd-chip-bordered\">Execute</button>\n <button (click)=\"query.execute({ skipCache: true })\" class=\"et-qd-chip et-qd-chip-bordered\">\n Execute (ignore cache)\n </button>\n\n <button (click)=\"query.abort()\" class=\"et-qd-chip et-qd-chip-bordered\">Abort</button>\n <div class=\"et-qd-queries__divider\"></div>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': !query.isPolling }\"\n (click)=\"query.poll({ interval: 5000, takeUntil: _destroy$ })\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Poll\n </button>\n\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': query.isPolling }\"\n (click)=\"query.stopPolling()\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Stop polling\n </button>\n @if (query.isPolling || query._isPollingPaused) {\n <button (click)=\"query.pausePolling()\" class=\"et-qd-chip et-qd-chip-secondary et-qd-chip-bordered\">\n Pause polling\n </button>\n <button (click)=\"query.resumePolling()\" class=\"et-qd-chip et-qd-chip-secondary et-qd-chip-bordered\">\n Resume polling\n </button>\n }\n </div>\n\n <div class=\"et-qd-list\">\n <div class=\"et-qd-list-item\">\n <p>State type</p>\n <pre>{{ query.rawState.type }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Dependents</p>\n <pre>{{ query._dependents | json }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Is expired</p>\n <pre>{{ query.isExpired }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Is in use</p>\n <pre>{{ query.isInUse }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Subscriber count</p>\n <pre>{{ query._subscriberCount }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Is polling</p>\n <pre>{{ query.isPolling }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Is polling paused</p>\n <pre>{{ query._isPollingPaused }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Enable smart polling</p>\n <pre>{{ query._enableSmartPolling }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Query store key</p>\n <pre>{{ query._queryStoreKey }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Arguments</p>\n\n <div>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': !showArguments() }\"\n (click)=\"toggleShowArguments()\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Toggle\n </button>\n </div>\n @if (showArguments()) {\n <pre>{{ query._arguments | json }}</pre>\n }\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>State</p>\n <p><i> Warning, this will cause a subscription if shown!</i></p>\n <div>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': !showResponse() }\"\n (click)=\"toggleShowResponse()\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Toggle\n </button>\n </div>\n @if (showResponse()) {\n <pre>{{ query.state$ | async | json }}</pre>\n }\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Raw state</p>\n <p><i> The query state unaffected by entity stores</i></p>\n\n <div>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': !showRawResponse() }\"\n (click)=\"toggleShowRawResponse()\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Toggle\n </button>\n </div>\n @if (showRawResponse()) {\n <pre>{{ query.rawState | json }}</pre>\n }\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Query config</p>\n\n <div>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': !showQueryConfig() }\"\n (click)=\"toggleShowQueryConfig()\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Toggle\n </button>\n </div>\n @if (showQueryConfig()) {\n <pre>{{ stringifiedQueryConfig() | json }}</pre>\n }\n </div>\n\n @if (!!query._queryConfig.entity) {\n <div class=\"et-qd-list-item\">\n <p>Entity store value</p>\n\n <div>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': !showEntityStoreValue() }\"\n (click)=\"toggleShowEntityStoreValue()\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Toggle\n </button>\n </div>\n @if (showEntityStoreValue()) {\n <pre>{{ selectedQueryEntityStoreValue$ | async | json }}</pre>\n }\n </div>\n }\n </div>\n }\n </div>\n </div>\n } @else if (viewMode() === 'authProvider') {\n <div class=\"et-qd-auth-provider__viewer\">\n @if (authProviderDetails(); as details) {\n <div class=\"et-qd-list\">\n <div class=\"et-qd-list-item\">\n <p>Type</p>\n <pre>{{ details.type }}</pre>\n </div>\n <div class=\"et-qd-list-item\">\n <p>Header value</p>\n <pre>{{ details.header() | json }}</pre>\n </div>\n <div class=\"et-qd-list-item\">\n <p>Config</p>\n <pre>{{ details.config | json }}</pre>\n </div>\n\n @if (details.type === 'BearerAuthProvider') {\n <div class=\"et-qd-list-item\">\n <p>Tokens</p>\n <pre>{{ details.provider.tokens$ | async | json }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Should refresh on unauthorized response</p>\n <pre>{{ details.provider.shouldRefreshOnUnauthorizedResponse }}</pre>\n </div>\n\n <ng-container\n *etQuery=\"\n details.provider.currentRefreshQuery$ | async as response;\n loading as loading;\n error as error;\n query as query\n \"\n >\n <div class=\"et-qd-list-item\">\n <p>Refresh query response</p>\n\n <div>\n <button (click)=\"details.provider._refreshQuery()\" class=\"et-qd-chip et-qd-chip-bordered\">\n Refresh\n </button>\n </div>\n <pre>{{ response | json }}</pre>\n </div>\n <div class=\"et-qd-list-item\">\n <p>Refresh query loading</p>\n <pre>{{ loading }}</pre>\n </div>\n <div class=\"et-qd-list-item\">\n <p>Refresh query error</p>\n <pre>{{ error ?? 'null' }}</pre>\n </div>\n <div class=\"et-qd-list-item\">\n <p>State</p>\n <pre>{{ query?.state$ | async | json }}</pre>\n </div>\n </ng-container>\n }\n </div>\n } @else {\n <p>No auth provider set</p>\n }\n </div>\n }\n </div>\n }\n </div>\n}\n", styles: [":host{position:fixed;top:0;z-index:1000000;font-size:14px;color:#fff}.et-query-devtools-container{position:fixed;inset:0;background-color:#25292e;z-index:10000;overflow:auto;font-family:monospace;display:grid;grid-template-rows:auto auto auto minmax(0,1fr)}.et-query-devtools-container.et-query-devtools-container--transparent{opacity:.25;pointer-events:none}.et-query-devtools-container.et-query-devtools-container--transparent .et-query-devtools-translucent-btn{pointer-events:all}.et-query-devtools-container.et-query-devtools-container--snap-left{inset-inline-start:0;inset-block-start:0;inset-block-end:0;width:50%;border-right:1px solid rgb(37,41,46)}.et-query-devtools-container.et-query-devtools-container--snap-right{inset-inline-start:unset;inset-inline-end:0;inset-block-start:0;inset-block-end:0;width:50%;border-left:1px solid rgb(37,41,46)}.et-query-devtools-container.et-query-devtools-container--snap-top{inset-inline-start:0;inset-block-start:0;inset-inline-end:0;height:50%;border-bottom:1px solid rgb(37,41,46)}.et-query-devtools-container.et-query-devtools-container--snap-bottom{inset-inline-start:0;inset-block-start:unset;inset-block-end:0;inset-inline-end:0;height:50%;border-top:1px solid rgb(37,41,46)}button.et-query-devtools-open-btn{position:fixed;inset-inline-end:20px;inset-block-end:0;z-index:9999;font-family:monospace;border-radius:3px 3px 0 0;line-height:14px;font-size:12px}.et-qd-header{background-color:#00ffa1;padding:12px;display:grid;grid-template-columns:1fr auto auto;gap:12px;align-items:center}.et-qd-header__title{color:#25292e;margin:0;font-size:22px}.et-qd-header__select{display:grid;background-color:#25292e;border-radius:10px;overflow:hidden}.et-qd-header__select select{width:250px;color:#fff;padding:3px 10px 2px;border:none;background-color:#25292e;font-family:monospace}.et-qd-header__select label{padding:3px 10px;color:#25292e;font-size:12px;font-weight:700;color:#fff;border-bottom:1px solid gray}.et-qd-sub-header{background-color:#00b371;padding:12px;display:flex;gap:12px;flex-wrap:wrap}.et-qd-sub-header__divider{width:1px;background-color:#25292e}.et-qd-btn{background-color:#00ffa1;color:#25292e;border:none;padding:12px;cursor:pointer;font-size:14px;font-weight:700;text-align:center;text-decoration:none;display:inline-block;width:100%;transition:all .3s ease-in-out;font-family:monospace;border-radius:10px}.et-qd-btn:hover{background-color:#00cc81}.et-qd-btn.et-qd-btn-secondary{background-color:#25292e;color:#00ffa1}.et-qd-btn.et-qd-btn-secondary:hover{background-color:#3c424a}.et-qd-chip{background-color:#00ffa1;color:#25292e;border:none;padding:4px 9px;cursor:pointer;font-size:12px;font-weight:700;text-align:center;text-decoration:none;display:inline-block;transition:all .3s ease-in-out;font-family:monospace;border-radius:10px}.et-qd-chip:hover{background-color:#00cc81}.et-qd-chip.et-qd-chip-secondary{background-color:#25292e;color:#00ffa1}.et-qd-chip.et-qd-chip-secondary:hover{background-color:#3c424a}.et-qd-chip.et-qd-chip-bordered{border:1px solid rgb(0,255,161)}.et-qd-translucent-clickable{pointer-events:all}.et-qd-client{border-bottom:1px solid rgb(59.734939759,66.1927710843,74.265060241);padding:12px}.et-qd-client__title{margin:0;font-size:14px;color:#fff;font-weight:700}.et-qd-client__actions{display:flex;gap:12px;margin-top:12px}.et-qd-queries{padding:12px;display:grid;grid-template-rows:auto auto minmax(0,1fr)}.et-qd-queries__actions{display:flex;gap:12px;margin-top:12px;margin-bottom:16px}.et-qd-queries__title{margin:0;font-size:14px;color:#fff;font-weight:700}.et-qd-queries__divider{width:1px;background-color:#3c424a}.et-qd-queries__browser{display:grid;grid-template-columns:1fr minmax(0,3fr);margin-left:-12px;margin-right:-12px;border-top:1px solid rgb(59.734939759,66.1927710843,74.265060241);margin-bottom:-12px}.et-qd-queries__browser-list{border-right:1px solid rgb(59.734939759,66.1927710843,74.265060241);list-style:none;padding:0;margin:0;display:grid;grid-auto-flow:row;grid-auto-rows:55px;overflow-y:auto;overflow-x:hidden}.et-qd-queries__browser-list li{margin:0}.et-qd-queries__browser-list li button{all:unset;font-family:monospace;box-sizing:border-box;width:100%;border:none;border-bottom:1px solid rgb(59.734939759,66.1927710843,74.265060241);background-color:#25292e;color:#fff;text-align:left;padding:12px;height:100%;transition:all .3s ease-in-out;cursor:pointer;display:grid;grid-template-columns:auto minmax(0,1fr);gap:2px;display:block}.et-qd-queries__browser-list li button span{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.et-qd-queries__browser-list li button span:first-of-type{font-weight:700}.et-qd-queries__browser-list li button:hover,.et-qd-queries__browser-list li button.et-qd-query--active{background-color:#30363c}.et-qd-queries__browser-detail{padding:12px;overflow-y:auto;overflow-x:hidden}.et-qd-queries__browser-detail__title{margin:0;font-size:14px;color:#fff;font-weight:700}.et-qd-auth-provider__viewer{border-top:1px solid rgb(59.734939759,66.1927710843,74.265060241);margin-left:-12px;margin-right:-12px;margin-bottom:-12px;padding:12px;overflow-y:auto;overflow-x:hidden}.et-qd-list{display:grid;gap:12px}.et-qd-list-item{display:grid}.et-qd-list-item p{font-weight:700;margin:0;padding-bottom:8px}.et-qd-list-item p+p{margin-top:-8px}.et-qd-list-item div+pre{margin-top:8px}.et-qd-list-item pre{margin:0;padding:4px;background-color:#0e1012;border-radius:4px;max-height:450px;overflow:auto}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: QueryDirective, selector: "[etQuery]", inputs: ["etQuery", "etQueryCache"] }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "pipe", type: JsonPipe, name: "json" }, { kind: "pipe", type: QueryShortNamePipe, name: "queryShortName" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.ShadowDom }); }
|
|
4790
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: QueryDevtoolsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
4791
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.13", type: QueryDevtoolsComponent, isStandalone: true, selector: "et-query-devtools", host: { classAttribute: "et-query-devtools" }, ngImport: i0, template: "@if (!isOpen()) {\n <button (click)=\"toggleOpen()\" class=\"et-query-devtools-open-btn et-qd-chip\">Query Devtools</button>\n}\n\n@if (isOpen()) {\n <div\n [class.et-query-devtools-container--transparent]=\"isTranslucent()\"\n class=\"et-query-devtools-container et-query-devtools-container--snap-{{ snapLayout() }}\"\n >\n <header class=\"et-qd-header\">\n <h3 class=\"et-qd-header__title\">Query Devtools</h3>\n\n <div class=\"et-qd-header__select\">\n <label for=\"et-query-client-instance\">Client instance</label>\n <select [formControl]=\"selectedClientIdCtrl\" id=\"et-query-client-instance\">\n @for (clientConfig of queryClientConfigs; track trackByClient(i, clientConfig); let i = $index) {\n <option [value]=\"i\">\n {{ clientConfig.displayName ?? clientConfig.client.config.baseRoute }}\n </option>\n }\n </select>\n </div>\n\n <button (click)=\"toggleOpen()\" class=\"et-qd-btn et-qd-btn-secondary\">Close</button>\n </header>\n\n <div class=\"et-qd-sub-header\">\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': !isTranslucent() }\"\n (click)=\"toggleTranslucent()\"\n class=\"et-qd-chip et-qd-translucent-clickable\"\n >\n Translucent\n </button>\n <div class=\"et-qd-sub-header__divider\"></div>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': snapLayout() !== 'full' }\"\n (click)=\"selectSnapLayout('full')\"\n class=\"et-qd-chip\"\n >\n Fullscreen\n </button>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': snapLayout() !== 'top' }\"\n (click)=\"selectSnapLayout('top')\"\n class=\"et-qd-chip\"\n >\n Top\n </button>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': snapLayout() !== 'bottom' }\"\n (click)=\"selectSnapLayout('bottom')\"\n class=\"et-qd-chip\"\n >\n Bottom\n </button>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': snapLayout() !== 'left' }\"\n (click)=\"selectSnapLayout('left')\"\n class=\"et-qd-chip\"\n >\n Left\n </button>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': snapLayout() !== 'right' }\"\n (click)=\"selectSnapLayout('right')\"\n class=\"et-qd-chip\"\n >\n Right\n </button>\n </div>\n\n @if (selectedClientConfig(); as cfg) {\n <div class=\"et-qd-client\">\n <p class=\"et-qd-client__title\">{{ cfg.displayName ?? cfg.client.config.baseRoute }}</p>\n\n <div class=\"et-qd-client__actions\">\n <button (click)=\"cfg.client._store.refreshQueriesInUse()\" class=\"et-qd-chip\">Refresh all</button>\n <button (click)=\"cfg.client._store.refreshQueriesInUse({ ignoreCacheValidity: true })\" class=\"et-qd-chip\">\n Refresh all (ignore caches)\n </button>\n <button\n (click)=\"cfg.client._store.refreshQueriesInUse({ ignoreCacheValidity: true, purgeUnused: true })\"\n class=\"et-qd-chip\"\n >\n Refresh all (ignore caches & purge unused)\n </button>\n </div>\n </div>\n }\n\n @if (selectedClientConfig(); as cfg) {\n <div class=\"et-qd-queries\">\n <p class=\"et-qd-queries__title\">Inspector</p>\n <div class=\"et-qd-queries__actions\">\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': queryListMode() !== 'live' || viewMode() !== 'query' }\"\n (click)=\"selectQueryListMode('live'); selectViewMode('query')\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Live Queries ({{ queries()?.length ?? 0 }})\n </button>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': queryListMode() !== 'history' || viewMode() !== 'query' }\"\n (click)=\"selectQueryListMode('history'); selectViewMode('query')\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Query History ({{ (queryHistory$ | async)?.length ?? 0 }}/50)\n </button>\n @if (queryListMode() === 'history' && viewMode() === 'query') {\n <div class=\"et-qd-queries__divider\"></div>\n <button (click)=\"clearQueryHistory()\" class=\"et-qd-chip et-qd-chip-bordered\">Clear history</button>\n }\n\n <div class=\"et-qd-queries__divider\"></div>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': viewMode() !== 'authProvider' }\"\n (click)=\"selectViewMode('authProvider')\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Auth Provider\n </button>\n </div>\n\n @if (viewMode() === 'query') {\n <div class=\"et-qd-queries__browser\">\n @if (queryListMode() === 'live') {\n <ul class=\"et-qd-queries__browser-list\">\n @for (query of queries(); track trackByQuery($index, query)) {\n <li>\n <button\n [class.et-qd-query--active]=\"selectedQuery()?._id === query._id\"\n (click)=\"selectQuery(query)\"\n >\n <span> {{ query._queryConfig.method }}</span>\n <span> {{ query | queryShortName }}</span>\n </button>\n </li>\n }\n </ul>\n }\n @if (queryListMode() === 'history') {\n <ul class=\"et-qd-queries__browser-list\">\n @for (query of queryHistory$ | async; track trackByQuery($index, query)) {\n <li>\n <button\n [class.et-qd-query--active]=\"selectedQuery()?._id === query._id\"\n (click)=\"selectQuery(query)\"\n >\n <span> {{ query._queryConfig.method }}</span>\n <span> {{ query | queryShortName }}</span>\n </button>\n </li>\n }\n </ul>\n }\n <div class=\"et-qd-queries__browser-detail\">\n @if (selectedQuery(); as query) {\n <p class=\"et-qd-queries__browser-detail__title\">\n {{ query._queryConfig.method }} {{ query._routeWithParams }}\n </p>\n\n <div class=\"et-qd-queries__actions\">\n <button (click)=\"query.execute()\" class=\"et-qd-chip et-qd-chip-bordered\">Execute</button>\n <button (click)=\"query.execute({ skipCache: true })\" class=\"et-qd-chip et-qd-chip-bordered\">\n Execute (ignore cache)\n </button>\n\n <button (click)=\"query.abort()\" class=\"et-qd-chip et-qd-chip-bordered\">Abort</button>\n <div class=\"et-qd-queries__divider\"></div>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': !query.isPolling }\"\n (click)=\"query.poll({ interval: 5000, takeUntil: _destroy$ })\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Poll\n </button>\n\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': query.isPolling }\"\n (click)=\"query.stopPolling()\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Stop polling\n </button>\n @if (query.isPolling || query._isPollingPaused) {\n <button (click)=\"query.pausePolling()\" class=\"et-qd-chip et-qd-chip-secondary et-qd-chip-bordered\">\n Pause polling\n </button>\n <button (click)=\"query.resumePolling()\" class=\"et-qd-chip et-qd-chip-secondary et-qd-chip-bordered\">\n Resume polling\n </button>\n }\n </div>\n\n <div class=\"et-qd-list\">\n <div class=\"et-qd-list-item\">\n <p>State type</p>\n <pre>{{ query.rawState.type }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Dependents</p>\n <pre>{{ query._dependents | json }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Is expired</p>\n <pre>{{ query.isExpired }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Is in use</p>\n <pre>{{ query.isInUse }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Subscriber count</p>\n <pre>{{ query._subscriberCount }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Is polling</p>\n <pre>{{ query.isPolling }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Is polling paused</p>\n <pre>{{ query._isPollingPaused }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Enable smart polling</p>\n <pre>{{ query._enableSmartPolling }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Query store key</p>\n <pre>{{ query._queryStoreKey }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Arguments</p>\n\n <div>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': !showArguments() }\"\n (click)=\"toggleShowArguments()\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Toggle\n </button>\n </div>\n @if (showArguments()) {\n <pre>{{ query._arguments | json }}</pre>\n }\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>State</p>\n <p><i> Warning, this will cause a subscription if shown!</i></p>\n <div>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': !showResponse() }\"\n (click)=\"toggleShowResponse()\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Toggle\n </button>\n </div>\n @if (showResponse()) {\n <pre>{{ query.state$ | async | json }}</pre>\n }\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Raw state</p>\n <p><i> The query state unaffected by entity stores</i></p>\n\n <div>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': !showRawResponse() }\"\n (click)=\"toggleShowRawResponse()\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Toggle\n </button>\n </div>\n @if (showRawResponse()) {\n <pre>{{ query.rawState | json }}</pre>\n }\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Query config</p>\n\n <div>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': !showQueryConfig() }\"\n (click)=\"toggleShowQueryConfig()\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Toggle\n </button>\n </div>\n @if (showQueryConfig()) {\n <pre>{{ stringifiedQueryConfig() | json }}</pre>\n }\n </div>\n\n @if (!!query._queryConfig.entity) {\n <div class=\"et-qd-list-item\">\n <p>Entity store value</p>\n\n <div>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': !showEntityStoreValue() }\"\n (click)=\"toggleShowEntityStoreValue()\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Toggle\n </button>\n </div>\n @if (showEntityStoreValue()) {\n <pre>{{ selectedQueryEntityStoreValue$ | async | json }}</pre>\n }\n </div>\n }\n </div>\n }\n </div>\n </div>\n } @else if (viewMode() === 'authProvider') {\n <div class=\"et-qd-auth-provider__viewer\">\n @if (authProviderDetails(); as details) {\n <div class=\"et-qd-list\">\n <div class=\"et-qd-list-item\">\n <p>Type</p>\n <pre>{{ details.type }}</pre>\n </div>\n <div class=\"et-qd-list-item\">\n <p>Header value</p>\n <pre>{{ details.header() | json }}</pre>\n </div>\n <div class=\"et-qd-list-item\">\n <p>Config</p>\n <pre>{{ details.config | json }}</pre>\n </div>\n\n @if (details.type === 'BearerAuthProvider') {\n <div class=\"et-qd-list-item\">\n <p>Tokens</p>\n <pre>{{ details.provider.tokens$ | async | json }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Should refresh on unauthorized response</p>\n <pre>{{ details.provider.shouldRefreshOnUnauthorizedResponse }}</pre>\n </div>\n\n <ng-container\n *etQuery=\"\n details.provider.currentRefreshQuery$ | async as response;\n loading as loading;\n error as error;\n query as query\n \"\n >\n <div class=\"et-qd-list-item\">\n <p>Refresh query response</p>\n\n <div>\n <button (click)=\"details.provider._refreshQuery()\" class=\"et-qd-chip et-qd-chip-bordered\">\n Refresh\n </button>\n </div>\n <pre>{{ response | json }}</pre>\n </div>\n <div class=\"et-qd-list-item\">\n <p>Refresh query loading</p>\n <pre>{{ loading }}</pre>\n </div>\n <div class=\"et-qd-list-item\">\n <p>Refresh query error</p>\n <pre>{{ error ?? 'null' }}</pre>\n </div>\n <div class=\"et-qd-list-item\">\n <p>State</p>\n <pre>{{ query?.state$ | async | json }}</pre>\n </div>\n </ng-container>\n }\n </div>\n } @else {\n <p>No auth provider set</p>\n }\n </div>\n }\n </div>\n }\n </div>\n}\n", styles: [":host{position:fixed;top:0;z-index:1000000;font-size:14px;color:#fff}.et-query-devtools-container{position:fixed;inset:0;background-color:#25292e;z-index:10000;overflow:auto;font-family:monospace;display:grid;grid-template-rows:auto auto auto minmax(0,1fr)}.et-query-devtools-container.et-query-devtools-container--transparent{opacity:.25;pointer-events:none}.et-query-devtools-container.et-query-devtools-container--transparent .et-query-devtools-translucent-btn{pointer-events:all}.et-query-devtools-container.et-query-devtools-container--snap-left{inset-inline-start:0;inset-block-start:0;inset-block-end:0;width:50%;border-right:1px solid rgb(37,41,46)}.et-query-devtools-container.et-query-devtools-container--snap-right{inset-inline-start:unset;inset-inline-end:0;inset-block-start:0;inset-block-end:0;width:50%;border-left:1px solid rgb(37,41,46)}.et-query-devtools-container.et-query-devtools-container--snap-top{inset-inline-start:0;inset-block-start:0;inset-inline-end:0;height:50%;border-bottom:1px solid rgb(37,41,46)}.et-query-devtools-container.et-query-devtools-container--snap-bottom{inset-inline-start:0;inset-block-start:unset;inset-block-end:0;inset-inline-end:0;height:50%;border-top:1px solid rgb(37,41,46)}button.et-query-devtools-open-btn{position:fixed;inset-inline-end:20px;inset-block-end:0;z-index:9999;font-family:monospace;border-radius:3px 3px 0 0;line-height:14px;font-size:12px}.et-qd-header{background-color:#00ffa1;padding:12px;display:grid;grid-template-columns:1fr auto auto;gap:12px;align-items:center}.et-qd-header__title{color:#25292e;margin:0;font-size:22px}.et-qd-header__select{display:grid;background-color:#25292e;border-radius:10px;overflow:hidden}.et-qd-header__select select{width:250px;color:#fff;padding:3px 10px 2px;border:none;background-color:#25292e;font-family:monospace}.et-qd-header__select label{padding:3px 10px;color:#25292e;font-size:12px;font-weight:700;color:#fff;border-bottom:1px solid gray}.et-qd-sub-header{background-color:#00b371;padding:12px;display:flex;gap:12px;flex-wrap:wrap}.et-qd-sub-header__divider{width:1px;background-color:#25292e}.et-qd-btn{background-color:#00ffa1;color:#25292e;border:none;padding:12px;cursor:pointer;font-size:14px;font-weight:700;text-align:center;text-decoration:none;display:inline-block;width:100%;transition:all .3s ease-in-out;font-family:monospace;border-radius:10px}.et-qd-btn:hover{background-color:#00cc81}.et-qd-btn.et-qd-btn-secondary{background-color:#25292e;color:#00ffa1}.et-qd-btn.et-qd-btn-secondary:hover{background-color:#3c424a}.et-qd-chip{background-color:#00ffa1;color:#25292e;border:none;padding:4px 9px;cursor:pointer;font-size:12px;font-weight:700;text-align:center;text-decoration:none;display:inline-block;transition:all .3s ease-in-out;font-family:monospace;border-radius:10px}.et-qd-chip:hover{background-color:#00cc81}.et-qd-chip.et-qd-chip-secondary{background-color:#25292e;color:#00ffa1}.et-qd-chip.et-qd-chip-secondary:hover{background-color:#3c424a}.et-qd-chip.et-qd-chip-bordered{border:1px solid rgb(0,255,161)}.et-qd-translucent-clickable{pointer-events:all}.et-qd-client{border-bottom:1px solid rgb(59.734939759,66.1927710843,74.265060241);padding:12px}.et-qd-client__title{margin:0;font-size:14px;color:#fff;font-weight:700}.et-qd-client__actions{display:flex;gap:12px;margin-top:12px}.et-qd-queries{padding:12px;display:grid;grid-template-rows:auto auto minmax(0,1fr)}.et-qd-queries__actions{display:flex;gap:12px;margin-top:12px;margin-bottom:16px}.et-qd-queries__title{margin:0;font-size:14px;color:#fff;font-weight:700}.et-qd-queries__divider{width:1px;background-color:#3c424a}.et-qd-queries__browser{display:grid;grid-template-columns:1fr minmax(0,3fr);margin-left:-12px;margin-right:-12px;border-top:1px solid rgb(59.734939759,66.1927710843,74.265060241);margin-bottom:-12px}.et-qd-queries__browser-list{border-right:1px solid rgb(59.734939759,66.1927710843,74.265060241);list-style:none;padding:0;margin:0;display:grid;grid-auto-flow:row;grid-auto-rows:55px;overflow-y:auto;overflow-x:hidden}.et-qd-queries__browser-list li{margin:0}.et-qd-queries__browser-list li button{all:unset;font-family:monospace;box-sizing:border-box;width:100%;border:none;border-bottom:1px solid rgb(59.734939759,66.1927710843,74.265060241);background-color:#25292e;color:#fff;text-align:left;padding:12px;height:100%;transition:all .3s ease-in-out;cursor:pointer;display:grid;grid-template-columns:auto minmax(0,1fr);gap:2px;display:block}.et-qd-queries__browser-list li button span{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.et-qd-queries__browser-list li button span:first-of-type{font-weight:700}.et-qd-queries__browser-list li button:hover,.et-qd-queries__browser-list li button.et-qd-query--active{background-color:#30363c}.et-qd-queries__browser-detail{padding:12px;overflow-y:auto;overflow-x:hidden}.et-qd-queries__browser-detail__title{margin:0;font-size:14px;color:#fff;font-weight:700}.et-qd-auth-provider__viewer{border-top:1px solid rgb(59.734939759,66.1927710843,74.265060241);margin-left:-12px;margin-right:-12px;margin-bottom:-12px;padding:12px;overflow-y:auto;overflow-x:hidden}.et-qd-list{display:grid;gap:12px}.et-qd-list-item{display:grid}.et-qd-list-item p{font-weight:700;margin:0;padding-bottom:8px}.et-qd-list-item p+p{margin-top:-8px}.et-qd-list-item div+pre{margin-top:8px}.et-qd-list-item pre{margin:0;padding:4px;background-color:#0e1012;border-radius:4px;max-height:450px;overflow:auto}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: QueryDirective, selector: "[etQuery]", inputs: ["etQuery", "etQueryCache"] }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "pipe", type: JsonPipe, name: "json" }, { kind: "pipe", type: QueryShortNamePipe, name: "queryShortName" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.ShadowDom }); }
|
|
4791
4792
|
}
|
|
4792
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
4793
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: QueryDevtoolsComponent, decorators: [{
|
|
4793
4794
|
type: Component,
|
|
4794
4795
|
args: [{ selector: 'et-query-devtools', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.ShadowDom, host: {
|
|
4795
4796
|
class: 'et-query-devtools',
|
|
@@ -5164,7 +5165,10 @@ const setupLeaderElection = () => {
|
|
|
5164
5165
|
const leaderTimeout = 3000;
|
|
5165
5166
|
const storageKey = 'ethlete-auth-leader-heartbeat';
|
|
5166
5167
|
const tabId = `tab-${Date.now()}-${Math.random().toString(36).substring(2, 9)}`;
|
|
5167
|
-
const isLeader = signal(false, ...(ngDevMode ? [{ debugName: "isLeader" }] : []));
|
|
5168
|
+
const isLeader = signal(false, ...(ngDevMode ? [{ debugName: "isLeader" }] : /* istanbul ignore next */ []));
|
|
5169
|
+
const instanceCount = signal(1, ...(ngDevMode ? [{ debugName: "instanceCount" }] : /* istanbul ignore next */ []));
|
|
5170
|
+
const knownTabs = new Map();
|
|
5171
|
+
knownTabs.set(tabId, Date.now());
|
|
5168
5172
|
let channel = null;
|
|
5169
5173
|
let heartbeatIntervalId = null;
|
|
5170
5174
|
let leaderCheckIntervalId = null;
|
|
@@ -5172,6 +5176,7 @@ const setupLeaderElection = () => {
|
|
|
5172
5176
|
isLeader.set(true);
|
|
5173
5177
|
return {
|
|
5174
5178
|
isLeader: isLeader.asReadonly(),
|
|
5179
|
+
instanceCount: instanceCount.asReadonly(),
|
|
5175
5180
|
becomeLeader: () => {
|
|
5176
5181
|
/* no-op */
|
|
5177
5182
|
},
|
|
@@ -5181,6 +5186,7 @@ const setupLeaderElection = () => {
|
|
|
5181
5186
|
};
|
|
5182
5187
|
}
|
|
5183
5188
|
channel = new BroadcastChannel(channelName);
|
|
5189
|
+
channel.postMessage({ type: 'instance-register', tabId });
|
|
5184
5190
|
const updateLeaderHeartbeat = (newTabId = tabId) => {
|
|
5185
5191
|
try {
|
|
5186
5192
|
localStorage.setItem(storageKey, JSON.stringify({ tabId: newTabId, timestamp: Date.now() }));
|
|
@@ -5227,48 +5233,60 @@ const setupLeaderElection = () => {
|
|
|
5227
5233
|
const heartbeat = getLeaderHeartbeat();
|
|
5228
5234
|
const now = Date.now();
|
|
5229
5235
|
if (!heartbeat || now - heartbeat.timestamp > leaderTimeout) {
|
|
5230
|
-
// No leader or leader is dead
|
|
5231
5236
|
if (!isLeader()) {
|
|
5232
5237
|
becomeLeader();
|
|
5233
5238
|
}
|
|
5234
5239
|
}
|
|
5235
5240
|
else if (heartbeat.tabId === tabId) {
|
|
5236
|
-
// We are the leader, update heartbeat
|
|
5237
5241
|
if (!isLeader()) {
|
|
5238
5242
|
isLeader.set(true);
|
|
5239
5243
|
}
|
|
5240
5244
|
updateLeaderHeartbeat();
|
|
5241
5245
|
}
|
|
5242
5246
|
else {
|
|
5243
|
-
// Another tab is leader
|
|
5244
5247
|
if (isLeader()) {
|
|
5245
5248
|
isLeader.set(false);
|
|
5246
5249
|
}
|
|
5247
5250
|
}
|
|
5248
5251
|
};
|
|
5249
|
-
// Handle messages from other tabs
|
|
5250
5252
|
channel.onmessage = (event) => {
|
|
5251
5253
|
const message = event.data;
|
|
5252
5254
|
if (message.type === 'heartbeat') {
|
|
5255
|
+
if (message.tabId !== tabId) {
|
|
5256
|
+
knownTabs.set(message.tabId, Date.now());
|
|
5257
|
+
}
|
|
5253
5258
|
if (message.tabId !== tabId && isLeader()) {
|
|
5254
|
-
// Another tab claims to be leader, resolve conflict
|
|
5255
5259
|
const heartbeat = getLeaderHeartbeat();
|
|
5256
5260
|
if (heartbeat && heartbeat.tabId === message.tabId) {
|
|
5257
|
-
// Other tab is legitimate leader
|
|
5258
5261
|
releaseLeadership();
|
|
5259
5262
|
}
|
|
5260
5263
|
}
|
|
5261
5264
|
}
|
|
5265
|
+
else if (message.type === 'tab-heartbeat') {
|
|
5266
|
+
if (message.tabId !== tabId) {
|
|
5267
|
+
knownTabs.set(message.tabId, Date.now());
|
|
5268
|
+
}
|
|
5269
|
+
}
|
|
5270
|
+
else if (message.type === 'instance-register') {
|
|
5271
|
+
if (message.tabId !== tabId) {
|
|
5272
|
+
knownTabs.set(message.tabId, Date.now());
|
|
5273
|
+
instanceCount.set(knownTabs.size);
|
|
5274
|
+
channel?.postMessage({ type: 'tab-heartbeat', tabId });
|
|
5275
|
+
}
|
|
5276
|
+
}
|
|
5277
|
+
else if (message.type === 'instance-unregister') {
|
|
5278
|
+
if (message.tabId !== tabId) {
|
|
5279
|
+
knownTabs.delete(message.tabId);
|
|
5280
|
+
instanceCount.set(knownTabs.size);
|
|
5281
|
+
}
|
|
5282
|
+
}
|
|
5262
5283
|
else if (message.type === 'leader-claim') {
|
|
5263
5284
|
if (message.tabId !== tabId && isLeader()) {
|
|
5264
|
-
// Conflict: both tabs think they're leader
|
|
5265
|
-
// Let the tab with earlier heartbeat win
|
|
5266
5285
|
const heartbeat = getLeaderHeartbeat();
|
|
5267
5286
|
if (heartbeat && heartbeat.tabId === message.tabId) {
|
|
5268
5287
|
releaseLeadership();
|
|
5269
5288
|
}
|
|
5270
5289
|
else {
|
|
5271
|
-
// We were leader first, send heartbeat to assert dominance
|
|
5272
5290
|
const assertMessage = {
|
|
5273
5291
|
type: 'heartbeat',
|
|
5274
5292
|
tabId,
|
|
@@ -5279,35 +5297,40 @@ const setupLeaderElection = () => {
|
|
|
5279
5297
|
}
|
|
5280
5298
|
else if (message.type === 'leader-release') {
|
|
5281
5299
|
if (message.tabId !== tabId) {
|
|
5282
|
-
// Leader released, try to become new leader
|
|
5283
5300
|
setTimeout(() => checkLeaderStatus(), 100);
|
|
5284
5301
|
}
|
|
5285
5302
|
}
|
|
5286
5303
|
};
|
|
5287
|
-
// Try to become leader on startup
|
|
5288
5304
|
checkLeaderStatus();
|
|
5289
|
-
// Send heartbeat periodically if we're the leader
|
|
5290
5305
|
heartbeatIntervalId = setInterval(() => {
|
|
5306
|
+
knownTabs.set(tabId, Date.now());
|
|
5291
5307
|
if (isLeader()) {
|
|
5292
5308
|
updateLeaderHeartbeat();
|
|
5293
|
-
|
|
5294
|
-
|
|
5295
|
-
|
|
5296
|
-
};
|
|
5297
|
-
|
|
5309
|
+
channel?.postMessage({ type: 'heartbeat', tabId });
|
|
5310
|
+
}
|
|
5311
|
+
else {
|
|
5312
|
+
channel?.postMessage({ type: 'tab-heartbeat', tabId });
|
|
5313
|
+
}
|
|
5314
|
+
const now = Date.now();
|
|
5315
|
+
let changed = false;
|
|
5316
|
+
for (const [id, lastSeen] of knownTabs) {
|
|
5317
|
+
if (id !== tabId && now - lastSeen > leaderTimeout) {
|
|
5318
|
+
knownTabs.delete(id);
|
|
5319
|
+
changed = true;
|
|
5320
|
+
}
|
|
5321
|
+
}
|
|
5322
|
+
if (changed) {
|
|
5323
|
+
instanceCount.set(knownTabs.size);
|
|
5298
5324
|
}
|
|
5299
5325
|
}, heartbeatInterval);
|
|
5300
|
-
// Check leader status periodically
|
|
5301
5326
|
leaderCheckIntervalId = setInterval(() => {
|
|
5302
5327
|
checkLeaderStatus();
|
|
5303
5328
|
}, heartbeatInterval);
|
|
5304
|
-
// Handle tab visibility changes
|
|
5305
5329
|
const handleVisibilityChange = () => {
|
|
5306
5330
|
if (document.hidden && isLeader()) {
|
|
5307
5331
|
// Tab is hidden but we're leader - keep leadership but other tabs will take over if we die
|
|
5308
5332
|
}
|
|
5309
5333
|
else if (!document.hidden && !isLeader()) {
|
|
5310
|
-
// Tab became visible and we're not leader - check if we should become leader
|
|
5311
5334
|
checkLeaderStatus();
|
|
5312
5335
|
}
|
|
5313
5336
|
};
|
|
@@ -5319,10 +5342,10 @@ const setupLeaderElection = () => {
|
|
|
5319
5342
|
if (leaderCheckIntervalId) {
|
|
5320
5343
|
clearInterval(leaderCheckIntervalId);
|
|
5321
5344
|
}
|
|
5345
|
+
channel?.postMessage({ type: 'instance-unregister', tabId });
|
|
5322
5346
|
releaseLeadership();
|
|
5323
5347
|
document.removeEventListener('visibilitychange', handleVisibilityChange);
|
|
5324
5348
|
channel?.close();
|
|
5325
|
-
// Clean up storage if we were the leader
|
|
5326
5349
|
const heartbeat = getLeaderHeartbeat();
|
|
5327
5350
|
if (heartbeat?.tabId === tabId) {
|
|
5328
5351
|
try {
|
|
@@ -5336,6 +5359,7 @@ const setupLeaderElection = () => {
|
|
|
5336
5359
|
destroyRef.onDestroy(cleanup);
|
|
5337
5360
|
return {
|
|
5338
5361
|
isLeader: isLeader.asReadonly(),
|
|
5362
|
+
instanceCount: instanceCount.asReadonly(),
|
|
5339
5363
|
becomeLeader,
|
|
5340
5364
|
cleanup,
|
|
5341
5365
|
};
|
|
@@ -5516,11 +5540,20 @@ const defaultExtractTokens = (response) => {
|
|
|
5516
5540
|
}
|
|
5517
5541
|
return { accessToken: response['accessToken'], refreshToken: response['refreshToken'] };
|
|
5518
5542
|
};
|
|
5519
|
-
const
|
|
5543
|
+
const deriveExecutionStateType = (builder, triggeredBy) => {
|
|
5544
|
+
if (triggeredBy === 'persistent-auth')
|
|
5545
|
+
return 'autoLogin';
|
|
5546
|
+
if (builder._type === 'tokenRefreshQuery')
|
|
5547
|
+
return 'tokenRefresh';
|
|
5548
|
+
if (triggeredBy === 'token-revocation')
|
|
5549
|
+
return 'revocation';
|
|
5550
|
+
return builder.key;
|
|
5551
|
+
};
|
|
5552
|
+
const setupBearerQueryRegistry = (builders, injector, latestExecutedQuery, latestNonInternalQuery, setTokens, executionState) => {
|
|
5520
5553
|
const queries = {};
|
|
5521
5554
|
const querySnapshots = new Map();
|
|
5522
5555
|
for (const builder of builders) {
|
|
5523
|
-
const querySnapshot = signal(null, ...(ngDevMode ? [{ debugName: "querySnapshot" }] : []));
|
|
5556
|
+
const querySnapshot = signal(null, ...(ngDevMode ? [{ debugName: "querySnapshot" }] : /* istanbul ignore next */ []));
|
|
5524
5557
|
querySnapshots.set(builder.key, querySnapshot);
|
|
5525
5558
|
const extractTokens = builder.config.extractTokens ?? defaultExtractTokens;
|
|
5526
5559
|
effect(() => {
|
|
@@ -5549,10 +5582,27 @@ const setupBearerQueryRegistry = (builders, injector, latestExecutedQuery, lates
|
|
|
5549
5582
|
});
|
|
5550
5583
|
query.execute({ args, options });
|
|
5551
5584
|
const snapshot = query.createSnapshot();
|
|
5552
|
-
|
|
5553
|
-
if (
|
|
5554
|
-
|
|
5585
|
+
const stateType = deriveExecutionStateType(builder, options?.triggeredBy);
|
|
5586
|
+
if (stateType !== 'revocation') {
|
|
5587
|
+
latestExecutedQuery.set({ key: builder.key, snapshot });
|
|
5588
|
+
if (!snapshot.triggeredBy()) {
|
|
5589
|
+
latestNonInternalQuery.set({ key: builder.key, snapshot });
|
|
5590
|
+
}
|
|
5555
5591
|
}
|
|
5592
|
+
executionState.set({ type: stateType, state: 'loading' });
|
|
5593
|
+
effect(() => {
|
|
5594
|
+
const response = snapshot.response();
|
|
5595
|
+
const loading = snapshot.loading();
|
|
5596
|
+
const error = snapshot.error();
|
|
5597
|
+
if (loading)
|
|
5598
|
+
return;
|
|
5599
|
+
if (error) {
|
|
5600
|
+
executionState.set({ type: stateType, state: 'error', error });
|
|
5601
|
+
}
|
|
5602
|
+
else if (response) {
|
|
5603
|
+
executionState.set({ type: stateType, state: 'success', response });
|
|
5604
|
+
}
|
|
5605
|
+
}, { injector });
|
|
5556
5606
|
querySnapshot.set(snapshot);
|
|
5557
5607
|
return snapshot;
|
|
5558
5608
|
};
|
|
@@ -5602,13 +5652,18 @@ const createLeaderElection = (config) => {
|
|
|
5602
5652
|
const leaderElectionEnabled = multiTabSyncEnabled &&
|
|
5603
5653
|
(typeof multiTabSyncConfig === 'object' ? (multiTabSyncConfig?.leaderElection ?? true) : true);
|
|
5604
5654
|
const leaderElection = leaderElectionEnabled ? setupLeaderElection() : null;
|
|
5605
|
-
|
|
5655
|
+
const isLeaderFn = () => (leaderElectionEnabled ? (leaderElection?.isLeader() ?? true) : true);
|
|
5656
|
+
const leaderElectionContext = leaderElection
|
|
5657
|
+
? { isLeader: leaderElection.isLeader, instanceCount: leaderElection.instanceCount }
|
|
5658
|
+
: undefined;
|
|
5659
|
+
return { isLeaderFn, leaderElectionContext };
|
|
5606
5660
|
};
|
|
5607
5661
|
const createBearerAuthProviderImpl = (config) => {
|
|
5608
5662
|
const injector = inject(Injector);
|
|
5663
|
+
const destroyRef = inject(DestroyRef);
|
|
5609
5664
|
const queryClient = config.queryClientRef[1]();
|
|
5610
|
-
const accessToken = signal(null, ...(ngDevMode ? [{ debugName: "accessToken" }] : []));
|
|
5611
|
-
const refreshToken = signal(null, ...(ngDevMode ? [{ debugName: "refreshToken" }] : []));
|
|
5665
|
+
const accessToken = signal(null, ...(ngDevMode ? [{ debugName: "accessToken" }] : /* istanbul ignore next */ []));
|
|
5666
|
+
const refreshToken = signal(null, ...(ngDevMode ? [{ debugName: "refreshToken" }] : /* istanbul ignore next */ []));
|
|
5612
5667
|
const afterTokenRefresh$ = new Subject();
|
|
5613
5668
|
const bearerData = computed(() => {
|
|
5614
5669
|
const token = accessToken();
|
|
@@ -5623,20 +5678,24 @@ const createBearerAuthProviderImpl = (config) => {
|
|
|
5623
5678
|
}
|
|
5624
5679
|
return null;
|
|
5625
5680
|
}
|
|
5626
|
-
}, ...(ngDevMode ? [{ debugName: "bearerData" }] : []));
|
|
5627
|
-
const isAuthenticated = computed(() => !!accessToken(), ...(ngDevMode ? [{ debugName: "isAuthenticated" }] : []));
|
|
5628
|
-
const latestExecutedQuery = signal(null, ...(ngDevMode ? [{ debugName: "latestExecutedQuery" }] : []));
|
|
5629
|
-
const latestNonInternalQuery = signal(null, ...(ngDevMode ? [{ debugName: "latestNonInternalQuery" }] : []));
|
|
5681
|
+
}, ...(ngDevMode ? [{ debugName: "bearerData" }] : /* istanbul ignore next */ []));
|
|
5682
|
+
const isAuthenticated = computed(() => !!accessToken(), ...(ngDevMode ? [{ debugName: "isAuthenticated" }] : /* istanbul ignore next */ []));
|
|
5683
|
+
const latestExecutedQuery = signal(null, ...(ngDevMode ? [{ debugName: "latestExecutedQuery" }] : /* istanbul ignore next */ []));
|
|
5684
|
+
const latestNonInternalQuery = signal(null, ...(ngDevMode ? [{ debugName: "latestNonInternalQuery" }] : /* istanbul ignore next */ []));
|
|
5685
|
+
const executionState = signal(null, ...(ngDevMode ? [{ debugName: "executionState" }] : /* istanbul ignore next */ []));
|
|
5630
5686
|
const setTokens = (access, refresh) => {
|
|
5631
5687
|
accessToken.set(access);
|
|
5632
5688
|
refreshToken.set(refresh);
|
|
5633
5689
|
afterTokenRefresh$.next();
|
|
5634
5690
|
};
|
|
5635
|
-
const { queries } = setupBearerQueryRegistry(config.queries, injector, latestExecutedQuery, latestNonInternalQuery, setTokens);
|
|
5691
|
+
const { queries } = setupBearerQueryRegistry(config.queries, injector, latestExecutedQuery, latestNonInternalQuery, setTokens, executionState);
|
|
5636
5692
|
const logout = () => {
|
|
5637
5693
|
accessToken.set(null);
|
|
5638
5694
|
refreshToken.set(null);
|
|
5639
5695
|
queryClient.repository.unbindAllSecure();
|
|
5696
|
+
latestExecutedQuery.set(null);
|
|
5697
|
+
latestNonInternalQuery.set(null);
|
|
5698
|
+
executionState.set({ type: 'logout', state: 'success' });
|
|
5640
5699
|
};
|
|
5641
5700
|
const isLeader = createLeaderElection(config);
|
|
5642
5701
|
const querySetupContext = {
|
|
@@ -5645,7 +5704,7 @@ const createBearerAuthProviderImpl = (config) => {
|
|
|
5645
5704
|
bearerDecryptFn: config.bearerDecryptFn,
|
|
5646
5705
|
queryClient,
|
|
5647
5706
|
repository: queryClient.repository,
|
|
5648
|
-
isLeader,
|
|
5707
|
+
isLeader: isLeader.isLeaderFn,
|
|
5649
5708
|
afterTokenRefresh$,
|
|
5650
5709
|
queries: queries,
|
|
5651
5710
|
};
|
|
@@ -5658,10 +5717,13 @@ const createBearerAuthProviderImpl = (config) => {
|
|
|
5658
5717
|
bearerData,
|
|
5659
5718
|
logout,
|
|
5660
5719
|
injector,
|
|
5720
|
+
destroyRef,
|
|
5661
5721
|
setTokens,
|
|
5662
|
-
isLeader,
|
|
5722
|
+
isLeader: isLeader.isLeaderFn,
|
|
5723
|
+
leaderElection: isLeader.leaderElectionContext,
|
|
5663
5724
|
afterTokenRefresh$,
|
|
5664
5725
|
queries: queries,
|
|
5726
|
+
executionState,
|
|
5665
5727
|
};
|
|
5666
5728
|
const features = setupFeatures(config.features, featureSetupContext);
|
|
5667
5729
|
setupMultiTabSyncIfEnabled(config, accessToken, refreshToken, queryClient);
|
|
@@ -5674,6 +5736,7 @@ const createBearerAuthProviderImpl = (config) => {
|
|
|
5674
5736
|
isAuthenticated,
|
|
5675
5737
|
latestExecutedQuery: latestExecutedQuery.asReadonly(),
|
|
5676
5738
|
latestNonInternalQuery: latestNonInternalQuery.asReadonly(),
|
|
5739
|
+
executionState: executionState.asReadonly(),
|
|
5677
5740
|
logout,
|
|
5678
5741
|
afterTokenRefresh$,
|
|
5679
5742
|
};
|
|
@@ -5823,8 +5886,8 @@ const withInactivityLogout = (config = {}) => {
|
|
|
5823
5886
|
const activityEvents = config.activityEvents ?? ['mousedown', 'keydown', 'scroll', 'touchstart'];
|
|
5824
5887
|
const destroyRef = inject(DestroyRef);
|
|
5825
5888
|
const document = inject(DOCUMENT);
|
|
5826
|
-
const enabled = signal(true, ...(ngDevMode ? [{ debugName: "enabled" }] : []));
|
|
5827
|
-
const lastActivityTime = signal(Date.now(), ...(ngDevMode ? [{ debugName: "lastActivityTime" }] : []));
|
|
5889
|
+
const enabled = signal(true, ...(ngDevMode ? [{ debugName: "enabled" }] : /* istanbul ignore next */ []));
|
|
5890
|
+
const lastActivityTime = signal(Date.now(), ...(ngDevMode ? [{ debugName: "lastActivityTime" }] : /* istanbul ignore next */ []));
|
|
5828
5891
|
const resetTimer = () => {
|
|
5829
5892
|
lastActivityTime.set(Date.now());
|
|
5830
5893
|
};
|
|
@@ -5907,7 +5970,7 @@ const createPersistentAuthFeature = (config, context) => {
|
|
|
5907
5970
|
}
|
|
5908
5971
|
return config.defaultRememberMe ?? false;
|
|
5909
5972
|
};
|
|
5910
|
-
const rememberMeSignal = signal(initializeRememberMe(), ...(ngDevMode ? [{ debugName: "rememberMeSignal" }] : []));
|
|
5973
|
+
const rememberMeSignal = signal(initializeRememberMe(), ...(ngDevMode ? [{ debugName: "rememberMeSignal" }] : /* istanbul ignore next */ []));
|
|
5911
5974
|
effect(() => {
|
|
5912
5975
|
const token = refreshToken();
|
|
5913
5976
|
const rememberMe = rememberMeSignal();
|
|
@@ -5968,7 +6031,7 @@ const withTokenExpirationWarning = (config = {}) => {
|
|
|
5968
6031
|
if (typeof exp !== 'number')
|
|
5969
6032
|
return null;
|
|
5970
6033
|
return new Date(exp * 1000);
|
|
5971
|
-
}, ...(ngDevMode ? [{ debugName: "expiresAt" }] : []));
|
|
6034
|
+
}, ...(ngDevMode ? [{ debugName: "expiresAt" }] : /* istanbul ignore next */ []));
|
|
5972
6035
|
const expiresIn$ = combineLatest([interval(checkInterval), toObservable(context.bearerData)]).pipe(map(() => {
|
|
5973
6036
|
const expiry = expiresAt();
|
|
5974
6037
|
if (!expiry)
|
|
@@ -5999,23 +6062,26 @@ const withTokenExpirationWarning = (config = {}) => {
|
|
|
5999
6062
|
const withTokenRevocation = (config) => {
|
|
6000
6063
|
return (context) => {
|
|
6001
6064
|
const revokeOnLogout = config.revokeOnLogout ?? true;
|
|
6002
|
-
const enabled = signal(true, ...(ngDevMode ? [{ debugName: "enabled" }] : []));
|
|
6065
|
+
const enabled = signal(true, ...(ngDevMode ? [{ debugName: "enabled" }] : /* istanbul ignore next */ []));
|
|
6003
6066
|
let previousAccessToken = null;
|
|
6067
|
+
let previousRefreshToken = null;
|
|
6004
6068
|
let currentRevocationSnapshot = null;
|
|
6005
|
-
const
|
|
6069
|
+
const revokeWithTokens = (accessToken, refreshToken) => {
|
|
6006
6070
|
if (currentRevocationSnapshot?.isAlive())
|
|
6007
6071
|
return currentRevocationSnapshot;
|
|
6008
|
-
const accessToken = context.accessToken();
|
|
6009
|
-
const refreshToken = context.refreshToken();
|
|
6010
6072
|
if (!accessToken && !refreshToken) {
|
|
6011
6073
|
return null;
|
|
6012
6074
|
}
|
|
6013
6075
|
const args = config.buildArgs({ accessToken, refreshToken });
|
|
6076
|
+
context.executionState.set({ type: 'revocation', state: 'loading' });
|
|
6014
6077
|
currentRevocationSnapshot = context.queries[config.queryKey].execute(args, {
|
|
6015
6078
|
triggeredBy: 'token-revocation',
|
|
6016
6079
|
});
|
|
6017
6080
|
return currentRevocationSnapshot;
|
|
6018
6081
|
};
|
|
6082
|
+
const revoke = () => {
|
|
6083
|
+
return revokeWithTokens(context.accessToken(), context.refreshToken());
|
|
6084
|
+
};
|
|
6019
6085
|
const enable = () => {
|
|
6020
6086
|
enabled.set(true);
|
|
6021
6087
|
};
|
|
@@ -6025,10 +6091,12 @@ const withTokenRevocation = (config) => {
|
|
|
6025
6091
|
if (revokeOnLogout) {
|
|
6026
6092
|
effect(() => {
|
|
6027
6093
|
const currentToken = context.accessToken();
|
|
6094
|
+
const currentRefreshToken = context.refreshToken();
|
|
6028
6095
|
if (previousAccessToken && !currentToken && enabled()) {
|
|
6029
|
-
untracked(() =>
|
|
6096
|
+
untracked(() => revokeWithTokens(previousAccessToken, previousRefreshToken));
|
|
6030
6097
|
}
|
|
6031
6098
|
previousAccessToken = currentToken;
|
|
6099
|
+
previousRefreshToken = currentRefreshToken;
|
|
6032
6100
|
}, { injector: context.injector });
|
|
6033
6101
|
}
|
|
6034
6102
|
const instance = {
|
|
@@ -6074,7 +6142,7 @@ const createTrackingFeature = (context, config) => {
|
|
|
6074
6142
|
}
|
|
6075
6143
|
}
|
|
6076
6144
|
};
|
|
6077
|
-
const
|
|
6145
|
+
const fireHandlers = (event, data) => {
|
|
6078
6146
|
const eventHandlers = handlers.get(event);
|
|
6079
6147
|
if (eventHandlers) {
|
|
6080
6148
|
eventHandlers.forEach((handler) => {
|
|
@@ -6087,6 +6155,27 @@ const createTrackingFeature = (context, config) => {
|
|
|
6087
6155
|
});
|
|
6088
6156
|
}
|
|
6089
6157
|
};
|
|
6158
|
+
const forwardingChannel = context.leaderElection && typeof BroadcastChannel !== 'undefined'
|
|
6159
|
+
? new BroadcastChannel('ethlete-auth-tracking')
|
|
6160
|
+
: null;
|
|
6161
|
+
if (forwardingChannel) {
|
|
6162
|
+
forwardingChannel.onmessage = (messageEvent) => {
|
|
6163
|
+
if (context.isLeader()) {
|
|
6164
|
+
fireHandlers(messageEvent.data.event, messageEvent.data.data);
|
|
6165
|
+
}
|
|
6166
|
+
};
|
|
6167
|
+
context.destroyRef.onDestroy(() => forwardingChannel.close());
|
|
6168
|
+
}
|
|
6169
|
+
const emit = (event, data) => {
|
|
6170
|
+
if (forwardingChannel && !context.isLeader()) {
|
|
6171
|
+
forwardingChannel.postMessage({ event, data });
|
|
6172
|
+
return;
|
|
6173
|
+
}
|
|
6174
|
+
fireHandlers(event, data);
|
|
6175
|
+
};
|
|
6176
|
+
const emitDirect = (event, data) => {
|
|
6177
|
+
fireHandlers(event, data);
|
|
6178
|
+
};
|
|
6090
6179
|
const trackedQueries = new Map();
|
|
6091
6180
|
Object.entries(context.queries).forEach(([key, queryEntry]) => {
|
|
6092
6181
|
const query = queryEntry; // eslint-disable-line @typescript-eslint/no-explicit-any
|
|
@@ -6103,17 +6192,11 @@ const createTrackingFeature = (context, config) => {
|
|
|
6103
6192
|
const prevState = trackedQueries.get(key);
|
|
6104
6193
|
if (response && !loading && !error && prevState?.lastResult !== 'success') {
|
|
6105
6194
|
trackedQueries.set(key, { loading: false, lastResult: 'success' });
|
|
6106
|
-
emit(`${key}Success`, {
|
|
6107
|
-
queryKey: key,
|
|
6108
|
-
snapshot,
|
|
6109
|
-
});
|
|
6195
|
+
emit(`${key}Success`, { snapshot });
|
|
6110
6196
|
}
|
|
6111
6197
|
if (error && !loading && prevState?.lastResult !== 'error') {
|
|
6112
6198
|
trackedQueries.set(key, { loading: false, lastResult: 'error' });
|
|
6113
|
-
emit(`${key}Failure`, {
|
|
6114
|
-
queryKey: key,
|
|
6115
|
-
error,
|
|
6116
|
-
});
|
|
6199
|
+
emit(`${key}Failure`, { error });
|
|
6117
6200
|
}
|
|
6118
6201
|
if (loading) {
|
|
6119
6202
|
trackedQueries.set(key, { loading: true, lastResult: null });
|
|
@@ -6143,6 +6226,17 @@ const createTrackingFeature = (context, config) => {
|
|
|
6143
6226
|
}
|
|
6144
6227
|
});
|
|
6145
6228
|
}
|
|
6229
|
+
if (context.leaderElection) {
|
|
6230
|
+
const { isLeader: isLeaderSignal, instanceCount: instanceCountSignal } = context.leaderElection;
|
|
6231
|
+
effect(() => {
|
|
6232
|
+
emitDirect('leaderStatusChange', { isLeader: isLeaderSignal() });
|
|
6233
|
+
});
|
|
6234
|
+
effect(() => {
|
|
6235
|
+
emitDirect('leaderInstanceCountChange', {
|
|
6236
|
+
count: instanceCountSignal(),
|
|
6237
|
+
});
|
|
6238
|
+
});
|
|
6239
|
+
}
|
|
6146
6240
|
return {
|
|
6147
6241
|
on,
|
|
6148
6242
|
off,
|
|
@@ -6326,10 +6420,10 @@ class ParseHttpErrorCodeToTitleDePipe {
|
|
|
6326
6420
|
constructor() {
|
|
6327
6421
|
this.transform = parseHttpErrorCodeToTitleDe;
|
|
6328
6422
|
}
|
|
6329
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
6330
|
-
static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.2.
|
|
6423
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: ParseHttpErrorCodeToTitleDePipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
|
|
6424
|
+
static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.2.13", ngImport: i0, type: ParseHttpErrorCodeToTitleDePipe, isStandalone: true, name: "parseHttpErrorCodeToTitleDe" }); }
|
|
6331
6425
|
}
|
|
6332
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
6426
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: ParseHttpErrorCodeToTitleDePipe, decorators: [{
|
|
6333
6427
|
type: Pipe,
|
|
6334
6428
|
args: [{
|
|
6335
6429
|
name: 'parseHttpErrorCodeToTitleDe',
|
|
@@ -6339,10 +6433,10 @@ class ParseHttpErrorCodeToMessageDePipe {
|
|
|
6339
6433
|
constructor() {
|
|
6340
6434
|
this.transform = parseHttpErrorCodeToMessageDe;
|
|
6341
6435
|
}
|
|
6342
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
6343
|
-
static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.2.
|
|
6436
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: ParseHttpErrorCodeToMessageDePipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
|
|
6437
|
+
static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.2.13", ngImport: i0, type: ParseHttpErrorCodeToMessageDePipe, isStandalone: true, name: "parseHttpErrorCodeToMessageDe" }); }
|
|
6344
6438
|
}
|
|
6345
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
6439
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: ParseHttpErrorCodeToMessageDePipe, decorators: [{
|
|
6346
6440
|
type: Pipe,
|
|
6347
6441
|
args: [{
|
|
6348
6442
|
name: 'parseHttpErrorCodeToMessageDe',
|
|
@@ -6526,10 +6620,10 @@ class ParseHttpErrorCodeToTitleEnPipe {
|
|
|
6526
6620
|
constructor() {
|
|
6527
6621
|
this.transform = parseHttpErrorCodeToTitleEn;
|
|
6528
6622
|
}
|
|
6529
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
6530
|
-
static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.2.
|
|
6623
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: ParseHttpErrorCodeToTitleEnPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
|
|
6624
|
+
static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.2.13", ngImport: i0, type: ParseHttpErrorCodeToTitleEnPipe, isStandalone: true, name: "parseHttpErrorCodeToTitleEn" }); }
|
|
6531
6625
|
}
|
|
6532
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
6626
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: ParseHttpErrorCodeToTitleEnPipe, decorators: [{
|
|
6533
6627
|
type: Pipe,
|
|
6534
6628
|
args: [{
|
|
6535
6629
|
name: 'parseHttpErrorCodeToTitleEn',
|
|
@@ -6539,10 +6633,10 @@ class ParseHttpErrorCodeToMessageEnPipe {
|
|
|
6539
6633
|
constructor() {
|
|
6540
6634
|
this.transform = parseHttpErrorCodeToMessageEn;
|
|
6541
6635
|
}
|
|
6542
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
6543
|
-
static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.2.
|
|
6636
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: ParseHttpErrorCodeToMessageEnPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
|
|
6637
|
+
static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.2.13", ngImport: i0, type: ParseHttpErrorCodeToMessageEnPipe, isStandalone: true, name: "parseHttpErrorCodeToMessageEn" }); }
|
|
6544
6638
|
}
|
|
6545
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
6639
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: ParseHttpErrorCodeToMessageEnPipe, decorators: [{
|
|
6546
6640
|
type: Pipe,
|
|
6547
6641
|
args: [{
|
|
6548
6642
|
name: 'parseHttpErrorCodeToMessageEn',
|
|
@@ -6966,8 +7060,11 @@ class QueryForm {
|
|
|
6966
7060
|
continue;
|
|
6967
7061
|
const valueGotRemoved = value === ET_PROPERTY_REMOVED;
|
|
6968
7062
|
if (valueGotRemoved) {
|
|
6969
|
-
|
|
6970
|
-
|
|
7063
|
+
const defaultValue = this._getDefaultValue(key);
|
|
7064
|
+
if (!equal(field.control.value, defaultValue)) {
|
|
7065
|
+
field.control.setValue(defaultValue, { emitEvent: false });
|
|
7066
|
+
didValueChanges = true;
|
|
7067
|
+
}
|
|
6971
7068
|
continue;
|
|
6972
7069
|
}
|
|
6973
7070
|
let deserializedValue = value;
|
|
@@ -7139,6 +7236,21 @@ class QueryForm {
|
|
|
7139
7236
|
});
|
|
7140
7237
|
}
|
|
7141
7238
|
_handleFormChange(forceOverwrite = false) {
|
|
7239
|
+
// Normalize values that have a valueToQueryParamTransformFn returning null/undefined to their
|
|
7240
|
+
// field default before capturing the new value. This prevents intermediate "empty object" states
|
|
7241
|
+
// (e.g. Sort emitting { active: '', direction: '' } when cleared) from being
|
|
7242
|
+
// emitted as distinct form values.
|
|
7243
|
+
for (const [key, field] of Object.entries(this._fields)) {
|
|
7244
|
+
if (!field.data.valueToQueryParamTransformFn)
|
|
7245
|
+
continue;
|
|
7246
|
+
const rawValue = this._formValue[key];
|
|
7247
|
+
if (this._isDefaultValue(key, rawValue))
|
|
7248
|
+
continue;
|
|
7249
|
+
const serialized = field.data.valueToQueryParamTransformFn(rawValue);
|
|
7250
|
+
if (serialized !== null && serialized !== undefined)
|
|
7251
|
+
continue;
|
|
7252
|
+
this.form.controls[key]?.setValue(this._getDefaultValue(key), { emitEvent: false });
|
|
7253
|
+
}
|
|
7142
7254
|
const currentVal = clone(this._currentFormValue$.value);
|
|
7143
7255
|
const newVal = clone(this._formValue);
|
|
7144
7256
|
if (equal(currentVal, newVal)) {
|
|
@@ -7194,17 +7306,17 @@ const createWebSocketClient = (options) => {
|
|
|
7194
7306
|
transports: options.transports,
|
|
7195
7307
|
});
|
|
7196
7308
|
const rooms = new Map();
|
|
7197
|
-
const isConnected = signal(false, ...(ngDevMode ? [{ debugName: "isConnected" }] : []));
|
|
7309
|
+
const isConnected = signal(false, ...(ngDevMode ? [{ debugName: "isConnected" }] : /* istanbul ignore next */ []));
|
|
7198
7310
|
const joinRoom = (room) => {
|
|
7199
7311
|
const roomFn = typeof room === 'function' ? room : () => room;
|
|
7200
7312
|
const pre = previousSignalValue(computed(() => roomFn()));
|
|
7201
|
-
const roomData = signal(null, ...(ngDevMode ? [{ debugName: "roomData" }] : []));
|
|
7313
|
+
const roomData = signal(null, ...(ngDevMode ? [{ debugName: "roomData" }] : /* istanbul ignore next */ []));
|
|
7202
7314
|
const join = (name) => {
|
|
7203
7315
|
socket.emit('join-room', name);
|
|
7204
7316
|
const existingRoom = rooms.get(name);
|
|
7205
7317
|
if (existingRoom)
|
|
7206
7318
|
return existingRoom;
|
|
7207
|
-
const message = signal(null, ...(ngDevMode ? [{ debugName: "message" }] : []));
|
|
7319
|
+
const message = signal(null, ...(ngDevMode ? [{ debugName: "message" }] : /* istanbul ignore next */ []));
|
|
7208
7320
|
const newRoom = {
|
|
7209
7321
|
latestMessage: message,
|
|
7210
7322
|
};
|