@zhin.js/client 1.0.17 → 1.0.18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/client/app.ts +228 -0
- package/client/index.ts +42 -14
- package/client/websocket/hooks.ts +218 -510
- package/client/websocket/index.ts +6 -43
- package/client/websocket/instance.ts +10 -32
- package/client/websocket/manager.ts +173 -390
- package/client/websocket/types.ts +58 -222
- package/dist/app.d.ts +95 -0
- package/dist/app.d.ts.map +1 -0
- package/dist/app.js +147 -0
- package/dist/app.js.map +1 -0
- package/dist/index.d.ts +7 -7
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +10 -14
- package/dist/index.js.map +1 -1
- package/dist/websocket/hooks.d.ts +35 -58
- package/dist/websocket/hooks.d.ts.map +1 -1
- package/dist/websocket/hooks.js +134 -410
- package/dist/websocket/hooks.js.map +1 -1
- package/dist/websocket/index.d.ts +5 -10
- package/dist/websocket/index.d.ts.map +1 -1
- package/dist/websocket/index.js +5 -25
- package/dist/websocket/index.js.map +1 -1
- package/dist/websocket/instance.d.ts +1 -14
- package/dist/websocket/instance.d.ts.map +1 -1
- package/dist/websocket/instance.js +2 -20
- package/dist/websocket/instance.js.map +1 -1
- package/dist/websocket/manager.d.ts +23 -93
- package/dist/websocket/manager.d.ts.map +1 -1
- package/dist/websocket/manager.js +87 -227
- package/dist/websocket/manager.js.map +1 -1
- package/dist/websocket/types.d.ts +35 -122
- package/dist/websocket/types.d.ts.map +1 -1
- package/dist/websocket/types.js +4 -13
- package/dist/websocket/types.js.map +1 -1
- package/package.json +12 -11
- package/client/router/index.tsx +0 -54
- package/client/store/index.ts +0 -132
- package/client/store/reducers/config.ts +0 -135
- package/client/store/reducers/index.ts +0 -19
- package/client/store/reducers/route.ts +0 -126
- package/client/store/reducers/script.ts +0 -109
- package/client/store/reducers/ui.ts +0 -31
- package/client/websocket/messageHandler.ts +0 -208
- package/dist/router/index.d.ts +0 -25
- package/dist/router/index.d.ts.map +0 -1
- package/dist/router/index.js +0 -48
- package/dist/router/index.js.map +0 -1
- package/dist/store/index.d.ts +0 -19
- package/dist/store/index.d.ts.map +0 -1
- package/dist/store/index.js +0 -67
- package/dist/store/index.js.map +0 -1
- package/dist/store/reducers/config.d.ts +0 -54
- package/dist/store/reducers/config.d.ts.map +0 -1
- package/dist/store/reducers/config.js +0 -78
- package/dist/store/reducers/config.js.map +0 -1
- package/dist/store/reducers/index.d.ts +0 -13
- package/dist/store/reducers/index.d.ts.map +0 -1
- package/dist/store/reducers/index.js +0 -11
- package/dist/store/reducers/index.js.map +0 -1
- package/dist/store/reducers/route.d.ts +0 -30
- package/dist/store/reducers/route.d.ts.map +0 -1
- package/dist/store/reducers/route.js +0 -85
- package/dist/store/reducers/route.js.map +0 -1
- package/dist/store/reducers/script.d.ts +0 -13
- package/dist/store/reducers/script.d.ts.map +0 -1
- package/dist/store/reducers/script.js +0 -78
- package/dist/store/reducers/script.js.map +0 -1
- package/dist/store/reducers/ui.d.ts +0 -8
- package/dist/store/reducers/ui.d.ts.map +0 -1
- package/dist/store/reducers/ui.js +0 -23
- package/dist/store/reducers/ui.js.map +0 -1
- package/dist/websocket/messageHandler.d.ts +0 -58
- package/dist/websocket/messageHandler.d.ts.map +0 -1
- package/dist/websocket/messageHandler.js +0 -174
- package/dist/websocket/messageHandler.js.map +0 -1
|
@@ -1,126 +0,0 @@
|
|
|
1
|
-
import { createSlice, PayloadAction } from "@reduxjs/toolkit"
|
|
2
|
-
import { ComponentType, ReactNode } from "react"
|
|
3
|
-
|
|
4
|
-
// 路由菜单项接口
|
|
5
|
-
export interface RouteMenuItem {
|
|
6
|
-
key: string
|
|
7
|
-
path: string
|
|
8
|
-
title: string
|
|
9
|
-
index?: boolean
|
|
10
|
-
icon?: ReactNode
|
|
11
|
-
element?: ReactNode
|
|
12
|
-
Component?: ComponentType
|
|
13
|
-
children?: RouteMenuItem[]
|
|
14
|
-
meta?: {
|
|
15
|
-
hideInMenu?: boolean
|
|
16
|
-
requiresAuth?: boolean
|
|
17
|
-
order?: number
|
|
18
|
-
/** 侧栏分组标签,同组内按 order 排序 */
|
|
19
|
-
group?: string
|
|
20
|
-
/** 主内容区全宽(无 max-w-7xl) */
|
|
21
|
-
fullWidth?: boolean
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
export interface RouteState {
|
|
26
|
-
routes: RouteMenuItem[]
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
const initialState: RouteState = {
|
|
30
|
-
routes: []
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
// 辅助函数:查找最佳父路由
|
|
34
|
-
const findBestParent = (routes: RouteMenuItem[], fullPath: string): RouteMenuItem | null => {
|
|
35
|
-
const segments = fullPath.split('/').filter(Boolean)
|
|
36
|
-
|
|
37
|
-
for (let i = segments.length - 1; i > 0; i--) {
|
|
38
|
-
const parentPath = '/' + segments.slice(0, i).join('/')
|
|
39
|
-
const parent = routes.find(r => r.path === parentPath)
|
|
40
|
-
if (parent) return parent
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
return routes.find(r=>r.path==='/')||null
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
// 辅助函数:计算相对路径
|
|
47
|
-
const calculateRelativePath = (parentPath: string, fullPath: string): string => {
|
|
48
|
-
if (parentPath === '/') return fullPath
|
|
49
|
-
return fullPath.replace(parentPath + '/', '')
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
const routeSlice = createSlice({
|
|
53
|
-
name: 'route',
|
|
54
|
-
initialState,
|
|
55
|
-
reducers: {
|
|
56
|
-
addRoute: (state, action: PayloadAction<RouteMenuItem>) => {
|
|
57
|
-
const route = action.payload
|
|
58
|
-
const parent = findBestParent(state.routes, route.path)
|
|
59
|
-
|
|
60
|
-
if (parent) {
|
|
61
|
-
if (!parent.children) parent.children = []
|
|
62
|
-
const relativePath = calculateRelativePath(parent.path, route.path)
|
|
63
|
-
parent.children.push({ ...route, path: relativePath })
|
|
64
|
-
} else {
|
|
65
|
-
state.routes.push(route)
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
state.routes.sort((a, b) => (a.meta?.order || 999) - (b.meta?.order || 999))
|
|
69
|
-
},
|
|
70
|
-
|
|
71
|
-
removeRoute: (state, action: PayloadAction<string>) => {
|
|
72
|
-
const path = action.payload
|
|
73
|
-
|
|
74
|
-
const removeFromArray = (routes: RouteMenuItem[]): boolean => {
|
|
75
|
-
const index = routes.findIndex(r => r.path === path)
|
|
76
|
-
if (index >= 0) {
|
|
77
|
-
routes.splice(index, 1)
|
|
78
|
-
return true
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
for (const route of routes) {
|
|
82
|
-
if (route.children && removeFromArray(route.children)) {
|
|
83
|
-
return true
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
return false
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
removeFromArray(state.routes)
|
|
90
|
-
},
|
|
91
|
-
|
|
92
|
-
updateRoute: (state, action: PayloadAction<{ path: string; updates: Partial<RouteMenuItem> }>) => {
|
|
93
|
-
const { path, updates } = action.payload
|
|
94
|
-
|
|
95
|
-
const updateInArray = (routes: RouteMenuItem[]): boolean => {
|
|
96
|
-
const index = routes.findIndex(r => r.path === path)
|
|
97
|
-
if (index >= 0) {
|
|
98
|
-
routes[index] = { ...routes[index], ...updates }
|
|
99
|
-
return true
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
for (const route of routes) {
|
|
103
|
-
if (route.children && updateInArray(route.children)) {
|
|
104
|
-
return true
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
return false
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
updateInArray(state.routes)
|
|
111
|
-
},
|
|
112
|
-
|
|
113
|
-
setRoutes: (state, action: PayloadAction<RouteMenuItem[]>) => {
|
|
114
|
-
state.routes = action.payload
|
|
115
|
-
state.routes.sort((a, b) => (a.meta?.order || 999) - (b.meta?.order || 999))
|
|
116
|
-
},
|
|
117
|
-
|
|
118
|
-
clearRoutes: (state) => {
|
|
119
|
-
state.routes = []
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
})
|
|
123
|
-
|
|
124
|
-
export const { addRoute, removeRoute, updateRoute, setRoutes, clearRoutes } = routeSlice.actions
|
|
125
|
-
export default routeSlice.reducer
|
|
126
|
-
|
|
@@ -1,109 +0,0 @@
|
|
|
1
|
-
import { createSlice, PayloadAction, createAsyncThunk } from "@reduxjs/toolkit"
|
|
2
|
-
|
|
3
|
-
export interface ScriptState {
|
|
4
|
-
entries: string[]
|
|
5
|
-
loadedScripts: string[]
|
|
6
|
-
/** 是否已收到 WebSocket 的首次 entries 同步 */
|
|
7
|
-
synced: boolean
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
const initialState: ScriptState = {
|
|
11
|
-
entries: [],
|
|
12
|
-
loadedScripts: [],
|
|
13
|
-
synced: false
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
// AsyncThunk: 加载单个脚本
|
|
17
|
-
export const loadScript = createAsyncThunk(
|
|
18
|
-
'script/loadScript',
|
|
19
|
-
async (src: string) => {
|
|
20
|
-
return new Promise<string>((resolve, reject) => {
|
|
21
|
-
const script = document.createElement('script')
|
|
22
|
-
script.type = 'module'
|
|
23
|
-
script.src = src
|
|
24
|
-
script.dataset.dynamicEntry = 'true'
|
|
25
|
-
|
|
26
|
-
script.onload = () => resolve(src)
|
|
27
|
-
script.onerror = (error) => {
|
|
28
|
-
console.error('[Script] Load failed:', src)
|
|
29
|
-
reject(error)
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
document.body.appendChild(script)
|
|
33
|
-
})
|
|
34
|
-
}
|
|
35
|
-
)
|
|
36
|
-
|
|
37
|
-
// AsyncThunk: 批量加载脚本
|
|
38
|
-
export const loadScripts = createAsyncThunk(
|
|
39
|
-
'script/loadScripts',
|
|
40
|
-
async (entries: string[], { dispatch }) => {
|
|
41
|
-
const results = await Promise.allSettled(
|
|
42
|
-
entries.map(entry => dispatch(loadScript(entry)).unwrap())
|
|
43
|
-
)
|
|
44
|
-
|
|
45
|
-
return results
|
|
46
|
-
.filter((r): r is PromiseFulfilledResult<string> => r.status === 'fulfilled')
|
|
47
|
-
.map(r => r.value)
|
|
48
|
-
}
|
|
49
|
-
)
|
|
50
|
-
|
|
51
|
-
// AsyncThunk: 卸载脚本
|
|
52
|
-
export const unloadScript = createAsyncThunk(
|
|
53
|
-
'script/unloadScript',
|
|
54
|
-
async (src: string) => {
|
|
55
|
-
const scripts = document.querySelectorAll(`script[src="${src}"][data-dynamic-entry="true"]`)
|
|
56
|
-
scripts.forEach(script => script.remove())
|
|
57
|
-
return src
|
|
58
|
-
}
|
|
59
|
-
)
|
|
60
|
-
|
|
61
|
-
const scriptSlice = createSlice({
|
|
62
|
-
name: 'script',
|
|
63
|
-
initialState,
|
|
64
|
-
reducers: {
|
|
65
|
-
syncEntries: (state, action: PayloadAction<string[]>) => {
|
|
66
|
-
state.entries = action.payload
|
|
67
|
-
// 清理掉不在新 entries 中的 loadedScripts(重启后 entries 可能变化)
|
|
68
|
-
state.loadedScripts = state.loadedScripts.filter(s => action.payload.includes(s))
|
|
69
|
-
state.synced = true
|
|
70
|
-
},
|
|
71
|
-
|
|
72
|
-
addEntry: (state, action: PayloadAction<string>) => {
|
|
73
|
-
if (!state.entries.includes(action.payload)) {
|
|
74
|
-
state.entries.push(action.payload)
|
|
75
|
-
}
|
|
76
|
-
},
|
|
77
|
-
|
|
78
|
-
removeEntry: (state, action: PayloadAction<string>) => {
|
|
79
|
-
state.entries = state.entries.filter(e => e !== action.payload)
|
|
80
|
-
state.loadedScripts = state.loadedScripts.filter(s => s !== action.payload)
|
|
81
|
-
}
|
|
82
|
-
},
|
|
83
|
-
extraReducers: (builder) => {
|
|
84
|
-
// loadScript 成功
|
|
85
|
-
builder.addCase(loadScript.fulfilled, (state, action) => {
|
|
86
|
-
if (!state.loadedScripts.includes(action.payload)) {
|
|
87
|
-
state.loadedScripts.push(action.payload)
|
|
88
|
-
}
|
|
89
|
-
})
|
|
90
|
-
|
|
91
|
-
// loadScripts 成功
|
|
92
|
-
builder.addCase(loadScripts.fulfilled, (state, action) => {
|
|
93
|
-
action.payload.forEach(src => {
|
|
94
|
-
if (!state.loadedScripts.includes(src)) {
|
|
95
|
-
state.loadedScripts.push(src)
|
|
96
|
-
}
|
|
97
|
-
})
|
|
98
|
-
})
|
|
99
|
-
|
|
100
|
-
// unloadScript 成功
|
|
101
|
-
builder.addCase(unloadScript.fulfilled, (state, action) => {
|
|
102
|
-
state.loadedScripts = state.loadedScripts.filter(s => s !== action.payload)
|
|
103
|
-
})
|
|
104
|
-
}
|
|
105
|
-
})
|
|
106
|
-
|
|
107
|
-
export const { syncEntries, addEntry, removeEntry } = scriptSlice.actions
|
|
108
|
-
export default scriptSlice.reducer
|
|
109
|
-
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
import { createSlice, PayloadAction } from "@reduxjs/toolkit"
|
|
2
|
-
|
|
3
|
-
export interface UIState {
|
|
4
|
-
sidebarOpen: boolean
|
|
5
|
-
activeMenu: string
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
const initialState: UIState = {
|
|
9
|
-
sidebarOpen: true,
|
|
10
|
-
activeMenu: 'home'
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
const uiSlice = createSlice({
|
|
14
|
-
name: 'ui',
|
|
15
|
-
initialState,
|
|
16
|
-
reducers: {
|
|
17
|
-
toggleSidebar: (state) => {
|
|
18
|
-
state.sidebarOpen = !state.sidebarOpen
|
|
19
|
-
},
|
|
20
|
-
setSidebarOpen: (state, action: PayloadAction<boolean>) => {
|
|
21
|
-
state.sidebarOpen = action.payload
|
|
22
|
-
},
|
|
23
|
-
setActiveMenu: (state, action: PayloadAction<string>) => {
|
|
24
|
-
state.activeMenu = action.payload
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
})
|
|
28
|
-
|
|
29
|
-
export const { toggleSidebar, setSidebarOpen, setActiveMenu } = uiSlice.actions
|
|
30
|
-
export default uiSlice.reducer
|
|
31
|
-
|
|
@@ -1,208 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* WebSocket 消息处理器
|
|
3
|
-
* 负责处理不同类型的 WebSocket 消息并分发到对应的处理逻辑
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import {
|
|
7
|
-
store,
|
|
8
|
-
syncEntries,
|
|
9
|
-
addEntry,
|
|
10
|
-
removeEntry,
|
|
11
|
-
loadScripts,
|
|
12
|
-
loadScript,
|
|
13
|
-
unloadScript,
|
|
14
|
-
updateConfig,
|
|
15
|
-
updateSchema,
|
|
16
|
-
updateConfigs,
|
|
17
|
-
updateSchemas,
|
|
18
|
-
setError
|
|
19
|
-
} from '../store'
|
|
20
|
-
import type { WebSocketMessage } from './types'
|
|
21
|
-
|
|
22
|
-
export class MessageHandler {
|
|
23
|
-
/**
|
|
24
|
-
* 处理 WebSocket 消息
|
|
25
|
-
*/
|
|
26
|
-
static handle(message: WebSocketMessage): void {
|
|
27
|
-
try {
|
|
28
|
-
const t = (message as { type: string }).type
|
|
29
|
-
if (t === 'bot:request' || t === 'bot:notice' || t === 'bot:message') {
|
|
30
|
-
if (typeof window !== 'undefined') {
|
|
31
|
-
window.dispatchEvent(
|
|
32
|
-
new CustomEvent('zhin-console-bot-push', { detail: message })
|
|
33
|
-
)
|
|
34
|
-
}
|
|
35
|
-
return
|
|
36
|
-
}
|
|
37
|
-
switch (message.type) {
|
|
38
|
-
// 脚本管理相关消息
|
|
39
|
-
case 'sync':
|
|
40
|
-
this.handleScriptSync(message)
|
|
41
|
-
break
|
|
42
|
-
case 'add':
|
|
43
|
-
this.handleScriptAdd(message)
|
|
44
|
-
break
|
|
45
|
-
case 'delete':
|
|
46
|
-
this.handleScriptDelete(message)
|
|
47
|
-
break
|
|
48
|
-
|
|
49
|
-
// 配置管理相关消息
|
|
50
|
-
case 'config:updated':
|
|
51
|
-
this.handleConfigUpdated(message)
|
|
52
|
-
break
|
|
53
|
-
case 'config:batch':
|
|
54
|
-
this.handleConfigBatch(message)
|
|
55
|
-
break
|
|
56
|
-
case 'config:error':
|
|
57
|
-
this.handleConfigError(message)
|
|
58
|
-
break
|
|
59
|
-
|
|
60
|
-
// Schema 管理相关消息
|
|
61
|
-
case 'schema:updated':
|
|
62
|
-
this.handleSchemaUpdated(message)
|
|
63
|
-
break
|
|
64
|
-
case 'schema:batch':
|
|
65
|
-
this.handleSchemaBatch(message)
|
|
66
|
-
break
|
|
67
|
-
|
|
68
|
-
// 轻量 HMR:文件变更时刷新页面
|
|
69
|
-
case 'hmr:reload':
|
|
70
|
-
this.handleHmrReload(message)
|
|
71
|
-
break
|
|
72
|
-
|
|
73
|
-
// 系统重启通知:延迟后刷新页面
|
|
74
|
-
case 'system:restarting':
|
|
75
|
-
this.handleSystemRestart()
|
|
76
|
-
break
|
|
77
|
-
|
|
78
|
-
// 系统消息
|
|
79
|
-
case 'init-data':
|
|
80
|
-
case 'data-update':
|
|
81
|
-
this.handleSystemMessage(message)
|
|
82
|
-
break
|
|
83
|
-
|
|
84
|
-
default:
|
|
85
|
-
console.warn('[WebSocket] Unknown message type:', message.type)
|
|
86
|
-
}
|
|
87
|
-
} catch (error) {
|
|
88
|
-
console.error('[WebSocket] Message handling error:', error)
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
/**
|
|
93
|
-
* 处理脚本同步消息
|
|
94
|
-
*/
|
|
95
|
-
private static handleScriptSync(message: any): void {
|
|
96
|
-
if (message.data?.key === 'entries') {
|
|
97
|
-
const entries = Array.isArray(message.data.value)
|
|
98
|
-
? message.data.value
|
|
99
|
-
: [message.data.value]
|
|
100
|
-
|
|
101
|
-
store.dispatch(syncEntries(entries))
|
|
102
|
-
store.dispatch(loadScripts(entries))
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
/**
|
|
107
|
-
* 处理脚本添加消息
|
|
108
|
-
*/
|
|
109
|
-
private static handleScriptAdd(message: any): void {
|
|
110
|
-
if (message.data?.key === 'entries') {
|
|
111
|
-
store.dispatch(addEntry(message.data.value))
|
|
112
|
-
store.dispatch(loadScript(message.data.value))
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
/**
|
|
117
|
-
* 处理脚本删除消息
|
|
118
|
-
*/
|
|
119
|
-
private static handleScriptDelete(message: any): void {
|
|
120
|
-
if (message.data?.key === 'entries') {
|
|
121
|
-
store.dispatch(removeEntry(message.data.value))
|
|
122
|
-
store.dispatch(unloadScript(message.data.value))
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
/**
|
|
127
|
-
* 处理配置更新消息
|
|
128
|
-
*/
|
|
129
|
-
private static handleConfigUpdated(message: any): void {
|
|
130
|
-
if (message.pluginName && message.data !== undefined) {
|
|
131
|
-
store.dispatch(updateConfig({
|
|
132
|
-
pluginName: message.pluginName,
|
|
133
|
-
config: message.data
|
|
134
|
-
}))
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
/**
|
|
139
|
-
* 处理批量配置消息
|
|
140
|
-
*/
|
|
141
|
-
private static handleConfigBatch(message: any): void {
|
|
142
|
-
if (message.data) {
|
|
143
|
-
store.dispatch(updateConfigs(message.data))
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
/**
|
|
148
|
-
* 处理配置错误消息
|
|
149
|
-
*/
|
|
150
|
-
private static handleConfigError(message: any): void {
|
|
151
|
-
if (message.pluginName && message.error) {
|
|
152
|
-
store.dispatch(setError({
|
|
153
|
-
pluginName: message.pluginName,
|
|
154
|
-
error: message.error
|
|
155
|
-
}))
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
/**
|
|
160
|
-
* 处理 Schema 更新消息
|
|
161
|
-
*/
|
|
162
|
-
private static handleSchemaUpdated(message: any): void {
|
|
163
|
-
if (message.pluginName && message.data !== undefined) {
|
|
164
|
-
store.dispatch(updateSchema({
|
|
165
|
-
pluginName: message.pluginName,
|
|
166
|
-
schema: message.data
|
|
167
|
-
}))
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
/**
|
|
172
|
-
* 处理批量 Schema 消息
|
|
173
|
-
*/
|
|
174
|
-
private static handleSchemaBatch(message: any): void {
|
|
175
|
-
if (message.data) {
|
|
176
|
-
store.dispatch(updateSchemas(message.data))
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
/**
|
|
181
|
-
* 处理轻量 HMR 刷新通知
|
|
182
|
-
* 服务端监听到入口目录文件变更后发送此消息,客户端直接刷新页面
|
|
183
|
-
*/
|
|
184
|
-
private static handleHmrReload(message: any): void {
|
|
185
|
-
const file = message.data?.file || ''
|
|
186
|
-
console.info(`[HMR] 文件变更: ${file},正在刷新页面...`)
|
|
187
|
-
window.location.reload()
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
/**
|
|
191
|
-
* 处理系统重启通知
|
|
192
|
-
* 服务端即将重启,延迟后刷新页面以重新连接
|
|
193
|
-
*/
|
|
194
|
-
private static handleSystemRestart(): void {
|
|
195
|
-
console.info('[System] 服务端正在重启,稍后将自动刷新...')
|
|
196
|
-
setTimeout(() => {
|
|
197
|
-
window.location.reload()
|
|
198
|
-
}, 3000)
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
/**
|
|
202
|
-
* 处理系统消息
|
|
203
|
-
*/
|
|
204
|
-
private static handleSystemMessage(message: WebSocketMessage): void {
|
|
205
|
-
// 系统消息暂时不需要特殊处理
|
|
206
|
-
// 可以在这里添加系统级别的消息处理逻辑
|
|
207
|
-
}
|
|
208
|
-
}
|
package/dist/router/index.d.ts
DELETED
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import { RouteMenuItem } from '../store';
|
|
2
|
-
export { useOutlet, Outlet, Link, useNavigate, useParams } from 'react-router';
|
|
3
|
-
export declare const addPage: (route: RouteMenuItem) => {
|
|
4
|
-
payload: RouteMenuItem;
|
|
5
|
-
type: "route/addRoute";
|
|
6
|
-
};
|
|
7
|
-
export declare const removePage: (path: string) => {
|
|
8
|
-
payload: string;
|
|
9
|
-
type: "route/removeRoute";
|
|
10
|
-
};
|
|
11
|
-
export declare const updatePage: (path: string, route: RouteMenuItem) => {
|
|
12
|
-
payload: {
|
|
13
|
-
path: string;
|
|
14
|
-
updates: Partial<RouteMenuItem>;
|
|
15
|
-
};
|
|
16
|
-
type: "route/updateRoute";
|
|
17
|
-
};
|
|
18
|
-
export declare const getPage: (path: string) => RouteMenuItem | undefined;
|
|
19
|
-
export declare const getAllPages: () => RouteMenuItem[];
|
|
20
|
-
export declare const clearPages: () => {
|
|
21
|
-
payload: undefined;
|
|
22
|
-
type: "route/clearRoutes";
|
|
23
|
-
};
|
|
24
|
-
export declare function DynamicRouter(): import("react/jsx-runtime").JSX.Element;
|
|
25
|
-
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../client/router/index.tsx"],"names":[],"mappings":"AAEA,OAAO,EAA0D,aAAa,EAAe,MAAM,UAAU,CAAA;AAC7G,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,cAAc,CAAA;AAK9E,eAAO,MAAM,OAAO,GAAI,OAAO,aAAa;;;CAAoC,CAAA;AAChF,eAAO,MAAM,UAAU,GAAI,MAAM,MAAM;;;CAAsC,CAAA;AAC7E,eAAO,MAAM,UAAU,GAAI,MAAM,MAAM,EAAE,OAAO,aAAa;;;;;;CAG1D,CAAA;AACH,eAAO,MAAM,OAAO,GAAI,MAAM,MAAM,8BAAqE,CAAA;AACzG,eAAO,MAAM,WAAW,uBAAsC,CAAA;AAC9D,eAAO,MAAM,UAAU;;;CAAsC,CAAA;AAG7D,wBAAgB,aAAa,4CAkC5B"}
|
package/dist/router/index.js
DELETED
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import { useMemo } from 'react';
|
|
3
|
-
import { createBrowserRouter, RouterProvider as ReactRouterProvider, Outlet } from 'react-router';
|
|
4
|
-
import { store, addRoute, removeRoute, updateRoute, clearRoutes, useSelector } from '../store';
|
|
5
|
-
export { useOutlet, Outlet, Link, useNavigate, useParams } from 'react-router';
|
|
6
|
-
export const addPage = (route) => store.dispatch(addRoute(route));
|
|
7
|
-
export const removePage = (path) => store.dispatch(removeRoute(path));
|
|
8
|
-
export const updatePage = (path, route) => store.dispatch(updateRoute({
|
|
9
|
-
path,
|
|
10
|
-
updates: route
|
|
11
|
-
}));
|
|
12
|
-
export const getPage = (path) => store.getState().route.routes.find(route => route.path === path);
|
|
13
|
-
export const getAllPages = () => store.getState().route.routes;
|
|
14
|
-
export const clearPages = () => store.dispatch(clearRoutes());
|
|
15
|
-
// 动态路由组件(从 Redux store 读取)
|
|
16
|
-
export function DynamicRouter() {
|
|
17
|
-
const storeRoutes = useSelector((state) => state.route?.routes || []);
|
|
18
|
-
const router = useMemo(() => {
|
|
19
|
-
// 递归转换路由(支持多层嵌套)
|
|
20
|
-
const convertRoute = (route) => {
|
|
21
|
-
const routeObj = {
|
|
22
|
-
path: route.path,
|
|
23
|
-
element: route.element,
|
|
24
|
-
Component: route.Component,
|
|
25
|
-
};
|
|
26
|
-
// 递归处理子路由
|
|
27
|
-
if (route.children && route.children.length > 0) {
|
|
28
|
-
routeObj.children = route.children.map((child) => convertRoute(child));
|
|
29
|
-
}
|
|
30
|
-
return routeObj;
|
|
31
|
-
};
|
|
32
|
-
const routeObjects = storeRoutes.map(convertRoute);
|
|
33
|
-
const defaultRoutes = [
|
|
34
|
-
{
|
|
35
|
-
path: '/',
|
|
36
|
-
element: _jsx(Outlet, {}),
|
|
37
|
-
children: routeObjects,
|
|
38
|
-
},
|
|
39
|
-
{
|
|
40
|
-
path: '*',
|
|
41
|
-
element: _jsx("div", { children: "404 - Page Not Found" }),
|
|
42
|
-
}
|
|
43
|
-
];
|
|
44
|
-
return createBrowserRouter(defaultRoutes);
|
|
45
|
-
}, [storeRoutes]);
|
|
46
|
-
return _jsx(ReactRouterProvider, { router: router });
|
|
47
|
-
}
|
|
48
|
-
//# sourceMappingURL=index.js.map
|
package/dist/router/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../client/router/index.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,OAAO,CAAA;AAC/B,OAAO,EAAE,mBAAmB,EAAE,cAAc,IAAI,mBAAmB,EAAe,MAAM,EAAC,MAAM,cAAc,CAAA;AAC7G,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,WAAW,EAAE,WAAW,EAAE,WAAW,EAAiB,WAAW,EAAE,MAAM,UAAU,CAAA;AAC7G,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,cAAc,CAAA;AAK9E,MAAM,CAAC,MAAM,OAAO,GAAG,CAAC,KAAoB,EAAE,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAA;AAChF,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,IAAY,EAAE,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAA;AAC7E,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,IAAY,EAAE,KAAoB,EAAE,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,WAAW,CAAC;IAC3F,IAAI;IACJ,OAAO,EAAE,KAAK;CACf,CAAC,CAAC,CAAA;AACH,MAAM,CAAC,MAAM,OAAO,GAAG,CAAC,IAAY,EAAE,EAAE,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,KAAK,IAAI,CAAC,CAAA;AACzG,MAAM,CAAC,MAAM,WAAW,GAAG,GAAG,EAAE,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,KAAK,CAAC,MAAM,CAAA;AAC9D,MAAM,CAAC,MAAM,UAAU,GAAG,GAAG,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC,CAAA;AAE7D,2BAA2B;AAC3B,MAAM,UAAU,aAAa;IAC3B,MAAM,WAAW,GAAG,WAAW,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,EAAE,MAAM,IAAI,EAAE,CAAC,CAAA;IACrE,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,EAAE;QAC1B,iBAAiB;QACjB,MAAM,YAAY,GAAG,CAAC,KAAoB,EAAe,EAAE;YACzD,MAAM,QAAQ,GAAgB;gBAC5B,IAAI,EAAE,KAAK,CAAC,IAAI;gBAChB,OAAO,EAAE,KAAK,CAAC,OAAO;gBACtB,SAAS,EAAE,KAAK,CAAC,SAAS;aAC3B,CAAA;YAED,UAAU;YACV,IAAI,KAAK,CAAC,QAAQ,IAAI,KAAK,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAChD,QAAQ,CAAC,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,KAAoB,EAAE,EAAE,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,CAAA;YACvF,CAAC;YACD,OAAO,QAAQ,CAAA;QACjB,CAAC,CAAA;QACD,MAAM,YAAY,GAAkB,WAAW,CAAC,GAAG,CAAC,YAAY,CAAC,CAAA;QACjE,MAAM,aAAa,GAAkB;YACnC;gBACE,IAAI,EAAE,GAAG;gBACT,OAAO,EAAE,KAAC,MAAM,KAAG;gBACnB,QAAQ,EAAE,YAAY;aACvB;YACD;gBACE,IAAI,EAAE,GAAG;gBACT,OAAO,EAAE,iDAA+B;aACzC;SACF,CAAA;QAED,OAAO,mBAAmB,CAAC,aAAa,CAAC,CAAA;IAC3C,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,CAAA;IAEjB,OAAO,KAAC,mBAAmB,IAAC,MAAM,EAAE,MAAM,GAAI,CAAA;AAChD,CAAC"}
|
package/dist/store/index.d.ts
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import { Reducer, Action } from '@reduxjs/toolkit';
|
|
2
|
-
import { Reducers } from './reducers';
|
|
3
|
-
import { TypedUseSelectorHook } from 'react-redux';
|
|
4
|
-
export declare const store: import("@reduxjs/toolkit").EnhancedStore<Reducers, import("@reduxjs/toolkit").UnknownAction, import("@reduxjs/toolkit").Tuple<[import("@reduxjs/toolkit").StoreEnhancer<{
|
|
5
|
-
dispatch: import("@reduxjs/toolkit").ThunkDispatch<Reducers, undefined, import("@reduxjs/toolkit").UnknownAction>;
|
|
6
|
-
}>, import("@reduxjs/toolkit").StoreEnhancer]>>;
|
|
7
|
-
export declare const persistor: import("redux-persist").Persistor;
|
|
8
|
-
export declare function addReducer<T, A extends Action>(name: keyof Reducers, reducer: Reducer<T, A>): void;
|
|
9
|
-
export type RootState = ReturnType<typeof store.getState>;
|
|
10
|
-
export type AppDispatch = typeof store.dispatch;
|
|
11
|
-
export declare const useDispatch: () => AppDispatch;
|
|
12
|
-
export declare const useSelector: TypedUseSelectorHook<RootState>;
|
|
13
|
-
export { toggleSidebar, setSidebarOpen, setActiveMenu } from './reducers/ui';
|
|
14
|
-
export { addRoute, removeRoute, updateRoute, setRoutes, clearRoutes } from './reducers/route';
|
|
15
|
-
export { syncEntries, addEntry, removeEntry, loadScript, loadScripts, unloadScript } from './reducers/script';
|
|
16
|
-
export { setConnected, setLoading, setError, updateConfig, updateSchema, updateConfigs, updateSchemas, removeConfig, clearConfigs, selectConfig, selectSchema, selectConfigLoading, selectConfigError, selectConfigConnected, selectAllConfigs, selectAllSchemas } from './reducers/config';
|
|
17
|
-
export type { RouteMenuItem } from './reducers/route';
|
|
18
|
-
export type { ConfigMessage } from './reducers/config';
|
|
19
|
-
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../client/store/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiB,OAAO,EAAE,MAAM,EAAiB,MAAM,kBAAkB,CAAA;AAahF,OAAO,EAAW,QAAQ,EAAE,MAAM,YAAY,CAAC;AAC/C,OAAO,EAAmC,oBAAoB,EAAmC,MAAM,aAAa,CAAC;AA+BrH,eAAO,MAAM,KAAK;;+CAqBhB,CAAA;AACF,eAAO,MAAM,SAAS,mCAAsB,CAAC;AAO7C,wBAAgB,UAAU,CAAC,CAAC,EAAC,CAAC,SAAS,MAAM,EAAE,IAAI,EAAC,MAAM,QAAQ,EAAC,OAAO,EAAC,OAAO,CAAC,CAAC,EAAC,CAAC,CAAC,QAItF;AACD,MAAM,MAAM,SAAS,GAAG,UAAU,CAAC,OAAO,KAAK,CAAC,QAAQ,CAAC,CAAA;AACzD,MAAM,MAAM,WAAW,GAAG,OAAO,KAAK,CAAC,QAAQ,CAAA;AAC/C,eAAO,MAAM,WAAW,EAAC,MAAI,WAA8B,CAAA;AAC3D,eAAO,MAAM,WAAW,EAAC,oBAAoB,CAAC,SAAS,CAAoB,CAAA;AAG3E,OAAO,EACH,aAAa,EACb,cAAc,EACd,aAAa,EAChB,MAAM,eAAe,CAAA;AAGtB,OAAO,EACH,QAAQ,EACR,WAAW,EACX,WAAW,EACX,SAAS,EACT,WAAW,EACd,MAAM,kBAAkB,CAAA;AAGzB,OAAO,EACH,WAAW,EACX,QAAQ,EACR,WAAW,EACX,UAAU,EACV,WAAW,EACX,YAAY,EACf,MAAM,mBAAmB,CAAA;AAG1B,OAAO,EACH,YAAY,EACZ,UAAU,EACV,QAAQ,EACR,YAAY,EACZ,YAAY,EACZ,aAAa,EACb,aAAa,EACb,YAAY,EACZ,YAAY,EACZ,YAAY,EACZ,YAAY,EACZ,mBAAmB,EACnB,iBAAiB,EACjB,qBAAqB,EACrB,gBAAgB,EAChB,gBAAgB,EACnB,MAAM,mBAAmB,CAAA;AAE1B,YAAY,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAA;AACrD,YAAY,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAA"}
|
package/dist/store/index.js
DELETED
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
import { configureStore, combineReducers } from '@reduxjs/toolkit';
|
|
2
|
-
import { FLUSH, PAUSE, PERSIST, persistReducer, persistStore, PURGE, REGISTER, REHYDRATE, createTransform, } from 'redux-persist';
|
|
3
|
-
import storage from 'redux-persist/es/storage';
|
|
4
|
-
import { reducers } from './reducers';
|
|
5
|
-
import { useDispatch as useReduxDispatch, useSelector as useReduxSelector } from 'react-redux';
|
|
6
|
-
// 创建 transform 过滤不可序列化的字段
|
|
7
|
-
const routeTransform = createTransform((inboundState) => {
|
|
8
|
-
const { routes, ...rest } = inboundState;
|
|
9
|
-
return rest;
|
|
10
|
-
}, (outboundState) => {
|
|
11
|
-
return { ...outboundState, routes: [] };
|
|
12
|
-
}, { whitelist: ['route'] });
|
|
13
|
-
const scriptTransform = createTransform((inboundState) => {
|
|
14
|
-
const { entries, loadedScripts, synced, ...rest } = inboundState;
|
|
15
|
-
return rest;
|
|
16
|
-
}, (outboundState) => {
|
|
17
|
-
return { ...outboundState, entries: [], loadedScripts: [], synced: false };
|
|
18
|
-
}, { whitelist: ['script'] });
|
|
19
|
-
const persistConfig = {
|
|
20
|
-
key: 'root',
|
|
21
|
-
storage: storage,
|
|
22
|
-
transforms: [routeTransform, scriptTransform],
|
|
23
|
-
};
|
|
24
|
-
const persistedReducer = persistReducer(persistConfig, combineReducers(reducers));
|
|
25
|
-
export const store = configureStore({
|
|
26
|
-
reducer: persistedReducer,
|
|
27
|
-
middleware: (getDefaultMiddleware) => getDefaultMiddleware({
|
|
28
|
-
serializableCheck: {
|
|
29
|
-
ignoredActions: [
|
|
30
|
-
FLUSH,
|
|
31
|
-
REHYDRATE,
|
|
32
|
-
PAUSE,
|
|
33
|
-
PERSIST,
|
|
34
|
-
PURGE,
|
|
35
|
-
REGISTER,
|
|
36
|
-
// 忽略包含 React 组件的路由 actions
|
|
37
|
-
'route/addRoute',
|
|
38
|
-
'route/updateRoute',
|
|
39
|
-
'route/setRoutes',
|
|
40
|
-
],
|
|
41
|
-
// 忽略 state 中的 routes 字段
|
|
42
|
-
ignoredPaths: ['route.routes'],
|
|
43
|
-
},
|
|
44
|
-
}),
|
|
45
|
-
});
|
|
46
|
-
export const persistor = persistStore(store);
|
|
47
|
-
// 将 store 挂载到 window 以供 DynamicRouter 使用
|
|
48
|
-
if (typeof window !== 'undefined') {
|
|
49
|
-
// @ts-ignore
|
|
50
|
-
window.__REDUX_STORE__ = store;
|
|
51
|
-
}
|
|
52
|
-
export function addReducer(name, reducer) {
|
|
53
|
-
reducers[name] = reducer;
|
|
54
|
-
const newPersistedReducer = persistReducer(persistConfig, combineReducers(reducers));
|
|
55
|
-
store.replaceReducer(newPersistedReducer);
|
|
56
|
-
}
|
|
57
|
-
export const useDispatch = useReduxDispatch;
|
|
58
|
-
export const useSelector = useReduxSelector;
|
|
59
|
-
// 导出 UI actions
|
|
60
|
-
export { toggleSidebar, setSidebarOpen, setActiveMenu } from './reducers/ui';
|
|
61
|
-
// 导出 Route actions
|
|
62
|
-
export { addRoute, removeRoute, updateRoute, setRoutes, clearRoutes } from './reducers/route';
|
|
63
|
-
// 导出 Script actions 和 thunks
|
|
64
|
-
export { syncEntries, addEntry, removeEntry, loadScript, loadScripts, unloadScript } from './reducers/script';
|
|
65
|
-
// 导出 Config actions 和 selectors
|
|
66
|
-
export { setConnected, setLoading, setError, updateConfig, updateSchema, updateConfigs, updateSchemas, removeConfig, clearConfigs, selectConfig, selectSchema, selectConfigLoading, selectConfigError, selectConfigConnected, selectAllConfigs, selectAllSchemas } from './reducers/config';
|
|
67
|
-
//# sourceMappingURL=index.js.map
|
package/dist/store/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../client/store/index.ts"],"names":[],"mappings":"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"}
|