@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/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 provides a standardized way for plugins to communicate
5
- * between the application runtime (window) and the DevTools iframe.
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 listeners;
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
- * Открыть DevTools
217
+ * Open DevTools
55
218
  */
56
219
  open(): void;
57
220
  /**
58
- * Закрыть DevTools
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 added to the Vite config
92
- * These plugins will be merged with the main DevTools plugin
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 с результатом (true если подтверждено)
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 с введенным текстом или null если отменено
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 const OVERLAY_EVENT = "u-devtools:register-menu-item";
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
- * Открыть основное окно DevTools
417
+ * Open the main DevTools window
162
418
  */
163
419
  open: () => void;
164
420
  /**
165
- * Закрыть основное окно DevTools
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
- renderSidebar?: (el: HTMLElement, api: ClientApi) => UnmountFn;
220
- renderMain?: (el: HTMLElement, api: ClientApi) => UnmountFn;
221
- renderSettings?: (el: HTMLElement, api: ClientApi) => UnmountFn;
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
- repo?: string;
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
- * Функция для регистрации кнопки в оверлее (вызывается из app.ts плагина)
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 function registerMenuItem(item: OverlayMenuItem): void;
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
- * Реактивный объект всех настроек (для UI биндингов)
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 Массив клавиш (например, ['Meta', 'K'])
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 { }