Skip to content

Commit 091d719

Browse files
committed
feat: enable editing of state
1 parent e135e7f commit 091d719

3 files changed

Lines changed: 112 additions & 9 deletions

File tree

demo/src/myComposable.ts

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,22 @@
1-
import { ref } from 'vue'
1+
import { computed, reactive, ref } from 'vue'
22
import { debug } from '../../src'
33

44
export function useFoo() {
55
const priv = ref(0)
66

7+
const squared = computed(() => priv.value * priv.value)
8+
9+
const foo = reactive({
10+
vin: 'was here',
11+
one: 1,
12+
bool: false,
13+
nested: { vin: 'still here' },
14+
})
15+
716
const inc = () => priv.value++
817
const dec = () => priv.value--
918

10-
debug('useFoo', { priv })
19+
debug('useFoo', { value: priv, squared, foo })
1120

1221
return { inc, dec }
1322
}

src/devtools.test.ts

Lines changed: 84 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import { beforeEach, expect, test, vi } from 'vitest'
2-
import { ref } from 'vue'
2+
import { computed, ref } from 'vue'
33
import { INSPECTOR_ID } from './constants'
44
import {
5+
handleEditInspectorState,
56
handleGetInspectorState,
67
handleGetInspectorTree,
78
handleInspectComponent,
@@ -169,7 +170,23 @@ test('getInspectorState for individual entry', () => {
169170
{
170171
"editable": true,
171172
"key": "foo",
172-
"value": "bar",
173+
"value": RefImpl {
174+
"__v_isRef": true,
175+
"__v_isShallow": false,
176+
"_rawValue": "bar",
177+
"_value": "bar",
178+
"dep": Dep {
179+
"__v_skip": true,
180+
"activeLink": undefined,
181+
"computed": undefined,
182+
"key": undefined,
183+
"map": undefined,
184+
"sc": 0,
185+
"subs": undefined,
186+
"subsHead": undefined,
187+
"version": 0,
188+
},
189+
},
173190
},
174191
],
175192
}
@@ -264,3 +281,68 @@ test('inspectComponent adds state to payload', () => {
264281
]
265282
`)
266283
})
284+
285+
test('editInspectorState for existent entry', () => {
286+
const debugState = { value: computed(() => 23) }
287+
upsert({
288+
groupId: 'groupid',
289+
uid: 'uid',
290+
componentName: 'Foo',
291+
componentInstance: null,
292+
debugState,
293+
})
294+
295+
const setMock = vi.fn()
296+
297+
const payload: DevtoolsApiHandlerPayload<'editInspectorState'> =
298+
{
299+
app: {},
300+
inspectorId: INSPECTOR_ID,
301+
nodeId: 'uid',
302+
path: [],
303+
type: '',
304+
state: {
305+
value: 'yess',
306+
newKey: undefined,
307+
remove: undefined,
308+
},
309+
set: setMock,
310+
}
311+
312+
handleEditInspectorState(payload)
313+
314+
expect(setMock).toHaveBeenCalledExactlyOnceWith(
315+
debugState,
316+
)
317+
})
318+
319+
test('editInspectorState for non-existent entry', () => {
320+
upsert({
321+
groupId: 'groupid',
322+
uid: 'uid',
323+
componentName: 'Foo',
324+
componentInstance: null,
325+
debugState: { value: computed(() => 23) },
326+
})
327+
328+
const setMock = vi.fn()
329+
330+
const payload: DevtoolsApiHandlerPayload<'editInspectorState'> =
331+
{
332+
app: {},
333+
inspectorId: INSPECTOR_ID,
334+
nodeId: 'rando',
335+
path: [],
336+
type: '',
337+
state: {
338+
value: 'yess',
339+
newKey: undefined,
340+
remove: undefined,
341+
},
342+
set: setMock,
343+
}
344+
345+
handleEditInspectorState(payload)
346+
347+
expect(setMock).not.toHaveBeenCalled()
348+
})

src/devtools.ts

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { setupDevToolsPlugin } from '@vue/devtools-api'
22
import type { App } from 'vue'
3-
import { toValue } from 'vue'
3+
import { isReadonly, toValue } from 'vue'
44
import { INSPECTOR_ID, TIMELINE_ID } from './constants'
55
import { byGroupId, byUid, onUpdate } from './registry'
66
import type {
@@ -71,8 +71,8 @@ export const handleGetInspectorState =
7171
entry.debugState,
7272
).map(([key, value]) => ({
7373
key,
74-
value: toValue(value),
75-
editable: true,
74+
value,
75+
editable: !isReadonly(value),
7676
})),
7777
}
7878
if (entry.componentInstance)
@@ -96,15 +96,26 @@ export const handleInspectComponent: DevtoolsApiHandler<
9696
([key, value]) => ({
9797
type: entry.uid,
9898
key,
99-
value: toValue(value),
100-
editable: true,
99+
value,
100+
editable: !isReadonly(value),
101101
}),
102102
)
103103
})
104104
.toArray()
105105
payload.instanceData.state.push(...entries)
106106
}
107107

108+
export const handleEditInspectorState: DevtoolsApiHandler<
109+
'editInspectorState'
110+
> = (payload) => {
111+
if (payload.inspectorId === INSPECTOR_ID) {
112+
const uid = payload.nodeId
113+
const entry = byUid.get(uid)
114+
if (!entry) return
115+
payload.set(entry.debugState)
116+
}
117+
}
118+
108119
export function setupComposableDevtools<T>(app: App<T>) {
109120
console.log('🐞 Vuebugger ready to use')
110121
setupDevToolsPlugin(
@@ -146,6 +157,7 @@ export function setupComposableDevtools<T>(app: App<T>) {
146157
api.on.getInspectorTree(handleGetInspectorTree)
147158
api.on.getInspectorState(handleGetInspectorState(api))
148159
api.on.inspectComponent(handleInspectComponent)
160+
api.on.editInspectorState(handleEditInspectorState)
149161
},
150162
)
151163
}

0 commit comments

Comments
 (0)