Skip to content

Commit

Permalink
feat: update tracking
Browse files Browse the repository at this point in the history
  • Loading branch information
Akryum committed Mar 11, 2022
1 parent 32e60cf commit 6204a28
Show file tree
Hide file tree
Showing 9 changed files with 124 additions and 4 deletions.
13 changes: 12 additions & 1 deletion packages/app-backend-core/src/component.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { stringify, BridgeEvents, parse, SharedData } from '@vue-devtools/shared-utils'
import { AppRecord, BackendContext, BuiltinBackendFeature } from '@vue-devtools/app-backend-api'
import { getAppRecord } from './app'
import { App, ComponentInstance, EditStatePayload } from '@vue/devtools-api'
import { App, ComponentInstance, EditStatePayload, now } from '@vue/devtools-api'

const MAX_$VM = 10
const $vmQueue = []
Expand Down Expand Up @@ -130,3 +130,14 @@ export async function refreshComponentTreeSearch (ctx: BackendContext) {
if (!ctx.currentAppRecord.componentFilter) return
await sendComponentTreeData(ctx.currentAppRecord, '_root', ctx.currentAppRecord.componentFilter, null, ctx)
}

export async function sendComponentUpdateTracking (appRecord: AppRecord, instanceId: string, ctx: BackendContext) {
if (!instanceId) return
const instance = getComponentInstance(appRecord, instanceId, ctx)
if (!instance) return
const payload = {
instanceId,
time: Date.now(), // Use normal date
}
ctx.bridge.send(BridgeEvents.TO_FRONT_COMPONENT_UPDATED, payload)
}
17 changes: 15 additions & 2 deletions packages/app-backend-core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import {
editComponentState,
getComponentInstance,
refreshComponentTreeSearch,
sendComponentUpdateTracking,
} from './component'
import { addQueuedPlugins, addPlugin, sendPluginList, addPreviouslyRegisteredPlugins } from './plugin'
import { PluginDescriptor, SetupFunction, TimelineLayerOptions, TimelineEventOptions, CustomInspectorOptions, Hooks, now } from '@vue/devtools-api'
Expand Down Expand Up @@ -131,6 +132,10 @@ async function connect () {
if (isSubscribed(BridgeSubscriptions.COMPONENT_TREE, sub => sub.payload.instanceId === id)) {
sendComponentTreeData(appRecord, id, appRecord.componentFilter, 0, ctx)
}

if (SharedData.trackUpdates) {
sendComponentUpdateTracking(appRecord, id, ctx)
}
} catch (e) {
if (SharedData.debugInfo) {
console.error(e)
Expand All @@ -155,13 +160,17 @@ async function connect () {
const parentInstances = await appRecord.backend.api.walkComponentParents(component)
if (parentInstances.length) {
// Check two parents level to update `hasChildren
for (let i = 0; i < 2 && i < parentInstances.length; i++) {
for (let i = 0; i < parentInstances.length; i++) {
const parentId = await getComponentId(app, parentUid, parentInstances[i], ctx)
if (isSubscribed(BridgeSubscriptions.COMPONENT_TREE, sub => sub.payload.instanceId === parentId)) {
if (i < 2 && isSubscribed(BridgeSubscriptions.COMPONENT_TREE, sub => sub.payload.instanceId === parentId)) {
requestAnimationFrame(() => {
sendComponentTreeData(appRecord, parentId, appRecord.componentFilter, null, ctx)
})
}

if (SharedData.trackUpdates) {
sendComponentUpdateTracking(appRecord, parentId, ctx)
}
}
}
}
Expand All @@ -170,6 +179,10 @@ async function connect () {
sendSelectedComponentData(appRecord, id, ctx)
}

if (SharedData.trackUpdates) {
sendComponentUpdateTracking(appRecord, id, ctx)
}

await refreshComponentTreeSearch(ctx)
} catch (e) {
if (SharedData.debugInfo) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@ import { computed, toRefs, onMounted, ref, watch, defineComponent, PropType } fr
import { ComponentTreeNode } from '@vue/devtools-api'
import scrollIntoView from 'scroll-into-view-if-needed'
import { getComponentDisplayName, UNDEFINED, SharedData } from '@vue-devtools/shared-utils'
import { sortChildren, useComponent, useComponentHighlight } from './composable'
import { sortChildren, useComponent, useComponentHighlight, updateTrackingEvents, updateTrackingLimit } from './composable'
import { onKeyDown } from '@front/util/keyboard'
import { reactiveNow, useTimeAgo } from '@front/util/time'
const DEFAULT_EXPAND_DEPTH = 2
Expand Down Expand Up @@ -140,6 +141,14 @@ export default defineComponent({
}
}
// Update tracking
const updateTracking = computed(() => updateTrackingEvents.value[props.instance.id])
const showUpdateTracking = computed(() => updateTracking.value?.time > updateTrackingLimit.value && updateTracking.value?.time > reactiveNow.value - 20_000)
const updateTrackingTime = computed(() => updateTracking.value?.time)
const { timeAgo: updateTrackingTimeAgo } = useTimeAgo(updateTrackingTime)
const updateTrackingOpacity = computed(() => showUpdateTracking.value ? 1 - (reactiveNow.value - updateTracking.value?.time) / 20_000 : 0)
return {
toggleEl,
sortedChildren,
Expand All @@ -153,6 +162,10 @@ export default defineComponent({
unhighlight,
selectNextSibling,
selectPreviousSibling,
showUpdateTracking,
updateTracking,
updateTrackingTimeAgo,
updateTrackingOpacity,
}
},
})
Expand Down Expand Up @@ -259,6 +272,29 @@ export default defineComponent({
{{ instance.domOrder }}
</span>
</template>

<VTooltip
v-if="showUpdateTracking"
class="h-4"
>
<div class="px-3 -mx-2 h-full flex items-center">
<div
class="w-1 h-1 rounded-full"
:class="[
selected ? 'bg-white' : 'bg-green-500',
]"
:style="{
opacity: updateTrackingOpacity,
}"
/>
</div>

<template #popper>
<div>
Updated {{ updateTrackingTimeAgo }}
</div>
</template>
</VTooltip>
</span>
</div>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,8 @@ export function resetComponents () {
rootInstances.value = []
componentsMap.value = {}
componentsParent = {}
updateTrackingEvents.value = {}
updateTrackingLimit.value = Date.now() + 5_000
}

export const requestedComponentTree = new Set()
Expand Down Expand Up @@ -383,3 +385,26 @@ export function getAppIdFromComponentId (id: string) {
const appId = id.substring(0, index)
return appId
}

export interface ComponentUpdateTrackingEvent {
instanceId: string
time: number
count: number
}

export const updateTrackingEvents = ref<Record<string, ComponentUpdateTrackingEvent>>({})
export const updateTrackingLimit = ref(Date.now() + 5_000)

export function addUpdateTrackingEvent (instanceId: string, time: number) {
const event = updateTrackingEvents.value[instanceId]
if (event) {
event.count++
event.time = time
} else {
Vue.set(updateTrackingEvents.value, instanceId, {
instanceId,
time,
count: 1,
})
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
requestedComponentTree,
getAppIdFromComponentId,
lastSelectedComponentId,
addUpdateTrackingEvent,
} from './components'

export function setupComponentsBridgeEvents (bridge: Bridge) {
Expand Down Expand Up @@ -71,6 +72,10 @@ export function setupComponentsBridgeEvents (bridge: Bridge) {
chrome.devtools.inspectedWindow.eval('inspect(window.__VUE_DEVTOOLS_INSPECT_TARGET__)')
})

bridge.on(BridgeEvents.TO_FRONT_COMPONENT_UPDATED, ({ instanceId, time }) => {
addUpdateTrackingEvent(instanceId, time)
})

// Persistance

Object.assign(lastSelectedComponentId, getStorage('lastSelectedComponentId', {}))
Expand Down
11 changes: 11 additions & 0 deletions packages/app-frontend/src/features/settings/GlobalSettings.vue
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,17 @@ export default defineComponent({})
</template>
</VueFormField>

<VueFormField
title="Update tracking"
>
<VueSwitch v-model="$shared.trackUpdates">
Enable
</VueSwitch>
<template #subtitle>
Turn off if your app is slowed down
</template>
</VueFormField>

<VueFormField
title="Debugging info"
>
Expand Down
16 changes: 16 additions & 0 deletions packages/app-frontend/src/util/time.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { computed, Ref, ref } from '@vue/composition-api'

export const reactiveNow = ref(Date.now())

setInterval(() => {
reactiveNow.value = Date.now()
}, 100)

export function useTimeAgo (time: Ref<number>) {
return {
timeAgo: computed(() => {
const diff = reactiveNow.value - time.value
return `${Math.round(diff / 1000)}s ago`
}),
}
}
1 change: 1 addition & 0 deletions packages/shared-utils/src/consts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ export enum BridgeEvents {
TO_FRONT_COMPONENT_INSPECT_DOM = 'f:component:inspect-dom',
TO_BACK_COMPONENT_RENDER_CODE = 'b:component:render-code',
TO_FRONT_COMPONENT_RENDER_CODE = 'f:component:render-code',
TO_FRONT_COMPONENT_UPDATED = 'f:component:updated',

// Timeline
TO_FRONT_TIMELINE_EVENT = 'f:timeline:event',
Expand Down
2 changes: 2 additions & 0 deletions packages/shared-utils/src/shared-data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ const internalSharedData = {
pluginSettings: {} as any,
pageConfig: {} as any,
legacyApps: false,
trackUpdates: true,
debugInfo: false,
}

Expand All @@ -52,6 +53,7 @@ const persisted = [
'pluginSettings',
'performanceMonitoringEnabled',
'componentEventsEnabled',
'trackUpdates',
'debugInfo',
]

Expand Down

0 comments on commit 6204a28

Please sign in to comment.