@tanstack/query-devtools 5.55.1 → 5.58.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/build/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { createSignal, render, lazy, setupStyleSheet, createComponent, mergeProps } from './chunk/TU4XCPXB.js';
1
+ import { createSignal, render, lazy, setupStyleSheet, createComponent, mergeProps } from './chunk/BLREPECS.js';
2
2
 
3
3
  // src/TanstackQueryDevtools.tsx
4
4
  var TanstackQueryDevtools = class {
@@ -69,7 +69,7 @@ var TanstackQueryDevtools = class {
69
69
  if (this.#Component) {
70
70
  Devtools = this.#Component;
71
71
  } else {
72
- Devtools = lazy(() => import('./DevtoolsComponent/LU2ND2BF.js'));
72
+ Devtools = lazy(() => import('./DevtoolsComponent/COOQDZLH.js'));
73
73
  this.#Component = Devtools;
74
74
  }
75
75
  setupStyleSheet(this.#styleNonce, this.#shadowDOMTarget);
@@ -192,7 +192,7 @@ var TanstackQueryDevtoolsPanel = class {
192
192
  if (this.#Component) {
193
193
  Devtools = this.#Component;
194
194
  } else {
195
- Devtools = lazy(() => import('./DevtoolsPanelComponent/XJJMEBKY.js'));
195
+ Devtools = lazy(() => import('./DevtoolsPanelComponent/MU7WGUJF.js'));
196
196
  this.#Component = Devtools;
197
197
  }
198
198
  setupStyleSheet(this.#styleNonce, this.#shadowDOMTarget);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tanstack/query-devtools",
3
- "version": "5.55.1",
3
+ "version": "5.58.0",
4
4
  "description": "Developer tools to interact with and visualize the TanStack Query cache",
5
5
  "author": "tannerlinsley",
6
6
  "license": "MIT",
@@ -54,7 +54,7 @@
54
54
  "superjson": "^2.2.1",
55
55
  "tsup-preset-solid": "^2.2.0",
56
56
  "vite-plugin-solid": "^2.10.2",
57
- "@tanstack/query-core": "5.54.1"
57
+ "@tanstack/query-core": "5.56.2"
58
58
  },
59
59
  "scripts": {}
60
60
  }
package/src/Devtools.tsx CHANGED
@@ -1700,6 +1700,8 @@ const QueryDetails = () => {
1700
1700
  const queryClient = useQueryDevtoolsContext().client
1701
1701
 
1702
1702
  const [restoringLoading, setRestoringLoading] = createSignal(false)
1703
+ const [dataMode, setDataMode] = createSignal<'view' | 'edit'>('view')
1704
+ const [dataEditError, setDataEditError] = createSignal<boolean>(false)
1703
1705
 
1704
1706
  const errorTypes = createMemo(() => {
1705
1707
  return useQueryDevtoolsContext().errorTypes || []
@@ -2047,22 +2049,85 @@ const QueryDetails = () => {
2047
2049
  </Show>
2048
2050
  </div>
2049
2051
  <div class={cx(styles().detailsHeader, 'tsqd-query-details-header')}>
2050
- Data Explorer
2051
- </div>
2052
- <div
2053
- style={{
2054
- padding: tokens.size[2],
2055
- }}
2056
- class="tsqd-query-details-explorer-container tsqd-query-details-data-explorer"
2057
- >
2058
- <Explorer
2059
- label="Data"
2060
- defaultExpanded={['Data']}
2061
- value={activeQueryStateData()}
2062
- editable={true}
2063
- activeQuery={activeQuery()}
2064
- />
2052
+ Data {dataMode() === 'view' ? 'Explorer' : 'Editor'}
2065
2053
  </div>
2054
+ <Show when={dataMode() === 'view'}>
2055
+ <div
2056
+ style={{
2057
+ padding: tokens.size[2],
2058
+ }}
2059
+ class="tsqd-query-details-explorer-container tsqd-query-details-data-explorer"
2060
+ >
2061
+ <Explorer
2062
+ label="Data"
2063
+ defaultExpanded={['Data']}
2064
+ value={activeQueryStateData()}
2065
+ editable={true}
2066
+ onEdit={() => setDataMode('edit')}
2067
+ activeQuery={activeQuery()}
2068
+ />
2069
+ </div>
2070
+ </Show>
2071
+ <Show when={dataMode() === 'edit'}>
2072
+ <form
2073
+ class={cx(
2074
+ styles().devtoolsEditForm,
2075
+ 'tsqd-query-details-data-editor',
2076
+ )}
2077
+ onSubmit={(e) => {
2078
+ e.preventDefault()
2079
+ const formData = new FormData(e.currentTarget)
2080
+ const data = formData.get('data') as string
2081
+ try {
2082
+ const parsedData = JSON.parse(data)
2083
+ activeQuery()!.setState({
2084
+ ...activeQuery()!.state,
2085
+ data: parsedData,
2086
+ })
2087
+ setDataMode('view')
2088
+ } catch (error) {
2089
+ setDataEditError(true)
2090
+ }
2091
+ }}
2092
+ >
2093
+ <textarea
2094
+ name="data"
2095
+ class={styles().devtoolsEditTextarea}
2096
+ onFocus={() => setDataEditError(false)}
2097
+ data-error={dataEditError()}
2098
+ value={JSON.stringify(activeQueryStateData(), null, 2)}
2099
+ ></textarea>
2100
+ <div class={styles().devtoolsEditFormActions}>
2101
+ <span class={styles().devtoolsEditFormError}>
2102
+ {dataEditError() ? 'Invalid Value' : ''}
2103
+ </span>
2104
+ <div class={styles().devtoolsEditFormActionContainer}>
2105
+ <button
2106
+ class={cx(
2107
+ styles().devtoolsEditFormAction,
2108
+ css`
2109
+ color: ${t(colors.gray[600], colors.gray[300])};
2110
+ `,
2111
+ )}
2112
+ type="button"
2113
+ onClick={() => setDataMode('view')}
2114
+ >
2115
+ Cancel
2116
+ </button>
2117
+ <button
2118
+ class={cx(
2119
+ styles().devtoolsEditFormAction,
2120
+ css`
2121
+ color: ${t(colors.blue[600], colors.blue[400])};
2122
+ `,
2123
+ )}
2124
+ >
2125
+ Save
2126
+ </button>
2127
+ </div>
2128
+ </div>
2129
+ </form>
2130
+ </Show>
2066
2131
  <div class={cx(styles().detailsHeader, 'tsqd-query-details-header')}>
2067
2132
  Query Explorer
2068
2133
  </div>
@@ -3318,6 +3383,74 @@ const stylesFactory = (
3318
3383
  }
3319
3384
  }
3320
3385
  `,
3386
+ devtoolsEditForm: css`
3387
+ padding: ${size[2]};
3388
+ & > [data-error='true'] {
3389
+ outline: 2px solid ${t(colors.red[200], colors.red[800])};
3390
+ outline-offset: 2px;
3391
+ border-radius: ${border.radius.xs};
3392
+ }
3393
+ `,
3394
+ devtoolsEditTextarea: css`
3395
+ width: 100%;
3396
+ max-height: 500px;
3397
+ font-family: 'Fira Code', monospace;
3398
+ font-size: ${font.size.xs};
3399
+ border-radius: ${border.radius.sm};
3400
+ field-sizing: content;
3401
+ padding: ${size[2]};
3402
+ background-color: ${t(colors.gray[100], colors.darkGray[800])};
3403
+ color: ${t(colors.gray[900], colors.gray[100])};
3404
+ border: 1px solid ${t(colors.gray[200], colors.gray[700])};
3405
+ resize: none;
3406
+ &:focus {
3407
+ outline-offset: 2px;
3408
+ border-radius: ${border.radius.xs};
3409
+ outline: 2px solid ${t(colors.blue[200], colors.blue[800])};
3410
+ }
3411
+ `,
3412
+ devtoolsEditFormActions: css`
3413
+ display: flex;
3414
+ justify-content: space-between;
3415
+ gap: ${size[2]};
3416
+ align-items: center;
3417
+ padding-top: ${size[1]};
3418
+ font-size: ${font.size.xs};
3419
+ `,
3420
+ devtoolsEditFormError: css`
3421
+ color: ${t(colors.red[700], colors.red[500])};
3422
+ `,
3423
+ devtoolsEditFormActionContainer: css`
3424
+ display: flex;
3425
+ gap: ${size[2]};
3426
+ `,
3427
+ devtoolsEditFormAction: css`
3428
+ font-family: ui-sans-serif, Inter, system-ui, sans-serif, sans-serif;
3429
+ font-size: ${font.size.xs};
3430
+ padding: ${size[1]} ${tokens.size[2]};
3431
+ display: flex;
3432
+ border-radius: ${border.radius.sm};
3433
+ background-color: ${t(colors.gray[100], colors.darkGray[600])};
3434
+ border: 1px solid ${t(colors.gray[300], colors.darkGray[400])};
3435
+ align-items: center;
3436
+ gap: ${size[2]};
3437
+ font-weight: ${font.weight.medium};
3438
+ line-height: ${font.lineHeight.xs};
3439
+ cursor: pointer;
3440
+ &:focus-visible {
3441
+ outline-offset: 2px;
3442
+ border-radius: ${border.radius.xs};
3443
+ outline: 2px solid ${colors.blue[800]};
3444
+ }
3445
+ &:hover {
3446
+ background-color: ${t(colors.gray[200], colors.darkGray[500])};
3447
+ }
3448
+
3449
+ &:disabled {
3450
+ opacity: 0.6;
3451
+ cursor: not-allowed;
3452
+ }
3453
+ `,
3321
3454
  }
3322
3455
  }
3323
3456
 
package/src/Explorer.tsx CHANGED
@@ -1,4 +1,4 @@
1
- import { stringify } from 'superjson'
1
+ import { serialize, stringify } from 'superjson'
2
2
  import { clsx as cx } from 'clsx'
3
3
  import { Index, Match, Show, Switch, createMemo, createSignal } from 'solid-js'
4
4
  import { Key } from '@solid-primitives/keyed'
@@ -9,7 +9,15 @@ import {
9
9
  displayValue,
10
10
  updateNestedDataByPath,
11
11
  } from './utils'
12
- import { Check, CopiedCopier, Copier, ErrorCopier, List, Trash } from './icons'
12
+ import {
13
+ Check,
14
+ CopiedCopier,
15
+ Copier,
16
+ ErrorCopier,
17
+ List,
18
+ Pencil,
19
+ Trash,
20
+ } from './icons'
13
21
  import { useQueryDevtoolsContext, useTheme } from './contexts'
14
22
  import type { Query } from '@tanstack/query-core'
15
23
 
@@ -243,6 +251,7 @@ type ExplorerProps = {
243
251
  dataPath?: Array<string>
244
252
  activeQuery?: Query
245
253
  itemsDeletable?: boolean
254
+ onEdit?: () => void
246
255
  }
247
256
 
248
257
  function isIterable(x: any): x is Iterable<unknown> {
@@ -351,6 +360,19 @@ export default function Explorer(props: ExplorerProps) {
351
360
  dataPath={currentDataPath}
352
361
  />
353
362
  </Show>
363
+
364
+ <Show when={!!props.onEdit && !serialize(props.value).meta}>
365
+ <button
366
+ class={styles().actionButton}
367
+ title={'Bulk Edit Data'}
368
+ aria-label={'Bulk Edit Data'}
369
+ onClick={() => {
370
+ props.onEdit?.()
371
+ }}
372
+ >
373
+ <Pencil />
374
+ </button>
375
+ </Show>
354
376
  </div>
355
377
  </Show>
356
378
  </div>
@@ -309,6 +309,26 @@ export function Copier() {
309
309
  )
310
310
  }
311
311
 
312
+ export function Pencil() {
313
+ return (
314
+ <svg
315
+ width="24"
316
+ height="24"
317
+ viewBox="0 0 24 24"
318
+ fill="none"
319
+ xmlns="http://www.w3.org/2000/svg"
320
+ >
321
+ <path
322
+ d="M2.5 21.4998L8.04927 19.3655C8.40421 19.229 8.58168 19.1607 8.74772 19.0716C8.8952 18.9924 9.0358 18.901 9.16804 18.7984C9.31692 18.6829 9.45137 18.5484 9.72028 18.2795L21 6.99982C22.1046 5.89525 22.1046 4.10438 21 2.99981C19.8955 1.89525 18.1046 1.89524 17 2.99981L5.72028 14.2795C5.45138 14.5484 5.31692 14.6829 5.20139 14.8318C5.09877 14.964 5.0074 15.1046 4.92823 15.2521C4.83911 15.4181 4.77085 15.5956 4.63433 15.9506L2.5 21.4998ZM2.5 21.4998L4.55812 16.1488C4.7054 15.7659 4.77903 15.5744 4.90534 15.4867C5.01572 15.4101 5.1523 15.3811 5.2843 15.4063C5.43533 15.4351 5.58038 15.5802 5.87048 15.8703L8.12957 18.1294C8.41967 18.4195 8.56472 18.5645 8.59356 18.7155C8.61877 18.8475 8.58979 18.9841 8.51314 19.0945C8.42545 19.2208 8.23399 19.2944 7.85107 19.4417L2.5 21.4998Z"
323
+ stroke="currentColor"
324
+ stroke-width="2"
325
+ stroke-linecap="round"
326
+ stroke-linejoin="round"
327
+ />
328
+ </svg>
329
+ )
330
+ }
331
+
312
332
  export function CopiedCopier(props: { theme: 'light' | 'dark' }) {
313
333
  return (
314
334
  <svg