import { Layout } from './Layout'
import './custom.css'
import './code-theme.css'
-// import { createPinia } from '../../../src'
+import { createPinia } from '../../../src'
/** @type {import('vitepress').Theme} */
const config = {
Layout,
enhanceApp({ app }) {
- // app.use(createPinia())
+ app.use(createPinia())
},
}
---
<ThemeToggle/>
-<!-- <TestStore/> -->
+<TestStore/>
<HomeSponsors />
<script setup>
import HomeSponsors from './.vitepress/components/HomeSponsors.vue'
import ThemeToggle from './.vitepress/components/ThemeToggle.vue'
-// import TestStore from './.vitepress/components/TestStore.vue'
+import TestStore from './.vitepress/components/TestStore.vue'
</script>
import { CustomInspectorNode, CustomInspectorState } from '@vue/devtools-api'
-import { Store, GettersTree, MutationType, StateTree } from '../types'
+import { Store, MutationType } from '../types'
import { DebuggerEvent } from 'vue'
+import { Pinia } from '../rootStore'
export function formatDisplay(display: string) {
return {
}
}
-export function formatStoreForInspectorTree(store: Store): CustomInspectorNode {
- return {
- id: store.$id,
- label: store.$id,
- tags: [],
- }
+export const PINIA_ROOT_LABEL = '🍍 Pinia (root)'
+export const PINIA_ROOT_ID = '_root'
+
+export function formatStoreForInspectorTree(
+ store: Store | Pinia
+): CustomInspectorNode {
+ return '$id' in store
+ ? {
+ id: store.$id,
+ label: store.$id,
+ }
+ : {
+ id: PINIA_ROOT_ID,
+ label: PINIA_ROOT_LABEL,
+ }
}
export function formatStoreForInspectorState(
- store: Store
-): CustomInspectorState[string] {
- const fields: CustomInspectorState[string] = [
- { editable: false, key: 'id', value: formatDisplay(store.$id) },
- { editable: true, key: 'state', value: store.$state },
- ]
+ store: Store | Pinia
+): CustomInspectorState {
+ if (!('$id' in store)) {
+ const state: CustomInspectorState = {
+ state: Object.keys(store.state.value).map((storeId) => ({
+ editable: true,
+ key: storeId,
+ value: store.state.value[storeId],
+ })),
+ }
+ // TODO: use this version when possible
+ // Object.keys(store.state.value).forEach((storeId) => {
+ // const currentState = store.state.value[storeId]
+ // state[storeId] = Object.keys(currentState).map((key) => ({
+ // // is not possible to made editable because no way to get the storeId in
+ // // edit inspector state callback
+ // editable: false,
+ // key,
+ // value: currentState[key],
+ // }))
+ // })
+
+ return state
+ }
+
+ const state: CustomInspectorState = {
+ state: Object.keys(store.$state).map((key) => ({
+ editable: true,
+ key,
+ // @ts-expect-error
+ value: store.$state[key],
+ })),
+ }
// avoid adding empty getters
if (store._getters && store._getters.length) {
- fields.push({
+ state.getters = store._getters.map((getterName) => ({
editable: false,
- key: 'getters',
- value: store._getters.reduce((getters, key) => {
- // @ts-expect-error
- getters[key] = store[key]
- return getters
- }, {} as GettersTree<StateTree>),
- })
+ key: getterName,
+ // @ts-expect-error
+ value: store[getterName],
+ }))
}
- return fields
+ return state
}
export function formatEventData(
import { setupDevtoolsPlugin, TimelineEvent } from '@vue/devtools-api'
import { App, ComponentPublicInstance } from 'vue'
-import { PiniaPluginContext, setActivePinia } from '../rootStore'
+import { Pinia, PiniaPluginContext, setActivePinia } from '../rootStore'
import {
Store,
GettersTree,
formatMutationType,
formatStoreForInspectorState,
formatStoreForInspectorTree,
+ PINIA_ROOT_ID,
+ PINIA_ROOT_LABEL,
} from './formatting'
import { toastMessage } from './utils'
api.on.getInspectorTree((payload) => {
if (payload.app === app && payload.inspectorId === INSPECTOR_ID) {
- const stores = Array.from(registeredStores.values())
+ let stores: Array<Store | Pinia> = [store._p]
+ stores = stores.concat(Array.from(registeredStores.values()))
payload.rootNodes = (
payload.filter
? stores.filter((store) =>
- store.$id
- .toLowerCase()
- .includes(payload.filter.toLowerCase())
+ '$id' in store
+ ? store.$id
+ .toLowerCase()
+ .includes(payload.filter.toLowerCase())
+ : PINIA_ROOT_LABEL.toLowerCase().includes(
+ payload.filter.toLowerCase()
+ )
)
: stores
).map(formatStoreForInspectorTree)
api.on.getInspectorState((payload) => {
if (payload.app === app && payload.inspectorId === INSPECTOR_ID) {
- const store = registeredStores.get(payload.nodeId)
+ const inspectedStore =
+ payload.nodeId === PINIA_ROOT_ID
+ ? store._p
+ : registeredStores.get(payload.nodeId)
- if (!store) {
+ if (!inspectedStore) {
return toastMessage(
`store "${payload.nodeId}" not found`,
'error'
)
}
- if (store) {
- payload.state = {
- options: formatStoreForInspectorState(store),
- }
+ if (inspectedStore) {
+ payload.state = formatStoreForInspectorState(inspectedStore)
}
}
})
- api.on.editInspectorState((payload) => {
+ api.on.editInspectorState((payload, ctx) => {
if (payload.app === app && payload.inspectorId === INSPECTOR_ID) {
- const store = registeredStores.get(payload.nodeId)
+ const inspectedStore =
+ payload.nodeId === PINIA_ROOT_ID
+ ? store._p
+ : registeredStores.get(payload.nodeId)
- if (!store) {
+ if (!inspectedStore) {
return toastMessage(
`store "${payload.nodeId}" not found`,
'error'
}
const { path } = payload
- if (path[0] !== 'state') {
- return toastMessage(
- `Invalid path for store "${payload.nodeId}":\n${path}\nOnly state can be modified.`
- )
- }
- // rewrite the first entry to be able to directly set the state as
- // well as any other path
- path[0] = '$state'
+ if ('$id' in inspectedStore) {
+ // access only the state
+ path.unshift('$state')
+ } else {
+ path.unshift('state', 'value')
+ }
isTimelineActive = false
- payload.set(store, path, payload.state.value)
+ payload.set(inspectedStore, path, payload.state.value)
isTimelineActive = true
}
})