Skip to content

Commit

Permalink
feat: further compatibility with v6 pluign API
Browse files Browse the repository at this point in the history
  • Loading branch information
webfansplz committed Jun 5, 2024
1 parent a696b1c commit d69723f
Show file tree
Hide file tree
Showing 20 changed files with 323 additions and 48 deletions.
4 changes: 3 additions & 1 deletion packages/applet/src/components/state/ChildStateViewer.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@ withDefaults(defineProps<{
data: CustomInspectorState[]
depth: number
index: string
expandedStateId?: string
}>(), {
depth: 0,
expandedStateId: '',
})
</script>

Expand All @@ -17,7 +19,7 @@ withDefaults(defineProps<{
v-for="(item, i) in data"
:key="i"
>
<StateFieldViewer :data="item" :depth="depth + 1" :index="`${index}-${i}`" />
<StateFieldViewer :data="item" :depth="depth + 1" :index="`${index}-${i}`" :expanded-state-id="expandedStateId" />
</div>
</div>
</template>
2 changes: 1 addition & 1 deletion packages/applet/src/components/state/RootStateViewer.vue
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ const { expanded, toggleExpanded } = useToggleExpanded(props.expandedStateId)
<div
v-if="item?.length && expanded.includes(`${index}`)"
>
<ChildStateViewer :data="item" :index="`${index}`" />
<ChildStateViewer :data="item" :index="`${index}`" :expanded-state-id="expandedStateId" />
</div>
</div>
</div>
Expand Down
5 changes: 3 additions & 2 deletions packages/applet/src/components/state/StateFieldEditor.vue
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,8 @@ const buttonClass = computed(() => ({
'opacity-0': !props.hovering,
}))
function quickEdit(v: unknown, remove: boolean = false) {
rpc.value.editInspectorState({
async function quickEdit(v: unknown, remove: boolean = false) {
await rpc.value.editInspectorState({
path: props.data.path || [props.data.key],
inspectorId: state.value.inspectorId,
type: props.data.stateType!,
Expand All @@ -57,6 +57,7 @@ function quickEdit(v: unknown, remove: boolean = false) {
remove,
},
} as unknown as DevToolsV6PluginAPIHookPayloads[DevToolsV6PluginAPIHookKeys.EDIT_COMPONENT_STATE])
await rpc.value.sendInspectorState(state.value.inspectorId)
}
function quickEditNum(v: number | string, offset: 1 | -1) {
Expand Down
13 changes: 8 additions & 5 deletions packages/applet/src/components/state/StateFieldViewer.vue
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ const props = defineProps<{
data: CustomInspectorState
depth: number
index: string
expandedStateId?: string
}>()
const STATE_FIELDS_LIMIT_SIZE = 30
Expand All @@ -30,7 +31,7 @@ const displayedValue = computed(() => formatInspectorStateValue(props.data.value
}))
const type = computed(() => getInspectorStateValueType(props.data.value))
const raw = computed(() => getRaw(props.data.value))
const { expanded, toggleExpanded } = useToggleExpanded()
const { expanded, toggleExpanded } = useToggleExpanded(props.expandedStateId ?? '')
// custom state format class
const stateFormatClass = computed(() => {
Expand Down Expand Up @@ -135,9 +136,9 @@ watch(() => editing.value, (v) => {
}
})
function submit() {
async async function submit() {
const data = props.data
rpc.value.editInspectorState({
await rpc.value.editInspectorState({
path: normalizedPath.value,
inspectorId: state.value.inspectorId,
type: data.stateType!,
Expand All @@ -148,6 +149,7 @@ function submit() {
value: toSubmit(editingText.value, raw.value.customType),
},
} as unknown as DevToolsV6PluginAPIHookPayloads[DevToolsV6PluginAPIHookKeys.EDIT_COMPONENT_STATE])
await rpc.value.sendInspectorState(state.value.inspectorId)
toggleEditing()
}
Expand All @@ -162,9 +164,9 @@ function addNewProp(type: EditorAddNewPropType) {
addNewPropApi(type, raw.value.value)
}
function submitDrafting() {
async function submitDrafting() {
const data = props.data
rpc.value.editInspectorState({
await rpc.value.editInspectorState({
path: [...normalizedPath.value, draftingNewProp.value.key],
inspectorId: state.value.inspectorId,
type: data.stateType!,
Expand All @@ -175,6 +177,7 @@ function submitDrafting() {
value: toSubmit(draftingNewProp.value.value),
},
} as unknown as DevToolsV6PluginAPIHookPayloads[DevToolsV6PluginAPIHookKeys.EDIT_COMPONENT_STATE])
await rpc.value.sendInspectorState(state.value.inspectorId)
resetDrafting()
}
Expand Down
1 change: 1 addition & 0 deletions packages/applet/src/composables/custom-inspector.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ export interface CustomInspectorType {
id: string
label: string
logo: string
icon: string
packageName: string | undefined
homepage: string | undefined
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,31 +1,55 @@
<script setup lang="ts">
import { computed, onUnmounted, ref, watch } from 'vue'
import { Pane, Splitpanes } from 'splitpanes'
import { DevToolsMessagingEvents, rpc } from '@vue/devtools-core'
import { DevToolsMessagingEvents, onRpcConnected, rpc } from '@vue/devtools-core'
import { parse } from '@vue/devtools-kit'
import type { CustomInspectorNode, CustomInspectorOptions, CustomInspectorState } from '@vue/devtools-kit'
import { vTooltip } from '@vue/devtools-ui'
import Navbar from '~/components/basic/Navbar.vue'
import SelectiveList from '~/components/basic/SelectiveList.vue'
import DevToolsHeader from '~/components/basic/DevToolsHeader.vue'
import Empty from '~/components/basic/Empty.vue'
import RootStateViewer from '~/components/state/RootStateViewer.vue'
import { createExpandedContext } from '~/composables/toggle-expanded'
import { useCustomInspectorState } from '~/composables/custom-inspector-state'
import ComponentTree from '~/components/tree/TreeViewer.vue'
const { expanded: expandedStateNodes } = createExpandedContext('vue-query-state')
const { expanded: expandedTreeNodes } = createExpandedContext()
const { expanded: expandedStateNodes } = createExpandedContext('custom-inspector-state')
const customInspectState = useCustomInspectorState()
const inspectorId = computed(() => customInspectState.value.id!)
const nodeActions = ref<CustomInspectorOptions['nodeActions']>([])
const actions = ref<CustomInspectorOptions['nodeActions']>([])
const selected = ref('')
const tree = ref<CustomInspectorNode[]>([])
const treeNodeLinkedList = computed(() => tree.value?.length ? dfs(tree.value?.[0]) : [])
const selected = ref('')
const state = ref<Record<string, CustomInspectorState[]>>({})
const emptyState = computed(() => !Object.keys(state.value).length)
// tree
function dfs(node: { id: string, children?: { id: string }[] }, path: string[] = [], linkedList: string[][] = []) {
path.push(node.id)
if (node.children?.length === 0)
linkedList.push([...path])
node.children?.forEach((child) => {
dfs(child, path, linkedList)
})
path.pop()
return linkedList
}
function getNodesByDepth(list: string[][], depth: number) {
const nodes: string[] = []
list.forEach((item) => {
nodes.push(...item.slice(0, depth + 1))
})
return [...new Set(nodes)]
}
function getNodeActions() {
rpc.value.getInspectorNodeActions(inspectorId.value).then((actions) => {
nodeActions.value = actions
Expand Down Expand Up @@ -80,6 +104,7 @@ const getInspectorTree = () => {
tree.value = data
if (!selected.value && data.length) {
selected.value = data[0].id
expandedTreeNodes.value = getNodesByDepth(treeNodeLinkedList.value, 1)
getInspectorState(data[0].id)
}
})
Expand All @@ -94,10 +119,11 @@ function onInspectorTreeUpdated(_data: string) {
if (!data.rootNodes.length || data.inspectorId !== inspectorId.value)
return
tree.value = data.rootNodes
if ((!selected.value && data.rootNodes.length) || (selected.value && !data.rootNodes.find(node => node.id === selected.value))) {
selected.value = data.rootNodes[0].id
getInspectorState(data.rootNodes[0].id)
}
expandedTreeNodes.value = getNodesByDepth(treeNodeLinkedList.value, 1)
// if ((!selected.value && data.rootNodes.length) || (selected.value && !data.rootNodes.find(node => node.id === selected.value))) {
// selected.value = data.rootNodes[0].id
// getInspectorState(data.rootNodes[0].id)
// }
}
function onInspectorStateUpdated(_data: string) {
Expand All @@ -106,17 +132,19 @@ function onInspectorStateUpdated(_data: string) {
state: CustomInspectorState
nodeId: string
}
if (data.inspectorId !== inspectorId.value || !data.state)
if (data.inspectorId !== inspectorId.value || !data.state || data.nodeId !== selected.value)
return
const { inspectorId: _inspectorId, ...filtered } = data.state
state.value = filterEmptyState(filtered as any)
expandedStateNodes.value = Array.from({ length: Object.keys(state.value).length }, (_, i) => `${i}`)
// expandedStateNodes.value = Array.from({ length: Object.keys(state.value).length }, (_, i) => `${i}`)
}
rpc.functions.on(DevToolsMessagingEvents.INSPECTOR_TREE_UPDATED, onInspectorTreeUpdated)
rpc.functions.on(DevToolsMessagingEvents.INSPECTOR_STATE_UPDATED, onInspectorStateUpdated)
onRpcConnected(() => {
rpc.functions.on(DevToolsMessagingEvents.INSPECTOR_TREE_UPDATED, onInspectorTreeUpdated)
rpc.functions.on(DevToolsMessagingEvents.INSPECTOR_STATE_UPDATED, onInspectorStateUpdated)
})
onUnmounted(() => {
rpc.functions.off(DevToolsMessagingEvents.INSPECTOR_TREE_UPDATED, onInspectorTreeUpdated)
Expand All @@ -140,7 +168,7 @@ onUnmounted(() => {
</div>
</div>
</div>
<SelectiveList v-model="selected" :data="tree" />
<ComponentTree v-model="selected" :data="tree" />
</div>
</Pane>
<Pane size="60">
Expand All @@ -152,7 +180,7 @@ onUnmounted(() => {
</div>
</div>
</div>
<RootStateViewer v-if="selected && !emptyState" :data="state" :node-id="selected" :inspector-id="inspectorId" expanded-state-id="vue-query-state" class="no-scrollbar flex-1 select-none overflow-scroll" />
<RootStateViewer v-if="selected && !emptyState" :data="state" :node-id="selected" :inspector-id="inspectorId" expanded-state-id="custom-inspector-state" class="no-scrollbar flex-1 select-none overflow-scroll" />
<Empty v-else>
No Data
</Empty>
Expand Down
1 change: 1 addition & 0 deletions packages/client/src/components/common/SideNavItem.vue
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ function onClick() {
<TabIcon
text-xl
:icon="tab.icon"
:fallback="tab.fallbackIcon"
title="Settings"
:show-title="false"
/>
Expand Down
16 changes: 12 additions & 4 deletions packages/client/src/components/common/TabIcon.vue
Original file line number Diff line number Diff line change
@@ -1,23 +1,31 @@
<script setup lang="ts">
withDefaults(defineProps<{
const props = withDefaults(defineProps<{
icon?: string
title?: string
showTitle?: boolean
fallback?: string
}>(), {
showTitle: true,
})
const _icon = ref<string | undefined>(props.icon)
function onLoadError() {
_icon.value = props.fallback
}
</script>

<template>
<img
v-if="icon && (icon.startsWith('/') || icon.match(/^https?:/))"
v-if="_icon && (_icon.startsWith('/') || _icon.match(/^https?:/))"
:style="{
width: '1em',
height: '1em',
}"
v-bind="$attrs"
:src="icon"
:src="_icon"
:alt="title"
@error="onLoadError"
>
<div
v-else
Expand All @@ -26,7 +34,7 @@ withDefaults(defineProps<{
height: '1em',
}"
v-bind="$attrs"
:class="icon || 'i-carbon-bring-forward'"
:class="_icon || 'i-carbon-bring-forward'"
:title="showTitle ? title : undefined"
/>
</template>
1 change: 1 addition & 0 deletions packages/client/src/composables/custom-inspector-tabs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ export function useCustomInspectorTabs() {
order: index,
name: inspector.id,
icon: inspector.logo,
fallbackIcon: inspector.icon,
title: inspector.label,
path: `${CUSTOM_INSPECTOR_TAB_VIEW}/${inspector.id}`,
category: 'modules',
Expand Down
1 change: 1 addition & 0 deletions packages/client/src/types/tab.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import type { MaybeRefOrGetter } from 'vue'
import type { CustomTab } from '@vue/devtools-kit'

export interface ModuleBuiltinTab extends Pick<CustomTab, 'name' | 'icon' | 'title' | 'category'> {
fallbackIcon?: string
order?: number
path: string
show?: () => MaybeRefOrGetter<any>
Expand Down
3 changes: 3 additions & 0 deletions packages/core/src/rpc/global.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,9 @@ export const functions = {
async editInspectorState(payload: DevToolsV6PluginAPIHookPayloads[DevToolsV6PluginAPIHookKeys.EDIT_INSPECTOR_STATE]) {
return await devtools.ctx.api.editInspectorState(payload)
},
sendInspectorState(id: string) {
return devtools.ctx.api.sendInspectorState(id)
},
inspectComponentInspector() {
return devtools.ctx.api.inspectComponentInspector()
},
Expand Down
30 changes: 18 additions & 12 deletions packages/devtools-kit/src/api/v6/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { DevToolsContextHookKeys, DevToolsV6PluginAPIHookKeys, DevToolsV6PluginA
import { devtoolsPluginBuffer } from '../../ctx/plugin'
import { devtoolsHooks } from '../../hook'
import { DevToolsHooks } from '../../types'
import { getActiveInspectors } from '../../ctx/inspector'

export class DevToolsV6PluginAPI {
private plugin: DevToolsPlugin
Expand Down Expand Up @@ -54,18 +55,23 @@ export class DevToolsV6PluginAPI {

// component inspector
notifyComponentUpdate(instance?: ComponentInstance) {
if (instance) {
const args = [
instance.appContext.app,
instance.uid,
instance.parent?.uid,
instance,
] as const
devtoolsHooks.callHook(DevToolsHooks.COMPONENT_UPDATED, ...args)
}
else {
// @ts-expect-error skip type check
devtoolsHooks.callHook(DevToolsHooks.COMPONENT_UPDATED)
const inspector = getActiveInspectors().find(i => i.packageName === this.plugin.descriptor.packageName)
if (inspector?.id) {
// @TODO: handler
if (instance) {
const args = [
instance.appContext.app,
instance.uid,
instance.parent?.uid,
instance,
] as const
devtoolsHooks.callHook(DevToolsHooks.COMPONENT_UPDATED, ...args)
}
else {
// @ts-expect-error skip type check
devtoolsHooks.callHook(DevToolsHooks.COMPONENT_UPDATED)
}
this.hooks.callHook(DevToolsContextHookKeys.SEND_INSPECTOR_STATE, { inspectorId: inspector.id, plugin: this.plugin })
}
}

Expand Down
13 changes: 11 additions & 2 deletions packages/devtools-kit/src/ctx/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ import { openInEditor } from '../core/open-in-editor'
import { normalizeRouterInfo } from '../core/router'
import { getComponentInspector } from '../core/component-inspector'
import type { DevToolsContextHooks, DevToolsMessagingHooks, DevToolsV6PluginAPIHookPayloads } from './hook'
import { DevToolsV6PluginAPIHookKeys } from './hook'
import { DevToolsContextHookKeys, DevToolsV6PluginAPIHookKeys } from './hook'
import { activeAppRecord, devtoolsAppRecords, setActiveAppRecord, setActiveAppRecordId } from './state'
import { callInspectorUpdatedHook } from './inspector'
import { callInspectorUpdatedHook, getInspector } from './inspector'

export function createDevToolsApi(hooks: Hookable<DevToolsContextHooks & DevToolsMessagingHooks, HookKeys<DevToolsContextHooks & DevToolsMessagingHooks>>) {
return {
Expand Down Expand Up @@ -60,11 +60,20 @@ export function createDevToolsApi(hooks: Hookable<DevToolsContextHooks & DevTool
stateEditor.set(obj, path, value, cb || stateEditor.createDefaultSetCallback(payload.state))
},
}

// @ts-expect-error hookable
hooks.callHookWith((callbacks) => {
callbacks.forEach(cb => cb(_payload))
}, DevToolsV6PluginAPIHookKeys.EDIT_INSPECTOR_STATE)
},
// send inspector state
sendInspectorState(inspectorId: string) {
const inspector = getInspector(inspectorId)
hooks.callHook(DevToolsContextHookKeys.SEND_INSPECTOR_STATE, { inspectorId, plugin: {
descriptor: inspector!.descriptor,
setupFn: () => ({}),
} })
},
// inspect component inspector
inspectComponentInspector() {
return inspectComponentHighLighter()
Expand Down
Loading

0 comments on commit d69723f

Please sign in to comment.