@tanstack/query-devtools 5.0.0-rc.1 → 5.0.0-rc.9

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.
@@ -9478,6 +9478,86 @@ var sortFns = {
9478
9478
  var convertRemToPixels = (rem) => {
9479
9479
  return rem * parseFloat(getComputedStyle(document.documentElement).fontSize);
9480
9480
  };
9481
+ var updateNestedDataByPath = (oldData, updatePath2, value) => {
9482
+ if (updatePath2.length === 0) {
9483
+ return value;
9484
+ }
9485
+ if (oldData instanceof Map) {
9486
+ const newData = new Map(oldData);
9487
+ if (updatePath2.length === 1) {
9488
+ newData.set(updatePath2[0], value);
9489
+ return newData;
9490
+ }
9491
+ const [head, ...tail] = updatePath2;
9492
+ newData.set(head, updateNestedDataByPath(newData.get(head), tail, value));
9493
+ return newData;
9494
+ }
9495
+ if (oldData instanceof Set) {
9496
+ const setAsArray = updateNestedDataByPath(
9497
+ Array.from(oldData),
9498
+ updatePath2,
9499
+ value
9500
+ );
9501
+ return new Set(setAsArray);
9502
+ }
9503
+ if (Array.isArray(oldData)) {
9504
+ const newData = [...oldData];
9505
+ if (updatePath2.length === 1) {
9506
+ newData[updatePath2[0]] = value;
9507
+ return newData;
9508
+ }
9509
+ const [head, ...tail] = updatePath2;
9510
+ newData[head] = updateNestedDataByPath(newData[head], tail, value);
9511
+ return newData;
9512
+ }
9513
+ if (oldData instanceof Object) {
9514
+ const newData = { ...oldData };
9515
+ if (updatePath2.length === 1) {
9516
+ newData[updatePath2[0]] = value;
9517
+ return newData;
9518
+ }
9519
+ const [head, ...tail] = updatePath2;
9520
+ newData[head] = updateNestedDataByPath(newData[head], tail, value);
9521
+ return newData;
9522
+ }
9523
+ return oldData;
9524
+ };
9525
+ var deleteNestedDataByPath = (oldData, deletePath) => {
9526
+ if (oldData instanceof Map) {
9527
+ const newData = new Map(oldData);
9528
+ if (deletePath.length === 1) {
9529
+ newData.delete(deletePath[0]);
9530
+ return newData;
9531
+ }
9532
+ const [head, ...tail] = deletePath;
9533
+ newData.set(head, deleteNestedDataByPath(newData.get(head), tail));
9534
+ return newData;
9535
+ }
9536
+ if (oldData instanceof Set) {
9537
+ const setAsArray = deleteNestedDataByPath(Array.from(oldData), deletePath);
9538
+ return new Set(setAsArray);
9539
+ }
9540
+ if (Array.isArray(oldData)) {
9541
+ const newData = [...oldData];
9542
+ if (deletePath.length === 1) {
9543
+ return newData.filter((_, idx) => idx.toString() !== deletePath[0]);
9544
+ }
9545
+ const [head, ...tail] = deletePath;
9546
+ newData[head] = deleteNestedDataByPath(newData[head], tail);
9547
+ return newData;
9548
+ }
9549
+ if (oldData instanceof Object) {
9550
+ const newData = { ...oldData };
9551
+ if (deletePath.length === 1) {
9552
+ delete newData[deletePath[0]];
9553
+ return newData;
9554
+ }
9555
+ const [head, ...tail] = deletePath;
9556
+ newData[head] = deleteNestedDataByPath(newData[head], tail);
9557
+ return newData;
9558
+ }
9559
+ return oldData;
9560
+ };
9481
9561
 
9482
9562
  // src/icons/index.tsx
9483
9563
  function Search() {
@@ -9692,6 +9772,22 @@ function ErrorCopier() {
9692
9772
  stroke-linejoin="round"
9693
9773
  /></svg>;
9694
9774
  }
9775
+ function List() {
9776
+ return <svg
9777
+ width="24"
9778
+ height="24"
9779
+ viewBox="0 0 24 24"
9780
+ fill="none"
9781
+ stroke="#98A2B3"
9782
+ stroke-width="2"
9783
+ xmlns="http://www.w3.org/2000/svg"
9784
+ >
9785
+ <rect class="list" width="20" height="20" y="2" x="2" rx="2" />
9786
+ <line class="list-item" y1="7" y2="7" x1="6" x2="18" />
9787
+ <line class="list-item" y2="12" y1="12" x1="6" x2="18" />
9788
+ <line class="list-item" y1="17" y2="17" x1="6" x2="18" />
9789
+ </svg>;
9790
+ }
9695
9791
  function TanstackLogo() {
9696
9792
  return <svg version="1.0" viewBox="0 0 633 633">
9697
9793
  <linearGradient
@@ -10408,6 +10504,17 @@ function TanstackLogo() {
10408
10504
  </svg>;
10409
10505
  }
10410
10506
 
10507
+ // src/Context.ts
10508
+ var QueryDevtoolsContext = createContext({
10509
+ client: void 0,
10510
+ onlineManager: void 0,
10511
+ queryFlavor: "",
10512
+ version: ""
10513
+ });
10514
+ function useQueryDevtoolsContext() {
10515
+ return useContext(QueryDevtoolsContext);
10516
+ }
10517
+
10411
10518
  // src/Explorer.tsx
10412
10519
  function chunkArray(array, size2) {
10413
10520
  if (size2 < 1)
@@ -10451,7 +10558,8 @@ var CopyButton = (props) => {
10451
10558
  const styles = getStyles();
10452
10559
  const [copyState, setCopyState] = createSignal("NoCopy");
10453
10560
  return <button
10454
- class={styles.copyButton}
10561
+ class={styles.actionButton}
10562
+ title="Copy object to clipboard"
10455
10563
  aria-label={`${copyState() === "NoCopy" ? "Copy object to clipboard" : copyState() === "SuccessCopy" ? "Object copied to clipboard" : "Error copying object to clipboard"}`}
10456
10564
  onClick={copyState() === "NoCopy" ? () => {
10457
10565
  navigator.clipboard.writeText(stringify(props.value)).then(
@@ -10476,11 +10584,40 @@ var CopyButton = (props) => {
10476
10584
  <Match when={copyState() === "ErrorCopy"}><ErrorCopier /></Match>
10477
10585
  </Switch></button>;
10478
10586
  };
10587
+ var ClearArrayButton = (props) => {
10588
+ const styles = getStyles();
10589
+ const queryClient = useQueryDevtoolsContext().client;
10590
+ return <button
10591
+ class={styles.actionButton}
10592
+ title="Remove all items"
10593
+ aria-label="Remove all items"
10594
+ onClick={() => {
10595
+ const oldData = props.activeQuery.state.data;
10596
+ const newData = updateNestedDataByPath(oldData, props.dataPath, []);
10597
+ queryClient.setQueryData(props.activeQuery.queryKey, newData);
10598
+ }}
10599
+ ><List /></button>;
10600
+ };
10601
+ var DeleteItemButton = (props) => {
10602
+ const styles = getStyles();
10603
+ const queryClient = useQueryDevtoolsContext().client;
10604
+ return <button
10605
+ class={clsx(styles.actionButton)}
10606
+ title="Delete item"
10607
+ aria-label="Delete item"
10608
+ onClick={() => {
10609
+ const oldData = props.activeQuery.state.data;
10610
+ const newData = deleteNestedDataByPath(oldData, props.dataPath);
10611
+ queryClient.setQueryData(props.activeQuery.queryKey, newData);
10612
+ }}
10613
+ ><Trash /></button>;
10614
+ };
10479
10615
  function isIterable(x) {
10480
10616
  return Symbol.iterator in x;
10481
10617
  }
10482
10618
  function Explorer(props) {
10483
10619
  const styles = getStyles();
10620
+ const queryClient = useQueryDevtoolsContext().client;
10484
10621
  const [expanded, setExpanded] = createSignal(
10485
10622
  (props.defaultExpanded || []).includes(props.label)
10486
10623
  );
@@ -10522,6 +10659,7 @@ function Explorer(props) {
10522
10659
  return typeof props.value;
10523
10660
  });
10524
10661
  const subEntryPages = createMemo(() => chunkArray(subEntries(), 100));
10662
+ const currentDataPath = props.dataPath ?? [];
10525
10663
  return <div class={styles.entry}>
10526
10664
  <Show when={subEntryPages().length}>
10527
10665
  <div class={styles.expanderButtonContainer}>
@@ -10540,7 +10678,21 @@ function Explorer(props) {
10540
10678
  {subEntries().length > 1 ? `items` : `item`}
10541
10679
  </span>
10542
10680
  </button>
10543
- <Show when={props.copyable}><CopyButton value={props.value} /></Show>
10681
+ <Show when={props.editable}><div class={styles.actions}>
10682
+ <CopyButton value={props.value} />
10683
+ <Show
10684
+ when={props.itemsDeletable && props.activeQuery !== void 0}
10685
+ ><DeleteItemButton
10686
+ activeQuery={props.activeQuery}
10687
+ dataPath={currentDataPath}
10688
+ /></Show>
10689
+ <Show
10690
+ when={type() === "array" && props.activeQuery !== void 0}
10691
+ ><ClearArrayButton
10692
+ activeQuery={props.activeQuery}
10693
+ dataPath={currentDataPath}
10694
+ /></Show>
10695
+ </div></Show>
10544
10696
  </div>
10545
10697
  <Show when={expanded()}>
10546
10698
  <Show when={subEntryPages().length === 1}><div class={styles.subEntry}><Key each={subEntries()} by={(item) => item.label}>{(entry) => {
@@ -10548,7 +10700,10 @@ function Explorer(props) {
10548
10700
  defaultExpanded={props.defaultExpanded}
10549
10701
  label={entry().label}
10550
10702
  value={entry().value}
10551
- copyable={props.copyable}
10703
+ editable={props.editable}
10704
+ dataPath={[...currentDataPath, entry().label]}
10705
+ activeQuery={props.activeQuery}
10706
+ itemsDeletable={type() === "array" || type() === "Iterable" || type() === "object"}
10552
10707
  />;
10553
10708
  }}</Key></div></Show>
10554
10709
  <Show when={subEntryPages().length > 1}><div class={styles.subEntry}><Index each={subEntryPages()}>{(entries3, index) => <div><div class={styles.entry}>
@@ -10570,22 +10725,41 @@ function Explorer(props) {
10570
10725
  defaultExpanded={props.defaultExpanded}
10571
10726
  label={entry().label}
10572
10727
  value={entry().value}
10573
- copyable={props.copyable}
10728
+ editable={props.editable}
10729
+ dataPath={[...currentDataPath, entry().label]}
10730
+ activeQuery={props.activeQuery}
10574
10731
  />}</Key></div></Show>
10575
10732
  </div></div>}</Index></div></Show>
10576
10733
  </Show>
10577
10734
  </Show>
10578
- <Show when={subEntryPages().length === 0}><div
10579
- style={{
10580
- "line-height": "1.125rem"
10581
- }}
10582
- >
10735
+ <Show when={subEntryPages().length === 0}><div class={styles.row}>
10583
10736
  <span class={styles.label}>
10584
10737
  {props.label}
10585
10738
  {":"}
10586
10739
  </span>
10587
- {" "}
10588
- <span class={styles.value}>{displayValue(props.value)}</span>
10740
+ <Show
10741
+ when={props.editable && props.activeQuery !== void 0 && (type() === "string" || type() === "number")}
10742
+ fallback={<span class={styles.value}>{displayValue(props.value)}</span>}
10743
+ ><input
10744
+ type={type() === "number" ? "number" : "text"}
10745
+ class={clsx(styles.value, styles.editableInput)}
10746
+ value={props.value}
10747
+ onChange={(changeEvent) => {
10748
+ const oldData = props.activeQuery.state.data;
10749
+ const newData = updateNestedDataByPath(
10750
+ oldData,
10751
+ currentDataPath,
10752
+ type() === "number" ? changeEvent.target.valueAsNumber : changeEvent.target.value
10753
+ );
10754
+ queryClient.setQueryData(props.activeQuery.queryKey, newData);
10755
+ }}
10756
+ /></Show>
10757
+ <Show
10758
+ when={props.editable && props.itemsDeletable && props.activeQuery !== void 0}
10759
+ ><DeleteItemButton
10760
+ activeQuery={props.activeQuery}
10761
+ dataPath={currentDataPath}
10762
+ /></Show>
10589
10763
  </div></Show>
10590
10764
  </div>;
10591
10765
  }
@@ -10625,6 +10799,7 @@ var getStyles = () => {
10625
10799
  align-items: center;
10626
10800
  line-height: 1.125rem;
10627
10801
  min-height: 1.125rem;
10802
+ gap: ${size2[2]};
10628
10803
  `,
10629
10804
  expanderButton: u`
10630
10805
  cursor: pointer;
@@ -10662,8 +10837,30 @@ var getStyles = () => {
10662
10837
  `,
10663
10838
  value: u`
10664
10839
  color: ${colors.purple[400]};
10840
+ flex-grow: 1;
10841
+ `,
10842
+ actions: u`
10843
+ display: inline-flex;
10844
+ gap: ${size2[2]};
10845
+ `,
10846
+ row: u`
10847
+ display: inline-flex;
10848
+ gap: ${size2[2]};
10849
+ width: 100%;
10850
+ margin-bottom: ${size2[0.5]};
10851
+ line-height: 1.125rem;
10665
10852
  `,
10666
- copyButton: u`
10853
+ editableInput: u`
10854
+ border: none;
10855
+ padding: 0px ${size2[1]};
10856
+ flex-grow: 1;
10857
+ background-color: ${colors.gray[900]};
10858
+
10859
+ &:hover {
10860
+ background-color: ${colors.gray[800]};
10861
+ }
10862
+ `,
10863
+ actionButton: u`
10667
10864
  background-color: transparent;
10668
10865
  border: none;
10669
10866
  display: inline-flex;
@@ -10674,11 +10871,17 @@ var getStyles = () => {
10674
10871
  width: ${size2[3]};
10675
10872
  height: ${size2[3]};
10676
10873
  position: relative;
10677
- left: ${size2[2]};
10678
10874
  z-index: 1;
10679
10875
 
10680
- &:hover svg .copier {
10681
- stroke: ${colors.gray[500]} !important;
10876
+ &:hover svg {
10877
+ .copier,
10878
+ .list {
10879
+ stroke: ${colors.gray[500]} !important;
10880
+ }
10881
+
10882
+ .list-item {
10883
+ stroke: ${colors.gray[700]};
10884
+ }
10682
10885
  }
10683
10886
 
10684
10887
  &:focus-visible {
@@ -10690,17 +10893,6 @@ var getStyles = () => {
10690
10893
  };
10691
10894
  };
10692
10895
 
10693
- // src/Context.ts
10694
- var QueryDevtoolsContext = createContext({
10695
- client: void 0,
10696
- onlineManager: void 0,
10697
- queryFlavor: "",
10698
- version: ""
10699
- });
10700
- function useQueryDevtoolsContext() {
10701
- return useContext(QueryDevtoolsContext);
10702
- }
10703
-
10704
10896
  // src/fonts.ts
10705
10897
  var loadFonts = () => {
10706
10898
  const link = document.createElement("link");
@@ -11628,7 +11820,8 @@ var QueryDetails = () => {
11628
11820
  label="Data"
11629
11821
  defaultExpanded={["Data"]}
11630
11822
  value={activeQueryStateData()}
11631
- copyable={true}
11823
+ editable={true}
11824
+ activeQuery={activeQuery()}
11632
11825
  /></div>
11633
11826
  <div class={clsx(styles.detailsHeader, "tsqd-query-details-header")}>Query Explorer</div>
11634
11827
  <div