@zhin.js/client 1.0.17 → 1.1.0
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/bootstrap/loadConsoleEntries.test.ts +32 -0
- package/client/bootstrap/loadConsoleEntries.ts +149 -0
- package/client/console-utils/cn.ts +6 -0
- package/client/console-utils/remoteApi.ts +48 -0
- package/client/index.ts +61 -14
- package/client/persistence/idb-store.ts +76 -0
- package/client/runtime/index.ts +12 -0
- package/client/store/createRegistryStore.ts +46 -0
- 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 +301 -385
- package/client/websocket/remote-settings.ts +25 -0
- 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/bootstrap/loadConsoleEntries.d.ts +26 -0
- package/dist/bootstrap/loadConsoleEntries.d.ts.map +1 -0
- package/dist/bootstrap/loadConsoleEntries.js +111 -0
- package/dist/bootstrap/loadConsoleEntries.js.map +1 -0
- package/dist/bootstrap/loadConsoleEntries.test.d.ts +2 -0
- package/dist/bootstrap/loadConsoleEntries.test.d.ts.map +1 -0
- package/dist/bootstrap/loadConsoleEntries.test.js +27 -0
- package/dist/bootstrap/loadConsoleEntries.test.js.map +1 -0
- package/dist/console-utils/cn.d.ts +3 -0
- package/dist/console-utils/cn.d.ts.map +1 -0
- package/dist/console-utils/cn.js +6 -0
- package/dist/console-utils/cn.js.map +1 -0
- package/dist/console-utils/remoteApi.d.ts +7 -0
- package/dist/console-utils/remoteApi.d.ts.map +1 -0
- package/dist/console-utils/remoteApi.js +41 -0
- package/dist/console-utils/remoteApi.js.map +1 -0
- package/dist/index.d.ts +11 -7
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +13 -14
- package/dist/index.js.map +1 -1
- package/dist/persistence/idb-store.d.ts +15 -0
- package/dist/persistence/idb-store.d.ts.map +1 -0
- package/dist/persistence/idb-store.js +61 -0
- package/dist/persistence/idb-store.js.map +1 -0
- package/dist/runtime/index.d.ts +6 -0
- package/dist/runtime/index.d.ts.map +1 -0
- package/dist/runtime/index.js +10 -0
- package/dist/runtime/index.js.map +1 -0
- package/dist/store/createRegistryStore.d.ts +9 -0
- package/dist/store/createRegistryStore.d.ts.map +1 -0
- package/dist/store/createRegistryStore.js +38 -0
- package/dist/store/createRegistryStore.js.map +1 -0
- 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 +28 -93
- package/dist/websocket/manager.d.ts.map +1 -1
- package/dist/websocket/manager.js +213 -221
- package/dist/websocket/manager.js.map +1 -1
- package/dist/websocket/remote-settings.d.ts +5 -0
- package/dist/websocket/remote-settings.d.ts.map +1 -0
- package/dist/websocket/remote-settings.js +23 -0
- package/dist/websocket/remote-settings.js.map +1 -0
- 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 +13 -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,581 +1,289 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
import { useCallback, useEffect, useMemo, useState } from 'react'
|
|
7
|
-
import {
|
|
8
|
-
useSelector,
|
|
9
|
-
useDispatch,
|
|
10
|
-
selectConfig,
|
|
11
|
-
selectSchema,
|
|
12
|
-
selectConfigLoading,
|
|
13
|
-
selectConfigError,
|
|
14
|
-
selectConfigConnected,
|
|
15
|
-
selectAllConfigs,
|
|
16
|
-
selectAllSchemas,
|
|
17
|
-
setLoading,
|
|
18
|
-
setError,
|
|
19
|
-
updateConfig,
|
|
20
|
-
updateSchema
|
|
21
|
-
} from '../store'
|
|
22
|
-
import { getWebSocketManager } from './instance'
|
|
23
|
-
import type { UseConfigOptions, UseWebSocketOptions, FileTreeNode, DatabaseInfo, TableInfo, SelectResult, KvEntry, DatabaseType } from './types'
|
|
24
|
-
|
|
25
|
-
// ============================================================================
|
|
26
|
-
// WebSocket 连接 Hook
|
|
27
|
-
// ============================================================================
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* WebSocket 连接状态和基础功能 Hook
|
|
31
|
-
*/
|
|
1
|
+
import { useCallback, useEffect, useMemo, useState } from "react";
|
|
2
|
+
import { getWebSocketManager } from "./instance";
|
|
3
|
+
import type { UseWebSocketOptions } from "./types";
|
|
4
|
+
|
|
32
5
|
export function useWebSocket(options: UseWebSocketOptions = {}) {
|
|
33
|
-
const { autoConnect = true } = options
|
|
34
|
-
|
|
35
|
-
const
|
|
36
|
-
|
|
37
|
-
// 从 Redux 获取状态
|
|
38
|
-
const connected = useSelector(selectConfigConnected)
|
|
39
|
-
const entries = useSelector((state: any) => state.script?.entries || [])
|
|
40
|
-
const loadedScripts = useSelector((state: any) => state.script?.loadedScripts || [])
|
|
41
|
-
|
|
42
|
-
// 连接控制
|
|
43
|
-
const connect = useCallback(() => {
|
|
44
|
-
wsManager.connect()
|
|
45
|
-
}, [wsManager])
|
|
46
|
-
|
|
47
|
-
const disconnect = useCallback(() => {
|
|
48
|
-
wsManager.disconnect()
|
|
49
|
-
}, [wsManager])
|
|
50
|
-
|
|
51
|
-
// 消息发送
|
|
52
|
-
const send = useCallback((message: any) => {
|
|
53
|
-
wsManager.send(message)
|
|
54
|
-
}, [wsManager])
|
|
55
|
-
|
|
56
|
-
const sendRequest = useCallback(async <T = any>(message: any): Promise<T> => {
|
|
57
|
-
// 临时使用旧方法,后续完善
|
|
58
|
-
return (wsManager as any).sendRequest(message)
|
|
59
|
-
}, [wsManager])
|
|
60
|
-
|
|
61
|
-
// 状态查询
|
|
62
|
-
const isConnected = useCallback(() => {
|
|
63
|
-
return wsManager.isConnected()
|
|
64
|
-
}, [wsManager])
|
|
65
|
-
|
|
66
|
-
const getState = useCallback(() => {
|
|
67
|
-
// 临时返回连接状态,后续完善
|
|
68
|
-
return wsManager.isConnected() ? 'connected' : 'disconnected'
|
|
69
|
-
}, [wsManager])
|
|
70
|
-
|
|
71
|
-
// 自动连接
|
|
6
|
+
const { autoConnect = true } = options;
|
|
7
|
+
const wsManager = getWebSocketManager();
|
|
8
|
+
const [connected, setConnected] = useState(wsManager.isConnected());
|
|
9
|
+
|
|
72
10
|
useEffect(() => {
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
}
|
|
76
|
-
}, [autoConnect, connected, connect])
|
|
77
|
-
|
|
78
|
-
return {
|
|
79
|
-
// 状态
|
|
80
|
-
connected,
|
|
81
|
-
entries,
|
|
82
|
-
loadedScripts,
|
|
83
|
-
|
|
84
|
-
// 方法
|
|
85
|
-
connect,
|
|
86
|
-
disconnect,
|
|
87
|
-
send,
|
|
88
|
-
sendRequest,
|
|
89
|
-
isConnected,
|
|
90
|
-
getState,
|
|
91
|
-
|
|
92
|
-
// WebSocket 实例(高级用法)
|
|
93
|
-
manager: wsManager
|
|
94
|
-
}
|
|
95
|
-
}
|
|
11
|
+
return wsManager.onConnectionChange(setConnected);
|
|
12
|
+
}, [wsManager]);
|
|
96
13
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
export function useConfig(pluginName: string, options: UseConfigOptions = {}) {
|
|
105
|
-
const { autoLoad = true, autoLoadSchema = true } = options
|
|
106
|
-
|
|
107
|
-
const dispatch = useDispatch()
|
|
108
|
-
const wsManager = getWebSocketManager()
|
|
109
|
-
|
|
110
|
-
// 状态选择器
|
|
111
|
-
const config = useSelector((state: any) => selectConfig(state, pluginName))
|
|
112
|
-
const schema = useSelector((state: any) => selectSchema(state, pluginName))
|
|
113
|
-
const loading = useSelector((state: any) => selectConfigLoading(state, pluginName))
|
|
114
|
-
const error = useSelector((state: any) => selectConfigError(state, pluginName))
|
|
115
|
-
const connected = useSelector(selectConfigConnected)
|
|
116
|
-
|
|
117
|
-
// 配置操作
|
|
118
|
-
const getConfig = useCallback(async () => {
|
|
119
|
-
dispatch(setLoading({ pluginName, loading: true }))
|
|
120
|
-
dispatch(setError({ pluginName, error: null }))
|
|
14
|
+
const connect = useCallback(() => wsManager.connect(), [wsManager]);
|
|
15
|
+
const disconnect = useCallback(() => wsManager.disconnect(), [wsManager]);
|
|
16
|
+
const send = useCallback((message: unknown) => wsManager.send(message), [wsManager]);
|
|
17
|
+
const sendRequest = useCallback(
|
|
18
|
+
<T = unknown>(message: unknown) => wsManager.sendRequest<T>(message),
|
|
19
|
+
[wsManager],
|
|
20
|
+
);
|
|
121
21
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
const errorMessage = error instanceof Error ? error.message : 'Unknown error'
|
|
129
|
-
dispatch(setError({ pluginName, error: errorMessage }))
|
|
130
|
-
throw error
|
|
131
|
-
} finally {
|
|
132
|
-
dispatch(setLoading({ pluginName, loading: false }))
|
|
133
|
-
}
|
|
134
|
-
}, [pluginName, wsManager, dispatch])
|
|
22
|
+
useEffect(() => {
|
|
23
|
+
if (autoConnect && !connected) connect();
|
|
24
|
+
}, [autoConnect, connected, connect]);
|
|
25
|
+
|
|
26
|
+
return { connected, connect, disconnect, send, sendRequest, manager: wsManager };
|
|
27
|
+
}
|
|
135
28
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
29
|
+
export function useConfig(pluginName: string, options?: { autoLoad?: boolean; autoLoadSchema?: boolean }) {
|
|
30
|
+
const { autoLoad = true, autoLoadSchema = true } = options ?? {};
|
|
31
|
+
const wsManager = getWebSocketManager();
|
|
32
|
+
const [connected, setConnected] = useState(wsManager.isConnected());
|
|
33
|
+
const [config, setConfigState] = useState<unknown>(null);
|
|
34
|
+
const [schema, setSchemaState] = useState<unknown>(null);
|
|
35
|
+
const [loading, setLoading] = useState(false);
|
|
36
|
+
const [error, setError] = useState<string | null>(null);
|
|
139
37
|
|
|
38
|
+
useEffect(() => wsManager.onConnectionChange(setConnected), [wsManager]);
|
|
39
|
+
|
|
40
|
+
const getConfig = useCallback(async () => {
|
|
41
|
+
setLoading(true);
|
|
42
|
+
setError(null);
|
|
140
43
|
try {
|
|
141
|
-
const result = await wsManager.
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
throw error
|
|
44
|
+
const result = await wsManager.getConfig(pluginName);
|
|
45
|
+
setConfigState(result);
|
|
46
|
+
return result;
|
|
47
|
+
} catch (e) {
|
|
48
|
+
setError(e instanceof Error ? e.message : "Unknown error");
|
|
49
|
+
throw e;
|
|
148
50
|
} finally {
|
|
149
|
-
|
|
150
|
-
}
|
|
151
|
-
}, [pluginName, wsManager
|
|
51
|
+
setLoading(false);
|
|
52
|
+
}
|
|
53
|
+
}, [pluginName, wsManager]);
|
|
54
|
+
|
|
55
|
+
const setConfig = useCallback(
|
|
56
|
+
async (newConfig: unknown) => {
|
|
57
|
+
setLoading(true);
|
|
58
|
+
setError(null);
|
|
59
|
+
try {
|
|
60
|
+
return await wsManager.setConfig(pluginName, newConfig);
|
|
61
|
+
} catch (e) {
|
|
62
|
+
setError(e instanceof Error ? e.message : "Unknown error");
|
|
63
|
+
throw e;
|
|
64
|
+
} finally {
|
|
65
|
+
setLoading(false);
|
|
66
|
+
}
|
|
67
|
+
},
|
|
68
|
+
[pluginName, wsManager],
|
|
69
|
+
);
|
|
152
70
|
|
|
153
71
|
const getSchema = useCallback(async () => {
|
|
154
72
|
try {
|
|
155
|
-
const result = await wsManager.getSchema(pluginName)
|
|
156
|
-
if (result)
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
} catch (error) {
|
|
161
|
-
console.error(`Failed to get schema for plugin ${pluginName}:`, error)
|
|
162
|
-
throw error
|
|
73
|
+
const result = await wsManager.getSchema(pluginName);
|
|
74
|
+
if (result) setSchemaState(result);
|
|
75
|
+
return result;
|
|
76
|
+
} catch (e) {
|
|
77
|
+
throw e;
|
|
163
78
|
}
|
|
164
|
-
}, [pluginName, wsManager
|
|
165
|
-
|
|
166
|
-
// 重新加载配置和 Schema
|
|
167
|
-
const reload = useCallback(async () => {
|
|
168
|
-
const promises = []
|
|
169
|
-
|
|
170
|
-
if (autoLoad) {
|
|
171
|
-
promises.push(getConfig())
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
if (autoLoadSchema) {
|
|
175
|
-
promises.push(getSchema())
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
await Promise.all(promises)
|
|
179
|
-
}, [autoLoad, autoLoadSchema, getConfig, getSchema])
|
|
79
|
+
}, [pluginName, wsManager]);
|
|
180
80
|
|
|
181
|
-
// 自动加载
|
|
182
81
|
useEffect(() => {
|
|
183
|
-
if (connected && autoLoad && !config && !loading) {
|
|
184
|
-
|
|
185
|
-
}
|
|
186
|
-
}, [connected, autoLoad, config, loading, getConfig])
|
|
82
|
+
if (connected && autoLoad && !config && !loading) getConfig().catch(() => {});
|
|
83
|
+
}, [connected, autoLoad, config, loading, getConfig]);
|
|
187
84
|
|
|
188
85
|
useEffect(() => {
|
|
189
|
-
if (connected && autoLoadSchema && !schema) {
|
|
190
|
-
|
|
191
|
-
}
|
|
192
|
-
}, [connected, autoLoadSchema, schema, getSchema])
|
|
193
|
-
|
|
194
|
-
return useMemo(() => ({
|
|
195
|
-
// 状态
|
|
196
|
-
config,
|
|
197
|
-
schema,
|
|
198
|
-
loading,
|
|
199
|
-
error,
|
|
200
|
-
connected,
|
|
201
|
-
|
|
202
|
-
// 方法
|
|
203
|
-
getConfig,
|
|
204
|
-
setConfig,
|
|
205
|
-
getSchema,
|
|
206
|
-
reload
|
|
207
|
-
}), [config, schema, loading, error, connected, getConfig, setConfig, getSchema, reload])
|
|
208
|
-
}
|
|
86
|
+
if (connected && autoLoadSchema && !schema) getSchema().catch(() => {});
|
|
87
|
+
}, [connected, autoLoadSchema, schema, getSchema]);
|
|
209
88
|
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
/**
|
|
215
|
-
* 所有配置管理 Hook
|
|
216
|
-
*/
|
|
217
|
-
export function useAllConfigs() {
|
|
218
|
-
const wsManager = getWebSocketManager()
|
|
219
|
-
|
|
220
|
-
const allConfigs = useSelector(selectAllConfigs)
|
|
221
|
-
const allSchemas = useSelector(selectAllSchemas)
|
|
222
|
-
const connected = useSelector(selectConfigConnected)
|
|
223
|
-
|
|
224
|
-
const refreshAll = useCallback(async () => {
|
|
225
|
-
try {
|
|
226
|
-
const [configs, schemas] = await Promise.all([
|
|
227
|
-
(wsManager as any).getAllConfigs(),
|
|
228
|
-
(wsManager as any).getAllSchemas()
|
|
229
|
-
])
|
|
230
|
-
|
|
231
|
-
return { configs, schemas }
|
|
232
|
-
} catch (error) {
|
|
233
|
-
console.error('Failed to refresh all configs:', error)
|
|
234
|
-
throw error
|
|
235
|
-
}
|
|
236
|
-
}, [wsManager])
|
|
237
|
-
|
|
238
|
-
return useMemo(() => ({
|
|
239
|
-
configs: allConfigs,
|
|
240
|
-
schemas: allSchemas,
|
|
241
|
-
connected,
|
|
242
|
-
refreshAll
|
|
243
|
-
}), [allConfigs, allSchemas, connected, refreshAll])
|
|
89
|
+
return useMemo(
|
|
90
|
+
() => ({ config, schema, loading, error, connected, getConfig, setConfig, getSchema }),
|
|
91
|
+
[config, schema, loading, error, connected, getConfig, setConfig, getSchema],
|
|
92
|
+
);
|
|
244
93
|
}
|
|
245
94
|
|
|
246
|
-
// ============================================================================
|
|
247
|
-
// 配置文件 YAML 读写 Hook
|
|
248
|
-
// ============================================================================
|
|
249
|
-
|
|
250
95
|
export function useConfigYaml() {
|
|
251
|
-
const wsManager = getWebSocketManager()
|
|
252
|
-
const connected =
|
|
96
|
+
const wsManager = getWebSocketManager();
|
|
97
|
+
const [connected, setConnected] = useState(wsManager.isConnected());
|
|
98
|
+
const [yaml, setYaml] = useState("");
|
|
99
|
+
const [pluginKeys, setPluginKeys] = useState<string[]>([]);
|
|
100
|
+
const [loading, setLoading] = useState(false);
|
|
101
|
+
const [error, setError] = useState<string | null>(null);
|
|
253
102
|
|
|
254
|
-
|
|
255
|
-
const [pluginKeys, setPluginKeys] = useState<string[]>([])
|
|
256
|
-
const [loading, setLoadingState] = useState(false)
|
|
257
|
-
const [error, setErrorState] = useState<string | null>(null)
|
|
103
|
+
useEffect(() => wsManager.onConnectionChange(setConnected), [wsManager]);
|
|
258
104
|
|
|
259
105
|
const load = useCallback(async () => {
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
try {
|
|
263
|
-
const result = await wsManager.getConfigYaml()
|
|
264
|
-
setYaml(result.yaml)
|
|
265
|
-
setPluginKeys(result.pluginKeys)
|
|
266
|
-
return result
|
|
267
|
-
} catch (err) {
|
|
268
|
-
const msg = err instanceof Error ? err.message : 'Unknown error'
|
|
269
|
-
setErrorState(msg)
|
|
270
|
-
throw err
|
|
271
|
-
} finally {
|
|
272
|
-
setLoadingState(false)
|
|
273
|
-
}
|
|
274
|
-
}, [wsManager])
|
|
275
|
-
|
|
276
|
-
const save = useCallback(async (content: string) => {
|
|
277
|
-
setLoadingState(true)
|
|
278
|
-
setErrorState(null)
|
|
106
|
+
setLoading(true);
|
|
107
|
+
setError(null);
|
|
279
108
|
try {
|
|
280
|
-
const result = await wsManager.
|
|
281
|
-
setYaml(
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
throw
|
|
109
|
+
const result = await wsManager.getConfigYaml();
|
|
110
|
+
setYaml(result.yaml);
|
|
111
|
+
setPluginKeys(result.pluginKeys);
|
|
112
|
+
return result;
|
|
113
|
+
} catch (e) {
|
|
114
|
+
setError(e instanceof Error ? e.message : "Unknown error");
|
|
115
|
+
throw e;
|
|
287
116
|
} finally {
|
|
288
|
-
|
|
289
|
-
}
|
|
290
|
-
}, [wsManager])
|
|
117
|
+
setLoading(false);
|
|
118
|
+
}
|
|
119
|
+
}, [wsManager]);
|
|
120
|
+
|
|
121
|
+
const save = useCallback(
|
|
122
|
+
async (content: string) => {
|
|
123
|
+
setLoading(true);
|
|
124
|
+
setError(null);
|
|
125
|
+
try {
|
|
126
|
+
const result = await wsManager.saveConfigYaml(content);
|
|
127
|
+
setYaml(content);
|
|
128
|
+
return result;
|
|
129
|
+
} catch (e) {
|
|
130
|
+
setError(e instanceof Error ? e.message : "Unknown error");
|
|
131
|
+
throw e;
|
|
132
|
+
} finally {
|
|
133
|
+
setLoading(false);
|
|
134
|
+
}
|
|
135
|
+
},
|
|
136
|
+
[wsManager],
|
|
137
|
+
);
|
|
291
138
|
|
|
292
139
|
useEffect(() => {
|
|
293
|
-
if (connected && !yaml && !loading) {
|
|
294
|
-
|
|
295
|
-
}
|
|
296
|
-
}, [connected, yaml, loading, load])
|
|
140
|
+
if (connected && !yaml && !loading) load().catch(() => {});
|
|
141
|
+
}, [connected, yaml, loading, load]);
|
|
297
142
|
|
|
298
|
-
return useMemo(() => ({
|
|
299
|
-
yaml, pluginKeys, loading, error, load, save
|
|
300
|
-
}), [yaml, pluginKeys, loading, error, load, save])
|
|
143
|
+
return useMemo(() => ({ yaml, pluginKeys, loading, error, load, save }), [yaml, pluginKeys, loading, error, load, save]);
|
|
301
144
|
}
|
|
302
145
|
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
const
|
|
309
|
-
const connected = useSelector(selectConfigConnected)
|
|
146
|
+
export function useFiles() {
|
|
147
|
+
const wsManager = getWebSocketManager();
|
|
148
|
+
const [connected, setConnected] = useState(wsManager.isConnected());
|
|
149
|
+
const [tree, setTree] = useState<import("./types").FileTreeNode[]>([]);
|
|
150
|
+
const [loading, setLoading] = useState(false);
|
|
151
|
+
const [error, setError] = useState<string | null>(null);
|
|
310
152
|
|
|
311
|
-
|
|
312
|
-
const [loading, setLoadingState] = useState(false)
|
|
313
|
-
const [error, setErrorState] = useState<string | null>(null)
|
|
153
|
+
useEffect(() => wsManager.onConnectionChange(setConnected), [wsManager]);
|
|
314
154
|
|
|
315
|
-
const
|
|
316
|
-
|
|
317
|
-
|
|
155
|
+
const loadTree = useCallback(async () => {
|
|
156
|
+
setLoading(true);
|
|
157
|
+
setError(null);
|
|
318
158
|
try {
|
|
319
|
-
const result = await wsManager.
|
|
320
|
-
|
|
321
|
-
return result.
|
|
322
|
-
} catch (
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
throw err
|
|
159
|
+
const result = await wsManager.getFileTree();
|
|
160
|
+
setTree(result.tree);
|
|
161
|
+
return result.tree;
|
|
162
|
+
} catch (e) {
|
|
163
|
+
setError(e instanceof Error ? e.message : "Unknown error");
|
|
164
|
+
throw e;
|
|
326
165
|
} finally {
|
|
327
|
-
|
|
166
|
+
setLoading(false);
|
|
328
167
|
}
|
|
329
|
-
}, [wsManager])
|
|
168
|
+
}, [wsManager]);
|
|
330
169
|
|
|
331
|
-
const
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
const msg = err instanceof Error ? err.message : 'Unknown error'
|
|
337
|
-
setErrorState(msg)
|
|
338
|
-
throw err
|
|
339
|
-
}
|
|
340
|
-
}, [wsManager])
|
|
341
|
-
|
|
342
|
-
const saveFile = useCallback(async (filename: string, content: string) => {
|
|
343
|
-
setLoadingState(true)
|
|
344
|
-
setErrorState(null)
|
|
345
|
-
try {
|
|
346
|
-
return await wsManager.saveEnvFile(filename, content)
|
|
347
|
-
} catch (err) {
|
|
348
|
-
const msg = err instanceof Error ? err.message : 'Unknown error'
|
|
349
|
-
setErrorState(msg)
|
|
350
|
-
throw err
|
|
351
|
-
} finally {
|
|
352
|
-
setLoadingState(false)
|
|
353
|
-
}
|
|
354
|
-
}, [wsManager])
|
|
170
|
+
const readFile = useCallback(async (filePath: string) => (await wsManager.readFile(filePath)).content, [wsManager]);
|
|
171
|
+
const saveFile = useCallback(
|
|
172
|
+
async (filePath: string, content: string) => wsManager.saveFile(filePath, content),
|
|
173
|
+
[wsManager],
|
|
174
|
+
);
|
|
355
175
|
|
|
356
176
|
useEffect(() => {
|
|
357
|
-
if (connected &&
|
|
358
|
-
|
|
359
|
-
}
|
|
360
|
-
}, [connected, files.length, loading, listFiles])
|
|
177
|
+
if (connected && tree.length === 0 && !loading) loadTree().catch(() => {});
|
|
178
|
+
}, [connected, tree.length, loading, loadTree]);
|
|
361
179
|
|
|
362
|
-
return useMemo(() => ({
|
|
363
|
-
files, loading, error, listFiles, getFile, saveFile
|
|
364
|
-
}), [files, loading, error, listFiles, getFile, saveFile])
|
|
180
|
+
return useMemo(() => ({ tree, loading, error, loadTree, readFile, saveFile }), [tree, loading, error, loadTree, readFile, saveFile]);
|
|
365
181
|
}
|
|
366
182
|
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
const
|
|
373
|
-
const connected = useSelector(selectConfigConnected)
|
|
183
|
+
export function useEnvFiles() {
|
|
184
|
+
const wsManager = getWebSocketManager();
|
|
185
|
+
const [connected, setConnected] = useState(wsManager.isConnected());
|
|
186
|
+
const [files, setFiles] = useState<Array<{ name: string; exists: boolean }>>([]);
|
|
187
|
+
const [loading, setLoading] = useState(false);
|
|
188
|
+
const [error, setError] = useState<string | null>(null);
|
|
374
189
|
|
|
375
|
-
|
|
376
|
-
const [loading, setLoadingState] = useState(false)
|
|
377
|
-
const [error, setErrorState] = useState<string | null>(null)
|
|
190
|
+
useEffect(() => wsManager.onConnectionChange(setConnected), [wsManager]);
|
|
378
191
|
|
|
379
|
-
const
|
|
380
|
-
|
|
381
|
-
|
|
192
|
+
const listFiles = useCallback(async () => {
|
|
193
|
+
setLoading(true);
|
|
194
|
+
setError(null);
|
|
382
195
|
try {
|
|
383
|
-
const result = await wsManager.
|
|
384
|
-
|
|
385
|
-
return result.
|
|
386
|
-
} catch (
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
throw err
|
|
196
|
+
const result = await wsManager.getEnvList();
|
|
197
|
+
setFiles(result.files);
|
|
198
|
+
return result.files;
|
|
199
|
+
} catch (e) {
|
|
200
|
+
setError(e instanceof Error ? e.message : "Unknown error");
|
|
201
|
+
throw e;
|
|
390
202
|
} finally {
|
|
391
|
-
|
|
203
|
+
setLoading(false);
|
|
392
204
|
}
|
|
393
|
-
}, [wsManager])
|
|
205
|
+
}, [wsManager]);
|
|
394
206
|
|
|
395
|
-
const
|
|
396
|
-
|
|
397
|
-
const result = await wsManager.
|
|
398
|
-
return result.content
|
|
399
|
-
}
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
throw err
|
|
403
|
-
}
|
|
404
|
-
}, [wsManager])
|
|
207
|
+
const getFile = useCallback(
|
|
208
|
+
async (filename: string) => {
|
|
209
|
+
const result = await wsManager.getEnvFile(filename);
|
|
210
|
+
return result.content;
|
|
211
|
+
},
|
|
212
|
+
[wsManager],
|
|
213
|
+
);
|
|
405
214
|
|
|
406
|
-
const saveFile = useCallback(
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
return await wsManager.saveFile(filePath, content)
|
|
411
|
-
} catch (err) {
|
|
412
|
-
const msg = err instanceof Error ? err.message : 'Unknown error'
|
|
413
|
-
setErrorState(msg)
|
|
414
|
-
throw err
|
|
415
|
-
} finally {
|
|
416
|
-
setLoadingState(false)
|
|
417
|
-
}
|
|
418
|
-
}, [wsManager])
|
|
215
|
+
const saveFile = useCallback(
|
|
216
|
+
async (filename: string, content: string) => wsManager.saveEnvFile(filename, content),
|
|
217
|
+
[wsManager],
|
|
218
|
+
);
|
|
419
219
|
|
|
420
220
|
useEffect(() => {
|
|
421
|
-
if (connected &&
|
|
422
|
-
|
|
423
|
-
}
|
|
424
|
-
}, [connected, tree.length, loading, loadTree])
|
|
221
|
+
if (connected && files.length === 0 && !loading) listFiles().catch(() => {});
|
|
222
|
+
}, [connected, files.length, loading, listFiles]);
|
|
425
223
|
|
|
426
|
-
return useMemo(
|
|
427
|
-
|
|
428
|
-
|
|
224
|
+
return useMemo(
|
|
225
|
+
() => ({ files, loading, error, listFiles, getFile, saveFile }),
|
|
226
|
+
[files, loading, error, listFiles, getFile, saveFile],
|
|
227
|
+
);
|
|
429
228
|
}
|
|
430
229
|
|
|
431
|
-
// ============================================================================
|
|
432
|
-
// 数据库管理 Hook
|
|
433
|
-
// ============================================================================
|
|
434
|
-
|
|
435
230
|
export function useDatabase() {
|
|
436
|
-
const wsManager = getWebSocketManager()
|
|
437
|
-
const connected =
|
|
231
|
+
const wsManager = getWebSocketManager();
|
|
232
|
+
const [connected, setConnected] = useState(wsManager.isConnected());
|
|
233
|
+
const [info, setInfo] = useState<import("./types").DatabaseInfo | null>(null);
|
|
234
|
+
const [tables, setTables] = useState<import("./types").TableInfo[]>([]);
|
|
235
|
+
const [loading, setLoading] = useState(false);
|
|
236
|
+
const [error, setError] = useState<string | null>(null);
|
|
438
237
|
|
|
439
|
-
|
|
440
|
-
const [tables, setTables] = useState<TableInfo[]>([])
|
|
441
|
-
const [loading, setLoadingState] = useState(false)
|
|
442
|
-
const [error, setErrorState] = useState<string | null>(null)
|
|
238
|
+
useEffect(() => wsManager.onConnectionChange(setConnected), [wsManager]);
|
|
443
239
|
|
|
444
240
|
const loadInfo = useCallback(async () => {
|
|
445
|
-
|
|
446
|
-
setErrorState(null)
|
|
241
|
+
setLoading(true);
|
|
447
242
|
try {
|
|
448
|
-
const result = await wsManager.getDbInfo()
|
|
449
|
-
setInfo(result)
|
|
450
|
-
return result
|
|
451
|
-
} catch (
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
throw err
|
|
243
|
+
const result = await wsManager.getDbInfo();
|
|
244
|
+
setInfo(result);
|
|
245
|
+
return result;
|
|
246
|
+
} catch (e) {
|
|
247
|
+
setError(e instanceof Error ? e.message : "Unknown error");
|
|
248
|
+
throw e;
|
|
455
249
|
} finally {
|
|
456
|
-
|
|
250
|
+
setLoading(false);
|
|
457
251
|
}
|
|
458
|
-
}, [wsManager])
|
|
252
|
+
}, [wsManager]);
|
|
459
253
|
|
|
460
254
|
const loadTables = useCallback(async () => {
|
|
461
|
-
|
|
462
|
-
setErrorState(null)
|
|
255
|
+
setLoading(true);
|
|
463
256
|
try {
|
|
464
|
-
const result = await wsManager.getDbTables()
|
|
465
|
-
setTables(result.tables)
|
|
466
|
-
return result.tables
|
|
467
|
-
} catch (
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
throw err
|
|
257
|
+
const result = await wsManager.getDbTables();
|
|
258
|
+
setTables(result.tables);
|
|
259
|
+
return result.tables;
|
|
260
|
+
} catch (e) {
|
|
261
|
+
setError(e instanceof Error ? e.message : "Unknown error");
|
|
262
|
+
throw e;
|
|
471
263
|
} finally {
|
|
472
|
-
|
|
473
|
-
}
|
|
474
|
-
}, [wsManager])
|
|
475
|
-
|
|
476
|
-
const select = useCallback(async (table: string, page?: number, pageSize?: number, where?: any) => {
|
|
477
|
-
try {
|
|
478
|
-
return await wsManager.dbSelect(table, page, pageSize, where)
|
|
479
|
-
} catch (err) {
|
|
480
|
-
const msg = err instanceof Error ? err.message : 'Unknown error'
|
|
481
|
-
setErrorState(msg)
|
|
482
|
-
throw err
|
|
264
|
+
setLoading(false);
|
|
483
265
|
}
|
|
484
|
-
}, [wsManager])
|
|
266
|
+
}, [wsManager]);
|
|
485
267
|
|
|
486
|
-
const
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
const update = useCallback(async (table: string, row: any, where: any) => {
|
|
497
|
-
try {
|
|
498
|
-
return await wsManager.dbUpdate(table, row, where)
|
|
499
|
-
} catch (err) {
|
|
500
|
-
const msg = err instanceof Error ? err.message : 'Unknown error'
|
|
501
|
-
setErrorState(msg)
|
|
502
|
-
throw err
|
|
503
|
-
}
|
|
504
|
-
}, [wsManager])
|
|
505
|
-
|
|
506
|
-
const remove = useCallback(async (table: string, where: any) => {
|
|
507
|
-
try {
|
|
508
|
-
return await wsManager.dbDelete(table, where)
|
|
509
|
-
} catch (err) {
|
|
510
|
-
const msg = err instanceof Error ? err.message : 'Unknown error'
|
|
511
|
-
setErrorState(msg)
|
|
512
|
-
throw err
|
|
513
|
-
}
|
|
514
|
-
}, [wsManager])
|
|
515
|
-
|
|
516
|
-
const dropTable = useCallback(async (table: string) => {
|
|
517
|
-
try {
|
|
518
|
-
const result = await wsManager.dbDropTable(table)
|
|
519
|
-
await loadTables()
|
|
520
|
-
return result
|
|
521
|
-
} catch (err) {
|
|
522
|
-
const msg = err instanceof Error ? err.message : 'Unknown error'
|
|
523
|
-
setErrorState(msg)
|
|
524
|
-
throw err
|
|
525
|
-
}
|
|
526
|
-
}, [wsManager, loadTables])
|
|
527
|
-
|
|
528
|
-
const kvGet = useCallback(async (table: string, key: string) => {
|
|
529
|
-
try {
|
|
530
|
-
return await wsManager.kvGet(table, key)
|
|
531
|
-
} catch (err) {
|
|
532
|
-
const msg = err instanceof Error ? err.message : 'Unknown error'
|
|
533
|
-
setErrorState(msg)
|
|
534
|
-
throw err
|
|
535
|
-
}
|
|
536
|
-
}, [wsManager])
|
|
537
|
-
|
|
538
|
-
const kvSet = useCallback(async (table: string, key: string, value: any, ttl?: number) => {
|
|
539
|
-
try {
|
|
540
|
-
return await wsManager.kvSet(table, key, value, ttl)
|
|
541
|
-
} catch (err) {
|
|
542
|
-
const msg = err instanceof Error ? err.message : 'Unknown error'
|
|
543
|
-
setErrorState(msg)
|
|
544
|
-
throw err
|
|
545
|
-
}
|
|
546
|
-
}, [wsManager])
|
|
547
|
-
|
|
548
|
-
const kvDelete = useCallback(async (table: string, key: string) => {
|
|
549
|
-
try {
|
|
550
|
-
return await wsManager.kvDelete(table, key)
|
|
551
|
-
} catch (err) {
|
|
552
|
-
const msg = err instanceof Error ? err.message : 'Unknown error'
|
|
553
|
-
setErrorState(msg)
|
|
554
|
-
throw err
|
|
555
|
-
}
|
|
556
|
-
}, [wsManager])
|
|
557
|
-
|
|
558
|
-
const kvEntries = useCallback(async (table: string) => {
|
|
559
|
-
try {
|
|
560
|
-
return await wsManager.kvGetEntries(table)
|
|
561
|
-
} catch (err) {
|
|
562
|
-
const msg = err instanceof Error ? err.message : 'Unknown error'
|
|
563
|
-
setErrorState(msg)
|
|
564
|
-
throw err
|
|
565
|
-
}
|
|
566
|
-
}, [wsManager])
|
|
268
|
+
const select = useCallback(async (table: string, page?: number, pageSize?: number, where?: unknown) => wsManager.dbSelect(table, page, pageSize, where), [wsManager]);
|
|
269
|
+
const insert = useCallback(async (table: string, row: unknown) => wsManager.dbInsert(table, row), [wsManager]);
|
|
270
|
+
const update = useCallback(async (table: string, row: unknown, where: unknown) => wsManager.dbUpdate(table, row, where), [wsManager]);
|
|
271
|
+
const remove = useCallback(async (table: string, where: unknown) => wsManager.dbDelete(table, where), [wsManager]);
|
|
272
|
+
const dropTable = useCallback(async (table: string) => { const r = await wsManager.dbDropTable(table); await loadTables(); return r; }, [wsManager, loadTables]);
|
|
273
|
+
const kvGet = useCallback(async (table: string, key: string) => wsManager.kvGet(table, key), [wsManager]);
|
|
274
|
+
const kvSet = useCallback(async (table: string, key: string, value: unknown, ttl?: number) => wsManager.kvSet(table, key, value, ttl), [wsManager]);
|
|
275
|
+
const kvDelete = useCallback(async (table: string, key: string) => wsManager.kvDelete(table, key), [wsManager]);
|
|
276
|
+
const kvEntries = useCallback(async (table: string) => wsManager.kvGetEntries(table), [wsManager]);
|
|
567
277
|
|
|
568
278
|
useEffect(() => {
|
|
569
279
|
if (connected && !info && !loading) {
|
|
570
|
-
loadInfo().catch(() => {})
|
|
571
|
-
loadTables().catch(() => {})
|
|
280
|
+
loadInfo().catch(() => {});
|
|
281
|
+
loadTables().catch(() => {});
|
|
572
282
|
}
|
|
573
|
-
}, [connected, info, loading, loadInfo, loadTables])
|
|
574
|
-
|
|
575
|
-
return useMemo(
|
|
576
|
-
info, tables, loading, error,
|
|
577
|
-
loadInfo, loadTables, dropTable,
|
|
578
|
-
|
|
579
|
-
kvGet, kvSet, kvDelete, kvEntries,
|
|
580
|
-
}), [info, tables, loading, error, loadInfo, loadTables, dropTable, select, insert, update, remove, kvGet, kvSet, kvDelete, kvEntries])
|
|
283
|
+
}, [connected, info, loading, loadInfo, loadTables]);
|
|
284
|
+
|
|
285
|
+
return useMemo(
|
|
286
|
+
() => ({ info, tables, loading, error, loadInfo, loadTables, dropTable, select, insert, update, remove, kvGet, kvSet, kvDelete, kvEntries }),
|
|
287
|
+
[info, tables, loading, error, loadInfo, loadTables, dropTable, select, insert, update, remove, kvGet, kvSet, kvDelete, kvEntries],
|
|
288
|
+
);
|
|
581
289
|
}
|