@ethlete/query 5.18.0 → 5.20.0
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 +12 -0
- package/esm2022/lib/devtools/components/query-devtools/query-devtools.component.mjs +3 -3
- package/esm2022/lib/devtools/pipes/query-short-name.pipe.mjs +3 -3
- package/esm2022/lib/directives/infinity-query-trigger.directive.mjs +3 -3
- package/esm2022/lib/directives/infinity-query.directive.mjs +3 -3
- package/esm2022/lib/directives/query.directive.mjs +3 -3
- package/esm2022/lib/experimental/bearer-auth-provider-config.mjs +2 -2
- package/esm2022/lib/experimental/bearer-auth-provider.mjs +2 -2
- package/esm2022/lib/experimental/http-request.mjs +10 -9
- package/esm2022/lib/experimental/index.mjs +2 -1
- package/esm2022/lib/experimental/query-dependencies.mjs +6 -6
- package/esm2022/lib/experimental/query-errors.mjs +7 -1
- package/esm2022/lib/experimental/query-execute-utils.mjs +19 -22
- package/esm2022/lib/experimental/query-execute.mjs +9 -7
- package/esm2022/lib/experimental/query-features.mjs +13 -13
- package/esm2022/lib/experimental/query-repository.mjs +28 -22
- package/esm2022/lib/experimental/query-snapshot.mjs +2 -1
- package/esm2022/lib/experimental/query-stack.mjs +65 -0
- package/esm2022/lib/experimental/query-utils.mjs +32 -4
- package/esm2022/lib/experimental/query.mjs +6 -14
- package/esm2022/lib/experimental/secure-query-execute.mjs +9 -6
- package/esm2022/lib/experimental/secure-query.mjs +6 -14
- package/esm2022/lib/query/query.types.mjs +1 -1
- package/esm2022/lib/query-form/query-form.mjs +15 -6
- package/esm2022/lib/query-form/query-form.types.mjs +1 -1
- package/fesm2022/ethlete-query.mjs +229 -123
- package/fesm2022/ethlete-query.mjs.map +1 -1
- package/lib/experimental/http-request.d.ts +72 -14
- package/lib/experimental/index.d.ts +1 -0
- package/lib/experimental/query-dependencies.d.ts +2 -2
- package/lib/experimental/query-errors.d.ts +5 -1
- package/lib/experimental/query-execute-utils.d.ts +12 -4
- package/lib/experimental/query-execute.d.ts +9 -2
- package/lib/experimental/query-features.d.ts +4 -1
- package/lib/experimental/query-repository.d.ts +41 -20
- package/lib/experimental/query-snapshot.d.ts +2 -0
- package/lib/experimental/query-stack.d.ts +46 -0
- package/lib/experimental/query-utils.d.ts +10 -2
- package/lib/experimental/query.d.ts +8 -5
- package/lib/experimental/secure-query.d.ts +2 -2
- package/lib/query/query.types.d.ts +3 -0
- package/lib/query-form/query-form.types.d.ts +8 -0
- package/package.json +1 -1
|
@@ -2,7 +2,7 @@ import * as i1 from '@ethlete/core';
|
|
|
2
2
|
import { createDestroy, computedTillTruthy, getCookie, setCookie, deleteCookie, DelayableDirective, nextFrame, RuntimeError, isObject, getDomain, syncSignal, injectQueryParamChanges, injectQueryParams, clone, equal, ET_PROPERTY_REMOVED } from '@ethlete/core';
|
|
3
3
|
import { Observable, takeUntil, startWith, pairwise, tap, switchMap, of, BehaviorSubject, Subject, fromEvent, timer, take, filter, takeWhile, map, shareReplay, ReplaySubject, combineLatest, interval, skip, withLatestFrom, debounceTime, Subscription, retry, throwError, catchError, merge } from 'rxjs';
|
|
4
4
|
import * as i0 from '@angular/core';
|
|
5
|
-
import { assertInInjectionContext, inject, Injector, computed, signal, isDevMode, untracked, TemplateRef, ViewContainerRef, ErrorHandler, ChangeDetectorRef, Directive, Input, InjectionToken, ElementRef, Pipe, effect, Component, ChangeDetectionStrategy, ViewEncapsulation,
|
|
5
|
+
import { assertInInjectionContext, inject, Injector, computed, signal, isDevMode, untracked, TemplateRef, ViewContainerRef, ErrorHandler, ChangeDetectorRef, Directive, Input, InjectionToken, ElementRef, Pipe, effect, Component, ChangeDetectionStrategy, ViewEncapsulation, runInInjectionContext, EnvironmentInjector, createEnvironmentInjector, DestroyRef, NgZone } from '@angular/core';
|
|
6
6
|
import { toSignal, toObservable, takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
|
7
7
|
import { AsyncPipe, JsonPipe, NgClass } from '@angular/common';
|
|
8
8
|
import * as i1$1 from '@angular/forms';
|
|
@@ -1959,10 +1959,10 @@ class QueryDirective {
|
|
|
1959
1959
|
this._viewContainerRef.createEmbeddedView(this._mainTemplateRef, this._viewContext);
|
|
1960
1960
|
}
|
|
1961
1961
|
}
|
|
1962
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.
|
|
1963
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.
|
|
1962
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.6", ngImport: i0, type: QueryDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
1963
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.2.6", type: QueryDirective, isStandalone: true, selector: "[etQuery]", inputs: { query: ["etQuery", "query"], cache: ["etQueryCache", "cache"] }, ngImport: i0 }); }
|
|
1964
1964
|
}
|
|
1965
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.
|
|
1965
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.6", ngImport: i0, type: QueryDirective, decorators: [{
|
|
1966
1966
|
type: Directive,
|
|
1967
1967
|
args: [{
|
|
1968
1968
|
// eslint-disable-next-line @angular-eslint/directive-selector
|
|
@@ -2270,10 +2270,10 @@ class InfinityQueryDirective {
|
|
|
2270
2270
|
this._viewContext.currentQuery = null;
|
|
2271
2271
|
this._data$.next([]);
|
|
2272
2272
|
}
|
|
2273
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.
|
|
2274
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.
|
|
2273
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.6", ngImport: i0, type: InfinityQueryDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
2274
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.2.6", type: InfinityQueryDirective, isStandalone: true, selector: "[etInfinityQuery]", inputs: { infinityQuery: ["etInfinityQuery", "infinityQuery"] }, providers: [{ provide: INFINITY_QUERY_TOKEN, useExisting: InfinityQueryDirective }], exportAs: ["etInfinityQuery"], hostDirectives: [{ directive: i1.DelayableDirective }], ngImport: i0 }); }
|
|
2275
2275
|
}
|
|
2276
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.
|
|
2276
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.6", ngImport: i0, type: InfinityQueryDirective, decorators: [{
|
|
2277
2277
|
type: Directive,
|
|
2278
2278
|
args: [{
|
|
2279
2279
|
// eslint-disable-next-line @angular-eslint/directive-selector
|
|
@@ -2326,10 +2326,10 @@ class InfinityQueryTriggerDirective {
|
|
|
2326
2326
|
});
|
|
2327
2327
|
this._observer.observe(this._elementRef.nativeElement);
|
|
2328
2328
|
}
|
|
2329
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.
|
|
2330
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.
|
|
2329
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.6", ngImport: i0, type: InfinityQueryTriggerDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
2330
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.2.6", type: InfinityQueryTriggerDirective, isStandalone: true, selector: "[etInfinityQueryTrigger], et-infinity-query-trigger", inputs: { scrollContainerSelector: "scrollContainerSelector" }, ngImport: i0 }); }
|
|
2331
2331
|
}
|
|
2332
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.
|
|
2332
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.6", ngImport: i0, type: InfinityQueryTriggerDirective, decorators: [{
|
|
2333
2333
|
type: Directive,
|
|
2334
2334
|
args: [{
|
|
2335
2335
|
// eslint-disable-next-line @angular-eslint/directive-selector
|
|
@@ -2354,10 +2354,10 @@ class QueryShortNamePipe {
|
|
|
2354
2354
|
}
|
|
2355
2355
|
return route;
|
|
2356
2356
|
}
|
|
2357
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.
|
|
2358
|
-
static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "18.
|
|
2357
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.6", ngImport: i0, type: QueryShortNamePipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
|
|
2358
|
+
static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "18.2.6", ngImport: i0, type: QueryShortNamePipe, isStandalone: true, name: "queryShortName" }); }
|
|
2359
2359
|
}
|
|
2360
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.
|
|
2360
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.6", ngImport: i0, type: QueryShortNamePipe, decorators: [{
|
|
2361
2361
|
type: Pipe,
|
|
2362
2362
|
args: [{ name: 'queryShortName', standalone: true }]
|
|
2363
2363
|
}] });
|
|
@@ -2648,10 +2648,10 @@ class QueryDevtoolsComponent {
|
|
|
2648
2648
|
clearQueryHistory() {
|
|
2649
2649
|
this.queryHistory$.next([]);
|
|
2650
2650
|
}
|
|
2651
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.
|
|
2652
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.1.4", 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 #3c424a;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 #3c424a;margin-bottom:-12px}.et-qd-queries__browser-list{border-right:1px solid #3c424a;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 #3c424a;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 #3c424a;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: "pipe", type: AsyncPipe, name: "async" }, { kind: "pipe", type: JsonPipe, name: "json" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1$1.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1$1.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "pipe", type: QueryShortNamePipe, name: "queryShortName" }, { kind: "directive", type: QueryDirective, selector: "[etQuery]", inputs: ["etQuery", "etQueryCache"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.ShadowDom }); }
|
|
2651
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.6", ngImport: i0, type: QueryDevtoolsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2652
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.6", 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 #3c424a;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 #3c424a;margin-bottom:-12px}.et-qd-queries__browser-list{border-right:1px solid #3c424a;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 #3c424a;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 #3c424a;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: "pipe", type: AsyncPipe, name: "async" }, { kind: "pipe", type: JsonPipe, name: "json" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1$1.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1$1.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "pipe", type: QueryShortNamePipe, name: "queryShortName" }, { kind: "directive", type: QueryDirective, selector: "[etQuery]", inputs: ["etQuery", "etQueryCache"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.ShadowDom }); }
|
|
2653
2653
|
}
|
|
2654
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.
|
|
2654
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.6", ngImport: i0, type: QueryDevtoolsComponent, decorators: [{
|
|
2655
2655
|
type: Component,
|
|
2656
2656
|
args: [{ selector: 'et-query-devtools', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.ShadowDom, host: {
|
|
2657
2657
|
class: 'et-query-devtools',
|
|
@@ -2865,6 +2865,12 @@ const unableToDecryptBearerToken = (token) => {
|
|
|
2865
2865
|
const bearerExpiresInPropertyNotNumber = (expiresIn) => {
|
|
2866
2866
|
return new RuntimeError(211 /* RuntimeErrorCode.BEARER_EXPIRES_IN_PROPERTY_NOT_NUMBER */, `The expires in property is not a number: ${expiresIn}`);
|
|
2867
2867
|
};
|
|
2868
|
+
const uncacheableRequestHasCacheKeyParam = (key) => {
|
|
2869
|
+
return new RuntimeError(300 /* RuntimeErrorCode.UNCACHEABLE_REQUEST_HAS_CACHE_KEY_PARAM */, `This request is uncacheable, but a cache key was provided: ${key}. Please remove it.`);
|
|
2870
|
+
};
|
|
2871
|
+
const uncacheableRequestHasSkipCacheParam = () => {
|
|
2872
|
+
return new RuntimeError(301 /* RuntimeErrorCode.UNCACHEABLE_REQUEST_HAS_SKIP_CACHE_PARAM */, `This request is uncacheable, but skipCache is set to true. Please remove it.`);
|
|
2873
|
+
};
|
|
2868
2874
|
|
|
2869
2875
|
/* eslint-disable @typescript-eslint/no-empty-function */
|
|
2870
2876
|
const defaultResponseTransformer = (response) => {
|
|
@@ -2910,7 +2916,7 @@ const createAuthProviderQuery = (config, authProviderConfig) => {
|
|
|
2910
2916
|
return remainingTime;
|
|
2911
2917
|
});
|
|
2912
2918
|
const execute = (newArgs, options) => {
|
|
2913
|
-
query.execute(newArgs);
|
|
2919
|
+
query.execute({ args: newArgs });
|
|
2914
2920
|
triggeredInternally.set(options?.triggeredInternally ?? false);
|
|
2915
2921
|
};
|
|
2916
2922
|
return {
|
|
@@ -3112,7 +3118,7 @@ const createBearerAuthProviderConfig = (options) => {
|
|
|
3112
3118
|
queryClientRef: options.queryClientRef,
|
|
3113
3119
|
token,
|
|
3114
3120
|
cookie: options.cookie,
|
|
3115
|
-
expiresInPropertyName: options.expiresInPropertyName
|
|
3121
|
+
expiresInPropertyName: options.expiresInPropertyName || 'exp',
|
|
3116
3122
|
refreshBuffer: options.refreshBuffer ?? 300000,
|
|
3117
3123
|
refreshOnUnauthorizedResponse: options.refreshOnUnauthorizedResponse ?? true,
|
|
3118
3124
|
login: options.login,
|
|
@@ -3134,7 +3140,19 @@ const QUERY_EFFECT_ERROR_MESSAGE = 'Effect triggered too often. This is probably
|
|
|
3134
3140
|
const queryEffect = (fn, errorMessage, options) => {
|
|
3135
3141
|
let lastTriggerTs = 0;
|
|
3136
3142
|
let illegalWrites = 0;
|
|
3137
|
-
|
|
3143
|
+
// The first run should be synchronous anf not depend on the angular scheduler
|
|
3144
|
+
if (options?.injector) {
|
|
3145
|
+
runInInjectionContext(options.injector, () => fn());
|
|
3146
|
+
}
|
|
3147
|
+
else {
|
|
3148
|
+
fn();
|
|
3149
|
+
}
|
|
3150
|
+
let isFirstRun = true;
|
|
3151
|
+
return untracked(() => effect(() => {
|
|
3152
|
+
if (isFirstRun) {
|
|
3153
|
+
isFirstRun = false;
|
|
3154
|
+
return;
|
|
3155
|
+
}
|
|
3138
3156
|
if (isDevMode()) {
|
|
3139
3157
|
const now = performance.now();
|
|
3140
3158
|
if (now - lastTriggerTs < 100) {
|
|
@@ -3146,7 +3164,7 @@ const queryEffect = (fn, errorMessage, options) => {
|
|
|
3146
3164
|
lastTriggerTs = now;
|
|
3147
3165
|
}
|
|
3148
3166
|
fn();
|
|
3149
|
-
}, options);
|
|
3167
|
+
}, options));
|
|
3150
3168
|
};
|
|
3151
3169
|
const shouldAutoExecuteQuery = (method) => {
|
|
3152
3170
|
return method === 'GET' || method === 'HEAD' || method === 'OPTIONS';
|
|
@@ -3266,11 +3284,28 @@ const maybeExecute = (options) => {
|
|
|
3266
3284
|
options.execute();
|
|
3267
3285
|
}
|
|
3268
3286
|
};
|
|
3287
|
+
const createQueryObject = (options) => {
|
|
3288
|
+
const { state, execute, createSnapshot, destroy } = options;
|
|
3289
|
+
const query = {
|
|
3290
|
+
execute,
|
|
3291
|
+
args: state.args.asReadonly(),
|
|
3292
|
+
response: state.response.asReadonly(),
|
|
3293
|
+
latestHttpEvent: state.latestHttpEvent.asReadonly(),
|
|
3294
|
+
loading: state.loading.asReadonly(),
|
|
3295
|
+
error: state.error.asReadonly(),
|
|
3296
|
+
lastTimeExecutedAt: state.lastTimeExecutedAt.asReadonly(),
|
|
3297
|
+
id: execute.currentRepositoryKey,
|
|
3298
|
+
createSnapshot,
|
|
3299
|
+
destroy,
|
|
3300
|
+
};
|
|
3301
|
+
return query;
|
|
3302
|
+
};
|
|
3269
3303
|
|
|
3270
3304
|
/* eslint-disable @typescript-eslint/no-empty-function */
|
|
3271
3305
|
const SPEED_BUFFER_TIME_IN_MS = 2000;
|
|
3272
3306
|
const createHttpRequest = (options) => {
|
|
3273
3307
|
let currentStreamSubscription = Subscription.EMPTY;
|
|
3308
|
+
const { args, clientOptions, dependencies } = options;
|
|
3274
3309
|
const currentEvent = signal(null);
|
|
3275
3310
|
const loading = signal(null);
|
|
3276
3311
|
const error = signal(null);
|
|
@@ -3283,16 +3318,16 @@ const createHttpRequest = (options) => {
|
|
|
3283
3318
|
const expiresInTs = expiresIn();
|
|
3284
3319
|
return expiresInTs === null || expiresInTs < Date.now();
|
|
3285
3320
|
});
|
|
3286
|
-
const stream =
|
|
3321
|
+
const stream = dependencies.httpClient
|
|
3287
3322
|
.request(options.method, options.fullPath, {
|
|
3288
3323
|
observe: 'events',
|
|
3289
|
-
body:
|
|
3290
|
-
reportProgress:
|
|
3291
|
-
withCredentials:
|
|
3292
|
-
transferCache:
|
|
3293
|
-
responseType:
|
|
3294
|
-
context:
|
|
3295
|
-
headers:
|
|
3324
|
+
body: args?.body,
|
|
3325
|
+
reportProgress: clientOptions?.reportProgress,
|
|
3326
|
+
withCredentials: clientOptions?.withCredentials,
|
|
3327
|
+
transferCache: clientOptions?.transferCache,
|
|
3328
|
+
responseType: clientOptions?.responseType || 'json',
|
|
3329
|
+
context: clientOptions?.context,
|
|
3330
|
+
headers: args?.headers,
|
|
3296
3331
|
})
|
|
3297
3332
|
.pipe(tap((event) => updateState(event)), retry({
|
|
3298
3333
|
delay: (error, retryCount) => {
|
|
@@ -3415,26 +3450,24 @@ const createHttpRequest = (options) => {
|
|
|
3415
3450
|
return httpRequest;
|
|
3416
3451
|
};
|
|
3417
3452
|
|
|
3418
|
-
/* eslint-disable @typescript-eslint/no-empty-function */
|
|
3419
3453
|
const setupQueryDependencies = (options) => {
|
|
3420
|
-
const
|
|
3454
|
+
const environmentInjector = inject(EnvironmentInjector);
|
|
3455
|
+
const queryEnvironmentInjector = createEnvironmentInjector([], environmentInjector);
|
|
3456
|
+
const destroyRef = queryEnvironmentInjector.get(DestroyRef);
|
|
3421
3457
|
const client = inject(options.clientConfig.token);
|
|
3422
|
-
const injector = inject(Injector);
|
|
3423
3458
|
const dependencies = {
|
|
3424
3459
|
destroyRef,
|
|
3425
3460
|
client,
|
|
3426
|
-
injector,
|
|
3461
|
+
injector: queryEnvironmentInjector,
|
|
3427
3462
|
};
|
|
3428
3463
|
return dependencies;
|
|
3429
3464
|
};
|
|
3430
3465
|
|
|
3431
3466
|
const resetExecuteState = (options) => {
|
|
3432
3467
|
const { executeState, executeOptions: opts } = options;
|
|
3433
|
-
const {
|
|
3434
|
-
|
|
3435
|
-
deps.client.repository.unbind(previousKey, deps.destroyRef);
|
|
3436
|
-
effectRefs.forEach((ref) => ref.destroy());
|
|
3437
|
-
effectRefs.length = 0;
|
|
3468
|
+
const { state } = opts;
|
|
3469
|
+
cleanupPreviousExecute({ executeOptions: opts, executeState });
|
|
3470
|
+
opts.deps.client.repository.unbind(executeState.previousKey(), opts.deps.destroyRef);
|
|
3438
3471
|
state.args.set(null);
|
|
3439
3472
|
state.error.set(null);
|
|
3440
3473
|
state.latestHttpEvent.set(null);
|
|
@@ -3445,27 +3478,28 @@ const resetExecuteState = (options) => {
|
|
|
3445
3478
|
const setupQueryExecuteState = () => {
|
|
3446
3479
|
return {
|
|
3447
3480
|
effectRefs: [],
|
|
3448
|
-
previousKey: false,
|
|
3481
|
+
previousKey: signal(false),
|
|
3449
3482
|
};
|
|
3450
3483
|
};
|
|
3451
3484
|
const queryExecute = (options) => {
|
|
3452
|
-
const { executeOptions, args, executeState } = options;
|
|
3485
|
+
const { executeOptions, args, executeState, options: runQueryOptions } = options;
|
|
3453
3486
|
const { deps, state, creator, creatorInternals, queryConfig } = executeOptions;
|
|
3454
3487
|
const { key, request } = deps.client.repository.request({
|
|
3455
|
-
method: creatorInternals.method,
|
|
3456
3488
|
route: creator.route,
|
|
3457
|
-
|
|
3458
|
-
|
|
3459
|
-
|
|
3460
|
-
|
|
3461
|
-
|
|
3462
|
-
|
|
3463
|
-
|
|
3489
|
+
method: creatorInternals.method,
|
|
3490
|
+
args,
|
|
3491
|
+
clientOptions: {
|
|
3492
|
+
reportProgress: creator.reportProgress,
|
|
3493
|
+
withCredentials: creator.withCredentials,
|
|
3494
|
+
transferCache: creator.transferCache,
|
|
3495
|
+
responseType: creator.responseType,
|
|
3496
|
+
},
|
|
3464
3497
|
destroyRef: deps.destroyRef,
|
|
3465
3498
|
key: queryConfig.key,
|
|
3466
|
-
|
|
3499
|
+
previousKey: executeState.previousKey(),
|
|
3500
|
+
runQueryOptions,
|
|
3467
3501
|
});
|
|
3468
|
-
executeState.previousKey
|
|
3502
|
+
executeState.previousKey.set(key);
|
|
3469
3503
|
runInInjectionContext(deps.injector, () => {
|
|
3470
3504
|
const responseRef = syncSignal(request.response, state.response);
|
|
3471
3505
|
const loadingRef = syncSignal(request.loading, state.loading);
|
|
@@ -3476,21 +3510,21 @@ const queryExecute = (options) => {
|
|
|
3476
3510
|
state.lastTimeExecutedAt.set(Date.now());
|
|
3477
3511
|
};
|
|
3478
3512
|
const cleanupPreviousExecute = (options) => {
|
|
3479
|
-
const {
|
|
3480
|
-
const { deps } = executeOptions;
|
|
3481
|
-
deps.client.repository.unbind(executeState.previousKey, deps.destroyRef);
|
|
3513
|
+
const { executeState } = options;
|
|
3482
3514
|
executeState.effectRefs.forEach((ref) => ref.destroy());
|
|
3483
3515
|
executeState.effectRefs.length = 0;
|
|
3484
3516
|
};
|
|
3485
3517
|
|
|
3486
|
-
const createExecuteFn = (
|
|
3518
|
+
const createExecuteFn = (executeOptions) => {
|
|
3487
3519
|
const executeState = setupQueryExecuteState();
|
|
3488
|
-
const reset = () => resetExecuteState({ executeState, executeOptions
|
|
3489
|
-
const exec = (
|
|
3490
|
-
|
|
3491
|
-
|
|
3520
|
+
const reset = () => resetExecuteState({ executeState, executeOptions });
|
|
3521
|
+
const exec = (executeArgs) => {
|
|
3522
|
+
const { args = executeOptions.state.args() } = executeArgs ?? {};
|
|
3523
|
+
cleanupPreviousExecute({ executeOptions, executeState });
|
|
3524
|
+
queryExecute({ executeOptions, executeState, args });
|
|
3492
3525
|
};
|
|
3493
3526
|
exec['reset'] = reset;
|
|
3527
|
+
exec['currentRepositoryKey'] = executeState.previousKey.asReadonly();
|
|
3494
3528
|
return exec;
|
|
3495
3529
|
};
|
|
3496
3530
|
|
|
@@ -3549,6 +3583,7 @@ const createQuerySnapshotFn = (options) => {
|
|
|
3549
3583
|
error: snapshotState.error.asReadonly(),
|
|
3550
3584
|
lastTimeExecutedAt: snapshotState.lastTimeExecutedAt.asReadonly(),
|
|
3551
3585
|
isAlive: isAlive.asReadonly(),
|
|
3586
|
+
id: options.execute.currentRepositoryKey,
|
|
3552
3587
|
};
|
|
3553
3588
|
return snapshot;
|
|
3554
3589
|
};
|
|
@@ -3563,7 +3598,8 @@ const createQuery = (options) => {
|
|
|
3563
3598
|
const { creator, creatorInternals, queryConfig } = options;
|
|
3564
3599
|
const flags = getQueryFeatureUsage(options);
|
|
3565
3600
|
const execute = createExecuteFn({ deps, state, creator, creatorInternals, queryConfig: options.queryConfig });
|
|
3566
|
-
const createSnapshot = createQuerySnapshotFn({ state, deps });
|
|
3601
|
+
const createSnapshot = createQuerySnapshotFn({ state, deps, execute });
|
|
3602
|
+
const destroy = () => deps.injector.destroy();
|
|
3567
3603
|
const featureFnContext = {
|
|
3568
3604
|
state,
|
|
3569
3605
|
queryConfig,
|
|
@@ -3571,67 +3607,64 @@ const createQuery = (options) => {
|
|
|
3571
3607
|
creatorInternals,
|
|
3572
3608
|
execute,
|
|
3573
3609
|
flags,
|
|
3610
|
+
deps,
|
|
3574
3611
|
};
|
|
3575
3612
|
applyQueryFeatures(options, featureFnContext);
|
|
3576
3613
|
maybeExecute({ execute, flags });
|
|
3577
|
-
|
|
3578
|
-
execute,
|
|
3579
|
-
args: state.args.asReadonly(),
|
|
3580
|
-
response: state.response.asReadonly(),
|
|
3581
|
-
latestHttpEvent: state.latestHttpEvent.asReadonly(),
|
|
3582
|
-
loading: state.loading.asReadonly(),
|
|
3583
|
-
error: state.error.asReadonly(),
|
|
3584
|
-
lastTimeExecutedAt: state.lastTimeExecutedAt.asReadonly(),
|
|
3585
|
-
createSnapshot,
|
|
3586
|
-
};
|
|
3587
|
-
return query;
|
|
3614
|
+
return createQueryObject({ state, execute, createSnapshot, destroy });
|
|
3588
3615
|
};
|
|
3589
3616
|
|
|
3590
|
-
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
3591
|
-
/* eslint-disable @typescript-eslint/no-empty-function */
|
|
3592
3617
|
const createQueryRepository = (config) => {
|
|
3593
3618
|
const httpClient = inject(HttpClient);
|
|
3594
3619
|
const cache = new Map();
|
|
3595
3620
|
const request = (options) => {
|
|
3621
|
+
const { args, clientOptions, runQueryOptions } = options;
|
|
3596
3622
|
const shouldCache = shouldCacheQuery(options.method);
|
|
3623
|
+
if (!shouldCache && options.key)
|
|
3624
|
+
throw uncacheableRequestHasCacheKeyParam(options.key);
|
|
3625
|
+
if (!shouldCache && runQueryOptions?.skipCache)
|
|
3626
|
+
throw uncacheableRequestHasSkipCacheParam();
|
|
3597
3627
|
const route = buildRoute({
|
|
3598
3628
|
base: config.baseUrl,
|
|
3599
3629
|
route: options.route,
|
|
3600
|
-
pathParams:
|
|
3601
|
-
queryParams:
|
|
3630
|
+
pathParams: args?.pathParams,
|
|
3631
|
+
queryParams: args?.queryParams,
|
|
3602
3632
|
queryParamConfig: config.queryString,
|
|
3603
3633
|
});
|
|
3604
3634
|
const key = shouldCache &&
|
|
3605
3635
|
buildQueryCacheKey(`${options.key ? options.key + '_' : ''}${route}`, {
|
|
3606
|
-
body:
|
|
3607
|
-
queryParams:
|
|
3608
|
-
pathParams:
|
|
3636
|
+
body: args?.body,
|
|
3637
|
+
queryParams: args?.queryParams,
|
|
3638
|
+
pathParams: args?.pathParams,
|
|
3609
3639
|
// TODO: remaining props
|
|
3640
|
+
// headers: args?.headers,
|
|
3610
3641
|
});
|
|
3642
|
+
const previousKey = options.previousKey;
|
|
3643
|
+
if (key !== previousKey && previousKey) {
|
|
3644
|
+
unbind(previousKey, options.destroyRef);
|
|
3645
|
+
}
|
|
3611
3646
|
if (shouldCache && key) {
|
|
3612
3647
|
const cacheEntry = cache.get(key);
|
|
3613
3648
|
if (cacheEntry) {
|
|
3614
3649
|
bind(key, options.destroyRef, cacheEntry.request);
|
|
3615
|
-
if (
|
|
3650
|
+
if (runQueryOptions?.skipCache || cacheEntry.request.isStale()) {
|
|
3616
3651
|
cacheEntry.request.execute();
|
|
3652
|
+
}
|
|
3617
3653
|
return { key, request: cacheEntry.request };
|
|
3618
3654
|
}
|
|
3619
3655
|
}
|
|
3620
3656
|
const request = createHttpRequest({
|
|
3621
3657
|
fullPath: route,
|
|
3622
|
-
|
|
3623
|
-
reportProgress: options.reportProgress,
|
|
3624
|
-
withCredentials: options.withCredentials,
|
|
3625
|
-
transferCache: options.transferCache,
|
|
3626
|
-
responseType: options.responseType || 'json',
|
|
3658
|
+
args,
|
|
3627
3659
|
method: options.method,
|
|
3628
|
-
|
|
3629
|
-
|
|
3660
|
+
dependencies: {
|
|
3661
|
+
httpClient,
|
|
3662
|
+
},
|
|
3663
|
+
clientOptions,
|
|
3630
3664
|
cacheAdapter: config.cacheAdapter,
|
|
3631
3665
|
retryFn: config.retryFn,
|
|
3632
3666
|
});
|
|
3633
|
-
|
|
3634
|
-
request.execute();
|
|
3667
|
+
request.execute();
|
|
3635
3668
|
if (shouldCache && key) {
|
|
3636
3669
|
bind(key, options.destroyRef, request);
|
|
3637
3670
|
}
|
|
@@ -3639,19 +3672,18 @@ const createQueryRepository = (config) => {
|
|
|
3639
3672
|
};
|
|
3640
3673
|
const unbind = (key, destroyRef) => {
|
|
3641
3674
|
if (!key)
|
|
3642
|
-
return;
|
|
3675
|
+
return false;
|
|
3643
3676
|
const cacheEntry = cache.get(key);
|
|
3644
3677
|
if (!cacheEntry)
|
|
3645
|
-
return;
|
|
3678
|
+
return false;
|
|
3646
3679
|
cacheEntry.consumers.delete(destroyRef);
|
|
3647
3680
|
if (cacheEntry.consumers.size === 0) {
|
|
3648
3681
|
cacheEntry.request.destroy();
|
|
3649
3682
|
cache.delete(key);
|
|
3650
3683
|
}
|
|
3684
|
+
return true;
|
|
3651
3685
|
};
|
|
3652
3686
|
const bind = (key, destroyRef, request) => {
|
|
3653
|
-
if (!key)
|
|
3654
|
-
return;
|
|
3655
3687
|
const destroyListener = destroyRef.onDestroy(() => unbind(key, destroyRef));
|
|
3656
3688
|
const cacheEntry = cache.get(key);
|
|
3657
3689
|
if (cacheEntry) {
|
|
@@ -3745,7 +3777,8 @@ const createSecureExecuteFn = (options) => {
|
|
|
3745
3777
|
state.latestHttpEvent.set(null);
|
|
3746
3778
|
state.args.set(null);
|
|
3747
3779
|
};
|
|
3748
|
-
const authAndExec = (
|
|
3780
|
+
const authAndExec = (executeArgs) => {
|
|
3781
|
+
const { args, options: runOptions } = executeArgs ?? {};
|
|
3749
3782
|
const tokens = authProvider.tokens();
|
|
3750
3783
|
let headers = args?.headers || new HttpHeaders();
|
|
3751
3784
|
if (!tokens) {
|
|
@@ -3759,12 +3792,13 @@ const createSecureExecuteFn = (options) => {
|
|
|
3759
3792
|
executeOptions: options,
|
|
3760
3793
|
executeState,
|
|
3761
3794
|
args: updatedArgs,
|
|
3795
|
+
options: runOptions,
|
|
3762
3796
|
});
|
|
3763
3797
|
};
|
|
3764
|
-
const exec = (
|
|
3798
|
+
const exec = (executeArgs) => {
|
|
3765
3799
|
authQuerySubscription.unsubscribe();
|
|
3766
3800
|
authQuerySubscription = Subscription.EMPTY;
|
|
3767
|
-
cleanupPreviousExecute({ executeOptions: options, executeState
|
|
3801
|
+
cleanupPreviousExecute({ executeOptions: options, executeState });
|
|
3768
3802
|
const authQuery = authProvider.latestExecutedQuery();
|
|
3769
3803
|
if (!authQuery || authQuery.loading()) {
|
|
3770
3804
|
options.state.loading.set({ executeTime: Date.now(), progress: null });
|
|
@@ -3779,14 +3813,14 @@ const createSecureExecuteFn = (options) => {
|
|
|
3779
3813
|
error(query);
|
|
3780
3814
|
}
|
|
3781
3815
|
else if (query.response()) {
|
|
3782
|
-
authAndExec(
|
|
3816
|
+
authAndExec(executeArgs);
|
|
3783
3817
|
}
|
|
3784
3818
|
}));
|
|
3785
3819
|
}))
|
|
3786
3820
|
.subscribe();
|
|
3787
3821
|
}
|
|
3788
3822
|
else if (authQuery.response()) {
|
|
3789
|
-
authAndExec(
|
|
3823
|
+
authAndExec(executeArgs);
|
|
3790
3824
|
}
|
|
3791
3825
|
else if (authQuery.error()) {
|
|
3792
3826
|
error(authQuery);
|
|
@@ -3796,6 +3830,7 @@ const createSecureExecuteFn = (options) => {
|
|
|
3796
3830
|
}
|
|
3797
3831
|
};
|
|
3798
3832
|
exec['reset'] = reset;
|
|
3833
|
+
exec['currentRepositoryKey'] = executeState.previousKey.asReadonly();
|
|
3799
3834
|
return exec;
|
|
3800
3835
|
};
|
|
3801
3836
|
|
|
@@ -3811,7 +3846,8 @@ const createSecureQuery = (options) => {
|
|
|
3811
3846
|
creatorInternals,
|
|
3812
3847
|
queryConfig: options.queryConfig,
|
|
3813
3848
|
});
|
|
3814
|
-
const createSnapshot = createQuerySnapshotFn({ state, deps });
|
|
3849
|
+
const createSnapshot = createQuerySnapshotFn({ state, deps, execute });
|
|
3850
|
+
const destroy = () => deps.injector.destroy();
|
|
3815
3851
|
const featureFnContext = {
|
|
3816
3852
|
state,
|
|
3817
3853
|
queryConfig,
|
|
@@ -3819,20 +3855,11 @@ const createSecureQuery = (options) => {
|
|
|
3819
3855
|
creatorInternals,
|
|
3820
3856
|
execute,
|
|
3821
3857
|
flags,
|
|
3858
|
+
deps,
|
|
3822
3859
|
};
|
|
3823
3860
|
applyQueryFeatures(options, featureFnContext);
|
|
3824
3861
|
maybeExecute({ execute, flags });
|
|
3825
|
-
|
|
3826
|
-
execute,
|
|
3827
|
-
args: state.args.asReadonly(),
|
|
3828
|
-
response: state.response.asReadonly(),
|
|
3829
|
-
latestHttpEvent: state.latestHttpEvent.asReadonly(),
|
|
3830
|
-
loading: state.loading.asReadonly(),
|
|
3831
|
-
error: state.error.asReadonly(),
|
|
3832
|
-
lastTimeExecutedAt: state.lastTimeExecutedAt.asReadonly(),
|
|
3833
|
-
createSnapshot,
|
|
3834
|
-
};
|
|
3835
|
-
return query;
|
|
3862
|
+
return createQueryObject({ state, execute, createSnapshot, destroy });
|
|
3836
3863
|
};
|
|
3837
3864
|
|
|
3838
3865
|
const createSecureQueryCreator = (options, internals) => {
|
|
@@ -3899,9 +3926,9 @@ const withArgs = (args) => {
|
|
|
3899
3926
|
}
|
|
3900
3927
|
context.state.args.set(currArgsNow);
|
|
3901
3928
|
if (context.flags.shouldAutoExecute)
|
|
3902
|
-
context.execute(currArgsNow);
|
|
3929
|
+
context.execute({ args: currArgsNow });
|
|
3903
3930
|
});
|
|
3904
|
-
}, QUERY_EFFECT_ERROR_MESSAGE);
|
|
3931
|
+
}, QUERY_EFFECT_ERROR_MESSAGE, { injector: context.deps.injector });
|
|
3905
3932
|
},
|
|
3906
3933
|
});
|
|
3907
3934
|
};
|
|
@@ -3921,14 +3948,14 @@ const withPolling = (options) => {
|
|
|
3921
3948
|
if (args === null)
|
|
3922
3949
|
return;
|
|
3923
3950
|
if (options.executeInitially) {
|
|
3924
|
-
context.execute(args);
|
|
3951
|
+
context.execute({ args });
|
|
3925
3952
|
}
|
|
3926
3953
|
intervalId = window.setInterval(() => {
|
|
3927
|
-
context.execute(args);
|
|
3954
|
+
context.execute({ args });
|
|
3928
3955
|
}, options.interval);
|
|
3929
3956
|
});
|
|
3930
|
-
}, QUERY_EFFECT_ERROR_MESSAGE);
|
|
3931
|
-
|
|
3957
|
+
}, QUERY_EFFECT_ERROR_MESSAGE, { injector: context.deps.injector });
|
|
3958
|
+
context.deps.destroyRef.onDestroy(() => intervalId !== null && clearInterval(intervalId));
|
|
3932
3959
|
},
|
|
3933
3960
|
});
|
|
3934
3961
|
};
|
|
@@ -3943,7 +3970,7 @@ const withLogging = (options) => {
|
|
|
3943
3970
|
untracked(() => {
|
|
3944
3971
|
options.logFn(event);
|
|
3945
3972
|
});
|
|
3946
|
-
});
|
|
3973
|
+
}, { injector: context.deps.injector });
|
|
3947
3974
|
},
|
|
3948
3975
|
});
|
|
3949
3976
|
};
|
|
@@ -3958,7 +3985,7 @@ const withErrorHandling = (options) => {
|
|
|
3958
3985
|
untracked(() => {
|
|
3959
3986
|
options.handler(error);
|
|
3960
3987
|
});
|
|
3961
|
-
});
|
|
3988
|
+
}, { injector: context.deps.injector });
|
|
3962
3989
|
},
|
|
3963
3990
|
});
|
|
3964
3991
|
};
|
|
@@ -3973,7 +4000,7 @@ const withSuccessHandling = (options) => {
|
|
|
3973
4000
|
untracked(() => {
|
|
3974
4001
|
options.handler(response);
|
|
3975
4002
|
});
|
|
3976
|
-
});
|
|
4003
|
+
}, { injector: context.deps.injector });
|
|
3977
4004
|
},
|
|
3978
4005
|
});
|
|
3979
4006
|
};
|
|
@@ -3995,13 +4022,77 @@ const withAutoRefresh = (options) => {
|
|
|
3995
4022
|
const args = context.state.args();
|
|
3996
4023
|
if (args === null)
|
|
3997
4024
|
return;
|
|
3998
|
-
context.execute(args);
|
|
4025
|
+
context.execute({ args });
|
|
3999
4026
|
});
|
|
4000
|
-
}, QUERY_EFFECT_ERROR_MESSAGE);
|
|
4027
|
+
}, QUERY_EFFECT_ERROR_MESSAGE, { injector: context.deps.injector });
|
|
4001
4028
|
},
|
|
4002
4029
|
});
|
|
4003
4030
|
};
|
|
4004
4031
|
|
|
4032
|
+
const transformArrayResponse = (responses) => responses.filter((r) => !!r).flatMap((r) => r);
|
|
4033
|
+
const transformPaginatedResponse = (responses) => responses.filter((r) => !!r).flatMap((r) => r.items);
|
|
4034
|
+
const createQueryStack = (computation, options) => {
|
|
4035
|
+
const { append = false, appendFn = (oldQueries, newQueries) => {
|
|
4036
|
+
const queries = [...oldQueries, ...newQueries];
|
|
4037
|
+
const lastQuery = newQueries[newQueries.length - 1] ?? oldQueries[oldQueries.length - 1] ?? null;
|
|
4038
|
+
return { queries, lastQuery };
|
|
4039
|
+
}, transform, } = options ?? {};
|
|
4040
|
+
const injector = inject(Injector);
|
|
4041
|
+
const queries = signal([]);
|
|
4042
|
+
const lastQuery = signal(null);
|
|
4043
|
+
effect(() => {
|
|
4044
|
+
const newQueryOrQueries = runInInjectionContext(injector, () => computation());
|
|
4045
|
+
const newQueries = Array.isArray(newQueryOrQueries) ? newQueryOrQueries : [newQueryOrQueries];
|
|
4046
|
+
untracked(() => {
|
|
4047
|
+
const oldQueries = queries();
|
|
4048
|
+
if (append) {
|
|
4049
|
+
const { queries: appendedQueries, lastQuery: lastAppendedQuery } = appendFn(oldQueries, newQueries);
|
|
4050
|
+
queries.set(appendedQueries);
|
|
4051
|
+
lastQuery.set(lastAppendedQuery);
|
|
4052
|
+
}
|
|
4053
|
+
else {
|
|
4054
|
+
for (const oldQuery of oldQueries) {
|
|
4055
|
+
if (!newQueries.some((q) => q.id() === oldQuery.id())) {
|
|
4056
|
+
oldQuery.destroy();
|
|
4057
|
+
}
|
|
4058
|
+
}
|
|
4059
|
+
queries.set(newQueries);
|
|
4060
|
+
lastQuery.set(newQueries[newQueries.length - 1] ?? null);
|
|
4061
|
+
}
|
|
4062
|
+
});
|
|
4063
|
+
});
|
|
4064
|
+
const loading = computed(() => queries().some((q) => q.loading()));
|
|
4065
|
+
const error = computed(() => queries()
|
|
4066
|
+
.map((q) => q.error())
|
|
4067
|
+
.find((e) => e !== null) ?? null);
|
|
4068
|
+
const response = computed(() => {
|
|
4069
|
+
const responses = queries().map((q) => q.response());
|
|
4070
|
+
return transform?.(responses) ?? responses;
|
|
4071
|
+
});
|
|
4072
|
+
const execute = () => {
|
|
4073
|
+
for (const query of queries()) {
|
|
4074
|
+
query.execute();
|
|
4075
|
+
}
|
|
4076
|
+
};
|
|
4077
|
+
const clear = () => {
|
|
4078
|
+
for (const query of queries()) {
|
|
4079
|
+
query.destroy();
|
|
4080
|
+
}
|
|
4081
|
+
queries.set([]);
|
|
4082
|
+
lastQuery.set(null);
|
|
4083
|
+
};
|
|
4084
|
+
const stack = {
|
|
4085
|
+
queries: queries.asReadonly(),
|
|
4086
|
+
lastQuery: lastQuery.asReadonly(),
|
|
4087
|
+
loading,
|
|
4088
|
+
error,
|
|
4089
|
+
response,
|
|
4090
|
+
execute,
|
|
4091
|
+
clear,
|
|
4092
|
+
};
|
|
4093
|
+
return stack;
|
|
4094
|
+
};
|
|
4095
|
+
|
|
4005
4096
|
var index = /*#__PURE__*/Object.freeze({
|
|
4006
4097
|
__proto__: null,
|
|
4007
4098
|
QUERY_ARGS_RESET: QUERY_ARGS_RESET,
|
|
@@ -4024,8 +4115,10 @@ var index = /*#__PURE__*/Object.freeze({
|
|
|
4024
4115
|
createQueryClient: createQueryClient,
|
|
4025
4116
|
createQueryClientConfig: createQueryClientConfig,
|
|
4026
4117
|
createQueryCreator: createQueryCreator,
|
|
4118
|
+
createQueryObject: createQueryObject,
|
|
4027
4119
|
createQueryRepository: createQueryRepository,
|
|
4028
4120
|
createQuerySnapshotFn: createQuerySnapshotFn,
|
|
4121
|
+
createQueryStack: createQueryStack,
|
|
4029
4122
|
createSecureDeleteQuery: createSecureDeleteQuery,
|
|
4030
4123
|
createSecureExecuteFn: createSecureExecuteFn,
|
|
4031
4124
|
createSecureGetQuery: createSecureGetQuery,
|
|
@@ -4058,7 +4151,11 @@ var index = /*#__PURE__*/Object.freeze({
|
|
|
4058
4151
|
shouldAutoExecuteQuery: shouldAutoExecuteQuery,
|
|
4059
4152
|
shouldRetryRequest: shouldRetryRequest,
|
|
4060
4153
|
splitQueryConfig: splitQueryConfig,
|
|
4154
|
+
transformArrayResponse: transformArrayResponse,
|
|
4155
|
+
transformPaginatedResponse: transformPaginatedResponse,
|
|
4061
4156
|
unableToDecryptBearerToken: unableToDecryptBearerToken,
|
|
4157
|
+
uncacheableRequestHasCacheKeyParam: uncacheableRequestHasCacheKeyParam,
|
|
4158
|
+
uncacheableRequestHasSkipCacheParam: uncacheableRequestHasSkipCacheParam,
|
|
4062
4159
|
withArgs: withArgs,
|
|
4063
4160
|
withArgsQueryFeatureMissingButRouteIsFunction: withArgsQueryFeatureMissingButRouteIsFunction,
|
|
4064
4161
|
withAutoRefresh: withAutoRefresh,
|
|
@@ -4401,11 +4498,20 @@ class QueryForm {
|
|
|
4401
4498
|
if (field.data.queryParamToValueTransformFn) {
|
|
4402
4499
|
deserializedValue = field.data.queryParamToValueTransformFn(value);
|
|
4403
4500
|
}
|
|
4404
|
-
else if (
|
|
4405
|
-
|
|
4406
|
-
|
|
4407
|
-
|
|
4408
|
-
|
|
4501
|
+
else if (!field.data.skipAutoTransform) {
|
|
4502
|
+
const defaultIsNum = this._getDefaultValue(key) === 'number';
|
|
4503
|
+
const valueIsNum = !isNaN(Number(value));
|
|
4504
|
+
const valueContainsWhitespace = typeof value === 'string' && value.trim() !== value;
|
|
4505
|
+
const valueHasLeadingZero = typeof value === 'string' && value.startsWith('0');
|
|
4506
|
+
const valueEndsWithDot = typeof value === 'string' && value.endsWith('.');
|
|
4507
|
+
const defaultIsBool = this._getDefaultValue(key) === 'boolean';
|
|
4508
|
+
const valueIsBool = value === 'true' || value === 'false';
|
|
4509
|
+
if (defaultIsNum || (valueIsNum && !valueContainsWhitespace && !valueHasLeadingZero && !valueEndsWithDot)) {
|
|
4510
|
+
deserializedValue = transformToNumber(value);
|
|
4511
|
+
}
|
|
4512
|
+
else if (defaultIsBool || valueIsBool) {
|
|
4513
|
+
deserializedValue = transformToBoolean(value);
|
|
4514
|
+
}
|
|
4409
4515
|
}
|
|
4410
4516
|
const valueIsEqualToCurrent = equal(deserializedValue, field.control.value);
|
|
4411
4517
|
if (valueIsEqualToCurrent)
|