Skip to content

Commit

Permalink
feat: kit
Browse files Browse the repository at this point in the history
  • Loading branch information
FliPPeDround committed Dec 10, 2024
1 parent c34b8a0 commit 8dfe3c8
Show file tree
Hide file tree
Showing 30 changed files with 195 additions and 247 deletions.
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@uni-helper/devtools-monorepo",
"type": "module",
"version": "0.1.0",
"version": "0.0.0",
"private": true,
"packageManager": "[email protected]",
"description": "devtools for uni",
Expand Down Expand Up @@ -31,6 +31,7 @@
"lint": "eslint .",
"lint:fix": "eslint . --fix",
"test": "vitest",
"release": "bumpp -r",
"preinstall": "npx only-allow pnpm",
"postinstall": "npx simple-git-hooks"
},
Expand Down
1 change: 1 addition & 0 deletions packages/client/components.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ declare module 'vue' {
CodeBlock: typeof import('./src/components/code/CodeBlock.vue')['default']
CodeSnippets: typeof import('./src/components/code/CodeSnippets.vue')['default']
ComponentTreeNode: typeof import('./src/components/components/ComponentTreeNode.vue')['default']
CustomTabComponent: typeof import('./src/components/CustomTabComponent.vue')['default']
DevToolsHeader: typeof import('./src/components/basic/DevToolsHeader.vue')['default']
DevToolsLogo: typeof import('./src/components/common/DevToolsLogo.vue')['default']
DockingPanel: typeof import('./src/components/common/DockingPanel.vue')['default']
Expand Down
2 changes: 1 addition & 1 deletion packages/client/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@uni-helper/devtools-client",
"type": "module",
"version": "0.1.0",
"version": "0.0.1",
"private": true,
"packageManager": "[email protected]",
"description": "uni-app 开发者工具客户端",
Expand Down
Binary file added packages/client/public/loading_icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions packages/client/src/App.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<script setup lang="ts">
const { init, loading } = useInitState()
const { init, versionState } = useInitState()
init()
const router = useRouter()
const clientState = devtoolsClientState
Expand All @@ -10,7 +10,7 @@ if (clientState.value.route !== '/')
<template>
<main fixed inset-0 h-screen w-screen>
<Suspense>
<AppConnecting v-if="loading" />
<AppConnecting v-if="!versionState?.vueVersion" />
<div
v-else
:class="clientState.isFirstVisit ? 'flex' : 'grid grid-cols-[50px_1fr]'" h-full h-screen of-hidden font-sans
Expand Down
2 changes: 1 addition & 1 deletion packages/client/src/components/AppConnecting.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<script setup lang="ts">
import Logo from '/icon.png'
import Logo from '/loading_icon.png'
</script>

<template>
Expand Down
49 changes: 49 additions & 0 deletions packages/client/src/components/CustomTabComponent.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<script setup lang="ts">
import type { CustomTab } from '@vue/devtools-kit'
const p = defineProps<{
tab: CustomTab
iframeInline?: boolean
}>()
const props = toRefs(p)
const tabName = computed(() => props.tab.value?.name)
const iframeViewVisible = ref(true)
watch(() => tabName.value, () => {
iframeViewVisible.value = false
setTimeout(() => {
iframeViewVisible.value = true
}, 100)
})
</script>

<template>
<template v-if="!tab">
<div flex="~ col" h-full items-center justify-center>
<div flex="~ col gap2" mxa items-center>
<div i-carbon-queued mb2 text-5xl op50 />
<p text-xl>
Tab <code text-rose>{{ tabName }}</code> not found
</p>
<p mt8 animate-pulse>
Redirecting to overview page...
</p>
</div>
</div>
</template>
<template v-else-if="tab?.view?.type === 'iframe'">
<IframeView v-if="iframeViewVisible" :src="tab.view.src" :inline="iframeInline" />
</template>
<template v-else-if="tab?.view?.type === 'vnode'">
<Component :is="tab.view.vnode" />
</template>
<template v-else>
<div>
<NCard flex="~ col" h-full items-center justify-center>
Unknown tab type {{ tab?.view }}
</NCard>
</div>
</template>
</template>
2 changes: 1 addition & 1 deletion packages/client/src/components/SideNav.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { VueDropdown } from '@vue/devtools-ui'
import Logo from '/icon.png'
import type { Tab } from '~/constants/tab'
const builtinTab = useTabs()
const { builtinTab } = useTabs()
</script>

<template>
Expand Down
37 changes: 31 additions & 6 deletions packages/client/src/components/TabIcon.vue
Original file line number Diff line number Diff line change
@@ -1,29 +1,54 @@
<script setup lang="ts">
defineProps<{
import { isUrlString } from '@vue/devtools-shared'
import { VueIcIcon } from '@vue/devtools-ui'
const props = withDefaults(defineProps<{
icon?: string
title?: string
}>()
showTitle?: boolean
fallback?: string
}>(), {
showTitle: true,
})
const _icon = ref<string | undefined>(props.icon)
watch(() => props.icon, (icon) => {
_icon.value = icon
})
function onLoadError() {
_icon.value = props.fallback
}
// For custom-inspector icons, the prefix is 'custom-ic-'
const CUSTOM_IC_ICON_PREFIX = 'custom-ic-'
</script>

<template>
<img
v-if="icon && (icon.startsWith('/') || icon.match(/^https?:/))"
v-if="_icon && isUrlString(_icon)"
:style="{
width: '1em',
height: '1em',
}"
v-bind="$attrs"
:src="icon"
:src="_icon"
:alt="title"
@error="onLoadError"
>
<VueIcIcon
v-else-if="_icon?.startsWith(CUSTOM_IC_ICON_PREFIX)" :name="_icon.slice(CUSTOM_IC_ICON_PREFIX.length)"
v-bind="$attrs" :title="showTitle ? title : undefined"
/>
<div
v-else
:style="{
width: '1em',
height: '1em',
}"
v-bind="$attrs"
:class="icon || 'carbon-bring-forward'"
:title="title"
:class="_icon || 'i-carbon-bring-forward'"
:title="showTitle ? title : undefined"
/>
</template>
45 changes: 30 additions & 15 deletions packages/client/src/composables/useTabs.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
// @unocss-include

import type { CustomTab } from '@vue/devtools-kit'
import type { ModuleBuiltinTab } from '~/types'

export interface TabItem {
icon: string
name: string
Expand Down Expand Up @@ -64,13 +69,13 @@ export function useTabs() {
path: '/documents',
title: 'Documents',
},
{
icon: 'i-tabler:terminal',
name: 'console',
order: 100,
path: '/console',
title: 'Console',
},
// {
// icon: 'i-tabler:terminal',
// name: 'console',
// order: 100,
// path: '/console',
// title: 'Console',
// },
{
icon: 'i-carbon-network-4',
name: 'graph',
Expand All @@ -89,22 +94,32 @@ export function useTabs() {
],
])

const CUSTOM_TAB_VIEW = 'custom-tab-view'

trpc.onTab.subscribe(undefined, {
onData: (data) => {
const category = data.category || 'app'
builtinTab.value.forEach(([c, tabs]) => {
if (c === category) {
tabs.push({
icon: data.icon!,
name: data.name,
order: -100,
path: `/${data.name}`,
title: data.title,
})
if (!tabs.find(t => t.name === data.name)) {
tabs.push({
...data,
path: `/${CUSTOM_TAB_VIEW}/${data.name}`,
} as unknown as TabItem)
}
}
})
},
})

return builtinTab
const flattenedTabs = computed(() => {
return builtinTab.value.reduce((prev, [_, tabs]) => {
tabs.forEach((tab) => {
prev.push(tab)
})
return prev
}, [] as Array<ModuleBuiltinTab | CustomTab>)
})

return { builtinTab, flattenedTabs }
}
1 change: 1 addition & 0 deletions packages/client/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,6 @@ const app = createApp(App)
const router = createRouter({
history: createMemoryHistory(),
})
console.log(router)
app.use(router)
app.mount('#app')
27 changes: 27 additions & 0 deletions packages/client/src/pages/custom-tab-view/[name].vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<script setup lang="ts">
import type { CustomTab } from '@vue/devtools-kit'
import type { ComputedRef } from 'vue'
const route = useRoute()
const router = useRouter()
const { flattenedTabs } = useTabs()
// @ts-expect-error name is defined in router
const tabName = computed(() => route.params.name)
const tab = computed(() => flattenedTabs.value.find(tab => tabName.value! === tab.name) || null!) as ComputedRef<CustomTab>
onMounted(() => {
if (!tab.value) {
const timer = setTimeout(() => {
if (tab.value) {
clearTimeout(timer)
return
}
router.replace('/overview')
}, 2000)
}
})
</script>

<template>
<CustomTabComponent :tab="tab" />
</template>
3 changes: 0 additions & 3 deletions packages/client/src/stores/init.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ export const useInitState = createGlobalState(
() => {
const versionState = ref<VersionState>()
const currentPage = ref('')
const loading = ref(false)
function init() {
trpc.onVersion.subscribe(undefined, {
onData: (data) => {
Expand All @@ -14,14 +13,12 @@ export const useInitState = createGlobalState(
trpc.onCurrentPage.subscribe(undefined, {
onData: (data) => {
currentPage.value = data
console.log('currentPage', data)
},
})
}

return {
init,
loading,
currentPage,
versionState,
}
Expand Down
12 changes: 12 additions & 0 deletions packages/client/src/types/index.d.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
import type { CustomTab } from '@vue/devtools-kit'
import type { MaybeRefOrGetter } from 'vue'

export interface ModuleInfo {
id: string
plugins: { name: string, transform?: number, resolveId?: number }[]
Expand Down Expand Up @@ -31,3 +34,12 @@ export interface InitState {
/** pinia数据 */
piniaState: { [key: string]: any }
}

export interface ModuleBuiltinTab extends Pick<CustomTab, 'name' | 'icon' | 'title' | 'category'> {
fallbackIcon?: string
order?: number
path: string
show?: () => MaybeRefOrGetter<any>
badge?: () => MaybeRefOrGetter<number | string | undefined>
onClick?: () => void
}
1 change: 1 addition & 0 deletions packages/client/typed-router.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ declare module 'vue-router/auto-routes' {
'/assets': RouteRecordInfo<'/assets', '/assets', Record<never, never>, Record<never, never>>,
'/components': RouteRecordInfo<'/components', '/components', Record<never, never>, Record<never, never>>,
'/console': RouteRecordInfo<'/console', '/console', Record<never, never>, Record<never, never>>,
'/custom-tab-view/[name]': RouteRecordInfo<'/custom-tab-view/[name]', '/custom-tab-view/:name', { name: ParamValue<true> }, { name: ParamValue<false> }>,
'/documents': RouteRecordInfo<'/documents', '/documents', Record<never, never>, Record<never, never>>,
'/graph': RouteRecordInfo<'/graph', '/graph', Record<never, never>, Record<never, never>>,
'/inspect': RouteRecordInfo<'/inspect', '/inspect', Record<never, never>, Record<never, never>>,
Expand Down
9 changes: 5 additions & 4 deletions packages/kit/package.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
{
"name": "@uni-helper/devtools-kit",
"type": "module",
"version": "0.1.0",
"private": true,
"version": "0.0.1",
"packageManager": "[email protected]",
"description": "devtools for uni",
"author": "FliPPeDround <[email protected]>",
Expand Down Expand Up @@ -44,9 +43,11 @@
"scripts": {
"build": "tsup",
"stub": "tsup --watch",
"test": "vitest"
"prepublishOnly": "build",
"release": "bumpp"
},
"dependencies": {
"@trpc/client": "10.45.2"
"@trpc/client": "10.45.2",
"@vue/devtools-kit": "^7.6.7"
}
}
21 changes: 20 additions & 1 deletion packages/kit/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,29 @@
import type { CustomTab } from '@vue/devtools-kit'
import { isUrlString } from '@vue/devtools-shared'
import { createTrpc } from './trpc'

function resolveIcon(icon?: string) {
if (!icon)
return
if (icon.startsWith('baseline-')) {
return `custom-ic-${icon}`
}
// devtools internal custom tab icons are starts with `i-` prefix, render as it is set in unocss safelist
// or if it's a url
if (icon.startsWith('i-') || isUrlString(icon))
return icon
// for custom-tab, we use `custom-ic-` prefix
return `custom-ic-baseline-${icon}`
}

export function addCustomTab(tab: CustomTab) {
console.log('addCustomTab', tab)
const trpc = createTrpc()!
trpc.sendTab.subscribe(tab, {
// @ts-expect-error type not important
trpc.sendTab.subscribe({
...tab,
icon: resolveIcon(tab.icon),
}, {
onComplete: () => {},
})
}
Loading

0 comments on commit 8dfe3c8

Please sign in to comment.