Skip to content

Commit

Permalink
feat: add devtools
Browse files Browse the repository at this point in the history
  • Loading branch information
posva committed Feb 8, 2025
1 parent 98a4b73 commit 43912aa
Show file tree
Hide file tree
Showing 6 changed files with 100 additions and 56 deletions.
17 changes: 15 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -79,13 +79,24 @@
"prepare": "simple-git-hooks"
},
"size-limit": [
{
"name": "useQuery only from source",
"path": "src/index.ts",
"import": "{ useQuery, PiniaColada }",
"ignore": [
"vue",
"pinia",
"@vue/devtools-api"
]
},
{
"name": "useQuery only",
"path": "dist/index.js",
"import": "{ useQuery, PiniaColada }",
"ignore": [
"vue",
"pinia"
"pinia",
"@vue/devtools-api"
]
},
{
Expand All @@ -94,7 +105,8 @@
"import": "{ useQuery, PiniaColada, useMutation }",
"ignore": [
"vue",
"pinia"
"pinia",
"@vue/devtools-api"
]
}
],
Expand All @@ -109,6 +121,7 @@
"@pinia/colada": "workspace:*",
"@posva/prompts": "^2.4.4",
"@shikijs/vitepress-twoslash": "^2.2.0",
"@size-limit/esbuild-why": "^11.1.6",
"@size-limit/preset-small-lib": "^11.1.6",
"@types/node": "^22.12.0",
"@vitejs/plugin-vue": "^5.2.1",
Expand Down
28 changes: 27 additions & 1 deletion pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 4 additions & 3 deletions src/devtools/DevtoolsPane.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import { onMounted, ref } from 'vue'
const count = ref(0)
onMounted(async () => {
console.log('WEWEWE FROM_DEVTOOLS')
const id = 'pinia-colada-devtools'
window.top?.postMessage({ id, type: 'FROM_DEVTOOLS', payload: 'Hello from devtools' })
})
Expand All @@ -13,8 +12,10 @@ onMounted(async () => {
<template>
<div class="h-full w-full flex flex-col items-center justify-center">
<pre>{{ $route.fullPath }}</pre>
<div>HELLO {{ count }}</div>
<button class="btn" @click="count++">increment</button>
<div>{{ count }}</div>
<button class="btn" @click="count++">
increment
</button>
</div>
</template>

Expand Down
91 changes: 47 additions & 44 deletions src/devtools/plugin.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,21 @@
import { addCustomTab, setupDevtoolsPlugin } from '@vue/devtools-api'
import { watch, type App } from 'vue'
import DevtoolsPanel from './DevtoolsPane.vue?raw'
// import DevtoolsPanel from './DevtoolsPane.vue?raw'
import type { Pinia } from 'pinia'
import { useQueryCache } from '../query-store'
import type { DataStateStatus } from '../data-state'

const QUERY_INSPECTOR_ID = 'pinia-colada-queries'
const ID_SEPARATOR = '\0'

function debounce(fn: () => void, delay: number) {
let timeout: ReturnType<typeof setTimeout>
return () => {
clearTimeout(timeout)
timeout = setTimeout(fn, delay)
}
}

export function addDevtools(app: App, pinia: Pinia) {
const queryCache = useQueryCache(pinia)

Expand All @@ -22,6 +30,11 @@ export function addDevtools(app: App, pinia: Pinia) {
componentStateTypes: [],
},
(api) => {
const updateQueryInspectorTree = debounce(() => {
api.sendInspectorTree(QUERY_INSPECTOR_ID)
api.sendInspectorState(QUERY_INSPECTOR_ID)
}, 100)

api.addInspector({
id: QUERY_INSPECTOR_ID,
label: 'Pinia Queries',
Expand All @@ -32,10 +45,7 @@ export function addDevtools(app: App, pinia: Pinia) {
actions: [
{
icon: 'refresh',
action: async () => {
api.sendInspectorTree(QUERY_INSPECTOR_ID)
api.sendInspectorState(QUERY_INSPECTOR_ID)
},
action: updateQueryInspectorTree,
tooltip: 'Sync',
},
],
Expand Down Expand Up @@ -91,25 +101,18 @@ export function addDevtools(app: App, pinia: Pinia) {
api.on.editInspectorState((payload) => {
if (payload.app !== app) return
if (payload.inspectorId === QUERY_INSPECTOR_ID) {
console.log(payload)
const entry = queryCache.getEntries({
key: payload.nodeId.split(ID_SEPARATOR),
exact: true,
})[0]
if (!entry) return
const path = payload.path.slice()
console.log(path, entry)
// if (path[0] === 'asyncStatus') {
// path.push('value')
// } else if (path[0] === 'state') {
// path.splice(1, 0, 'value')
// }
payload.set(entry, path, payload.state.value)
api.sendInspectorState(QUERY_INSPECTOR_ID)
}
})

const QUERY_FILTER_RE = /\b(active|inactive|stale|fresh|exact)\b/gi
const QUERY_FILTER_RE = /\b(active|inactive|stale|fresh|exact|loading|idle)\b/gi

api.on.getInspectorTree((payload) => {
if (payload.app !== app) return
Expand All @@ -131,13 +134,20 @@ export function addDevtools(app: App, pinia: Pinia) {
: filters?.includes('fresh')
? false
: undefined
const asyncStatus = filters?.includes('loading')
? 'loading'
: filters?.includes('idle')
? 'idle'
: undefined

payload.rootNodes = queryCache
.getEntries({
active,
stale,
exact: filters?.includes('exact'),
predicate(entry) {
// filter out by asyncStatus
if (asyncStatus && entry.asyncStatus.value !== asyncStatus) return false
if (filter) {
// TODO: fuzzy match between entry.key.join('/') and the filter
return entry.key.some((key) => String(key).includes(filter))
Expand Down Expand Up @@ -184,23 +194,14 @@ export function addDevtools(app: App, pinia: Pinia) {
name === 'invalidate' // includes cancel
|| name === 'fetch' // includes refresh
|| name === 'setEntryState' // includes set data
|| name === 'cancelQueries'
|| name === 'remove'
|| name === 'untrack'
|| name === 'track'
|| name === 'ensure' // includes create
) {
console.log('action', name)
api.sendInspectorTree(QUERY_INSPECTOR_ID)
api.sendInspectorState(QUERY_INSPECTOR_ID)
after(() => {
api.sendInspectorTree(QUERY_INSPECTOR_ID)
api.sendInspectorState(QUERY_INSPECTOR_ID)
})
onError(() => {
api.sendInspectorTree(QUERY_INSPECTOR_ID)
api.sendInspectorState(QUERY_INSPECTOR_ID)
})
updateQueryInspectorTree()
after(updateQueryInspectorTree)
onError(updateQueryInspectorTree)
}
})

Expand All @@ -211,26 +212,28 @@ export function addDevtools(app: App, pinia: Pinia) {
},
)

addCustomTab({
name: 'pinia-colada',
title: 'Pinia Colada',
icon: 'https://pinia-colada.esm.dev/logo.svg',
view: {
type: 'sfc',
sfc: DevtoolsPanel,
// type: 'vnode',
// vnode: h('p', ['hello world']),
// vnode: createVNode(DevtoolsPanel),
},
category: 'modules',
})
// TODO: custom tab?

// addCustomTab({
// name: 'pinia-colada',
// title: 'Pinia Colada',
// icon: 'https://pinia-colada.esm.dev/logo.svg',
// view: {
// type: 'sfc',
// sfc: DevtoolsPanel,
// // type: 'vnode',
// // vnode: h('p', ['hello world']),
// // vnode: createVNode(DevtoolsPanel),
// },
// category: 'modules',
// })

window.addEventListener('message', (event) => {
const data = event.data
if (data != null && typeof data === 'object' && data.id === 'pinia-colada-devtools') {
console.log('message', event)
}
})
// window.addEventListener('message', (event) => {
// const data = event.data
// if (data != null && typeof data === 'object' && data.id === 'pinia-colada-devtools') {
// console.log('message', event)
// }
// })
}

interface InspectorNodeTag {
Expand Down
11 changes: 6 additions & 5 deletions src/pinia-colada.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import type { UseQueryOptionsGlobal } from './query-options'
import { USE_QUERY_DEFAULTS, USE_QUERY_OPTIONS_KEY } from './query-options'
import { useQueryCache } from './query-store'
import type { PiniaColadaPlugin } from './plugins'
import { addDevtools } from './devtools/plugin'

/**
* Options for the Pinia Colada plugin.
Expand All @@ -29,11 +30,7 @@ export interface PiniaColadaOptions extends UseQueryOptionsGlobal {
* @param options - Pinia Colada options
*/
export function PiniaColada(app: App, options: PiniaColadaOptions = {}) {
const {
pinia = app.config.globalProperties.$pinia,
plugins,
...useQueryOptions
} = options
const { pinia = app.config.globalProperties.$pinia, plugins, ...useQueryOptions } = options

app.provide(USE_QUERY_OPTIONS_KEY, {
...USE_QUERY_DEFAULTS,
Expand All @@ -46,6 +43,10 @@ export function PiniaColada(app: App, options: PiniaColadaOptions = {}) {
)
}

if (typeof document !== 'undefined' && process.env.NODE_ENV === 'development') {
addDevtools(app, pinia)
}

// install plugins
const queryCache = useQueryCache(pinia)
plugins?.forEach((plugin) =>
Expand Down
2 changes: 1 addition & 1 deletion tsup.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ const commonOptions = {
// splitting: false,
sourcemap: true,
format: ['cjs', 'esm'],
external: ['vue', 'pinia', '@pinia/colada'],
external: ['vue', 'pinia', '@pinia/colada', '@vue/devtools-api'],
target: 'esnext',
dts: {
compilerOptions: {
Expand Down

0 comments on commit 43912aa

Please sign in to comment.