Skip to content

Commit 0252d70

Browse files
committed
Merge branch 'main' into feat/auth
2 parents 76aadd7 + ae4110e commit 0252d70

File tree

9 files changed

+161
-16
lines changed

9 files changed

+161
-16
lines changed

alias.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ export const alias = {
1111
'@vitejs/devtools-rpc/presets/ws/client': r('rpc/src/presets/ws/client.ts'),
1212
'@vitejs/devtools-kit/client': r('kit/src/client/index.ts'),
1313
'@vitejs/devtools-kit/utils/events': r('kit/src/utils/events.ts'),
14+
'@vitejs/devtools-kit/utils/nanoid': r('kit/src/utils/nanoid.ts'),
15+
'@vitejs/devtools-kit/utils/shared-state': r('kit/src/utils/shared-state.ts'),
1416
'@vitejs/devtools-kit': r('kit/src/index.ts'),
1517
'@vitejs/devtools-vite': r('vite/src/index.ts'),
1618
'@vitejs/devtools/client/inject': r('core/src/client/inject/index.ts'),

packages/core/src/client/webcomponents/state/docks.ts

Lines changed: 28 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -30,24 +30,36 @@ export function createDockEntryState(
3030
events: markRaw(events),
3131
})
3232

33-
watch(() => selected.value?.id, (newSelectedId) => {
34-
if (newSelectedId === entry.id) {
35-
events.emitOnce('entry:activated')
36-
}
37-
else {
38-
events.emitOnce('entry:deactivated')
39-
}
40-
}, { immediate: true })
33+
watch(
34+
() => selected.value?.id,
35+
(newSelectedId) => {
36+
if (newSelectedId === entry.id) {
37+
events.emit('entry:activated')
38+
}
39+
else {
40+
events.emit('entry:deactivated')
41+
}
42+
},
43+
{ immediate: true },
44+
)
4145

42-
watch(() => state.domElements.iframe, (newIframe) => {
43-
if (newIframe)
44-
events.emitOnce('dom:iframe:mounted', newIframe)
45-
}, { immediate: true })
46+
watch(
47+
() => state.domElements.iframe,
48+
(newIframe) => {
49+
if (newIframe)
50+
events.emit('dom:iframe:mounted', newIframe)
51+
},
52+
{ immediate: true },
53+
)
4654

47-
watch(() => state.domElements.panel, (newPanel) => {
48-
if (newPanel)
49-
events.emitOnce('dom:panel:mounted', newPanel)
50-
}, { immediate: true })
55+
watch(
56+
() => state.domElements.panel,
57+
(newPanel) => {
58+
if (newPanel)
59+
events.emit('dom:panel:mounted', newPanel)
60+
},
61+
{ immediate: true },
62+
)
5163

5264
return state
5365
}

packages/core/src/node/context.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import type { DevToolsNodeContext } from '@vitejs/devtools-kit'
22
import type { ResolvedConfig, ViteDevServer } from 'vite'
33
import Debug from 'debug'
44
import { debounce } from 'perfect-debounce'
5+
import { searchForWorkspaceRoot } from 'vite'
56
import { ContextUtils } from './context-utils'
67
import { DevToolsDockHost } from './host-docks'
78
import { RpcFunctionsHost } from './host-functions'
@@ -19,6 +20,7 @@ export async function createDevToolsContext(
1920

2021
const context: DevToolsNodeContext = {
2122
cwd,
23+
workspaceRoot: searchForWorkspaceRoot(cwd) ?? cwd,
2224
viteConfig,
2325
viteServer,
2426
mode: viteConfig.command === 'serve' ? 'dev' : 'build',

packages/core/src/node/storage.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import fs from 'node:fs'
2+
import { createSharedState } from '@vitejs/devtools-kit/utils/shared-state'
3+
4+
export interface CreateStorageOptions<T extends object> {
5+
filepath: string
6+
initialValue: T
7+
}
8+
9+
export async function createStorage<T extends object>(options: CreateStorageOptions<T>) {
10+
let initialState: T
11+
if (fs.existsSync(options.filepath)) {
12+
initialState = JSON.parse(await fs.readFileSync(options.filepath, 'utf-8')) as T
13+
}
14+
else {
15+
initialState = options.initialValue
16+
}
17+
18+
const state = createSharedState<T>({
19+
initialState,
20+
enablePatches: false,
21+
})
22+
23+
state.on('updated', (newState) => {
24+
fs.writeFileSync(options.filepath, `${JSON.stringify(newState, null, 2)}\n`)
25+
})
26+
27+
return state
28+
}

packages/kit/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
"./client": "./dist/client.mjs",
2424
"./utils/events": "./dist/utils/events.mjs",
2525
"./utils/nanoid": "./dist/utils/nanoid.mjs",
26+
"./utils/shared-state": "./dist/utils/shared-state.mjs",
2627
"./package.json": "./package.json"
2728
},
2829
"main": "./dist/index.mjs",

packages/kit/src/types/vite-plugin.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@ export interface DevToolsPluginOptions {
1919
}
2020

2121
export interface DevToolsNodeContext {
22+
/**
23+
* Workspace root directory of Vite DevTools
24+
*/
25+
readonly workspaceRoot: string
2226
/**
2327
* Current working directory of Vite DevTools
2428
*/
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
import type { Objectish, Patch } from 'immer'
2+
import type { EventEmitter } from '../types/events'
3+
import { applyPatches, produce, produceWithPatches } from 'immer'
4+
import { createEventEmitter } from './events'
5+
6+
// eslint-disable-next-line ts/no-unsafe-function-type
7+
type ImmutablePrimitive = undefined | null | boolean | string | number | Function
8+
9+
export type Immutable<T>
10+
= T extends ImmutablePrimitive ? T
11+
: T extends Array<infer U> ? ImmutableArray<U>
12+
: T extends Map<infer K, infer V> ? ImmutableMap<K, V>
13+
: T extends Set<infer M> ? ImmutableSet<M> : ImmutableObject<T>
14+
15+
export type ImmutableArray<T> = ReadonlyArray<Immutable<T>>
16+
export type ImmutableMap<K, V> = ReadonlyMap<Immutable<K>, Immutable<V>>
17+
export type ImmutableSet<T> = ReadonlySet<Immutable<T>>
18+
export type ImmutableObject<T> = { readonly [K in keyof T]: Immutable<T[K]> }
19+
20+
/**
21+
* State host that is immutable by default with explicit mutate.
22+
*/
23+
export interface SharedState<T> {
24+
/**
25+
* Get the current state. Immutable.
26+
*/
27+
get: () => Immutable<T>
28+
/**
29+
* Subscribe to state changes.
30+
*/
31+
on: EventEmitter<SharedStateEvents<T>>['on']
32+
/**
33+
* Mutate the state.
34+
*/
35+
mutate: (fn: (state: T) => void) => void
36+
/**
37+
* Apply patches to the state.
38+
*/
39+
patch: (patches: Patch[]) => void
40+
}
41+
42+
export interface SharedStateEvents<T> {
43+
updated: (state: T) => void
44+
patches: (patches: Patch[]) => void
45+
}
46+
47+
export interface SharedStateOptions<T> {
48+
/**
49+
* Initial state.
50+
*/
51+
initialState: T
52+
/**
53+
* Enable patches.
54+
*
55+
* @default false
56+
*/
57+
enablePatches?: boolean
58+
}
59+
60+
export function createSharedState<T extends Objectish>(
61+
options: SharedStateOptions<T>,
62+
): SharedState<T> {
63+
const {
64+
enablePatches = false,
65+
} = options
66+
67+
const events = createEventEmitter<SharedStateEvents<T>>()
68+
let state = options.initialState
69+
70+
return {
71+
on: events.on,
72+
get: () => state as Immutable<T>,
73+
patch: (patches: Patch[]) => {
74+
state = applyPatches<T>(state, patches)
75+
events.emit('updated', state)
76+
},
77+
mutate: (fn) => {
78+
if (enablePatches) {
79+
const [newState, patches] = produceWithPatches(state, fn)
80+
state = newState
81+
events.emit('patches', patches)
82+
}
83+
else {
84+
state = produce(state, fn)
85+
}
86+
events.emit('updated', state)
87+
},
88+
}
89+
}

packages/kit/tsdown.config.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ export default defineConfig({
55
'index': 'src/index.ts',
66
'utils/events': 'src/utils/events.ts',
77
'utils/nanoid': 'src/utils/nanoid.ts',
8+
'utils/shared-state': 'src/utils/shared-state.ts',
89
'client': 'src/client/index.ts',
910
},
1011
exports: true,

tsconfig.base.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,12 @@
2424
"@vitejs/devtools-kit/utils/events": [
2525
"./packages/kit/src/utils/events.ts"
2626
],
27+
"@vitejs/devtools-kit/utils/nanoid": [
28+
"./packages/kit/src/utils/nanoid.ts"
29+
],
30+
"@vitejs/devtools-kit/utils/shared-state": [
31+
"./packages/kit/src/utils/shared-state.ts"
32+
],
2733
"@vitejs/devtools-kit": [
2834
"./packages/kit/src/index.ts"
2935
],

0 commit comments

Comments
 (0)