@tanstack/query-devtools 5.0.0-beta.37 → 5.0.0-rc.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -9477,6 +9477,86 @@ var sortFns = {
9477
9477
  var convertRemToPixels = (rem) => {
9478
9478
  return rem * parseFloat(getComputedStyle(document.documentElement).fontSize);
9479
9479
  };
9480
+ var updateNestedDataByPath = (oldData, updatePath2, value) => {
9481
+ if (updatePath2.length === 0) {
9482
+ return value;
9483
+ }
9484
+ if (oldData instanceof Map) {
9485
+ const newData = new Map(oldData);
9486
+ if (updatePath2.length === 1) {
9487
+ newData.set(updatePath2[0], value);
9488
+ return newData;
9489
+ }
9490
+ const [head, ...tail] = updatePath2;
9491
+ newData.set(head, updateNestedDataByPath(newData.get(head), tail, value));
9492
+ return newData;
9493
+ }
9494
+ if (oldData instanceof Set) {
9495
+ const setAsArray = updateNestedDataByPath(
9496
+ Array.from(oldData),
9497
+ updatePath2,
9498
+ value
9499
+ );
9500
+ return new Set(setAsArray);
9501
+ }
9502
+ if (Array.isArray(oldData)) {
9503
+ const newData = [...oldData];
9504
+ if (updatePath2.length === 1) {
9505
+ newData[updatePath2[0]] = value;
9506
+ return newData;
9507
+ }
9508
+ const [head, ...tail] = updatePath2;
9509
+ newData[head] = updateNestedDataByPath(newData[head], tail, value);
9510
+ return newData;
9511
+ }
9512
+ if (oldData instanceof Object) {
9513
+ const newData = { ...oldData };
9514
+ if (updatePath2.length === 1) {
9515
+ newData[updatePath2[0]] = value;
9516
+ return newData;
9517
+ }
9518
+ const [head, ...tail] = updatePath2;
9519
+ newData[head] = updateNestedDataByPath(newData[head], tail, value);
9520
+ return newData;
9521
+ }
9522
+ return oldData;
9523
+ };
9524
+ var deleteNestedDataByPath = (oldData, deletePath) => {
9525
+ if (oldData instanceof Map) {
9526
+ const newData = new Map(oldData);
9527
+ if (deletePath.length === 1) {
9528
+ newData.delete(deletePath[0]);
9529
+ return newData;
9530
+ }
9531
+ const [head, ...tail] = deletePath;
9532
+ newData.set(head, deleteNestedDataByPath(newData.get(head), tail));
9533
+ return newData;
9534
+ }
9535
+ if (oldData instanceof Set) {
9536
+ const setAsArray = deleteNestedDataByPath(Array.from(oldData), deletePath);
9537
+ return new Set(setAsArray);
9538
+ }
9539
+ if (Array.isArray(oldData)) {
9540
+ const newData = [...oldData];
9541
+ if (deletePath.length === 1) {
9542
+ return newData.filter((_, idx) => idx.toString() !== deletePath[0]);
9543
+ }
9544
+ const [head, ...tail] = deletePath;
9545
+ newData[head] = deleteNestedDataByPath(newData[head], tail);
9546
+ return newData;
9547
+ }
9548
+ if (oldData instanceof Object) {
9549
+ const newData = { ...oldData };
9550
+ if (deletePath.length === 1) {
9551
+ delete newData[deletePath[0]];
9552
+ return newData;
9553
+ }
9554
+ const [head, ...tail] = deletePath;
9555
+ newData[head] = deleteNestedDataByPath(newData[head], tail);
9556
+ return newData;
9557
+ }
9558
+ return oldData;
9559
+ };
9480
9560
 
9481
9561
  // src/icons/index.tsx
9482
9562
  function Search() {
@@ -9691,6 +9771,53 @@ function ErrorCopier() {
9691
9771
  stroke-linejoin="round"
9692
9772
  /></svg>;
9693
9773
  }
9774
+ function List() {
9775
+ return <svg
9776
+ width="24"
9777
+ height="24"
9778
+ viewBox="0 0 24 24"
9779
+ fill="none"
9780
+ stroke="#98A2B3"
9781
+ stroke-width="2"
9782
+ xmlns="http://www.w3.org/2000/svg"
9783
+ >
9784
+ <rect class="list" width="20" height="20" y="2" x="2" rx="2" />
9785
+ <line class="list-item" y1="7" y2="7" x1="6" x2="18" />
9786
+ <line class="list-item" y2="12" y1="12" x1="6" x2="18" />
9787
+ <line class="list-item" y1="17" y2="17" x1="6" x2="18" />
9788
+ </svg>;
9789
+ }
9790
+ function Check(props) {
9791
+ return <svg
9792
+ width="24"
9793
+ height="24"
9794
+ viewBox="0 0 24 24"
9795
+ fill="none"
9796
+ stroke="#98A2B3"
9797
+ stroke-width="2"
9798
+ xmlns="http://www.w3.org/2000/svg"
9799
+ >
9800
+ <rect x="2" y="2" width="20" height="20" rx="2" class="check" />
9801
+ {props.checked && <g>
9802
+ <line
9803
+ transform="rotate(45 7.18873 14.6316)"
9804
+ x1="3.56453"
9805
+ y1="14.63158"
9806
+ x2="10.81294"
9807
+ y2="14.63158"
9808
+ class="check"
9809
+ />
9810
+ <line
9811
+ transform="rotate(-45 13.9674 11.5826)"
9812
+ x1="6.02012"
9813
+ y1="11.58263"
9814
+ x2="21.91469"
9815
+ y2="11.58263"
9816
+ class="check"
9817
+ />
9818
+ </g>}
9819
+ </svg>;
9820
+ }
9694
9821
  function TanstackLogo() {
9695
9822
  return <svg version="1.0" viewBox="0 0 633 633">
9696
9823
  <linearGradient
@@ -10407,6 +10534,17 @@ function TanstackLogo() {
10407
10534
  </svg>;
10408
10535
  }
10409
10536
 
10537
+ // src/Context.ts
10538
+ var QueryDevtoolsContext = createContext({
10539
+ client: void 0,
10540
+ onlineManager: void 0,
10541
+ queryFlavor: "",
10542
+ version: ""
10543
+ });
10544
+ function useQueryDevtoolsContext() {
10545
+ return useContext(QueryDevtoolsContext);
10546
+ }
10547
+
10410
10548
  // src/Explorer.tsx
10411
10549
  function chunkArray(array, size2) {
10412
10550
  if (size2 < 1)
@@ -10450,7 +10588,8 @@ var CopyButton = (props) => {
10450
10588
  const styles = getStyles();
10451
10589
  const [copyState, setCopyState] = createSignal("NoCopy");
10452
10590
  return <button
10453
- class={styles.copyButton}
10591
+ class={styles.actionButton}
10592
+ title="Copy object to clipboard"
10454
10593
  aria-label={`${copyState() === "NoCopy" ? "Copy object to clipboard" : copyState() === "SuccessCopy" ? "Object copied to clipboard" : "Error copying object to clipboard"}`}
10455
10594
  onClick={copyState() === "NoCopy" ? () => {
10456
10595
  navigator.clipboard.writeText(stringify(props.value)).then(
@@ -10474,11 +10613,58 @@ var CopyButton = (props) => {
10474
10613
  <Match when={copyState() === "ErrorCopy"}><ErrorCopier /></Match>
10475
10614
  </Switch></button>;
10476
10615
  };
10616
+ var ClearArrayButton = (props) => {
10617
+ const styles = getStyles();
10618
+ const queryClient = useQueryDevtoolsContext().client;
10619
+ return <button
10620
+ class={styles.actionButton}
10621
+ title="Remove all items"
10622
+ aria-label="Remove all items"
10623
+ onClick={() => {
10624
+ const oldData = props.activeQuery.state.data;
10625
+ const newData = updateNestedDataByPath(oldData, props.dataPath, []);
10626
+ queryClient.setQueryData(props.activeQuery.queryKey, newData);
10627
+ }}
10628
+ ><List /></button>;
10629
+ };
10630
+ var DeleteItemButton = (props) => {
10631
+ const styles = getStyles();
10632
+ const queryClient = useQueryDevtoolsContext().client;
10633
+ return <button
10634
+ class={clsx(styles.actionButton)}
10635
+ title="Delete item"
10636
+ aria-label="Delete item"
10637
+ onClick={() => {
10638
+ const oldData = props.activeQuery.state.data;
10639
+ const newData = deleteNestedDataByPath(oldData, props.dataPath);
10640
+ queryClient.setQueryData(props.activeQuery.queryKey, newData);
10641
+ }}
10642
+ ><Trash /></button>;
10643
+ };
10644
+ var ToggleValueButton = (props) => {
10645
+ const styles = getStyles();
10646
+ const queryClient = useQueryDevtoolsContext().client;
10647
+ return <button
10648
+ class={clsx(styles.actionButton)}
10649
+ title="Toggle value"
10650
+ aria-label="Toggle value"
10651
+ onClick={() => {
10652
+ const oldData = props.activeQuery.state.data;
10653
+ const newData = updateNestedDataByPath(
10654
+ oldData,
10655
+ props.dataPath,
10656
+ !props.value
10657
+ );
10658
+ queryClient.setQueryData(props.activeQuery.queryKey, newData);
10659
+ }}
10660
+ ><Check checked={props.value} /></button>;
10661
+ };
10477
10662
  function isIterable(x) {
10478
10663
  return Symbol.iterator in x;
10479
10664
  }
10480
10665
  function Explorer(props) {
10481
10666
  const styles = getStyles();
10667
+ const queryClient = useQueryDevtoolsContext().client;
10482
10668
  const [expanded, setExpanded] = createSignal(
10483
10669
  (props.defaultExpanded || []).includes(props.label)
10484
10670
  );
@@ -10520,6 +10706,7 @@ function Explorer(props) {
10520
10706
  return typeof props.value;
10521
10707
  });
10522
10708
  const subEntryPages = createMemo(() => chunkArray(subEntries(), 100));
10709
+ const currentDataPath = props.dataPath ?? [];
10523
10710
  return <div class={styles.entry}>
10524
10711
  <Show when={subEntryPages().length}>
10525
10712
  <div class={styles.expanderButtonContainer}>
@@ -10538,7 +10725,21 @@ function Explorer(props) {
10538
10725
  {subEntries().length > 1 ? `items` : `item`}
10539
10726
  </span>
10540
10727
  </button>
10541
- <Show when={props.copyable}><CopyButton value={props.value} /></Show>
10728
+ <Show when={props.editable}><div class={styles.actions}>
10729
+ <CopyButton value={props.value} />
10730
+ <Show
10731
+ when={props.itemsDeletable && props.activeQuery !== void 0}
10732
+ ><DeleteItemButton
10733
+ activeQuery={props.activeQuery}
10734
+ dataPath={currentDataPath}
10735
+ /></Show>
10736
+ <Show
10737
+ when={type() === "array" && props.activeQuery !== void 0}
10738
+ ><ClearArrayButton
10739
+ activeQuery={props.activeQuery}
10740
+ dataPath={currentDataPath}
10741
+ /></Show>
10742
+ </div></Show>
10542
10743
  </div>
10543
10744
  <Show when={expanded()}>
10544
10745
  <Show when={subEntryPages().length === 1}><div class={styles.subEntry}><Key each={subEntries()} by={(item) => item.label}>{(entry) => {
@@ -10546,7 +10747,10 @@ function Explorer(props) {
10546
10747
  defaultExpanded={props.defaultExpanded}
10547
10748
  label={entry().label}
10548
10749
  value={entry().value}
10549
- copyable={props.copyable}
10750
+ editable={props.editable}
10751
+ dataPath={[...currentDataPath, entry().label]}
10752
+ activeQuery={props.activeQuery}
10753
+ itemsDeletable={type() === "array" || type() === "Iterable" || type() === "object"}
10550
10754
  />;
10551
10755
  }}</Key></div></Show>
10552
10756
  <Show when={subEntryPages().length > 1}><div class={styles.subEntry}><Index each={subEntryPages()}>{(entries3, index) => <div><div class={styles.entry}>
@@ -10568,22 +10772,55 @@ function Explorer(props) {
10568
10772
  defaultExpanded={props.defaultExpanded}
10569
10773
  label={entry().label}
10570
10774
  value={entry().value}
10571
- copyable={props.copyable}
10775
+ editable={props.editable}
10776
+ dataPath={[...currentDataPath, entry().label]}
10777
+ activeQuery={props.activeQuery}
10572
10778
  />}</Key></div></Show>
10573
10779
  </div></div>}</Index></div></Show>
10574
10780
  </Show>
10575
10781
  </Show>
10576
- <Show when={subEntryPages().length === 0}><div
10577
- style={{
10578
- "line-height": "1.125rem"
10579
- }}
10580
- >
10782
+ <Show when={subEntryPages().length === 0}><div class={styles.row}>
10581
10783
  <span class={styles.label}>
10582
10784
  {props.label}
10583
10785
  {":"}
10584
10786
  </span>
10585
- {" "}
10586
- <span class={styles.value}>{displayValue(props.value)}</span>
10787
+ <Show
10788
+ when={props.editable && props.activeQuery !== void 0 && (type() === "string" || type() === "number" || type() === "boolean")}
10789
+ fallback={<span class={styles.value}>{displayValue(props.value)}</span>}
10790
+ >
10791
+ <Show
10792
+ when={props.editable && props.activeQuery !== void 0 && (type() === "string" || type() === "number")}
10793
+ ><input
10794
+ type={type() === "number" ? "number" : "text"}
10795
+ class={clsx(styles.value, styles.editableInput)}
10796
+ value={props.value}
10797
+ onChange={(changeEvent) => {
10798
+ const oldData = props.activeQuery.state.data;
10799
+ const newData = updateNestedDataByPath(
10800
+ oldData,
10801
+ currentDataPath,
10802
+ type() === "number" ? changeEvent.target.valueAsNumber : changeEvent.target.value
10803
+ );
10804
+ queryClient.setQueryData(props.activeQuery.queryKey, newData);
10805
+ }}
10806
+ /></Show>
10807
+ <Show when={type() === "boolean"}><span
10808
+ class={clsx(styles.value, styles.actions, styles.editableInput)}
10809
+ >
10810
+ <ToggleValueButton
10811
+ activeQuery={props.activeQuery}
10812
+ dataPath={currentDataPath}
10813
+ value={props.value}
10814
+ />
10815
+ {displayValue(props.value)}
10816
+ </span></Show>
10817
+ </Show>
10818
+ <Show
10819
+ when={props.editable && props.itemsDeletable && props.activeQuery !== void 0}
10820
+ ><DeleteItemButton
10821
+ activeQuery={props.activeQuery}
10822
+ dataPath={currentDataPath}
10823
+ /></Show>
10587
10824
  </div></Show>
10588
10825
  </div>;
10589
10826
  }
@@ -10623,6 +10860,7 @@ var getStyles = () => {
10623
10860
  align-items: center;
10624
10861
  line-height: 1.125rem;
10625
10862
  min-height: 1.125rem;
10863
+ gap: ${size2[2]};
10626
10864
  `,
10627
10865
  expanderButton: u`
10628
10866
  cursor: pointer;
@@ -10660,8 +10898,32 @@ var getStyles = () => {
10660
10898
  `,
10661
10899
  value: u`
10662
10900
  color: ${colors.purple[400]};
10901
+ flex-grow: 1;
10902
+ `,
10903
+ actions: u`
10904
+ display: inline-flex;
10905
+ gap: ${size2[2]};
10906
+ align-items: center;
10663
10907
  `,
10664
- copyButton: u`
10908
+ row: u`
10909
+ display: inline-flex;
10910
+ gap: ${size2[2]};
10911
+ width: 100%;
10912
+ margin-bottom: ${size2[0.5]};
10913
+ line-height: 1.125rem;
10914
+ align-items: center;
10915
+ `,
10916
+ editableInput: u`
10917
+ border: none;
10918
+ padding: ${size2[0.5]} ${size2[1]};
10919
+ flex-grow: 1;
10920
+ background-color: ${colors.gray[900]};
10921
+
10922
+ &:hover {
10923
+ background-color: ${colors.gray[800]};
10924
+ }
10925
+ `,
10926
+ actionButton: u`
10665
10927
  background-color: transparent;
10666
10928
  border: none;
10667
10929
  display: inline-flex;
@@ -10672,11 +10934,18 @@ var getStyles = () => {
10672
10934
  width: ${size2[3]};
10673
10935
  height: ${size2[3]};
10674
10936
  position: relative;
10675
- left: ${size2[2]};
10676
10937
  z-index: 1;
10677
10938
 
10678
- &:hover svg .copier {
10679
- stroke: ${colors.gray[500]} !important;
10939
+ &:hover svg {
10940
+ .copier,
10941
+ .check,
10942
+ .list {
10943
+ stroke: ${colors.gray[500]} !important;
10944
+ }
10945
+
10946
+ .list-item {
10947
+ stroke: ${colors.gray[700]};
10948
+ }
10680
10949
  }
10681
10950
 
10682
10951
  &:focus-visible {
@@ -10688,17 +10957,6 @@ var getStyles = () => {
10688
10957
  };
10689
10958
  };
10690
10959
 
10691
- // src/Context.ts
10692
- var QueryDevtoolsContext = createContext({
10693
- client: void 0,
10694
- onlineManager: void 0,
10695
- queryFlavor: "",
10696
- version: ""
10697
- });
10698
- function useQueryDevtoolsContext() {
10699
- return useContext(QueryDevtoolsContext);
10700
- }
10701
-
10702
10960
  // src/fonts.ts
10703
10961
  var loadFonts = () => {
10704
10962
  const link = document.createElement("link");
@@ -11626,7 +11884,8 @@ var QueryDetails = () => {
11626
11884
  label="Data"
11627
11885
  defaultExpanded={["Data"]}
11628
11886
  value={activeQueryStateData()}
11629
- copyable={true}
11887
+ editable={true}
11888
+ activeQuery={activeQuery()}
11630
11889
  /></div>
11631
11890
  <div class={clsx(styles.detailsHeader, "tsqd-query-details-header")}>Query Explorer</div>
11632
11891
  <div