Skip to content

Commit c6df7aa

Browse files
committed
feat(core): sharedState subscribe system
1 parent 9195537 commit c6df7aa

File tree

7 files changed

+42
-12
lines changed

7 files changed

+42
-12
lines changed

alias.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ const r = (path: string) => fileURLToPath(new URL(`./packages/${path}`, import.m
88
export const alias = {
99
'@vitejs/devtools-rpc/presets/ws/server': r('rpc/src/presets/ws/server.ts'),
1010
'@vitejs/devtools-rpc/presets/ws/client': r('rpc/src/presets/ws/client.ts'),
11+
'@vitejs/devtools-rpc/presets': r('rpc/src/presets/index.ts'),
1112
'@vitejs/devtools-rpc': r('rpc/src'),
1213
'@vitejs/devtools-kit/client': r('kit/src/client/index.ts'),
1314
'@vitejs/devtools-kit/utils/events': r('kit/src/utils/events.ts'),

packages/core/src/node/rpc-shared-state.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import type { SharedState } from '@vitejs/devtools-kit/utils/shared-state'
33
import { createSharedState } from '@vitejs/devtools-kit/utils/shared-state'
44
import { createDebug } from 'obug'
55

6-
const debug = createDebug('vite:devtools:rpc:shared-state')
6+
const debug = createDebug('vite:devtools:rpc:state:changed')
77

88
export function createRpcSharedStateServerHost(
99
rpc: RpcFunctionsHost,
@@ -14,21 +14,21 @@ export function createRpcSharedStateServerHost(
1414
const offs: (() => void)[] = []
1515

1616
offs.push(
17-
state.on('updated', (_fullState, patches, syncId) => {
17+
state.on('updated', (fullState, patches, syncId) => {
1818
if (patches) {
1919
debug('patch', { key, syncId })
2020
rpc.broadcast({
2121
method: 'vite:internal:rpc:client-state:patch',
2222
args: [key, patches, syncId],
23-
// TODO: filter: broadcast to clients only subscribed to its
23+
filter: client => client.$meta.subscribedStates.has(key),
2424
})
2525
}
2626
else {
2727
debug('updated', { key, syncId })
2828
rpc.broadcast({
2929
method: 'vite:internal:rpc:client-state:updated',
30-
args: [key, syncId],
31-
// TODO: filter: broadcast to clients only subscribed to its
30+
args: [key, fullState, syncId],
31+
filter: client => client.$meta.subscribedStates.has(key),
3232
})
3333
}
3434
}),

packages/core/src/node/rpc/index.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { rpcServerList } from './internal/rpc-server-list'
77
import { sharedStateGet } from './internal/state/get'
88
import { sharedStatePatch } from './internal/state/patch'
99
import { sharedStateSet } from './internal/state/set'
10+
import { sharedStateSubscribe } from './internal/state/subscribe'
1011
import { terminalsList } from './internal/terminals-list'
1112
import { terminalsRead } from './internal/terminals-read'
1213
import { openInEditor } from './public/open-in-editor'
@@ -30,6 +31,7 @@ export const builtinInternalRpcDeclarations = [
3031
sharedStateGet,
3132
sharedStatePatch,
3233
sharedStateSet,
34+
sharedStateSubscribe,
3335
terminalsList,
3436
terminalsRead,
3537
] as const
@@ -58,7 +60,7 @@ declare module '@vitejs/devtools-kit' {
5860
'vite:internal:docks:updated': () => Promise<void>
5961

6062
'vite:internal:rpc:client-state:patch': (key: string, patches: SharedStatePatch[], syncId: string) => Promise<void>
61-
'vite:internal:rpc:client-state:updated': (key: string, syncId: string) => Promise<void>
63+
'vite:internal:rpc:client-state:updated': (key: string, fullState: any, syncId: string) => Promise<void>
6264

6365
'vite:internal:terminals:stream-chunk': (data: DevToolsTerminalSessionStreamChunkEvent) => Promise<void>
6466
'vite:internal:terminals:updated': () => Promise<void>
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import type { DevToolsNodeContext } from '@vitejs/devtools-kit'
2+
import { defineRpcFunction } from '@vitejs/devtools-kit'
3+
import { createDebug } from 'obug'
4+
5+
const debug = createDebug('vite:devtools:rpc:state:subscribe')
6+
7+
export const sharedStateSubscribe = defineRpcFunction({
8+
name: 'vite:internal:rpc:server-state:subscribe',
9+
type: 'event',
10+
setup: (context: DevToolsNodeContext) => {
11+
return {
12+
handler: async (key: string): Promise<void> => {
13+
const session = context.rpc.getCurrentRpcSession()
14+
if (!session)
15+
return
16+
debug('subscribe', { key, session: session.meta.id })
17+
session.meta.subscribedStates.add(key)
18+
},
19+
}
20+
},
21+
})

packages/kit/src/client/rpc-shared-state.ts

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,22 +9,22 @@ export function createRpcSharedStateClientHost(rpc: DevToolsRpcClient): RpcShare
99
rpc.client.register({
1010
name: 'vite:internal:rpc:client-state:updated',
1111
type: 'event',
12-
handler: async (key: string, syncId: string) => {
12+
handler: (key: string, fullState: any, syncId: string) => {
1313
const state = sharedState.get(key)
1414
if (!state || state.syncIds.has(syncId))
1515
return
16-
const newState = await rpc.call('vite:internal:rpc:server-state:get', key)
17-
state.mutate(() => newState, syncId)
16+
state.mutate(() => fullState, syncId)
1817
},
1918
})
2019

2120
rpc.client.register({
2221
name: 'vite:internal:rpc:client-state:patch',
2322
type: 'event',
24-
handler: async (key: string, patches: SharedStatePatch[], syncId: string) => {
23+
handler: (key: string, patches: SharedStatePatch[], syncId: string) => {
2524
const state = sharedState.get(key)
26-
if (state)
27-
state.patch(patches, syncId)
25+
if (!state || state.syncIds.has(syncId))
26+
return
27+
state.patch(patches, syncId)
2828
},
2929
})
3030

@@ -61,6 +61,7 @@ export function createRpcSharedStateClientHost(rpc: DevToolsRpcClient): RpcShare
6161
return state
6262
}
6363
else {
64+
rpc.callEvent('vite:internal:rpc:server-state:subscribe', key)
6465
const initialState = await rpc.call('vite:internal:rpc:server-state:get', key) as T
6566
const state = createSharedState<T>({
6667
initialState,

packages/rpc/src/presets/ws/server.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ export interface DevToolsNodeRpcSessionMeta {
1111
ws?: WebSocket
1212
clientAuthId?: string
1313
isTrusted?: boolean
14+
subscribedStates: Set<string>
1415
}
1516

1617
export interface WebSocketRpcServerOptions {
@@ -59,6 +60,7 @@ export const createWsRpcPreset: RpcServerPreset<
5960
const meta: DevToolsNodeRpcSessionMeta = {
6061
id: id++,
6162
ws,
63+
subscribedStates: new Set(),
6264
}
6365

6466
const channel: ChannelOptions = {

tsconfig.base.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@
1515
"@vitejs/devtools-rpc/presets/ws/client": [
1616
"./packages/rpc/src/presets/ws/client.ts"
1717
],
18+
"@vitejs/devtools-rpc/presets": [
19+
"./packages/rpc/src/presets/index.ts"
20+
],
1821
"@vitejs/devtools-rpc": [
1922
"./packages/rpc/src"
2023
],

0 commit comments

Comments
 (0)