@ethlete/query-devtools 1.0.0-next.1 → 1.0.0-next.11
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 +114 -0
- package/fesm2022/ethlete-query-devtools-lazy.mjs +37 -21
- package/fesm2022/ethlete-query-devtools-lazy.mjs.map +1 -1
- package/fesm2022/ethlete-query-devtools-toggle.mjs +14 -5
- package/fesm2022/ethlete-query-devtools-toggle.mjs.map +1 -1
- package/fesm2022/ethlete-query-devtools.mjs +1914 -841
- package/fesm2022/ethlete-query-devtools.mjs.map +1 -1
- package/package.json +4 -4
- package/types/ethlete-query-devtools-lazy.d.ts +11 -3
- package/types/ethlete-query-devtools-toggle.d.ts +4 -0
- package/types/ethlete-query-devtools.d.ts +214 -29
package/package.json
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ethlete/query-devtools",
|
|
3
|
-
"version": "1.0.0-next.
|
|
3
|
+
"version": "1.0.0-next.11",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"sideEffects": false,
|
|
6
6
|
"peerDependencies": {
|
|
7
7
|
"@analogjs/vitest-angular": "2.6.3",
|
|
8
|
-
"@angular/common": "22.
|
|
9
|
-
"@angular/compiler": "22.
|
|
10
|
-
"@angular/core": "22.
|
|
8
|
+
"@angular/common": "22.1.6",
|
|
9
|
+
"@angular/compiler": "22.1.6",
|
|
10
|
+
"@angular/core": "22.1.6",
|
|
11
11
|
"@ethlete/components": "^1.0.0-next.42",
|
|
12
12
|
"@ethlete/core": "^5.0.0-beta.11",
|
|
13
13
|
"@ethlete/query": "^6.0.0-beta.8",
|
|
@@ -5,6 +5,9 @@ import * as _angular_core from '@angular/core';
|
|
|
5
5
|
* first asked for, then downloads `<et-query-devtools>` as its own chunk and hands over. Use it instead
|
|
6
6
|
* of `<et-query-devtools>` to keep the panel out of the bundle an application ships to its users.
|
|
7
7
|
*
|
|
8
|
+
* Without `provideQueryDevtools()` it renders nothing at all - no toggle, no shortcut, and the panel
|
|
9
|
+
* chunk is never requested - so it can be left mounted in a production build.
|
|
10
|
+
*
|
|
8
11
|
* Everything else is identical - the same toggle, the same `Ctrl/Cmd + Alt + Q` shortcut, and a panel
|
|
9
12
|
* that was open when the tab last stored its state comes back open without a click.
|
|
10
13
|
*
|
|
@@ -16,10 +19,15 @@ import * as _angular_core from '@angular/core';
|
|
|
16
19
|
declare class QueryDevtoolsLazyComponent {
|
|
17
20
|
private document;
|
|
18
21
|
/**
|
|
19
|
-
* Whether
|
|
20
|
-
*
|
|
22
|
+
* Whether `provideQueryDevtools()` is in the application. Everything else here is gated on it - the
|
|
23
|
+
* stored view state read, the shortcut listener and the template - so a build that ships the shell
|
|
24
|
+
* without the provider renders nothing and can never load the panel.
|
|
25
|
+
*/
|
|
26
|
+
protected enabled: boolean;
|
|
27
|
+
/**
|
|
28
|
+
* Whether the panel is wanted. Whether it was already open has to be answered before the panel exists,
|
|
29
|
+
* which is why the stored view state is read here rather than asked of the panel.
|
|
21
30
|
*/
|
|
22
|
-
private restoredOpen;
|
|
23
31
|
protected load: _angular_core.WritableSignal<boolean>;
|
|
24
32
|
/** A restored panel opens because it was open; one that was clicked open has to be told to. */
|
|
25
33
|
protected openOnLoad: _angular_core.WritableSignal<boolean>;
|
|
@@ -12,6 +12,10 @@ declare const queryDevtoolsShortcutLabel: () => "⌘⌥Q" | "Ctrl+Alt+Q";
|
|
|
12
12
|
* host application's global CSS (Tailwind resets, button styles, …) can never touch it and its own
|
|
13
13
|
* styles can never leak out. Uses px (not rem) internally so it doesn't depend on the host's root
|
|
14
14
|
* font-size; theme accent colour is read from an inherited custom property with a fallback.
|
|
15
|
+
*
|
|
16
|
+
* Mounted on its own - without `<et-query-devtools-lazy>` or `<et-query-devtools>` - it declares no
|
|
17
|
+
* devtools UI, so the floating API env and session pills take themselves off the page once the
|
|
18
|
+
* application settles. Call `setQueryDevtoolsUiMounted(true)` to keep them.
|
|
15
19
|
*/
|
|
16
20
|
declare class QueryDevtoolsToggleComponent {
|
|
17
21
|
tampered: _angular_core.InputSignal<boolean>;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as _angular_core from '@angular/core';
|
|
2
2
|
import { Signal, WritableSignal, OnInit } from '@angular/core';
|
|
3
3
|
import * as _ethlete_query from '@ethlete/query';
|
|
4
|
-
import { JsonPath, QueryDevtoolsOverridesRecorder, QueryRefreshCause, QueryRepositoryEntryDestroyedCause, Query, QueryRepositoryCacheEntry, HttpRequestRetryState, HttpRequestLoadingProgressState, QueryDevtoolsStats, QueryDevtoolsStatsHandle, QueryDevtoolsEntry, QueryRepository, QueryClient, QueryKeyLockState, QueryDevtoolsFeature, QueryDevtoolsFault, AnyQueryStack, AnyPagedQueryStack, QuerySequence, AnyBearerAuthProvider, WebSocketDevtoolsHandle, QueryDevtoolsFormHandle, QuerySequenceStatus, AnyQuerySnapshot, QueryDevtoolsRun, QueryDevtoolsRunError, WebSocketDevtoolsMessage, QueryDevtoolsStorageScope } from '@ethlete/query';
|
|
4
|
+
import { JsonPath, QueryDevtoolsOverridesRecorder, QueryRefreshCause, QueryRepositoryEntryDestroyedCause, Query, QueryRepositoryCacheEntry, HttpRequestRetryState, HttpRequestLoadingProgressState, QueryDevtoolsStats, QueryDevtoolsStatsHandle, QueryDevtoolsEntry, AnyQueryBatchItemResult, QueryRepository, QueryClient, QueryKeyLockState, QueryDevtoolsFeature, QueryDevtoolsFault, AnyQueryStack, AnyPagedQueryStack, QuerySequence, AnyQueryBatch, AnyBearerAuthProvider, WebSocketDevtoolsHandle, QueryDevtoolsFormHandle, QuerySequenceStatus, AnyQuerySnapshot, QueryDevtoolsRun, QueryDevtoolsRunError, WebSocketDevtoolsMessage, QueryDevtoolsStorageScope, QueryDevtoolsApiEnvSwitch } from '@ethlete/query';
|
|
5
5
|
import { ResizeEdge, DragMoveEvent, ResizeMoveEvent } from '@ethlete/core';
|
|
6
6
|
|
|
7
7
|
type AboutRow = {
|
|
@@ -19,6 +19,8 @@ type AboutGroup = {
|
|
|
19
19
|
declare class QueryDevtoolsAboutComponent {
|
|
20
20
|
protected readonly groups: AboutGroup[];
|
|
21
21
|
protected copied: _angular_core.WritableSignal<boolean>;
|
|
22
|
+
private copiedReset$;
|
|
23
|
+
constructor();
|
|
22
24
|
protected copy(): void;
|
|
23
25
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<QueryDevtoolsAboutComponent, never>;
|
|
24
26
|
static ɵcmp: _angular_core.ɵɵComponentDeclaration<QueryDevtoolsAboutComponent, "et-query-devtools-about", never, {}, {}, never, never, true, never>;
|
|
@@ -82,7 +84,10 @@ declare class QueryDevtoolsJsonComponent {
|
|
|
82
84
|
private shapePath;
|
|
83
85
|
protected annotation: _angular_core.Signal<string | null>;
|
|
84
86
|
protected annotationTitle: _angular_core.Signal<string>;
|
|
85
|
-
/**
|
|
87
|
+
/**
|
|
88
|
+
* A `Date` is object-typed but has nothing to expand into, so it renders as a leaf. A resolved
|
|
89
|
+
* header provider is the other way round: a function that does expand.
|
|
90
|
+
*/
|
|
86
91
|
protected isContainer: _angular_core.Signal<boolean>;
|
|
87
92
|
/** The entries this node covers: the container's own, or just the window a chunk stands for. */
|
|
88
93
|
ownEntries: _angular_core.Signal<JsonEntry[]>;
|
|
@@ -93,7 +98,7 @@ declare class QueryDevtoolsJsonComponent {
|
|
|
93
98
|
private togglePath;
|
|
94
99
|
private defaultExpanded;
|
|
95
100
|
private localExpanded;
|
|
96
|
-
|
|
101
|
+
private expanded;
|
|
97
102
|
/** Only slices that actually contain a match unfold while searching, so a filter stays cheap. */
|
|
98
103
|
private chunkHasHit;
|
|
99
104
|
protected effectiveExpanded: _angular_core.Signal<boolean>;
|
|
@@ -202,7 +207,7 @@ type QueryDevtoolsSelection = {
|
|
|
202
207
|
* to count, so the badge/overflow logic would push it behind **More** - it is reached from the header's
|
|
203
208
|
* gear instead.
|
|
204
209
|
*/
|
|
205
|
-
type DevtoolsTab = 'queries' | 'stacks' | 'sequences' | 'forms' | 'auth' | 'ws' | 'cache' | 'locks' | 'timeline' | 'events' | 'faults' | 'mocks' | 'about' | 'settings';
|
|
210
|
+
type DevtoolsTab = 'queries' | 'stacks' | 'sequences' | 'batches' | 'forms' | 'auth' | 'ws' | 'cache' | 'locks' | 'timeline' | 'events' | 'faults' | 'mocks' | 'about' | 'settings';
|
|
206
211
|
/**
|
|
207
212
|
* The sections of the query detail drawer. The head and its actions stay pinned above them - the detail
|
|
208
213
|
* holds more than fits a column, and everything below the actions is reading material.
|
|
@@ -261,6 +266,20 @@ type QueryLink = {
|
|
|
261
266
|
clientBaseUrl: string;
|
|
262
267
|
stats?: QueryDevtoolsStatsHandle;
|
|
263
268
|
};
|
|
269
|
+
/** One settled item of a query batch, with the route the args it was sent with resolve to. */
|
|
270
|
+
type BatchItemRow = {
|
|
271
|
+
result: AnyQueryBatchItemResult;
|
|
272
|
+
segments: RouteSegment[];
|
|
273
|
+
};
|
|
274
|
+
/**
|
|
275
|
+
* A batch's settled items as its card lists them. Capped, and `hidden` says by how much - a bulk run
|
|
276
|
+
* settles more items than a list can hold, and a truncated one must not read as the whole run.
|
|
277
|
+
*/
|
|
278
|
+
type BatchItemView = {
|
|
279
|
+
rows: BatchItemRow[];
|
|
280
|
+
total: number;
|
|
281
|
+
hidden: number;
|
|
282
|
+
};
|
|
264
283
|
/**
|
|
265
284
|
* Query stats plus the numbers the panel derives from them rather than storing: an execution that never
|
|
266
285
|
* reached the network was answered from the cache, and the averages come from the running totals.
|
|
@@ -391,6 +410,7 @@ type QueryDevtoolsHost = {
|
|
|
391
410
|
queryEntries: Signal<QueryDevtoolsEntry[]>;
|
|
392
411
|
stackEntries: Signal<QueryDevtoolsEntry[]>;
|
|
393
412
|
sequenceEntries: Signal<QueryDevtoolsEntry[]>;
|
|
413
|
+
batchEntries: Signal<QueryDevtoolsEntry[]>;
|
|
394
414
|
formEntries: Signal<QueryDevtoolsEntry[]>;
|
|
395
415
|
authEntries: Signal<QueryDevtoolsEntry[]>;
|
|
396
416
|
wsEntries: Signal<QueryDevtoolsEntry[]>;
|
|
@@ -450,6 +470,7 @@ type QueryDevtoolsHost = {
|
|
|
450
470
|
asStack(entry: QueryDevtoolsEntry): AnyQueryStack;
|
|
451
471
|
asPagedStack(entry: QueryDevtoolsEntry): AnyPagedQueryStack;
|
|
452
472
|
asSequence(entry: QueryDevtoolsEntry): QuerySequence<unknown[]>;
|
|
473
|
+
asBatch(entry: QueryDevtoolsEntry): AnyQueryBatch;
|
|
453
474
|
asAuth(entry: QueryDevtoolsEntry): AnyBearerAuthProvider;
|
|
454
475
|
asWs(entry: QueryDevtoolsEntry): WebSocketDevtoolsHandle;
|
|
455
476
|
asForm(entry: QueryDevtoolsEntry): QueryDevtoolsFormHandle;
|
|
@@ -475,6 +496,11 @@ type QueryDevtoolsHost = {
|
|
|
475
496
|
requestUrl(query: AnyQuery): string | null;
|
|
476
497
|
requestPath(url: string): string;
|
|
477
498
|
queryArgs(query: AnyQuery): unknown;
|
|
499
|
+
/**
|
|
500
|
+
* The headers the query's last run sent, or - before it has run - the ones its args and its client
|
|
501
|
+
* resolve to now. `null` when there are none, or while a header provider cannot resolve yet.
|
|
502
|
+
*/
|
|
503
|
+
requestHeaders(query: AnyQuery): Record<string, string> | null;
|
|
478
504
|
routeSegments(entry: QueryDevtoolsEntry | undefined, query: AnyQuery): RouteSegment[];
|
|
479
505
|
queryActivity(entry: QueryDevtoolsEntry): QueryActivity;
|
|
480
506
|
linkActivity(link: QueryLink): QueryActivity;
|
|
@@ -492,6 +518,30 @@ type QueryDevtoolsHost = {
|
|
|
492
518
|
/** Whether a sequence step's in/out detail (`<entryId>:<stepIndex>`) is expanded - persisted. */
|
|
493
519
|
isStepExpanded(entryId: string, index: number): boolean;
|
|
494
520
|
toggleStep(entryId: string, index: number): void;
|
|
521
|
+
/** A batch's route with its path params left as `:name` - a batch fills them in per item, not once. */
|
|
522
|
+
batchRouteSegments(entry: QueryDevtoolsEntry): RouteSegment[];
|
|
523
|
+
/**
|
|
524
|
+
* The batch entry that created a query, or `null` for a query no batch did. What lets the Queries list
|
|
525
|
+
* fold a bulk run's items under one row instead of listing whatever it has in flight.
|
|
526
|
+
*/
|
|
527
|
+
batchOf(entry: QueryDevtoolsEntry): QueryDevtoolsEntry | null;
|
|
528
|
+
/**
|
|
529
|
+
* The item queries a batch has in flight. Only those: a batch destroys each item's query the moment
|
|
530
|
+
* that item settles, so a settled item is read from {@link batchItems} instead.
|
|
531
|
+
*/
|
|
532
|
+
queriesForBatch(entry: QueryDevtoolsEntry): QueryLink[];
|
|
533
|
+
/** A batch's settled items, failures first and capped - see {@link BatchItemView}. */
|
|
534
|
+
batchItems(entry: QueryDevtoolsEntry): BatchItemView;
|
|
535
|
+
/**
|
|
536
|
+
* The registry entry of one of a batch's items, or `null` once it has fallen out of the batch's capped
|
|
537
|
+
* tombstone tail - which is what makes an item row openable only while its query is still kept.
|
|
538
|
+
*/
|
|
539
|
+
batchItemQueryId(entry: QueryDevtoolsEntry, index: number): string | null;
|
|
540
|
+
/** An item's throughput line (`12.4 items/s · ~8s left`), or `null` before there is a rate to show. */
|
|
541
|
+
batchThroughput(batch: AnyQueryBatch): string | null;
|
|
542
|
+
/** Whether a batch item's args/response detail (`<entryId>:<itemIndex>`) is expanded - persisted. */
|
|
543
|
+
isBatchItemExpanded(entryId: string, index: number): boolean;
|
|
544
|
+
toggleBatchItem(entryId: string, index: number): void;
|
|
495
545
|
/** Keys of the Queries-list groups of identical rows the user opened - persisted. */
|
|
496
546
|
expandedQueryGroups: Signal<ReadonlySet<string>>;
|
|
497
547
|
toggleQueryGroup(key: string): void;
|
|
@@ -632,6 +682,16 @@ type QueryDevtoolsHost = {
|
|
|
632
682
|
entry: QueryDevtoolsEntry;
|
|
633
683
|
query: AnyQuery;
|
|
634
684
|
} | null>;
|
|
685
|
+
batchSelectedQueryId: WritableSignal<string | null>;
|
|
686
|
+
batchSelectedQuery: Signal<{
|
|
687
|
+
entry: QueryDevtoolsEntry;
|
|
688
|
+
query: AnyQuery;
|
|
689
|
+
} | null>;
|
|
690
|
+
eventSelectedQueryId: WritableSignal<string | null>;
|
|
691
|
+
eventSelectedQuery: Signal<{
|
|
692
|
+
entry: QueryDevtoolsEntry;
|
|
693
|
+
query: AnyQuery;
|
|
694
|
+
} | null>;
|
|
635
695
|
formSelectedQueryId: WritableSignal<string | null>;
|
|
636
696
|
formSelectedQuery: Signal<{
|
|
637
697
|
entry: QueryDevtoolsEntry;
|
|
@@ -661,6 +721,12 @@ type QueryDevtoolsHost = {
|
|
|
661
721
|
entry: QueryDevtoolsEntry;
|
|
662
722
|
query: AnyQuery;
|
|
663
723
|
} | null>;
|
|
724
|
+
/**
|
|
725
|
+
* The type annotations of each seeded mock body, by mock id. A mock only stores the *name* it was
|
|
726
|
+
* seeded from, and a body seeded from an inline schema has none, so this is the only thing that can
|
|
727
|
+
* label such a body - and it has to outlive the Mocks tab being switched away from.
|
|
728
|
+
*/
|
|
729
|
+
seededTypes: WritableSignal<Record<string, ReadonlyMap<string, string>>>;
|
|
664
730
|
paneAxis: Signal<PaneAxis>;
|
|
665
731
|
listWidth: Signal<number | null>;
|
|
666
732
|
drawerWidth: Signal<number | null>;
|
|
@@ -673,7 +739,7 @@ type QueryDevtoolsHost = {
|
|
|
673
739
|
resetPaneSize(pane: PaneTarget): void;
|
|
674
740
|
};
|
|
675
741
|
|
|
676
|
-
type ScopeKey = 'viewState' | 'pins' | 'overrides' | 'mocks' | 'armedMocks' | 'armedFaults';
|
|
742
|
+
type ScopeKey = 'viewState' | 'pins' | 'overrides' | 'mocks' | 'armedMocks' | 'armedFaults' | 'authSessions';
|
|
677
743
|
type ScopeRow = {
|
|
678
744
|
key: ScopeKey;
|
|
679
745
|
label: string;
|
|
@@ -702,6 +768,7 @@ type LimitRow = {
|
|
|
702
768
|
* otherwise hold as constants, and the toggles their own tabs also carry.
|
|
703
769
|
*/
|
|
704
770
|
declare class QueryDevtoolsSettingsComponent {
|
|
771
|
+
private document;
|
|
705
772
|
protected host: QueryDevtoolsHost;
|
|
706
773
|
protected readonly SCOPE_ROWS: ScopeRow[];
|
|
707
774
|
protected readonly SCOPES: {
|
|
@@ -716,14 +783,36 @@ declare class QueryDevtoolsSettingsComponent {
|
|
|
716
783
|
/** What queries actually retain, which is the application's value unless this panel raised it. */
|
|
717
784
|
protected responseHistory: _angular_core.Signal<number>;
|
|
718
785
|
protected mockCount: _angular_core.Signal<number>;
|
|
786
|
+
protected sessionCount: _angular_core.Signal<number>;
|
|
719
787
|
protected armedMockCount: _angular_core.Signal<number>;
|
|
720
788
|
protected armedFaultCount: _angular_core.Signal<number>;
|
|
789
|
+
/** The same keys the Events tab's own picker offers - see {@link queryDevtoolsEventClients}. */
|
|
790
|
+
protected eventClients: _angular_core.Signal<string[]>;
|
|
721
791
|
protected resetConfirming: _angular_core.WritableSignal<boolean>;
|
|
792
|
+
protected readonly FORGET_SESSIONS: () => void;
|
|
793
|
+
/** The backends the application declared, or an empty list - the card renders only for a declared one. */
|
|
794
|
+
protected apiEnvs: _angular_core.Signal<QueryDevtoolsApiEnvSwitch[]>;
|
|
795
|
+
/** The env id (or typed URL) a switch's key holds, or `null` while the application picks for itself. */
|
|
796
|
+
protected apiEnvValue(apiSwitch: QueryDevtoolsApiEnvSwitch): string | null;
|
|
797
|
+
/** The env a switch falls back to with nothing stored, described for the default button. */
|
|
798
|
+
protected apiEnvFallback(apiSwitch: QueryDevtoolsApiEnvSwitch): {
|
|
799
|
+
label: string;
|
|
800
|
+
production: boolean;
|
|
801
|
+
};
|
|
802
|
+
/** Whether the pick in force - the stored env, or the fallback behind an unwritten key - is production. */
|
|
803
|
+
protected apiEnvIsProduction(apiSwitch: QueryDevtoolsApiEnvSwitch): boolean;
|
|
804
|
+
/** A stored value no declared env carries, which is a URL somebody typed in below. */
|
|
805
|
+
protected apiEnvCustomUrl(apiSwitch: QueryDevtoolsApiEnvSwitch): string;
|
|
806
|
+
/** Writes the application's own key and reloads - it is read before Angular boots, so nothing else can. */
|
|
807
|
+
protected pickApiEnv(apiSwitch: QueryDevtoolsApiEnvSwitch, value: string | null): void;
|
|
808
|
+
protected setCustomApiUrl(apiSwitch: QueryDevtoolsApiEnvSwitch, value: string): void;
|
|
722
809
|
protected settings(): _ethlete_query.QueryDevtoolsSettings;
|
|
723
810
|
protected scopeOf(key: ScopeKey): QueryDevtoolsStorageScope;
|
|
724
811
|
protected limitOf(key: LimitKey): number;
|
|
725
812
|
/** What the picked scope means beyond where the state is kept, or `null` while it means nothing extra. */
|
|
726
813
|
protected warningFor(row: ScopeRow, scope: QueryDevtoolsStorageScope): string | null;
|
|
814
|
+
/** Why one scope is not on offer for a row, for the button's title, or `null` while it is. */
|
|
815
|
+
protected unavailableReason(row: ScopeRow, scope: QueryDevtoolsStorageScope): "Unavailable outside a development build: live access and refresh tokens, and the credentials you typed in, must not outlive this tab on a deployed origin. Session keeps the vault for as long as the tab." | null;
|
|
727
816
|
protected setScope(key: ScopeKey, scope: QueryDevtoolsStorageScope): void;
|
|
728
817
|
protected setLimit(key: LimitKey, value: string): void;
|
|
729
818
|
protected setResponseHistory(value: string): void;
|
|
@@ -761,21 +850,6 @@ type FloatRect = {
|
|
|
761
850
|
width: number;
|
|
762
851
|
height: number;
|
|
763
852
|
};
|
|
764
|
-
/**
|
|
765
|
-
* A drag in progress: the panel's docked edge, the floating panel being moved or resized, or the
|
|
766
|
-
* divider between a two-pane tab's panes.
|
|
767
|
-
*/
|
|
768
|
-
type ResizeDrag = {
|
|
769
|
-
/** The document the pointer moves in - a popped-out panel lives in a window of its own. */
|
|
770
|
-
doc: Document;
|
|
771
|
-
} & ({
|
|
772
|
-
kind: 'panel';
|
|
773
|
-
} | {
|
|
774
|
-
kind: 'pane';
|
|
775
|
-
pane: PaneTarget;
|
|
776
|
-
axis: PaneAxis;
|
|
777
|
-
container: HTMLElement;
|
|
778
|
-
});
|
|
779
853
|
type PersistedState = {
|
|
780
854
|
open?: boolean;
|
|
781
855
|
height?: number;
|
|
@@ -785,12 +859,19 @@ type PersistedState = {
|
|
|
785
859
|
listHeight?: number | null;
|
|
786
860
|
drawerHeight?: number | null;
|
|
787
861
|
dock?: DevtoolsDock;
|
|
862
|
+
reservesSpace?: boolean;
|
|
788
863
|
floatRect?: FloatRect;
|
|
789
864
|
floatParked?: boolean;
|
|
790
865
|
activeTab?: DevtoolsTab;
|
|
791
866
|
detailTab?: DetailTab;
|
|
792
867
|
selectedClientName?: string | null;
|
|
793
868
|
selectedQueryId?: string | null;
|
|
869
|
+
stackSelectedQueryId?: string | null;
|
|
870
|
+
sequenceSelectedQueryId?: string | null;
|
|
871
|
+
batchSelectedQueryId?: string | null;
|
|
872
|
+
eventSelectedQueryId?: string | null;
|
|
873
|
+
formSelectedQueryId?: string | null;
|
|
874
|
+
timelineSelectedQueryId?: string | null;
|
|
794
875
|
selectedFormId?: string | null;
|
|
795
876
|
inspectFilterIds?: string[] | null;
|
|
796
877
|
queryFilter?: string;
|
|
@@ -803,6 +884,7 @@ type PersistedState = {
|
|
|
803
884
|
socketFilter?: string;
|
|
804
885
|
jsonSearch?: string;
|
|
805
886
|
expandedSteps?: string[];
|
|
887
|
+
expandedBatchItems?: string[];
|
|
806
888
|
expandedQueryGroups?: string[];
|
|
807
889
|
jsonExpanded?: string[];
|
|
808
890
|
jsonCollapsed?: string[];
|
|
@@ -875,6 +957,9 @@ declare class QueryDevtoolsComponent implements OnInit {
|
|
|
875
957
|
} | {
|
|
876
958
|
id: "sequences";
|
|
877
959
|
label: string;
|
|
960
|
+
} | {
|
|
961
|
+
id: "batches";
|
|
962
|
+
label: string;
|
|
878
963
|
} | {
|
|
879
964
|
id: "forms";
|
|
880
965
|
label: string;
|
|
@@ -956,7 +1041,7 @@ declare class QueryDevtoolsComponent implements OnInit {
|
|
|
956
1041
|
protected drawerWidth: WritableSignal<number | null>;
|
|
957
1042
|
protected listHeight: WritableSignal<number | null>;
|
|
958
1043
|
protected drawerHeight: WritableSignal<number | null>;
|
|
959
|
-
|
|
1044
|
+
private drag;
|
|
960
1045
|
protected resizing: _angular_core.Signal<boolean>;
|
|
961
1046
|
/** Which edge the panel is docked to, or `float` for a window of its own inside the page. */
|
|
962
1047
|
protected dock: WritableSignal<DevtoolsDock>;
|
|
@@ -992,6 +1077,11 @@ declare class QueryDevtoolsComponent implements OnInit {
|
|
|
992
1077
|
readonly label: "Pop out";
|
|
993
1078
|
readonly hint: "Move the panel into a window of its own - the same live panel, on your other screen";
|
|
994
1079
|
}>;
|
|
1080
|
+
/**
|
|
1081
|
+
* Whether a docked panel takes its size out of the page instead of covering it - so the last rows of a
|
|
1082
|
+
* long page can still be scrolled to. Only docks can: a float sits wherever it was dragged.
|
|
1083
|
+
*/
|
|
1084
|
+
protected reservesSpace: WritableSignal<boolean>;
|
|
995
1085
|
/** Where the floating panel sits and how big it is. Kept while docked, so a return to float restores it. */
|
|
996
1086
|
private floatRect;
|
|
997
1087
|
/** The rect a resize gesture started from, or `null` outside one. */
|
|
@@ -1029,14 +1119,36 @@ declare class QueryDevtoolsComponent implements OnInit {
|
|
|
1029
1119
|
/** The floating panel's offset from the viewport's top-left, or `null` while it is docked. */
|
|
1030
1120
|
protected panelInsetBlock: _angular_core.Signal<number | null>;
|
|
1031
1121
|
protected panelInsetInline: _angular_core.Signal<number | null>;
|
|
1122
|
+
/**
|
|
1123
|
+
* The panel's rendered size, not its dragged one - the stylesheet clamps a dock (`min-block-size`,
|
|
1124
|
+
* `max-block-size: 90vh`) and it is the clamped size the page has to give up.
|
|
1125
|
+
*/
|
|
1126
|
+
private panelSize;
|
|
1127
|
+
/** Which padding a docked panel asks of the page and how much, or `null` when it asks for none. */
|
|
1128
|
+
private pageReservation;
|
|
1129
|
+
/**
|
|
1130
|
+
* The viewport edge a docked panel covers, reserved for overlays whatever {@link reservesSpace} says:
|
|
1131
|
+
* page content can be scrolled out from under the panel, a dialog or a menu cannot. A dock edge is
|
|
1132
|
+
* logical, so which physical edge a side dock covers flips in RTL - read from the panel, since the
|
|
1133
|
+
* writing direction cannot change under a dock switch.
|
|
1134
|
+
*/
|
|
1135
|
+
private overlayReservation;
|
|
1032
1136
|
/** Which section of the query detail is showing. Shared by the Queries tab and both drawers. */
|
|
1033
1137
|
detailTab: WritableSignal<DetailTab>;
|
|
1034
1138
|
selectedClientName: WritableSignal<string | null>;
|
|
1035
1139
|
selectedQueryId: WritableSignal<string | null>;
|
|
1036
1140
|
/** The form whose detail the Forms tab has expanded. */
|
|
1037
1141
|
selectedFormId: WritableSignal<string | null>;
|
|
1142
|
+
/**
|
|
1143
|
+
* The type annotations of each seeded mock body, by mock id. It lives here rather than on the Mocks
|
|
1144
|
+
* tab because a tab is destroyed the moment another one is selected, and a body seeded from an inline
|
|
1145
|
+
* schema has no `schemaName` to recover its labels from.
|
|
1146
|
+
*/
|
|
1147
|
+
seededTypes: WritableSignal<Record<string, ReadonlyMap<string, string>>>;
|
|
1038
1148
|
stackSelectedQueryId: WritableSignal<string | null>;
|
|
1039
1149
|
sequenceSelectedQueryId: WritableSignal<string | null>;
|
|
1150
|
+
batchSelectedQueryId: WritableSignal<string | null>;
|
|
1151
|
+
eventSelectedQueryId: WritableSignal<string | null>;
|
|
1040
1152
|
formSelectedQueryId: WritableSignal<string | null>;
|
|
1041
1153
|
timelineSelectedQueryId: WritableSignal<string | null>;
|
|
1042
1154
|
/** Free-text narrowing of the Queries list. Every whitespace-separated term has to match. */
|
|
@@ -1082,6 +1194,8 @@ declare class QueryDevtoolsComponent implements OnInit {
|
|
|
1082
1194
|
private socketEmitError;
|
|
1083
1195
|
/** Keys (`<entryId>:<stepIndex>`) of the sequence steps whose in/out detail is expanded. */
|
|
1084
1196
|
private expandedSteps;
|
|
1197
|
+
/** Keys (`<entryId>:<itemIndex>`) of the batch items whose args/response detail is expanded. */
|
|
1198
|
+
private expandedBatchItems;
|
|
1085
1199
|
/** Keys of the Queries-list groups the user opened - the tab is rebuilt on every switch back. */
|
|
1086
1200
|
expandedQueryGroups: WritableSignal<ReadonlySet<string>>;
|
|
1087
1201
|
/** Shared value-explorer search term. */
|
|
@@ -1122,7 +1236,12 @@ declare class QueryDevtoolsComponent implements OnInit {
|
|
|
1122
1236
|
copiedGql: WritableSignal<boolean>;
|
|
1123
1237
|
copiedRoute: WritableSignal<boolean>;
|
|
1124
1238
|
private copiedReset$;
|
|
1125
|
-
/**
|
|
1239
|
+
/**
|
|
1240
|
+
* 1-second tick driving the cache freshness countdowns. Gated the way the locks poll is: an ungated
|
|
1241
|
+
* `interval` is a periodic macrotask zone.js counts forever, so a mounted panel would tick the host
|
|
1242
|
+
* application once a second and keep `ApplicationRef.whenStable()` from ever resolving. Every reader
|
|
1243
|
+
* sits inside `@if (open())`, so there is nothing to drive while the panel is shut or the tab hidden.
|
|
1244
|
+
*/
|
|
1126
1245
|
private clock;
|
|
1127
1246
|
/**
|
|
1128
1247
|
* The probe lock behind every Locks row's "this tab" answer, and the last snapshot read through it.
|
|
@@ -1135,7 +1254,8 @@ declare class QueryDevtoolsComponent implements OnInit {
|
|
|
1135
1254
|
lockRows: _angular_core.Signal<DevtoolsLockRow[] | null>;
|
|
1136
1255
|
/** "Inspect" mode: hover the live UI to find the query that a component created. */
|
|
1137
1256
|
protected inspectActive: WritableSignal<boolean>;
|
|
1138
|
-
|
|
1257
|
+
/** @internal */
|
|
1258
|
+
inspectHover: WritableSignal<{
|
|
1139
1259
|
rect: DOMRect;
|
|
1140
1260
|
entries: QueryDevtoolsEntry[];
|
|
1141
1261
|
} | null>;
|
|
@@ -1155,12 +1275,17 @@ declare class QueryDevtoolsComponent implements OnInit {
|
|
|
1155
1275
|
protected panelTampered: _angular_core.Signal<boolean>;
|
|
1156
1276
|
stackEntries: _angular_core.Signal<QueryDevtoolsEntry[]>;
|
|
1157
1277
|
sequenceEntries: _angular_core.Signal<QueryDevtoolsEntry[]>;
|
|
1278
|
+
batchEntries: _angular_core.Signal<QueryDevtoolsEntry[]>;
|
|
1158
1279
|
formEntries: _angular_core.Signal<QueryDevtoolsEntry[]>;
|
|
1159
1280
|
authEntries: _angular_core.Signal<QueryDevtoolsEntry[]>;
|
|
1160
1281
|
wsEntries: _angular_core.Signal<QueryDevtoolsEntry[]>;
|
|
1161
1282
|
/** Unique client names present across queries and auth providers, for the Queries-tab picker. */
|
|
1162
1283
|
clientNames: _angular_core.Signal<string[]>;
|
|
1163
|
-
/**
|
|
1284
|
+
/**
|
|
1285
|
+
* Unique repositories (with their client name + base URL) used by the Cache and Events tabs. A
|
|
1286
|
+
* tombstone keeps its `meta.repository`, so a destroyed client would otherwise keep its Cache card
|
|
1287
|
+
* and its **Evict all** long after its injector died.
|
|
1288
|
+
*/
|
|
1164
1289
|
private repositories;
|
|
1165
1290
|
/**
|
|
1166
1291
|
* Every client the Faults tab can arm, with the fault it currently carries. Clients with nothing armed
|
|
@@ -1212,6 +1337,9 @@ declare class QueryDevtoolsComponent implements OnInit {
|
|
|
1212
1337
|
} | {
|
|
1213
1338
|
id: "sequences";
|
|
1214
1339
|
label: string;
|
|
1340
|
+
} | {
|
|
1341
|
+
id: "batches";
|
|
1342
|
+
label: string;
|
|
1215
1343
|
} | {
|
|
1216
1344
|
id: "forms";
|
|
1217
1345
|
label: string;
|
|
@@ -1253,6 +1381,9 @@ declare class QueryDevtoolsComponent implements OnInit {
|
|
|
1253
1381
|
} | {
|
|
1254
1382
|
id: "sequences";
|
|
1255
1383
|
label: string;
|
|
1384
|
+
} | {
|
|
1385
|
+
id: "batches";
|
|
1386
|
+
label: string;
|
|
1256
1387
|
} | {
|
|
1257
1388
|
id: "forms";
|
|
1258
1389
|
label: string;
|
|
@@ -1296,6 +1427,14 @@ declare class QueryDevtoolsComponent implements OnInit {
|
|
|
1296
1427
|
entry: QueryDevtoolsEntry;
|
|
1297
1428
|
query: AnyQuery;
|
|
1298
1429
|
} | null>;
|
|
1430
|
+
batchSelectedQuery: _angular_core.Signal<{
|
|
1431
|
+
entry: QueryDevtoolsEntry;
|
|
1432
|
+
query: AnyQuery;
|
|
1433
|
+
} | null>;
|
|
1434
|
+
eventSelectedQuery: _angular_core.Signal<{
|
|
1435
|
+
entry: QueryDevtoolsEntry;
|
|
1436
|
+
query: AnyQuery;
|
|
1437
|
+
} | null>;
|
|
1299
1438
|
formSelectedQuery: _angular_core.Signal<{
|
|
1300
1439
|
entry: QueryDevtoolsEntry;
|
|
1301
1440
|
query: AnyQuery;
|
|
@@ -1422,7 +1561,20 @@ declare class QueryDevtoolsComponent implements OnInit {
|
|
|
1422
1561
|
* query) never writes them to its own `args` signal - only the `withArgs` feature does - so the args
|
|
1423
1562
|
* its current request was built from stand in.
|
|
1424
1563
|
*/
|
|
1425
|
-
queryArgs(query: AnyQuery): Omit<any, "response"> | null;
|
|
1564
|
+
queryArgs(query: AnyQuery): Omit<any, "response" | "rawResponse"> | null;
|
|
1565
|
+
/**
|
|
1566
|
+
* The headers a query's request carries, as a plain `name: value` record, or `null` for a query that
|
|
1567
|
+
* has none the panel can read. The set the last run sent, so it stays readable after the token it
|
|
1568
|
+
* used was replaced; for a query that has not run, what its current args and its client resolve to
|
|
1569
|
+
* now. `null` while a header provider throws - a secure query's needs an access token.
|
|
1570
|
+
*
|
|
1571
|
+
* The args tree cannot answer this on its own: a `withArgs` query reads its args from the feature's
|
|
1572
|
+
* source, which the secure `Authorization` provider is never written back to, and client-level
|
|
1573
|
+
* headers are merged in per execution rather than being part of the args at all.
|
|
1574
|
+
*/
|
|
1575
|
+
requestHeaders(query: AnyQuery): {
|
|
1576
|
+
[k: string]: string;
|
|
1577
|
+
} | null;
|
|
1426
1578
|
queryStatus(query: AnyQuery): QueryStatus;
|
|
1427
1579
|
/**
|
|
1428
1580
|
* A request in flight is already refreshing, so reporting it as stale on top of `loading` is noise -
|
|
@@ -1460,7 +1612,7 @@ declare class QueryDevtoolsComponent implements OnInit {
|
|
|
1460
1612
|
* What a run's status dot and timeline bar colour by. `pending` reuses the panel's loading colour;
|
|
1461
1613
|
* `aborted` matches no rule and so falls back to the neutral one.
|
|
1462
1614
|
*/
|
|
1463
|
-
runStatus(run: QueryDevtoolsRun): "
|
|
1615
|
+
runStatus(run: QueryDevtoolsRun): "loading" | "success" | "error" | "aborted";
|
|
1464
1616
|
/**
|
|
1465
1617
|
* Whether a run can be an end of the diff: it still holds its body, and so does some other run of the
|
|
1466
1618
|
* same query. Deliberately not "an *older* run" - a free pair means the oldest body held is pickable
|
|
@@ -1553,8 +1705,8 @@ declare class QueryDevtoolsComponent implements OnInit {
|
|
|
1553
1705
|
* holds, the event log, the cache totals and anything armed in the Faults tab. Unlike **Copy report**
|
|
1554
1706
|
* this is not scoped to one query - it is the attachment for a bug report about a screen.
|
|
1555
1707
|
*
|
|
1556
|
-
* Deliberately unfiltered: a report is read by someone who was not there, and a
|
|
1557
|
-
* left out the client you were not looking at is worse than no dump.
|
|
1708
|
+
* Deliberately unfiltered apart from credentials: a report is read by someone who was not there, and a
|
|
1709
|
+
* dump that silently left out the client you were not looking at is worse than no dump.
|
|
1558
1710
|
*/
|
|
1559
1711
|
protected downloadSession(): void;
|
|
1560
1712
|
openResponseEditor(query: AnyQuery): void;
|
|
@@ -1598,6 +1750,7 @@ declare class QueryDevtoolsComponent implements OnInit {
|
|
|
1598
1750
|
asStack(entry: QueryDevtoolsEntry): AnyQueryStack;
|
|
1599
1751
|
asPagedStack(entry: QueryDevtoolsEntry): AnyPagedQueryStack;
|
|
1600
1752
|
asSequence(entry: QueryDevtoolsEntry): QuerySequence<unknown[]>;
|
|
1753
|
+
asBatch(entry: QueryDevtoolsEntry): AnyQueryBatch;
|
|
1601
1754
|
asAuth(entry: QueryDevtoolsEntry): AnyBearerAuthProvider;
|
|
1602
1755
|
asWs(entry: QueryDevtoolsEntry): WebSocketDevtoolsHandle;
|
|
1603
1756
|
/**
|
|
@@ -1662,6 +1815,19 @@ declare class QueryDevtoolsComponent implements OnInit {
|
|
|
1662
1815
|
expandQueryGroup(key: string): void;
|
|
1663
1816
|
isStepExpanded(entryId: string, index: number): boolean;
|
|
1664
1817
|
toggleStep(entryId: string, index: number): void;
|
|
1818
|
+
/** A batch's route with its path params left as `:name` - a batch fills them in per item, not once. */
|
|
1819
|
+
batchRouteSegments(entry: QueryDevtoolsEntry): RouteSegment[];
|
|
1820
|
+
batchOf(entry: QueryDevtoolsEntry): QueryDevtoolsEntry | null;
|
|
1821
|
+
queriesForBatch(entry: QueryDevtoolsEntry): QueryLink[];
|
|
1822
|
+
/**
|
|
1823
|
+
* The registry entry of one of a batch's items, or `null` once it has fallen out of the batch's capped
|
|
1824
|
+
* tombstone tail - which is what makes an item row openable only while its query is still kept.
|
|
1825
|
+
*/
|
|
1826
|
+
batchItemQueryId(entry: QueryDevtoolsEntry, index: number): string | null;
|
|
1827
|
+
batchItems(entry: QueryDevtoolsEntry): BatchItemView;
|
|
1828
|
+
batchThroughput(batch: AnyQueryBatch): string | null;
|
|
1829
|
+
isBatchItemExpanded(entryId: string, index: number): boolean;
|
|
1830
|
+
toggleBatchItem(entryId: string, index: number): void;
|
|
1665
1831
|
/** Dedents a GraphQL document (template-literal indentation) for readable display. */
|
|
1666
1832
|
gqlDocument(doc: string): string;
|
|
1667
1833
|
featureLabel(type: string): string;
|
|
@@ -1687,6 +1853,18 @@ declare class QueryDevtoolsComponent implements OnInit {
|
|
|
1687
1853
|
content: string;
|
|
1688
1854
|
type: string;
|
|
1689
1855
|
}): void;
|
|
1856
|
+
/**
|
|
1857
|
+
* The headers an execution of this request would resolve to now: the client's with the per-request
|
|
1858
|
+
* ones merged on top, providers called. `undefined` when a provider throws, which for a secure query
|
|
1859
|
+
* means no access token is available yet.
|
|
1860
|
+
*/
|
|
1861
|
+
private resolvedHeaders;
|
|
1862
|
+
/**
|
|
1863
|
+
* The same route rendered from a set of args rather than from a query, which is what a batch item leaves
|
|
1864
|
+
* behind: the batch destroys its query the moment the item settles.
|
|
1865
|
+
*/
|
|
1866
|
+
private argsRouteSegments;
|
|
1867
|
+
private renderRoute;
|
|
1690
1868
|
/**
|
|
1691
1869
|
* Takes - or gives back - the lock whose name only this tab can have produced. Its `clientId` in the
|
|
1692
1870
|
* snapshot is what tells this tab's rows from another tab's: `LockInfo` carries no tab identity, and
|
|
@@ -1774,11 +1952,18 @@ declare class QueryDevtoolsComponent implements OnInit {
|
|
|
1774
1952
|
*/
|
|
1775
1953
|
private insomniaHeaders;
|
|
1776
1954
|
private sessionClients;
|
|
1955
|
+
/**
|
|
1956
|
+
* A bearer auth provider's login and token-refresh queries are ordinary registered queries, so the
|
|
1957
|
+
* export has to be told which ones they are before it can leave their bodies out. The provider's own
|
|
1958
|
+
* entry lists them by client, method and route, which is what a query entry is matched on.
|
|
1959
|
+
*/
|
|
1960
|
+
private sessionAuthQueryKeys;
|
|
1777
1961
|
/** Every registered entry, described by whatever its kind carries. */
|
|
1778
1962
|
private sessionEntries;
|
|
1779
1963
|
private sessionQuery;
|
|
1780
1964
|
private sessionActivity;
|
|
1781
1965
|
private sessionSequence;
|
|
1966
|
+
private sessionBatch;
|
|
1782
1967
|
private sessionForm;
|
|
1783
1968
|
/**
|
|
1784
1969
|
* An auth provider without its tokens. A session report is a file that gets attached to a ticket, and
|
|
@@ -1830,7 +2015,7 @@ declare class QueryDevtoolsComponent implements OnInit {
|
|
|
1830
2015
|
declare const QUERY_DEVTOOLS_IMPORTS: readonly [typeof QueryDevtoolsComponent];
|
|
1831
2016
|
|
|
1832
2017
|
/** The version of `@ethlete/query-devtools` this build was cut from. */
|
|
1833
|
-
declare const QUERY_DEVTOOLS_VERSION = "1.0.0-next.
|
|
2018
|
+
declare const QUERY_DEVTOOLS_VERSION = "1.0.0-next.11";
|
|
1834
2019
|
|
|
1835
2020
|
export { QUERY_DEVTOOLS_IMPORTS, QUERY_DEVTOOLS_VERSION, QueryDevtoolsAboutComponent, QueryDevtoolsComponent, QueryDevtoolsJsonComponent, QueryDevtoolsJsonStylesComponent, QueryDevtoolsSettingsComponent, QueryDevtoolsTimelineStylesComponent, clampFloatToPeek, kindOf, resizedFloatRect, settledFloatRect };
|
|
1836
2021
|
export type { JsonKind };
|