@u-devtools/core 0.1.6 → 0.2.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/LICENSE +1 -2
- package/README.md +50 -8
- package/dist/index.cjs.js +46 -1
- package/dist/index.d.ts +871 -64
- package/dist/index.es.js +3113 -56
- package/dist/vite/vite.config.base.cjs.js +1 -0
- package/dist/vite/vite.config.base.d.ts +59 -0
- package/dist/vite/vite.config.base.js +91 -0
- package/dist/vite.config.base.d.ts +42 -0
- package/package.json +25 -18
- package/src/bridge-app.ts +198 -51
- package/src/control.ts +23 -52
- package/src/event-bus.ts +126 -0
- package/src/index.ts +476 -44
- package/src/schemas/rpc.ts +36 -0
- package/src/schemas/settings.ts +125 -0
- package/src/transport.ts +172 -0
- package/src/transports/broadcast-transport.ts +174 -0
- package/src/transports/hmr-transport.ts +82 -0
- package/src/transports/websocket-transport.ts +158 -0
- package/vite/vite.config.base.ts +81 -14
- package/vite/clean-timestamp-plugin.ts +0 -28
package/dist/index.d.ts
CHANGED
|
@@ -1,46 +1,209 @@
|
|
|
1
1
|
import { PluginOption } from 'vite';
|
|
2
|
+
import { z } from 'zod';
|
|
2
3
|
|
|
3
4
|
/**
|
|
4
|
-
* AppBridge
|
|
5
|
-
*
|
|
5
|
+
* AppBridge - Typed communication bridge between App context (main window) and Client context (DevTools iframe).
|
|
6
|
+
*
|
|
7
|
+
* Communication: App ↔ Client via BroadcastChannel API
|
|
8
|
+
*
|
|
9
|
+
* Provides type-safe event-based communication with automatic state synchronization.
|
|
10
|
+
*
|
|
11
|
+
* @template Protocol - Type definition for events and their handlers
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```typescript
|
|
15
|
+
* import { AppBridge } from '@u-devtools/core';
|
|
16
|
+
*
|
|
17
|
+
* // Define protocol for type-safe communication
|
|
18
|
+
* interface MyPluginProtocol {
|
|
19
|
+
* 'element-selected': (data: { id: string; html: string }) => void;
|
|
20
|
+
* 'toggle-inspector': (data: { state: boolean }) => void;
|
|
21
|
+
* }
|
|
22
|
+
*
|
|
23
|
+
* const typedBridge = new AppBridge<MyPluginProtocol>('my-plugin');
|
|
24
|
+
*
|
|
25
|
+
* // Send events (type-safe)
|
|
26
|
+
* typedBridge.send('element-selected', { id: 'el-1', html: '<div>...</div>' });
|
|
27
|
+
*
|
|
28
|
+
* // Listen to events (type-safe)
|
|
29
|
+
* typedBridge.on('toggle-inspector', ({ state }) => {
|
|
30
|
+
* // state is automatically typed as { state: boolean }
|
|
31
|
+
* console.log('Inspector toggled:', state);
|
|
32
|
+
* });
|
|
33
|
+
*
|
|
34
|
+
* // Create synced state
|
|
35
|
+
* const selectedElement = typedBridge.state<HTMLElement | null>('selectedElement', null);
|
|
36
|
+
* selectedElement.value = document.getElementById('my-element');
|
|
37
|
+
* ```
|
|
6
38
|
*/
|
|
7
|
-
export declare class AppBridge {
|
|
39
|
+
export declare class AppBridge<Protocol = Record<string, (...args: any[]) => any>> {
|
|
40
|
+
private transport;
|
|
8
41
|
namespace: string;
|
|
42
|
+
displayName: string;
|
|
43
|
+
constructor(namespace: string);
|
|
44
|
+
send<K extends keyof Protocol>(event: K, ...args: Protocol[K] extends (...args: infer P) => any ? P : []): void;
|
|
45
|
+
on<K extends keyof Protocol>(event: K, cb: Protocol[K] extends (...args: any[]) => any ? (data: Parameters<Protocol[K]>[0]) => void : never): () => void;
|
|
46
|
+
request<RequestData, ResponseData>(requestEvent: string, requestData: RequestData, responseEvent: string, timeout?: number, responseFilter?: (request: RequestData, response: ResponseData) => boolean): Promise<ResponseData>;
|
|
47
|
+
close(): void;
|
|
48
|
+
state<T>(key: string, initialValue: T): SyncedState<T>;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Transport based on BroadcastChannel
|
|
53
|
+
* Used for communication between App (window) and Client (iframe)
|
|
54
|
+
* Does not support RPC (call), only events (send/on)
|
|
55
|
+
*/
|
|
56
|
+
export declare class BroadcastTransport extends Transport {
|
|
9
57
|
private channel;
|
|
10
|
-
private
|
|
58
|
+
private messageHandler?;
|
|
59
|
+
private namespace;
|
|
11
60
|
constructor(namespace: string);
|
|
12
61
|
/**
|
|
13
|
-
*
|
|
62
|
+
* Extract values from Vue reactive objects (ref, computed, reactive)
|
|
63
|
+
*/
|
|
64
|
+
private unwrapVueReactive;
|
|
65
|
+
/**
|
|
66
|
+
* Send event (not RPC)
|
|
14
67
|
*/
|
|
15
68
|
send(event: string, data?: unknown): void;
|
|
16
69
|
/**
|
|
17
|
-
*
|
|
70
|
+
* RPC calls are not supported in BroadcastChannel
|
|
71
|
+
*/
|
|
72
|
+
call<T = unknown>(_method: string, _payload?: unknown): Promise<T>;
|
|
73
|
+
protected sendMessage(_type: string, _data: unknown): void;
|
|
74
|
+
protected subscribe(event: string, handler: (data: unknown) => void): () => void;
|
|
75
|
+
protected unsubscribe(event: string, handler: (data: unknown) => void): void;
|
|
76
|
+
dispose(): void;
|
|
77
|
+
/**
|
|
78
|
+
* Close channel (alias for dispose)
|
|
18
79
|
*/
|
|
19
|
-
on<T = unknown>(event: string, cb: (data: T) => void): () => void;
|
|
20
80
|
close(): void;
|
|
21
81
|
}
|
|
22
82
|
|
|
83
|
+
/**
|
|
84
|
+
* Typed Event Bus for inter-plugin communication
|
|
85
|
+
*/
|
|
86
|
+
/**
|
|
87
|
+
* EventBus events interface.
|
|
88
|
+
* Plugins can extend this interface through module augmentation.
|
|
89
|
+
*
|
|
90
|
+
* @example
|
|
91
|
+
* ```typescript
|
|
92
|
+
* // In your plugin
|
|
93
|
+
* declare module '@u-devtools/core' {
|
|
94
|
+
* interface BusEvents {
|
|
95
|
+
* 'my-plugin:custom-event': { data: string };
|
|
96
|
+
* }
|
|
97
|
+
* }
|
|
98
|
+
* ```
|
|
99
|
+
*/
|
|
100
|
+
export declare interface BusEvents {
|
|
101
|
+
'plugin:mounted': {
|
|
102
|
+
name: string;
|
|
103
|
+
};
|
|
104
|
+
'plugin:unmounted': {
|
|
105
|
+
name: string;
|
|
106
|
+
};
|
|
107
|
+
navigate: {
|
|
108
|
+
path: string;
|
|
109
|
+
};
|
|
110
|
+
'settings:changed': {
|
|
111
|
+
key: string;
|
|
112
|
+
value: unknown;
|
|
113
|
+
};
|
|
114
|
+
'storage:changed': {
|
|
115
|
+
key: string;
|
|
116
|
+
value: unknown;
|
|
117
|
+
};
|
|
118
|
+
[key: string]: unknown;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Client API - Main API object provided to plugins in Client context.
|
|
123
|
+
* Provides access to all DevTools services: RPC, storage, settings, notifications, etc.
|
|
124
|
+
*
|
|
125
|
+
* Available in: Client context (Vue 3 iframe)
|
|
126
|
+
*
|
|
127
|
+
* @example
|
|
128
|
+
* ```typescript
|
|
129
|
+
* import type { PluginClientInstance } from '@u-devtools/core';
|
|
130
|
+
*
|
|
131
|
+
* const plugin: PluginClientInstance = {
|
|
132
|
+
* name: 'My Plugin',
|
|
133
|
+
* icon: 'Cube',
|
|
134
|
+
*
|
|
135
|
+
* renderMain(container, api) {
|
|
136
|
+
* // Use api.storage for plugin state
|
|
137
|
+
* api.storage.set('lastView', 'list');
|
|
138
|
+
* const lastView = api.storage.get('lastView', 'default');
|
|
139
|
+
*
|
|
140
|
+
* // Use api.settings for user preferences
|
|
141
|
+
* api.settings.set('fontSize', 16);
|
|
142
|
+
* const fontSize = api.settings.get('fontSize', 14);
|
|
143
|
+
*
|
|
144
|
+
* // Navigation
|
|
145
|
+
* api.navigation.openPlugin('other-plugin');
|
|
146
|
+
*
|
|
147
|
+
* // Event bus
|
|
148
|
+
* api.bus.on('other-plugin:event', (data) => {
|
|
149
|
+
* console.log('Received event:', data);
|
|
150
|
+
* });
|
|
151
|
+
* api.bus.emit('my-plugin:event', { data: 'value' });
|
|
152
|
+
*
|
|
153
|
+
* // Async operations (use async IIFE for await)
|
|
154
|
+
* (async () => {
|
|
155
|
+
* // Use api.rpc to call server methods
|
|
156
|
+
* const data = await api.rpc.call('my-plugin:getData');
|
|
157
|
+
*
|
|
158
|
+
* // Notifications
|
|
159
|
+
* api.notify('Data saved successfully', 'success');
|
|
160
|
+
*
|
|
161
|
+
* // Clipboard
|
|
162
|
+
* await api.clipboard.copy('text to copy');
|
|
163
|
+
*
|
|
164
|
+
* // Dialog
|
|
165
|
+
* const confirmed = await api.dialog.confirm({
|
|
166
|
+
* title: 'Confirm',
|
|
167
|
+
* message: 'Are you sure?',
|
|
168
|
+
* });
|
|
169
|
+
* })();
|
|
170
|
+
*
|
|
171
|
+
* return () => {}; // Cleanup function
|
|
172
|
+
* }
|
|
173
|
+
* };
|
|
174
|
+
* ```
|
|
175
|
+
*/
|
|
23
176
|
export declare interface ClientApi {
|
|
177
|
+
/** RPC client for calling server methods */
|
|
24
178
|
rpc: RpcClientInterface;
|
|
179
|
+
/** Show a notification to the user */
|
|
25
180
|
notify: (msg: string, type?: 'info' | 'error' | 'success') => void;
|
|
181
|
+
/** Storage API for plugin-specific persistent state (e.g., last opened file) */
|
|
26
182
|
storage: StorageApi;
|
|
183
|
+
/** Settings API for user-configurable preferences (e.g., font size, theme) */
|
|
27
184
|
settings: SettingsApi;
|
|
185
|
+
/** Keyboard shortcuts API */
|
|
28
186
|
shortcuts: ShortcutApi;
|
|
187
|
+
/** Clipboard operations API */
|
|
29
188
|
clipboard: ClipboardApi;
|
|
189
|
+
/** Event bus for plugin-to-plugin communication */
|
|
30
190
|
bus: EventBusApi;
|
|
191
|
+
/** Dialog API for confirmations and prompts */
|
|
31
192
|
dialog: DialogApi;
|
|
193
|
+
/** Navigation API for switching between plugins */
|
|
194
|
+
navigation: NavigationApi;
|
|
32
195
|
}
|
|
33
196
|
|
|
34
197
|
export declare interface ClipboardApi {
|
|
35
198
|
/**
|
|
36
|
-
*
|
|
37
|
-
* @param text
|
|
38
|
-
* @param successMessage
|
|
199
|
+
* Copy text to clipboard.
|
|
200
|
+
* @param text Text to copy
|
|
201
|
+
* @param successMessage Success message (optional)
|
|
39
202
|
*/
|
|
40
203
|
copy(text: string, successMessage?: string): Promise<void>;
|
|
41
204
|
/**
|
|
42
|
-
*
|
|
43
|
-
* @returns
|
|
205
|
+
* Read text from clipboard.
|
|
206
|
+
* @returns Text from clipboard or empty string on error
|
|
44
207
|
*/
|
|
45
208
|
read(): Promise<string>;
|
|
46
209
|
}
|
|
@@ -51,54 +214,83 @@ export declare class DevToolsControl {
|
|
|
51
214
|
private channel;
|
|
52
215
|
constructor();
|
|
53
216
|
/**
|
|
54
|
-
*
|
|
217
|
+
* Open DevTools
|
|
55
218
|
*/
|
|
56
219
|
open(): void;
|
|
57
220
|
/**
|
|
58
|
-
*
|
|
221
|
+
* Close DevTools
|
|
59
222
|
*/
|
|
60
223
|
close(): void;
|
|
61
224
|
/**
|
|
62
|
-
*
|
|
225
|
+
* Toggle state
|
|
63
226
|
*/
|
|
64
227
|
toggle(): void;
|
|
65
228
|
/**
|
|
66
|
-
*
|
|
229
|
+
* Get current state (asynchronously)
|
|
67
230
|
*/
|
|
68
231
|
isOpen(): Promise<boolean>;
|
|
69
232
|
/**
|
|
70
|
-
*
|
|
233
|
+
* Subscribe to state changes
|
|
71
234
|
*/
|
|
72
235
|
onStateChange(cb: (isOpen: boolean) => void): () => void;
|
|
73
236
|
/**
|
|
74
|
-
*
|
|
237
|
+
* Switch to plugin by name
|
|
75
238
|
*/
|
|
76
239
|
switchPlugin(pluginName: string): void;
|
|
77
240
|
/**
|
|
78
|
-
*
|
|
241
|
+
* Switch tab within plugin by tab name
|
|
79
242
|
*/
|
|
80
243
|
switchTab(pluginName: string, tabName: string): void;
|
|
81
244
|
destroy(): void;
|
|
82
245
|
}
|
|
83
246
|
|
|
247
|
+
/**
|
|
248
|
+
* DevTools Plugin Definition - Server-side plugin configuration.
|
|
249
|
+
* Defines a plugin's structure and entry points for all three execution contexts.
|
|
250
|
+
*
|
|
251
|
+
* Created using definePlugin() helper from @u-devtools/kit/define-plugin.
|
|
252
|
+
*
|
|
253
|
+
* @example
|
|
254
|
+
* ```ts
|
|
255
|
+
* import { definePlugin } from '@u-devtools/kit/define-plugin';
|
|
256
|
+
*
|
|
257
|
+
* export default definePlugin({
|
|
258
|
+
* name: 'My Plugin',
|
|
259
|
+
* root: import.meta.url,
|
|
260
|
+
* client: './client',
|
|
261
|
+
* app: './app',
|
|
262
|
+
* server: './server',
|
|
263
|
+
* });
|
|
264
|
+
* ```
|
|
265
|
+
*/
|
|
84
266
|
export declare interface DevToolsPlugin {
|
|
267
|
+
/** Display name of the plugin */
|
|
85
268
|
name: string;
|
|
269
|
+
/** Absolute path to client.ts file (Client context) */
|
|
86
270
|
clientPath?: string;
|
|
271
|
+
/** Absolute path to app.ts file (App context - main window) */
|
|
87
272
|
appPath?: string;
|
|
273
|
+
/**
|
|
274
|
+
* Server-side setup function (Server context - Node.js).
|
|
275
|
+
* Called when plugin is loaded to register RPC handlers.
|
|
276
|
+
* @param rpc - RPC server interface for handling requests
|
|
277
|
+
* @param ctx - Server context with root path and Vite server instance
|
|
278
|
+
*/
|
|
88
279
|
setupServer?: (rpc: RpcServerInterface, ctx: ServerContext) => void;
|
|
280
|
+
/** Plugin metadata (name, version, description, etc.) */
|
|
89
281
|
meta?: PluginMetadata;
|
|
90
282
|
/**
|
|
91
|
-
* Optional Vite plugins to be
|
|
92
|
-
* These plugins will be
|
|
283
|
+
* Optional Vite plugins to be merged with the main DevTools plugin.
|
|
284
|
+
* These plugins will be added to the Vite configuration.
|
|
93
285
|
*/
|
|
94
286
|
vitePlugins?: (() => PluginOption | PluginOption[])[];
|
|
95
287
|
}
|
|
96
288
|
|
|
97
289
|
export declare interface DialogApi {
|
|
98
290
|
/**
|
|
99
|
-
*
|
|
100
|
-
* @param options
|
|
101
|
-
* @returns Promise
|
|
291
|
+
* Show a confirmation dialog.
|
|
292
|
+
* @param options Dialog options
|
|
293
|
+
* @returns Promise with result (true if confirmed)
|
|
102
294
|
*/
|
|
103
295
|
confirm(options: {
|
|
104
296
|
title: string;
|
|
@@ -107,9 +299,9 @@ export declare interface DialogApi {
|
|
|
107
299
|
cancelText?: string;
|
|
108
300
|
}): Promise<boolean>;
|
|
109
301
|
/**
|
|
110
|
-
*
|
|
111
|
-
* @param options
|
|
112
|
-
* @returns Promise
|
|
302
|
+
* Show an input dialog.
|
|
303
|
+
* @param options Dialog options
|
|
304
|
+
* @returns Promise with entered text or null if cancelled
|
|
113
305
|
*/
|
|
114
306
|
prompt(options: {
|
|
115
307
|
title: string;
|
|
@@ -120,26 +312,85 @@ export declare interface DialogApi {
|
|
|
120
312
|
|
|
121
313
|
export declare interface EventBusApi {
|
|
122
314
|
/**
|
|
123
|
-
*
|
|
124
|
-
* @param event
|
|
125
|
-
* @param data
|
|
315
|
+
* Emit an event.
|
|
316
|
+
* @param event Event name
|
|
317
|
+
* @param data Event data
|
|
126
318
|
*/
|
|
127
319
|
emit(event: string, data?: unknown): void;
|
|
128
320
|
/**
|
|
129
|
-
*
|
|
130
|
-
* @param event
|
|
131
|
-
* @param handler
|
|
132
|
-
* @returns
|
|
321
|
+
* Subscribe to an event.
|
|
322
|
+
* @param event Event name
|
|
323
|
+
* @param handler Event handler
|
|
324
|
+
* @returns Function to unsubscribe
|
|
133
325
|
*/
|
|
134
326
|
on(event: string, handler: (data: unknown) => void): () => void;
|
|
135
327
|
/**
|
|
136
|
-
*
|
|
137
|
-
* @param event
|
|
138
|
-
* @param handler
|
|
328
|
+
* Unsubscribe from an event.
|
|
329
|
+
* @param event Event name
|
|
330
|
+
* @param handler Event handler
|
|
139
331
|
*/
|
|
140
332
|
off(event: string, handler: (data: unknown) => void): void;
|
|
141
333
|
}
|
|
142
334
|
|
|
335
|
+
/**
|
|
336
|
+
* Menu item for the "General" section in ActivityBar.
|
|
337
|
+
*
|
|
338
|
+
* Allows plugins to add their actions to the general menu, even if the plugin
|
|
339
|
+
* itself is hidden from the main ActivityBar menu.
|
|
340
|
+
*
|
|
341
|
+
* @example
|
|
342
|
+
* ```ts
|
|
343
|
+
* const plugin: PluginClientInstance = {
|
|
344
|
+
* name: 'Plugins',
|
|
345
|
+
* icon: 'Squares2X2',
|
|
346
|
+
* hideFromMenu: true,
|
|
347
|
+
* generalMenuItems: [
|
|
348
|
+
* {
|
|
349
|
+
* label: 'Extensions',
|
|
350
|
+
* icon: 'Squares2X2',
|
|
351
|
+
* action: (api) => {
|
|
352
|
+
* api.navigation.openPlugin('Plugins');
|
|
353
|
+
* }
|
|
354
|
+
* }
|
|
355
|
+
* ]
|
|
356
|
+
* };
|
|
357
|
+
* ```
|
|
358
|
+
*/
|
|
359
|
+
export declare interface GeneralMenuItem {
|
|
360
|
+
/** Menu item label text */
|
|
361
|
+
label: string;
|
|
362
|
+
/** Heroicons icon name (e.g., 'Cube', 'MagnifyingGlass') */
|
|
363
|
+
icon: string;
|
|
364
|
+
/**
|
|
365
|
+
* Action callback when menu item is clicked.
|
|
366
|
+
* @param api - Client API for interacting with DevTools
|
|
367
|
+
*/
|
|
368
|
+
action: (api: ClientApi) => void;
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
/**
|
|
372
|
+
* Transport based on Vite HMR (Hot Module Replacement)
|
|
373
|
+
* Used for communication between client (iframe) and server (Node.js)
|
|
374
|
+
*/
|
|
375
|
+
export declare class HmrTransport extends Transport {
|
|
376
|
+
private hot;
|
|
377
|
+
private responseHandler?;
|
|
378
|
+
private eventHandler?;
|
|
379
|
+
constructor(hot: {
|
|
380
|
+
send: (event: string, data: unknown) => void;
|
|
381
|
+
on: (event: string, handler: (data: unknown) => void) => void;
|
|
382
|
+
off?: (event: string, handler: (data: unknown) => void) => void;
|
|
383
|
+
});
|
|
384
|
+
/**
|
|
385
|
+
* Override on() for HMR, as subscription is already set up in constructor
|
|
386
|
+
*/
|
|
387
|
+
on(event: string, fn: (data: unknown) => void): () => void;
|
|
388
|
+
protected sendMessage(type: string, data: unknown): void;
|
|
389
|
+
protected subscribe(_type: string, _handler: (data: unknown) => void): () => void;
|
|
390
|
+
protected unsubscribe(_type: string, _handler: (data: unknown) => void): void;
|
|
391
|
+
dispose(): void;
|
|
392
|
+
}
|
|
393
|
+
|
|
143
394
|
export declare interface InspectorEvent {
|
|
144
395
|
type: 'element-selected';
|
|
145
396
|
data: {
|
|
@@ -154,36 +405,41 @@ export declare interface InspectorEvent {
|
|
|
154
405
|
};
|
|
155
406
|
}
|
|
156
407
|
|
|
157
|
-
export declare
|
|
408
|
+
export declare interface NavigationApi {
|
|
409
|
+
/**
|
|
410
|
+
* Switch active plugin
|
|
411
|
+
*/
|
|
412
|
+
openPlugin(pluginName: string): void;
|
|
413
|
+
}
|
|
158
414
|
|
|
159
415
|
export declare interface OverlayContext {
|
|
160
416
|
/**
|
|
161
|
-
*
|
|
417
|
+
* Open the main DevTools window
|
|
162
418
|
*/
|
|
163
419
|
open: () => void;
|
|
164
420
|
/**
|
|
165
|
-
*
|
|
421
|
+
* Close the main DevTools window
|
|
166
422
|
*/
|
|
167
423
|
close: () => void;
|
|
168
424
|
/**
|
|
169
|
-
*
|
|
425
|
+
* Toggle window state
|
|
170
426
|
*/
|
|
171
427
|
toggle: () => void;
|
|
172
428
|
/**
|
|
173
|
-
*
|
|
429
|
+
* Current state
|
|
174
430
|
*/
|
|
175
431
|
isOpen: boolean;
|
|
176
432
|
/**
|
|
177
|
-
*
|
|
433
|
+
* Switch to plugin by name
|
|
178
434
|
*/
|
|
179
435
|
switchPlugin: (pluginName: string) => void;
|
|
180
436
|
/**
|
|
181
|
-
*
|
|
437
|
+
* Switch tab within plugin by tab name
|
|
182
438
|
*/
|
|
183
439
|
switchTab: (pluginName: string, tabName: string) => void;
|
|
184
440
|
/**
|
|
185
|
-
*
|
|
186
|
-
*
|
|
441
|
+
* Create a temporary bridge for sending messages.
|
|
442
|
+
* Useful if you don't have access to the plugin's global bridge in this scope.
|
|
187
443
|
*/
|
|
188
444
|
createBridge: (namespace: string) => AppBridge;
|
|
189
445
|
}
|
|
@@ -196,7 +452,7 @@ export declare interface OverlayMenuItem {
|
|
|
196
452
|
iconUrl?: string;
|
|
197
453
|
order?: number;
|
|
198
454
|
/**
|
|
199
|
-
*
|
|
455
|
+
* Event handlers (receive context)
|
|
200
456
|
*/
|
|
201
457
|
onClick?: (ctx: OverlayContext, event: MouseEvent) => void;
|
|
202
458
|
onDoubleClick?: (ctx: OverlayContext, event: MouseEvent) => void;
|
|
@@ -211,21 +467,95 @@ export declare interface OverlayMenuItem {
|
|
|
211
467
|
onBlur?: (ctx: OverlayContext, event: FocusEvent) => void;
|
|
212
468
|
}
|
|
213
469
|
|
|
470
|
+
/**
|
|
471
|
+
* Plugin Client Instance - Definition of a plugin's UI and behavior in Client context.
|
|
472
|
+
* This is the main export from a plugin's client.ts file.
|
|
473
|
+
*
|
|
474
|
+
* @example
|
|
475
|
+
* ```ts
|
|
476
|
+
* import type { PluginClientInstance } from '@u-devtools/core';
|
|
477
|
+
*
|
|
478
|
+
* const plugin: PluginClientInstance = {
|
|
479
|
+
* name: 'My Plugin',
|
|
480
|
+
* icon: 'Cube',
|
|
481
|
+
* settings: { },
|
|
482
|
+
* commands: [ ],
|
|
483
|
+
* renderMain(container, api) {
|
|
484
|
+
* // Render your plugin UI
|
|
485
|
+
* return () => { };
|
|
486
|
+
* }
|
|
487
|
+
* };
|
|
488
|
+
*
|
|
489
|
+
* export default plugin;
|
|
490
|
+
* ```
|
|
491
|
+
*/
|
|
214
492
|
export declare interface PluginClientInstance {
|
|
493
|
+
/** Display name shown in DevTools UI */
|
|
215
494
|
name: string;
|
|
495
|
+
/** Heroicons icon name (e.g., 'Cube', 'MagnifyingGlass', 'WrenchScrewdriver') */
|
|
216
496
|
icon: string;
|
|
497
|
+
/**
|
|
498
|
+
* Hide plugin from main ActivityBar menu.
|
|
499
|
+
* Plugin will still be accessible via navigation API or generalMenuItems.
|
|
500
|
+
*/
|
|
501
|
+
hideFromMenu?: boolean;
|
|
502
|
+
/** Settings schema for user-configurable options */
|
|
217
503
|
settings?: PluginSettingsSchema;
|
|
504
|
+
/** Commands accessible via Command Palette (Cmd+K / Ctrl+K) */
|
|
218
505
|
commands?: PluginCommand[];
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
506
|
+
/**
|
|
507
|
+
* Menu items for the "General" section in ActivityBar.
|
|
508
|
+
* Allows plugins to add their actions to the general menu.
|
|
509
|
+
*/
|
|
510
|
+
generalMenuItems?: GeneralMenuItem[];
|
|
511
|
+
/**
|
|
512
|
+
* Render sidebar panel (optional).
|
|
513
|
+
* @param el - Container element to render into
|
|
514
|
+
* @param api - Client API for plugin functionality
|
|
515
|
+
* @param options - Additional options including AppBridge
|
|
516
|
+
* @returns Cleanup function called when plugin is unmounted
|
|
517
|
+
*/
|
|
518
|
+
renderSidebar?: (el: HTMLElement, api: ClientApi, options: {
|
|
519
|
+
bridge: AppBridge<any>;
|
|
520
|
+
}) => UnmountFn;
|
|
521
|
+
/**
|
|
522
|
+
* Render main panel (optional).
|
|
523
|
+
* This is the primary UI for your plugin.
|
|
524
|
+
* @param el - Container element to render into
|
|
525
|
+
* @param api - Client API for plugin functionality
|
|
526
|
+
* @param options - Additional options including AppBridge
|
|
527
|
+
* @returns Cleanup function called when plugin is unmounted
|
|
528
|
+
*/
|
|
529
|
+
renderMain?: (el: HTMLElement, api: ClientApi, options: {
|
|
530
|
+
bridge: AppBridge<any>;
|
|
531
|
+
}) => UnmountFn;
|
|
532
|
+
/**
|
|
533
|
+
* Render custom settings UI (optional).
|
|
534
|
+
* If not provided, settings will use the default form based on settings schema.
|
|
535
|
+
* @param el - Container element to render into
|
|
536
|
+
* @param api - Client API for plugin functionality
|
|
537
|
+
* @param options - Additional options including AppBridge
|
|
538
|
+
* @returns Cleanup function called when plugin is unmounted
|
|
539
|
+
*/
|
|
540
|
+
renderSettings?: (el: HTMLElement, api: ClientApi, options: {
|
|
541
|
+
bridge: AppBridge<any>;
|
|
542
|
+
}) => UnmountFn;
|
|
222
543
|
}
|
|
223
544
|
|
|
545
|
+
/**
|
|
546
|
+
* Command definition for Command Palette (accessible via Cmd+K / Ctrl+K).
|
|
547
|
+
* Commands allow users to quickly access plugin functionality.
|
|
548
|
+
*/
|
|
224
549
|
export declare interface PluginCommand {
|
|
550
|
+
/** Unique command identifier (e.g., 'my-plugin:clear') */
|
|
225
551
|
id: string;
|
|
552
|
+
/** Display label in command palette */
|
|
226
553
|
label: string;
|
|
554
|
+
/** Heroicons icon name (optional) */
|
|
227
555
|
icon?: string;
|
|
556
|
+
/** Action to execute when command is triggered */
|
|
228
557
|
action: () => void | Promise<void>;
|
|
558
|
+
/** Keyboard shortcut keys (e.g., ['Meta', 'K', 'C']) */
|
|
229
559
|
shortcut?: string[];
|
|
230
560
|
}
|
|
231
561
|
|
|
@@ -235,92 +565,569 @@ export declare interface PluginMetadata {
|
|
|
235
565
|
description?: string;
|
|
236
566
|
author?: string;
|
|
237
567
|
homepage?: string;
|
|
238
|
-
|
|
568
|
+
repository?: string;
|
|
239
569
|
}
|
|
240
570
|
|
|
571
|
+
/**
|
|
572
|
+
* Plugin settings schema - defines all user-configurable settings for a plugin.
|
|
573
|
+
*
|
|
574
|
+
* Settings are automatically displayed in the DevTools settings panel and
|
|
575
|
+
* can be accessed via `api.settings.get()` and `api.settings.set()`.
|
|
576
|
+
*
|
|
577
|
+
* @example
|
|
578
|
+
* ```ts
|
|
579
|
+
* const plugin: PluginClientInstance = {
|
|
580
|
+
* name: 'My Plugin',
|
|
581
|
+
* icon: 'Cube',
|
|
582
|
+
* settings: {
|
|
583
|
+
* apiUrl: {
|
|
584
|
+
* label: 'API URL',
|
|
585
|
+
* type: 'string',
|
|
586
|
+
* default: 'https://api.example.com'
|
|
587
|
+
* },
|
|
588
|
+
* timeout: {
|
|
589
|
+
* label: 'Timeout (ms)',
|
|
590
|
+
* type: 'number',
|
|
591
|
+
* default: 5000
|
|
592
|
+
* }
|
|
593
|
+
* }
|
|
594
|
+
* };
|
|
595
|
+
* ```
|
|
596
|
+
*/
|
|
241
597
|
export declare interface PluginSettingsSchema {
|
|
242
598
|
[key: string]: SettingSchemaDef;
|
|
243
599
|
}
|
|
244
600
|
|
|
245
601
|
/**
|
|
246
|
-
*
|
|
602
|
+
* Zod schema for plugin settings schema (record of setting definitions).
|
|
603
|
+
*/
|
|
604
|
+
export declare const PluginSettingsSchemaSchema: z.ZodRecord<z.ZodString, z.ZodType<any, unknown, z.core.$ZodTypeInternals<any, unknown>>>;
|
|
605
|
+
|
|
606
|
+
/**
|
|
607
|
+
* Type inferred from PluginSettingsSchemaSchema
|
|
247
608
|
*/
|
|
248
|
-
export declare
|
|
609
|
+
export declare type PluginSettingsSchemaType = z.infer<typeof PluginSettingsSchemaSchema>;
|
|
249
610
|
|
|
611
|
+
/**
|
|
612
|
+
* RPC Client Interface for making remote procedure calls.
|
|
613
|
+
* Provides methods to call server methods and subscribe to events.
|
|
614
|
+
*
|
|
615
|
+
* Communication: Server ↔ Client via WebSocket (Vite HMR or custom WebSocket)
|
|
616
|
+
*/
|
|
250
617
|
export declare interface RpcClientInterface {
|
|
618
|
+
/**
|
|
619
|
+
* Call a remote method on the server.
|
|
620
|
+
* @param method - Method name (e.g., 'sys:getPlugins')
|
|
621
|
+
* @param payload - Optional payload data
|
|
622
|
+
* @returns Promise that resolves with the method result
|
|
623
|
+
* @template T - Return type of the method
|
|
624
|
+
*/
|
|
251
625
|
call<T = unknown>(method: string, payload?: unknown): Promise<T>;
|
|
626
|
+
/**
|
|
627
|
+
* Subscribe to events from the server.
|
|
628
|
+
* @param event - Event name
|
|
629
|
+
* @param callback - Callback function to handle events
|
|
630
|
+
* @returns Function to unsubscribe from the event
|
|
631
|
+
*/
|
|
252
632
|
on(event: string, callback: (data: unknown) => void): () => void;
|
|
633
|
+
/**
|
|
634
|
+
* Unsubscribe from events (optional, some transports may not support it).
|
|
635
|
+
* @param event - Event name
|
|
636
|
+
* @param callback - Callback function to remove
|
|
637
|
+
*/
|
|
253
638
|
off?(event: string, callback: (data: unknown) => void): void;
|
|
254
639
|
}
|
|
255
640
|
|
|
641
|
+
/**
|
|
642
|
+
* RPC message structure for communication between Server and Client contexts.
|
|
643
|
+
* Used for typed RPC over WebSocket (Server ↔ Client).
|
|
644
|
+
*
|
|
645
|
+
* @template T - Type of the payload data
|
|
646
|
+
*/
|
|
256
647
|
export declare interface RpcMessage<T = unknown> {
|
|
648
|
+
/** Unique message identifier */
|
|
257
649
|
id: string;
|
|
650
|
+
/** Message type: 'request' for RPC calls, 'response' for replies, 'event' for broadcasts */
|
|
258
651
|
type: 'request' | 'response' | 'event';
|
|
652
|
+
/** RPC method name (for requests) */
|
|
259
653
|
method?: string;
|
|
654
|
+
/** Message payload data */
|
|
260
655
|
payload?: T;
|
|
656
|
+
/** Error information (for error responses) */
|
|
261
657
|
error?: unknown;
|
|
262
658
|
}
|
|
263
659
|
|
|
660
|
+
/**
|
|
661
|
+
* Zod schema for RPC message validation.
|
|
662
|
+
* Validates the structure of RPC messages used for communication between Server and Client contexts.
|
|
663
|
+
*/
|
|
664
|
+
export declare const RpcMessageSchema: z.ZodObject<{
|
|
665
|
+
id: z.ZodString;
|
|
666
|
+
type: z.ZodEnum<{
|
|
667
|
+
request: "request";
|
|
668
|
+
response: "response";
|
|
669
|
+
event: "event";
|
|
670
|
+
}>;
|
|
671
|
+
method: z.ZodOptional<z.ZodString>;
|
|
672
|
+
payload: z.ZodOptional<z.ZodUnknown>;
|
|
673
|
+
error: z.ZodOptional<z.ZodUnknown>;
|
|
674
|
+
}, z.core.$strip>;
|
|
675
|
+
|
|
676
|
+
/**
|
|
677
|
+
* Type inferred from RpcMessageSchema
|
|
678
|
+
*/
|
|
679
|
+
export declare type RpcMessageType = z.infer<typeof RpcMessageSchema>;
|
|
680
|
+
|
|
681
|
+
/**
|
|
682
|
+
* RPC Server Interface - Interface for handling RPC requests from clients.
|
|
683
|
+
* Used in server-side plugin setup to register method handlers.
|
|
684
|
+
*
|
|
685
|
+
* @example
|
|
686
|
+
* ```ts
|
|
687
|
+
* export function setupServer(rpc: RpcServerInterface, ctx: ServerContext) {
|
|
688
|
+
* rpc.handle('my-plugin:getData', async (payload) => {
|
|
689
|
+
* // Handle RPC call
|
|
690
|
+
* return { data: 'result' };
|
|
691
|
+
* });
|
|
692
|
+
*
|
|
693
|
+
* rpc.broadcast('my-plugin:update', { data: 'new' });
|
|
694
|
+
* }
|
|
695
|
+
* ```
|
|
696
|
+
*/
|
|
264
697
|
export declare interface RpcServerInterface {
|
|
698
|
+
/**
|
|
699
|
+
* Register a handler for an RPC method.
|
|
700
|
+
* @param method - Method name (e.g., 'my-plugin:getData')
|
|
701
|
+
* @param fn - Handler function that receives payload and returns result
|
|
702
|
+
*/
|
|
265
703
|
handle(method: string, fn: (payload: unknown) => Promise<unknown> | unknown): void;
|
|
704
|
+
/**
|
|
705
|
+
* Broadcast an event to all connected clients.
|
|
706
|
+
* @param event - Event name
|
|
707
|
+
* @param payload - Optional event data
|
|
708
|
+
*/
|
|
266
709
|
broadcast(event: string, payload?: unknown): void;
|
|
267
710
|
}
|
|
268
711
|
|
|
712
|
+
/**
|
|
713
|
+
* Server Context - Context object provided to server-side plugin setup.
|
|
714
|
+
* Available in: Server context (Node.js - Vite dev server)
|
|
715
|
+
*/
|
|
269
716
|
export declare interface ServerContext {
|
|
717
|
+
/** Project root directory path */
|
|
270
718
|
root: string;
|
|
719
|
+
/** Vite dev server instance (for advanced use cases) */
|
|
271
720
|
server: unknown;
|
|
272
721
|
}
|
|
273
722
|
|
|
723
|
+
/**
|
|
724
|
+
* Zod schema for setting option (used in select type).
|
|
725
|
+
*/
|
|
726
|
+
export declare const SettingOptionSchema: z.ZodObject<{
|
|
727
|
+
label: z.ZodString;
|
|
728
|
+
value: z.ZodUnknown;
|
|
729
|
+
}, z.core.$strip>;
|
|
730
|
+
|
|
731
|
+
/**
|
|
732
|
+
* Settings API for user-configurable plugin settings.
|
|
733
|
+
* Settings are displayed in DevTools settings panel and persist across sessions.
|
|
734
|
+
*
|
|
735
|
+
* @example
|
|
736
|
+
* ```typescript
|
|
737
|
+
* import type { SettingsApi } from '@u-devtools/core';
|
|
738
|
+
*
|
|
739
|
+
* function useSettings(api: SettingsApi) {
|
|
740
|
+
* // Get setting with default
|
|
741
|
+
* const fontSize = api.get('fontSize', 14);
|
|
742
|
+
* const theme = api.get('theme', 'dark');
|
|
743
|
+
* const enabled = api.get('enabled', true);
|
|
744
|
+
*
|
|
745
|
+
* // Set settings
|
|
746
|
+
* api.set('fontSize', 16);
|
|
747
|
+
* api.set('theme', 'light');
|
|
748
|
+
* api.set('enabled', false);
|
|
749
|
+
*
|
|
750
|
+
* // Access all settings reactively (for Vue bindings)
|
|
751
|
+
* const allSettings = api.all;
|
|
752
|
+
* }
|
|
753
|
+
* ```
|
|
754
|
+
*/
|
|
274
755
|
export declare interface SettingsApi {
|
|
275
756
|
/**
|
|
276
|
-
*
|
|
277
|
-
* @param key
|
|
278
|
-
* @param defaultValue
|
|
757
|
+
* Get a setting value.
|
|
758
|
+
* @param key Setting key (without plugin prefix)
|
|
759
|
+
* @param defaultValue Default value if setting is not set
|
|
279
760
|
*/
|
|
280
761
|
get<T>(key: string, defaultValue?: T): T;
|
|
281
762
|
/**
|
|
282
|
-
*
|
|
283
|
-
* @param key
|
|
284
|
-
* @param value
|
|
763
|
+
* Set a setting value.
|
|
764
|
+
* @param key Setting key
|
|
765
|
+
* @param value New value
|
|
285
766
|
*/
|
|
286
767
|
set(key: string, value: unknown): void;
|
|
287
768
|
/**
|
|
288
|
-
*
|
|
769
|
+
* Reactive object of all settings (for UI bindings)
|
|
289
770
|
*/
|
|
290
771
|
all: Record<string, unknown>;
|
|
291
772
|
}
|
|
292
773
|
|
|
774
|
+
/**
|
|
775
|
+
* Setting schema definition for a single setting.
|
|
776
|
+
* Used to define user-configurable settings that appear in the DevTools settings panel.
|
|
777
|
+
*
|
|
778
|
+
* @example
|
|
779
|
+
* ```typescript
|
|
780
|
+
* const pluginWithSettings: PluginClientInstance = {
|
|
781
|
+
* name: 'My Plugin',
|
|
782
|
+
* icon: 'Cube',
|
|
783
|
+
*
|
|
784
|
+
* settings: {
|
|
785
|
+
* fontSize: {
|
|
786
|
+
* label: 'Font Size',
|
|
787
|
+
* description: 'Base font size for the plugin',
|
|
788
|
+
* type: 'number',
|
|
789
|
+
* default: 14,
|
|
790
|
+
* },
|
|
791
|
+
* theme: {
|
|
792
|
+
* label: 'Theme',
|
|
793
|
+
* type: 'select',
|
|
794
|
+
* default: 'dark',
|
|
795
|
+
* options: [
|
|
796
|
+
* { label: 'Dark', value: 'dark' },
|
|
797
|
+
* { label: 'Light', value: 'light' },
|
|
798
|
+
* ],
|
|
799
|
+
* },
|
|
800
|
+
* },
|
|
801
|
+
*
|
|
802
|
+
* renderMain(container, api) {
|
|
803
|
+
* // Access settings
|
|
804
|
+
* const fontSize = api.settings.get('fontSize', 14);
|
|
805
|
+
* const theme = api.settings.get('theme', 'dark');
|
|
806
|
+
*
|
|
807
|
+
* return () => {};
|
|
808
|
+
* }
|
|
809
|
+
* };
|
|
810
|
+
* ```
|
|
811
|
+
*/
|
|
293
812
|
export declare interface SettingSchemaDef {
|
|
813
|
+
/** Display label for the setting */
|
|
294
814
|
label: string;
|
|
815
|
+
/** Optional description/tooltip text */
|
|
295
816
|
description?: string;
|
|
817
|
+
/** Setting type (determines input component) */
|
|
296
818
|
type: SettingType;
|
|
819
|
+
/** Default value */
|
|
297
820
|
default?: unknown;
|
|
821
|
+
/** Options for 'select' type settings */
|
|
298
822
|
options?: {
|
|
299
823
|
label: string;
|
|
300
824
|
value: unknown;
|
|
301
825
|
}[];
|
|
826
|
+
/** Schema for array items (for 'array' type with object items) */
|
|
302
827
|
items?: Record<string, SettingSchemaDef>;
|
|
828
|
+
/** Item type for 'array' type with primitive items ('string' or 'number') */
|
|
303
829
|
itemType?: 'string' | 'number';
|
|
304
830
|
}
|
|
305
831
|
|
|
832
|
+
/**
|
|
833
|
+
* Zod schema for setting schema definition.
|
|
834
|
+
* Recursive schema using z.lazy for items field.
|
|
835
|
+
*/
|
|
836
|
+
export declare const SettingSchemaDefSchema: z.ZodType<any>;
|
|
837
|
+
|
|
838
|
+
/**
|
|
839
|
+
* Type inferred from SettingSchemaDefSchema
|
|
840
|
+
*/
|
|
841
|
+
export declare type SettingSchemaDefType = z.infer<typeof SettingSchemaDefSchema>;
|
|
842
|
+
|
|
843
|
+
/**
|
|
844
|
+
* Setting type for plugin settings schema.
|
|
845
|
+
* Defines the input type for user-configurable settings.
|
|
846
|
+
*/
|
|
306
847
|
export declare type SettingType = 'string' | 'number' | 'boolean' | 'select' | 'array';
|
|
307
848
|
|
|
849
|
+
/**
|
|
850
|
+
* Zod schema for setting type validation.
|
|
851
|
+
*/
|
|
852
|
+
export declare const SettingTypeSchema: z.ZodEnum<{
|
|
853
|
+
string: "string";
|
|
854
|
+
number: "number";
|
|
855
|
+
boolean: "boolean";
|
|
856
|
+
select: "select";
|
|
857
|
+
array: "array";
|
|
858
|
+
}>;
|
|
859
|
+
|
|
308
860
|
export declare interface ShortcutApi {
|
|
309
861
|
/**
|
|
310
|
-
*
|
|
311
|
-
* @param keys
|
|
312
|
-
* @param action
|
|
313
|
-
* @returns
|
|
862
|
+
* Register a keyboard shortcut.
|
|
863
|
+
* @param keys Array of keys (e.g., ['Meta', 'K'])
|
|
864
|
+
* @param action Action to execute on key press
|
|
865
|
+
* @returns Function to unregister the shortcut
|
|
314
866
|
*/
|
|
315
867
|
register(keys: string[], action: () => void): () => void;
|
|
316
868
|
}
|
|
317
869
|
|
|
870
|
+
/**
|
|
871
|
+
* Storage API for plugin-specific persistent storage.
|
|
872
|
+
* Used for internal plugin state (e.g., last opened file, view preferences).
|
|
873
|
+
* Storage is isolated per plugin and persists across sessions.
|
|
874
|
+
*
|
|
875
|
+
* @example
|
|
876
|
+
* ```typescript
|
|
877
|
+
* import type { StorageApi } from '@u-devtools/core';
|
|
878
|
+
*
|
|
879
|
+
* function useStorage(api: StorageApi) {
|
|
880
|
+
* // Store values
|
|
881
|
+
* api.set('lastView', 'list');
|
|
882
|
+
* api.set('filters', { category: 'all', sort: 'name' });
|
|
883
|
+
* api.set('items', ['item1', 'item2', 'item3']);
|
|
884
|
+
*
|
|
885
|
+
* // Retrieve values with defaults
|
|
886
|
+
* const lastView = api.get('lastView', 'default');
|
|
887
|
+
* const filters = api.get('filters', { category: 'all' });
|
|
888
|
+
* const items = api.get<string[]>('items', []);
|
|
889
|
+
*
|
|
890
|
+
* // Remove values
|
|
891
|
+
* api.remove('lastView');
|
|
892
|
+
* }
|
|
893
|
+
* ```
|
|
894
|
+
*/
|
|
318
895
|
export declare interface StorageApi {
|
|
896
|
+
/**
|
|
897
|
+
* Get a stored value.
|
|
898
|
+
* @param key - Storage key
|
|
899
|
+
* @param def - Default value if key doesn't exist
|
|
900
|
+
* @returns Stored value or default
|
|
901
|
+
* @template T - Type of the stored value
|
|
902
|
+
*/
|
|
319
903
|
get<T>(key: string, def: T): T;
|
|
904
|
+
/**
|
|
905
|
+
* Set a stored value.
|
|
906
|
+
* @param key - Storage key
|
|
907
|
+
* @param value - Value to store
|
|
908
|
+
* @template T - Type of the value
|
|
909
|
+
*/
|
|
320
910
|
set<T>(key: string, value: T): void;
|
|
911
|
+
/**
|
|
912
|
+
* Remove a stored value.
|
|
913
|
+
* @param key - Storage key to remove
|
|
914
|
+
*/
|
|
321
915
|
remove(key: string): void;
|
|
322
916
|
}
|
|
323
917
|
|
|
918
|
+
/**
|
|
919
|
+
* Universal state class with automatic synchronization between App and Client contexts.
|
|
920
|
+
* Implements "Handshake" protocol for getting current data on initialization.
|
|
921
|
+
*
|
|
922
|
+
* Use this for state that needs to be shared between App context (main window)
|
|
923
|
+
* and Client context (DevTools iframe). Changes are automatically synchronized.
|
|
924
|
+
*
|
|
925
|
+
* @template T - Type of the state value
|
|
926
|
+
*
|
|
927
|
+
* @example
|
|
928
|
+
* ```typescript
|
|
929
|
+
* import { AppBridge } from '@u-devtools/core';
|
|
930
|
+
*
|
|
931
|
+
* // Create bridge
|
|
932
|
+
* const bridge = new AppBridge('my-plugin');
|
|
933
|
+
*
|
|
934
|
+
* // Create synced state
|
|
935
|
+
* const isOpen = bridge.state('isOpen', false);
|
|
936
|
+
* const count = bridge.state('count', 0);
|
|
937
|
+
*
|
|
938
|
+
* // Update value (automatically syncs to Client)
|
|
939
|
+
* isOpen.value = true;
|
|
940
|
+
* count.value = 42;
|
|
941
|
+
*
|
|
942
|
+
* // Subscribe to changes
|
|
943
|
+
* const unsubscribe = isOpen.subscribe((value) => {
|
|
944
|
+
* console.log('State changed:', value);
|
|
945
|
+
* });
|
|
946
|
+
*
|
|
947
|
+
* // Cleanup
|
|
948
|
+
* unsubscribe();
|
|
949
|
+
* ```
|
|
950
|
+
*/
|
|
951
|
+
export declare class SyncedState<T> {
|
|
952
|
+
private bridge;
|
|
953
|
+
private key;
|
|
954
|
+
private _value;
|
|
955
|
+
private listeners;
|
|
956
|
+
private isUpdating;
|
|
957
|
+
constructor(bridge: AppBridge<any>, key: string, initialValue: T);
|
|
958
|
+
get value(): T;
|
|
959
|
+
set value(newValue: T);
|
|
960
|
+
subscribe: (fn: (val: T) => void) => () => void;
|
|
961
|
+
getSnapshot: () => T;
|
|
962
|
+
private notify;
|
|
963
|
+
}
|
|
964
|
+
|
|
965
|
+
/**
|
|
966
|
+
* Abstract class for message transport.
|
|
967
|
+
* Provides common logic for RPC calls and event subscriptions.
|
|
968
|
+
*/
|
|
969
|
+
export declare abstract class Transport {
|
|
970
|
+
protected handlers: Map<string, {
|
|
971
|
+
resolve: (value: unknown) => void;
|
|
972
|
+
reject: (error: Error) => void;
|
|
973
|
+
}>;
|
|
974
|
+
protected eventListeners: Map<string, Set<(data: unknown) => void>>;
|
|
975
|
+
protected disposed: boolean;
|
|
976
|
+
protected timeout: number;
|
|
977
|
+
/**
|
|
978
|
+
* Send a message through the transport
|
|
979
|
+
*/
|
|
980
|
+
protected abstract sendMessage(type: string, data: unknown): void;
|
|
981
|
+
/**
|
|
982
|
+
* Subscribe to messages from the transport
|
|
983
|
+
*/
|
|
984
|
+
protected abstract subscribe(type: string, handler: (data: unknown) => void): () => void;
|
|
985
|
+
/**
|
|
986
|
+
* Unsubscribe from transport messages
|
|
987
|
+
*/
|
|
988
|
+
protected abstract unsubscribe?(type: string, handler: (data: unknown) => void): void;
|
|
989
|
+
/**
|
|
990
|
+
* RPC method call
|
|
991
|
+
*/
|
|
992
|
+
call<T = unknown>(method: string, payload?: unknown): Promise<T>;
|
|
993
|
+
/**
|
|
994
|
+
* Subscribe to events
|
|
995
|
+
*/
|
|
996
|
+
on(event: string, fn: (data: unknown) => void): () => void;
|
|
997
|
+
/**
|
|
998
|
+
* Unsubscribe from events
|
|
999
|
+
*/
|
|
1000
|
+
off(event: string, fn: (data: unknown) => void): void;
|
|
1001
|
+
/**
|
|
1002
|
+
* Handle incoming messages (called by transport)
|
|
1003
|
+
*/
|
|
1004
|
+
protected handleMessage(data: unknown): void;
|
|
1005
|
+
/**
|
|
1006
|
+
* Clean up all handlers and subscriptions
|
|
1007
|
+
*/
|
|
1008
|
+
dispose(): void;
|
|
1009
|
+
}
|
|
1010
|
+
|
|
1011
|
+
/**
|
|
1012
|
+
* Typed Event Emitter for inter-plugin communication.
|
|
1013
|
+
* Provides type-safe event emission and subscription.
|
|
1014
|
+
*
|
|
1015
|
+
* @template T - Type definition for events and their data
|
|
1016
|
+
*
|
|
1017
|
+
* @example
|
|
1018
|
+
* ```typescript
|
|
1019
|
+
* import { TypedEventBus, type BusEvents } from '@u-devtools/core';
|
|
1020
|
+
*
|
|
1021
|
+
* // Create event bus instance
|
|
1022
|
+
* const bus = new TypedEventBus<BusEvents>();
|
|
1023
|
+
*
|
|
1024
|
+
* // Emit events
|
|
1025
|
+
* bus.emit('plugin:mounted', { name: 'my-plugin' });
|
|
1026
|
+
* bus.emit('navigate', { path: '/settings' });
|
|
1027
|
+
* bus.emit('settings:changed', { key: 'theme', value: 'dark' });
|
|
1028
|
+
*
|
|
1029
|
+
* // Subscribe to events
|
|
1030
|
+
* const unsubscribe1 = bus.on('plugin:mounted', ({ name }) => {
|
|
1031
|
+
* console.log(`Plugin ${name} was mounted`);
|
|
1032
|
+
* });
|
|
1033
|
+
*
|
|
1034
|
+
* const unsubscribe2 = bus.on('navigate', ({ path }) => {
|
|
1035
|
+
* console.log(`Navigating to: ${path}`);
|
|
1036
|
+
* });
|
|
1037
|
+
*
|
|
1038
|
+
* // Unsubscribe
|
|
1039
|
+
* unsubscribe1();
|
|
1040
|
+
* unsubscribe2();
|
|
1041
|
+
*
|
|
1042
|
+
* // Or use off method (handler must be the same function reference)
|
|
1043
|
+
* const handler = ({ name }: { name: string }) => {
|
|
1044
|
+
* console.log(`Plugin ${name} was mounted`);
|
|
1045
|
+
* };
|
|
1046
|
+
* bus.on('plugin:mounted', handler);
|
|
1047
|
+
* bus.off('plugin:mounted', handler);
|
|
1048
|
+
* ```
|
|
1049
|
+
*/
|
|
1050
|
+
export declare class TypedEventBus<T extends Record<string, unknown> = BusEvents> {
|
|
1051
|
+
private listeners;
|
|
1052
|
+
/**
|
|
1053
|
+
* Emit an event
|
|
1054
|
+
*/
|
|
1055
|
+
emit<K extends keyof T>(event: K, data: T[K]): void;
|
|
1056
|
+
/**
|
|
1057
|
+
* Subscribe to an event
|
|
1058
|
+
*/
|
|
1059
|
+
on<K extends keyof T>(event: K, handler: (data: T[K]) => void): () => void;
|
|
1060
|
+
/**
|
|
1061
|
+
* Unsubscribe from an event
|
|
1062
|
+
*/
|
|
1063
|
+
off<K extends keyof T>(event: K, handler: (data: T[K]) => void): void;
|
|
1064
|
+
/**
|
|
1065
|
+
* Clear all subscriptions
|
|
1066
|
+
*/
|
|
1067
|
+
clear(): void;
|
|
1068
|
+
/**
|
|
1069
|
+
* Get the number of subscribers for an event
|
|
1070
|
+
*/
|
|
1071
|
+
listenerCount<K extends keyof T>(event: K): number;
|
|
1072
|
+
}
|
|
1073
|
+
|
|
324
1074
|
export declare type UnmountFn = () => void;
|
|
325
1075
|
|
|
1076
|
+
/**
|
|
1077
|
+
* Validates a plugin settings schema.
|
|
1078
|
+
* @param data - Data to validate
|
|
1079
|
+
* @returns Validated plugin settings schema or null if validation fails
|
|
1080
|
+
*/
|
|
1081
|
+
export declare function validatePluginSettingsSchema(data: unknown): PluginSettingsSchemaType | null;
|
|
1082
|
+
|
|
1083
|
+
/**
|
|
1084
|
+
* Validates an unknown value as an RPC message.
|
|
1085
|
+
* @param data - Data to validate
|
|
1086
|
+
* @returns Validated RPC message or null if validation fails
|
|
1087
|
+
*/
|
|
1088
|
+
export declare function validateRpcMessage(data: unknown): RpcMessageType | null;
|
|
1089
|
+
|
|
1090
|
+
/**
|
|
1091
|
+
* Validates a setting schema definition.
|
|
1092
|
+
* @param data - Data to validate
|
|
1093
|
+
* @returns Validated setting schema definition or null if validation fails
|
|
1094
|
+
*/
|
|
1095
|
+
export declare function validateSettingSchemaDef(data: unknown): SettingSchemaDefType | null;
|
|
1096
|
+
|
|
1097
|
+
/**
|
|
1098
|
+
* Validates a setting value against its schema definition.
|
|
1099
|
+
* @param value - Value to validate
|
|
1100
|
+
* @param schemaDef - Setting schema definition
|
|
1101
|
+
* @returns True if value is valid, false otherwise
|
|
1102
|
+
*/
|
|
1103
|
+
export declare function validateSettingValue(value: unknown, schemaDef: SettingSchemaDefType): boolean;
|
|
1104
|
+
|
|
1105
|
+
/**
|
|
1106
|
+
* Transport based on WebSocket
|
|
1107
|
+
* Used for communication between client and server when HMR is unavailable
|
|
1108
|
+
* (e.g., for remote debugging or production builds)
|
|
1109
|
+
*/
|
|
1110
|
+
export declare class WebSocketTransport extends Transport {
|
|
1111
|
+
private url;
|
|
1112
|
+
private ws;
|
|
1113
|
+
private reconnectAttempts;
|
|
1114
|
+
private maxReconnectAttempts;
|
|
1115
|
+
private reconnectDelay;
|
|
1116
|
+
private reconnectTimer;
|
|
1117
|
+
private isManualClose;
|
|
1118
|
+
private messageQueue;
|
|
1119
|
+
constructor(url: string);
|
|
1120
|
+
private connect;
|
|
1121
|
+
private scheduleReconnect;
|
|
1122
|
+
protected sendMessage(type: string, data: unknown): void;
|
|
1123
|
+
private flushQueue;
|
|
1124
|
+
protected subscribe(_type: string, _handler: (data: unknown) => void): () => void;
|
|
1125
|
+
protected unsubscribe(_type: string, _handler: (data: unknown) => void): void;
|
|
1126
|
+
dispose(): void;
|
|
1127
|
+
/**
|
|
1128
|
+
* Check connection status
|
|
1129
|
+
*/
|
|
1130
|
+
isConnected(): boolean;
|
|
1131
|
+
}
|
|
1132
|
+
|
|
326
1133
|
export { }
|