Skip to content

Commit b5bb2ab

Browse files
committed
fix(devtools): scope nitro storage watches
1 parent 0216c08 commit b5bb2ab

File tree

4 files changed

+60
-10
lines changed

4 files changed

+60
-10
lines changed

‎packages/devtools/src/server-rpc/server-routes.ts‎

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
import type { Nitro } from 'nitropack'
22
import type { NuxtDevtoolsServerContext, ServerFunctions, ServerRouteInfo } from '../types'
33
import { debounce } from 'perfect-debounce'
4+
import { watchStorageMount } from './storage-watch'
45

56
export function setupServerRoutesRPC({ nuxt, refresh }: NuxtDevtoolsServerContext) {
67
let nitro: Nitro
8+
let unwatchStorage: (() => Promise<void> | void) | undefined
79

810
let cache: ServerRouteInfo[] | null = null
911

@@ -18,13 +20,22 @@ export function setupServerRoutesRPC({ nuxt, refresh }: NuxtDevtoolsServerContex
1820
refresh('getServerRoutes')
1921
})
2022

21-
nuxt.hook('ready', () => {
22-
nitro?.storage.watch((event, key) => {
23+
nuxt.hook('ready', async () => {
24+
if (!nitro)
25+
return
26+
27+
await unwatchStorage?.()
28+
unwatchStorage = await watchStorageMount(nitro.storage, 'src', (_event, key) => {
2329
if (key.startsWith('src:api:') || key.startsWith('src:routes:'))
2430
refreshDebounced()
2531
})
2632
})
2733

34+
nuxt.hook('close', async () => {
35+
await unwatchStorage?.()
36+
unwatchStorage = undefined
37+
})
38+
2839
function scan() {
2940
if (cache)
3041
return cache

‎packages/devtools/src/server-rpc/server-tasks.ts‎

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
import type { Nitro } from 'nitropack'
22
import type { NuxtDevtoolsServerContext, ScannedNitroTasks, ServerFunctions } from '../types'
33
import { debounce } from 'perfect-debounce'
4+
import { watchStorageMount } from './storage-watch'
45

56
export function setupServerTasksRPC({ nuxt, refresh }: NuxtDevtoolsServerContext) {
67
let nitro: Nitro
8+
let unwatchStorage: (() => Promise<void> | void) | undefined
79

810
let cache: ScannedNitroTasks | null = null
911

@@ -18,13 +20,22 @@ export function setupServerTasksRPC({ nuxt, refresh }: NuxtDevtoolsServerContext
1820
refresh('getServerTasks')
1921
})
2022

21-
nuxt.hook('ready', () => {
22-
nitro?.storage.watch((event, key) => {
23+
nuxt.hook('ready', async () => {
24+
if (!nitro)
25+
return
26+
27+
await unwatchStorage?.()
28+
unwatchStorage = await watchStorageMount(nitro.storage, 'src', (_event, key) => {
2329
if (key.startsWith('src:tasks:'))
2430
refreshDebounced()
2531
})
2632
})
2733

34+
nuxt.hook('close', async () => {
35+
await unwatchStorage?.()
36+
unwatchStorage = undefined
37+
})
38+
2839
function scan() {
2940
if (cache)
3041
return cache
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import type { Storage, WatchCallback, WatchEvent } from 'unstorage'
2+
import { normalizeBaseKey, normalizeKey } from 'unstorage'
3+
4+
export type UnwatchStorageMount = () => Promise<void> | void
5+
6+
export async function watchStorageMount(storage: Storage, mountName: string, onChange: WatchCallback): Promise<UnwatchStorageMount> {
7+
const mountKey = normalizeBaseKey(mountName)
8+
const mount = storage.getMounts().find(item => item.base === mountKey)
9+
const watch = mount?.driver.watch
10+
11+
if (!watch)
12+
return () => {}
13+
14+
return await watch((event: WatchEvent, key: string) => {
15+
onChange(event, normalizeKey(`${mountKey}${key}`))
16+
})
17+
}

‎packages/devtools/src/server-rpc/storage.ts‎

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import type { StorageMounts } from 'nitropack'
22
import type { Storage, StorageValue } from 'unstorage'
33
import type { NuxtDevtoolsServerContext, ServerFunctions } from '../types'
4+
import { watchStorageMount } from './storage-watch'
45

56
const IGNORE_STORAGE_MOUNTS = ['root', 'build', 'src', 'cache']
67
function shouldIgnoreStorageKey(key: string) {
@@ -15,16 +16,26 @@ export function setupStorageRPC({
1516
const storageMounts: StorageMounts = {}
1617

1718
let storage: Storage | undefined
19+
let unwatchStorageMounts: Array<() => Promise<void> | void> = []
1820

1921
nuxt.hook('nitro:init', (nitro) => {
2022
storage = nitro.storage
2123

22-
nuxt.hook('ready', () => {
23-
storage!.watch((event, key) => {
24-
if (shouldIgnoreStorageKey(key))
25-
return
26-
rpc.broadcast.callHook.asEvent('storage:key:update', key, event)
27-
})
24+
nuxt.hook('close', async () => {
25+
await Promise.all(unwatchStorageMounts.map(unwatch => unwatch()))
26+
unwatchStorageMounts = []
27+
})
28+
29+
nuxt.hook('ready', async () => {
30+
if (!storage)
31+
return
32+
await Promise.all(unwatchStorageMounts.map(unwatch => unwatch()))
33+
unwatchStorageMounts = await Promise.all(Object.keys(storageMounts).map(mountName =>
34+
watchStorageMount(storage, mountName, (event, key) => {
35+
if (shouldIgnoreStorageKey(key))
36+
return
37+
rpc.broadcast.callHook.asEvent('storage:key:update', key, event)
38+
})))
2839
})
2940

3041
// Taken from https://github.com/unjs/nitro/blob/d83f2b65165d7ba996e7ef129ea99ff5b551dccc/src/storage.ts#L7-L10

0 commit comments

Comments
 (0)