From aa1c2d3f6019376229449cda1607da984dec8553 Mon Sep 17 00:00:00 2001 From: LoTwT <709937065@qq.com> Date: Tue, 30 Jan 2024 17:59:01 +0800 Subject: [PATCH] feat: update assets reactively --- packages/client/src/pages/assets.vue | 11 ++++++++++- packages/core/src/bridge/devtools.ts | 21 +++++++++++++++++++++ packages/core/src/vite-rpc/assets.ts | 22 ++++++++++++++++++++++ packages/core/src/vite-rpc/client.ts | 4 +++- packages/core/src/vite-rpc/types.ts | 1 + packages/vite/src/vite.ts | 8 +++++++- 6 files changed, 64 insertions(+), 3 deletions(-) diff --git a/packages/client/src/pages/assets.vue b/packages/client/src/pages/assets.vue index 96c77df84..3b67aea63 100644 --- a/packages/client/src/pages/assets.vue +++ b/packages/client/src/pages/assets.vue @@ -78,10 +78,19 @@ const byTree = computed(() => { return root.children }) -onDevToolsClientConnected(() => { +let cleanupAssetsUpdatedEffect: Function + +function fetchAssets() { bridgeRpc.getStaticAssets().then((res) => { assets.value = res }) +} + +onDevToolsClientConnected(() => { + fetchAssets() + cleanupAssetsUpdatedEffect = bridgeRpc.assetsUpdated(() => { + fetchAssets() + }) }) function toggleView() { view.value = view.value === 'list' ? 'grid' : 'list' diff --git a/packages/core/src/bridge/devtools.ts b/packages/core/src/bridge/devtools.ts index 8e58ee6dc..9f616f3cd 100644 --- a/packages/core/src/bridge/devtools.ts +++ b/packages/core/src/bridge/devtools.ts @@ -14,9 +14,11 @@ const devtoolsBridge: { api: ReturnType on: { moduleUpdated: (fn: Function) => void + assetsUpdated: (fn: Function) => void } off: { moduleUpdated: () => void + assetsUpdated: () => void } } rpc: InstanceType @@ -27,9 +29,11 @@ const devtoolsBridge: { api: null!, on: { moduleUpdated() {}, + assetsUpdated() {}, }, off: { moduleUpdated() {}, + assetsUpdated() {}, }, }, rpc: null!, @@ -44,10 +48,15 @@ export function registerBridgeRpc(options: BridgeRpcOptions) { devtoolsBridge.rpc = new BridgeRpcCore(options.bridge) const moduleUpdatedFn: Function[] = [] + const assetsUpdatedFn: Function[] = [] + const rpc = setupViteRPCClient(options.viteRPCContext, { moduleUpdated: () => { moduleUpdatedFn.forEach(fn => fn()) }, + assetsUpdated: () => { + assetsUpdatedFn.forEach(fn => fn()) + }, }) if (rpc) { @@ -58,11 +67,17 @@ export function registerBridgeRpc(options: BridgeRpcOptions) { moduleUpdated(fn: Function) { moduleUpdatedFn.push(fn) }, + assetsUpdated(fn) { + assetsUpdatedFn.push(fn) + }, }, off: { moduleUpdated() { moduleUpdatedFn.length = 0 }, + assetsUpdated() { + assetsUpdatedFn.length = 0 + }, }, } } @@ -211,4 +226,10 @@ export class BridgeRpc { devtoolsBridge.viteRpc!.on.moduleUpdated(fn) return () => devtoolsBridge.viteRpc!.off.moduleUpdated() } + + // assets updated + static assetsUpdated(fn: Function) { + devtoolsBridge.viteRpc!.on.assetsUpdated(fn) + return () => devtoolsBridge.viteRpc!.off.assetsUpdated() + } } diff --git a/packages/core/src/vite-rpc/assets.ts b/packages/core/src/vite-rpc/assets.ts index bf06534e8..c9cf13068 100644 --- a/packages/core/src/vite-rpc/assets.ts +++ b/packages/core/src/vite-rpc/assets.ts @@ -2,6 +2,9 @@ import fsp from 'node:fs/promises' import fg from 'fast-glob' import { join, resolve } from 'pathe' import { imageMeta } from 'image-meta' +import { BirpcGroupReturn } from 'birpc' +import type { ViteDevServer } from 'vite' +import { debounce } from 'perfect-debounce' import type { AssetInfo, AssetType, ImageMeta, ViteRPCFunctions } from './types' const defaultAllowedExtensions = [ @@ -52,9 +55,14 @@ function guessType(path: string): AssetType { interface SetupAssetsOptions { root: string base: string + server: any + getRpcServer: () => BirpcGroupReturn } export function setupAssetsRPC(config: SetupAssetsOptions) { + const server = config.server as ViteDevServer + const getRpcServer = config.getRpcServer + const _imageMetaCache = new Map() let cache: AssetInfo[] | null = null @@ -103,6 +111,19 @@ export function setupAssetsRPC(config: SetupAssetsOptions) { return cache } + function watchAssets() { + const debouncedAssetsUpdated = debounce(() => { + getRpcServer().assetsUpdated() + }, 100) + + server.watcher.on('all', (event) => { + if (event !== 'change') + debouncedAssetsUpdated() + }) + } + + watchAssets() + return { async getStaticAssets() { return await scan() @@ -131,5 +152,6 @@ export function setupAssetsRPC(config: SetupAssetsOptions) { return undefined } }, + assetsUpdated() {}, } satisfies Partial } diff --git a/packages/core/src/vite-rpc/client.ts b/packages/core/src/vite-rpc/client.ts index 169b62348..951265035 100644 --- a/packages/core/src/vite-rpc/client.ts +++ b/packages/core/src/vite-rpc/client.ts @@ -5,14 +5,16 @@ import type { ViteRPCFunctions } from './types' export interface SetupViteRPCClientOptions { moduleUpdated?: () => void + assetsUpdated?: () => void } export function setupViteRPCClient(ctx: ViteHotContext | undefined, options: SetupViteRPCClientOptions = {}): BirpcReturn { if (!ctx) return null! - const { moduleUpdated = () => {} } = options + const { moduleUpdated = () => {}, assetsUpdated = () => {} } = options const rpcClient = createRPCClient('vite-plugin-vue-devtools', ctx, { moduleUpdated, + assetsUpdated, }, { timeout: -1, }) diff --git a/packages/core/src/vite-rpc/types.ts b/packages/core/src/vite-rpc/types.ts index 57391eb1c..a6abee612 100644 --- a/packages/core/src/vite-rpc/types.ts +++ b/packages/core/src/vite-rpc/types.ts @@ -45,4 +45,5 @@ export interface ViteRPCFunctions { getImageMeta(filepath: string): Promise getTextAssetContent(filepath: string, limit?: number): Promise moduleUpdated: () => void + assetsUpdated: () => void } diff --git a/packages/vite/src/vite.ts b/packages/vite/src/vite.ts index a2fef99da..e00f5b1c8 100644 --- a/packages/vite/src/vite.ts +++ b/packages/vite/src/vite.ts @@ -83,14 +83,20 @@ export default function VitePluginVueDevTools(options?: VitePluginVueDevToolsOpt ...setupAssetsRPC({ root: config.root, base, + server, + getRpcServer, }), ...setupGraphRPC({ rpc: inspect.api.rpc, server, - getRpcServer: () => rpcServer, + getRpcServer, }), }) + function getRpcServer() { + return rpcServer + } + const _printUrls = server.printUrls const colorUrl = (url: string) => cyan(url.replace(/:(\d+)\//, (_, port) => `:${bold(port)}/`))