@qontinui/ui-bridge 0.1.1

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.
Files changed (47) hide show
  1. package/dist/control/index.d.mts +134 -0
  2. package/dist/control/index.d.ts +134 -0
  3. package/dist/control/index.js +924 -0
  4. package/dist/control/index.js.map +1 -0
  5. package/dist/control/index.mjs +919 -0
  6. package/dist/control/index.mjs.map +1 -0
  7. package/dist/core/index.d.mts +52 -0
  8. package/dist/core/index.d.ts +52 -0
  9. package/dist/core/index.js +1424 -0
  10. package/dist/core/index.js.map +1 -0
  11. package/dist/core/index.mjs +1409 -0
  12. package/dist/core/index.mjs.map +1 -0
  13. package/dist/debug/index.d.mts +93 -0
  14. package/dist/debug/index.d.ts +93 -0
  15. package/dist/debug/index.js +673 -0
  16. package/dist/debug/index.js.map +1 -0
  17. package/dist/debug/index.mjs +664 -0
  18. package/dist/debug/index.mjs.map +1 -0
  19. package/dist/index.d.mts +12 -0
  20. package/dist/index.d.ts +12 -0
  21. package/dist/index.js +4719 -0
  22. package/dist/index.js.map +1 -0
  23. package/dist/index.mjs +4665 -0
  24. package/dist/index.mjs.map +1 -0
  25. package/dist/metrics-BCG7z7Aq.d.mts +147 -0
  26. package/dist/metrics-QCnK0EFw.d.ts +147 -0
  27. package/dist/react/index.d.mts +786 -0
  28. package/dist/react/index.d.ts +786 -0
  29. package/dist/react/index.js +4312 -0
  30. package/dist/react/index.js.map +1 -0
  31. package/dist/react/index.mjs +4290 -0
  32. package/dist/react/index.mjs.map +1 -0
  33. package/dist/registry-CT6BVVKr.d.mts +253 -0
  34. package/dist/registry-D4mQ01B3.d.ts +253 -0
  35. package/dist/render-log/index.d.mts +340 -0
  36. package/dist/render-log/index.d.ts +340 -0
  37. package/dist/render-log/index.js +702 -0
  38. package/dist/render-log/index.js.map +1 -0
  39. package/dist/render-log/index.mjs +695 -0
  40. package/dist/render-log/index.mjs.map +1 -0
  41. package/dist/types-BDkXy5si.d.ts +354 -0
  42. package/dist/types-BpvpStn3.d.mts +802 -0
  43. package/dist/types-BpvpStn3.d.ts +802 -0
  44. package/dist/types-DdJD9yw5.d.mts +354 -0
  45. package/dist/websocket-client-B2LC9CYc.d.mts +124 -0
  46. package/dist/websocket-client-DupH0X7B.d.ts +124 -0
  47. package/package.json +83 -0
@@ -0,0 +1,1424 @@
1
+ 'use strict';
2
+
3
+ // src/core/element-identifier.ts
4
+ var ID_ATTRIBUTES = ["data-ui-id", "data-testid", "data-awas-element", "id"];
5
+ function generateXPath(element) {
6
+ if (element.id) {
7
+ return `//*[@id="${element.id}"]`;
8
+ }
9
+ const parts = [];
10
+ let current = element;
11
+ while (current && current.nodeType === Node.ELEMENT_NODE) {
12
+ let selector = current.nodeName.toLowerCase();
13
+ const uiId = current.getAttribute("data-ui-id");
14
+ if (uiId) {
15
+ selector += `[@data-ui-id="${uiId}"]`;
16
+ parts.unshift(selector);
17
+ break;
18
+ }
19
+ const testId = current.getAttribute("data-testid");
20
+ if (testId) {
21
+ selector += `[@data-testid="${testId}"]`;
22
+ parts.unshift(selector);
23
+ break;
24
+ }
25
+ const id = current.id;
26
+ if (id) {
27
+ selector += `[@id="${id}"]`;
28
+ parts.unshift(selector);
29
+ break;
30
+ }
31
+ const parentEl = current.parentElement;
32
+ if (parentEl) {
33
+ const currentEl = current;
34
+ const siblings = Array.from(parentEl.children).filter(
35
+ (child) => child.nodeName === currentEl.nodeName
36
+ );
37
+ if (siblings.length > 1) {
38
+ const index = siblings.indexOf(currentEl) + 1;
39
+ selector += `[${index}]`;
40
+ }
41
+ }
42
+ parts.unshift(selector);
43
+ current = parentEl;
44
+ }
45
+ return "/" + parts.join("/");
46
+ }
47
+ function generateCSSSelector(element) {
48
+ const uiId = element.getAttribute("data-ui-id");
49
+ if (uiId) {
50
+ return `[data-ui-id="${uiId}"]`;
51
+ }
52
+ const testId = element.getAttribute("data-testid");
53
+ if (testId) {
54
+ return `[data-testid="${testId}"]`;
55
+ }
56
+ const awasId = element.getAttribute("data-awas-element");
57
+ if (awasId) {
58
+ return `[data-awas-element="${awasId}"]`;
59
+ }
60
+ if (element.id) {
61
+ return `#${CSS.escape(element.id)}`;
62
+ }
63
+ const path = [];
64
+ let current = element;
65
+ while (current && current.nodeType === Node.ELEMENT_NODE) {
66
+ let selector = current.nodeName.toLowerCase();
67
+ const parentUiId = current.getAttribute("data-ui-id");
68
+ if (parentUiId && current !== element) {
69
+ path.unshift(`[data-ui-id="${parentUiId}"]`);
70
+ break;
71
+ }
72
+ const parentTestId = current.getAttribute("data-testid");
73
+ if (parentTestId && current !== element) {
74
+ path.unshift(`[data-testid="${parentTestId}"]`);
75
+ break;
76
+ }
77
+ if (current.id) {
78
+ path.unshift(`#${CSS.escape(current.id)}`);
79
+ break;
80
+ }
81
+ const parentEl = current.parentElement;
82
+ if (parentEl) {
83
+ const currentEl = current;
84
+ const siblings = Array.from(parentEl.children);
85
+ const sameTagSiblings = siblings.filter(
86
+ (s) => s.nodeName === currentEl.nodeName
87
+ );
88
+ if (sameTagSiblings.length > 1) {
89
+ const index = siblings.indexOf(currentEl) + 1;
90
+ selector += `:nth-child(${index})`;
91
+ }
92
+ }
93
+ path.unshift(selector);
94
+ current = current.parentElement;
95
+ }
96
+ return path.join(" > ");
97
+ }
98
+ function getBestIdentifier(element) {
99
+ const uiId = element.getAttribute("data-ui-id");
100
+ if (uiId) return uiId;
101
+ const testId = element.getAttribute("data-testid");
102
+ if (testId) return testId;
103
+ const awasId = element.getAttribute("data-awas-element");
104
+ if (awasId) return awasId;
105
+ if (element.id) return element.id;
106
+ return generateCSSSelector(element);
107
+ }
108
+ function createElementIdentifier(element) {
109
+ return {
110
+ uiId: element.getAttribute("data-ui-id") || void 0,
111
+ testId: element.getAttribute("data-testid") || void 0,
112
+ awasId: element.getAttribute("data-awas-element") || void 0,
113
+ htmlId: element.id || void 0,
114
+ xpath: generateXPath(element),
115
+ selector: generateCSSSelector(element)
116
+ };
117
+ }
118
+ function findElementByIdentifier(identifier, root = document) {
119
+ if (typeof identifier === "string") {
120
+ const byUiId = root.querySelector(`[data-ui-id="${identifier}"]`);
121
+ if (byUiId) return byUiId;
122
+ const byTestId = root.querySelector(`[data-testid="${identifier}"]`);
123
+ if (byTestId) return byTestId;
124
+ const byAwasId = root.querySelector(`[data-awas-element="${identifier}"]`);
125
+ if (byAwasId) return byAwasId;
126
+ const byId = root.querySelector(`#${CSS.escape(identifier)}`);
127
+ if (byId) return byId;
128
+ try {
129
+ const bySelector = root.querySelector(identifier);
130
+ if (bySelector) return bySelector;
131
+ } catch {
132
+ }
133
+ try {
134
+ const result = document.evaluate(
135
+ identifier,
136
+ root,
137
+ null,
138
+ XPathResult.FIRST_ORDERED_NODE_TYPE,
139
+ null
140
+ );
141
+ if (result.singleNodeValue instanceof HTMLElement) {
142
+ return result.singleNodeValue;
143
+ }
144
+ } catch {
145
+ }
146
+ return null;
147
+ }
148
+ if (identifier.uiId) {
149
+ const el = root.querySelector(`[data-ui-id="${identifier.uiId}"]`);
150
+ if (el) return el;
151
+ }
152
+ if (identifier.testId) {
153
+ const el = root.querySelector(`[data-testid="${identifier.testId}"]`);
154
+ if (el) return el;
155
+ }
156
+ if (identifier.awasId) {
157
+ const el = root.querySelector(`[data-awas-element="${identifier.awasId}"]`);
158
+ if (el) return el;
159
+ }
160
+ if (identifier.htmlId) {
161
+ const el = root.querySelector(`#${CSS.escape(identifier.htmlId)}`);
162
+ if (el) return el;
163
+ }
164
+ if (identifier.selector) {
165
+ try {
166
+ const el = root.querySelector(identifier.selector);
167
+ if (el) return el;
168
+ } catch {
169
+ }
170
+ }
171
+ if (identifier.xpath) {
172
+ try {
173
+ const result = document.evaluate(
174
+ identifier.xpath,
175
+ root,
176
+ null,
177
+ XPathResult.FIRST_ORDERED_NODE_TYPE,
178
+ null
179
+ );
180
+ if (result.singleNodeValue instanceof HTMLElement) {
181
+ return result.singleNodeValue;
182
+ }
183
+ } catch {
184
+ }
185
+ }
186
+ return null;
187
+ }
188
+ function findAllElementsByIdentifier(pattern, root = document) {
189
+ const results = [];
190
+ try {
191
+ const elements = root.querySelectorAll(pattern);
192
+ results.push(...Array.from(elements));
193
+ if (results.length > 0) return results;
194
+ } catch {
195
+ }
196
+ const partials = [
197
+ `[data-ui-id*="${pattern}"]`,
198
+ `[data-testid*="${pattern}"]`,
199
+ `[data-awas-element*="${pattern}"]`,
200
+ `[id*="${pattern}"]`
201
+ ];
202
+ for (const selector of partials) {
203
+ try {
204
+ const elements = root.querySelectorAll(selector);
205
+ for (const el of elements) {
206
+ if (!results.includes(el)) {
207
+ results.push(el);
208
+ }
209
+ }
210
+ } catch {
211
+ }
212
+ }
213
+ return results;
214
+ }
215
+ function elementMatchesIdentifier(element, identifier) {
216
+ if (typeof identifier === "string") {
217
+ return element.getAttribute("data-ui-id") === identifier || element.getAttribute("data-testid") === identifier || element.getAttribute("data-awas-element") === identifier || element.id === identifier || element.matches(identifier);
218
+ }
219
+ return identifier.uiId && element.getAttribute("data-ui-id") === identifier.uiId || identifier.testId && element.getAttribute("data-testid") === identifier.testId || identifier.awasId && element.getAttribute("data-awas-element") === identifier.awasId || identifier.htmlId && element.id === identifier.htmlId || false;
220
+ }
221
+
222
+ // src/core/registry.ts
223
+ function getElementState(element) {
224
+ const rect = element.getBoundingClientRect();
225
+ const computedStyle = window.getComputedStyle(element);
226
+ const state = {
227
+ visible: isElementVisible(element, rect, computedStyle),
228
+ enabled: !isElementDisabled(element),
229
+ focused: document.activeElement === element,
230
+ rect: {
231
+ x: rect.x,
232
+ y: rect.y,
233
+ width: rect.width,
234
+ height: rect.height,
235
+ top: rect.top,
236
+ right: rect.right,
237
+ bottom: rect.bottom,
238
+ left: rect.left
239
+ },
240
+ textContent: element.textContent?.trim() || void 0,
241
+ computedStyles: {
242
+ display: computedStyle.display,
243
+ visibility: computedStyle.visibility,
244
+ opacity: computedStyle.opacity,
245
+ pointerEvents: computedStyle.pointerEvents
246
+ }
247
+ };
248
+ if (element instanceof HTMLInputElement) {
249
+ state.value = element.value;
250
+ if (element.type === "checkbox" || element.type === "radio") {
251
+ state.checked = element.checked;
252
+ }
253
+ } else if (element instanceof HTMLTextAreaElement) {
254
+ state.value = element.value;
255
+ } else if (element instanceof HTMLSelectElement) {
256
+ state.value = element.value;
257
+ state.selectedOptions = Array.from(element.selectedOptions).map((opt) => opt.value);
258
+ }
259
+ return state;
260
+ }
261
+ function isElementVisible(element, rect, style) {
262
+ if (rect.width === 0 || rect.height === 0) return false;
263
+ if (style.display === "none") return false;
264
+ if (style.visibility === "hidden") return false;
265
+ if (parseFloat(style.opacity) === 0) return false;
266
+ const inViewport = rect.top < window.innerHeight && rect.bottom > 0 && rect.left < window.innerWidth && rect.right > 0;
267
+ return inViewport;
268
+ }
269
+ function isElementDisabled(element) {
270
+ if ("disabled" in element && element.disabled) {
271
+ return true;
272
+ }
273
+ if (element.getAttribute("aria-disabled") === "true") {
274
+ return true;
275
+ }
276
+ return false;
277
+ }
278
+ function inferActions(type) {
279
+ const baseActions = ["focus", "blur", "hover"];
280
+ switch (type) {
281
+ case "button":
282
+ return [...baseActions, "click", "doubleClick", "rightClick"];
283
+ case "input":
284
+ return [...baseActions, "click", "type", "clear"];
285
+ case "textarea":
286
+ return [...baseActions, "click", "type", "clear"];
287
+ case "select":
288
+ return [...baseActions, "click", "select"];
289
+ case "checkbox":
290
+ return [...baseActions, "click", "check", "uncheck", "toggle"];
291
+ case "radio":
292
+ return [...baseActions, "click", "check"];
293
+ case "link":
294
+ return [...baseActions, "click"];
295
+ case "form":
296
+ return ["focus", "blur"];
297
+ case "menu":
298
+ case "menuitem":
299
+ return [...baseActions, "click"];
300
+ case "tab":
301
+ return [...baseActions, "click"];
302
+ case "dialog":
303
+ return ["focus", "blur"];
304
+ case "custom":
305
+ default:
306
+ return [...baseActions, "click"];
307
+ }
308
+ }
309
+ function inferElementType(element) {
310
+ const tagName = element.tagName.toLowerCase();
311
+ const role = element.getAttribute("role");
312
+ if (role) {
313
+ switch (role) {
314
+ case "button":
315
+ return "button";
316
+ case "textbox":
317
+ return "input";
318
+ case "checkbox":
319
+ return "checkbox";
320
+ case "radio":
321
+ return "radio";
322
+ case "link":
323
+ return "link";
324
+ case "listbox":
325
+ case "combobox":
326
+ return "select";
327
+ case "menu":
328
+ return "menu";
329
+ case "menuitem":
330
+ return "menuitem";
331
+ case "tab":
332
+ return "tab";
333
+ case "dialog":
334
+ return "dialog";
335
+ }
336
+ }
337
+ switch (tagName) {
338
+ case "button":
339
+ return "button";
340
+ case "input": {
341
+ const inputType = element.type;
342
+ if (inputType === "checkbox") return "checkbox";
343
+ if (inputType === "radio") return "radio";
344
+ if (inputType === "submit" || inputType === "button") return "button";
345
+ return "input";
346
+ }
347
+ case "textarea":
348
+ return "textarea";
349
+ case "select":
350
+ return "select";
351
+ case "a":
352
+ return "link";
353
+ case "form":
354
+ return "form";
355
+ default:
356
+ return "custom";
357
+ }
358
+ }
359
+ var UIBridgeRegistry = class {
360
+ constructor(options = {}) {
361
+ this.elements = /* @__PURE__ */ new Map();
362
+ this.components = /* @__PURE__ */ new Map();
363
+ this.workflows = /* @__PURE__ */ new Map();
364
+ this.eventListeners = /* @__PURE__ */ new Map();
365
+ // State management
366
+ this.states = /* @__PURE__ */ new Map();
367
+ this.stateGroups = /* @__PURE__ */ new Map();
368
+ this.transitions = /* @__PURE__ */ new Map();
369
+ this.activeStates = /* @__PURE__ */ new Set();
370
+ this.options = options;
371
+ }
372
+ /**
373
+ * Emit an event
374
+ */
375
+ emit(type, data) {
376
+ const event = {
377
+ type,
378
+ timestamp: Date.now(),
379
+ data
380
+ };
381
+ this.options.onEvent?.(event);
382
+ const listeners = this.eventListeners.get(type);
383
+ if (listeners) {
384
+ for (const listener of listeners) {
385
+ try {
386
+ listener(event);
387
+ } catch (error) {
388
+ console.error(`Error in event listener for ${type}:`, error);
389
+ }
390
+ }
391
+ }
392
+ if (this.options.verbose) {
393
+ console.log("[UIBridge]", type, data);
394
+ }
395
+ }
396
+ /**
397
+ * Register an event listener
398
+ */
399
+ on(type, listener) {
400
+ if (!this.eventListeners.has(type)) {
401
+ this.eventListeners.set(type, /* @__PURE__ */ new Set());
402
+ }
403
+ this.eventListeners.get(type).add(listener);
404
+ return () => {
405
+ this.eventListeners.get(type)?.delete(listener);
406
+ };
407
+ }
408
+ /**
409
+ * Remove an event listener
410
+ */
411
+ off(type, listener) {
412
+ this.eventListeners.get(type)?.delete(listener);
413
+ }
414
+ /**
415
+ * Register an element
416
+ */
417
+ registerElement(id, element, options = {}) {
418
+ const type = options.type ?? inferElementType(element);
419
+ const actions = options.actions ?? inferActions(type);
420
+ element.setAttribute("data-ui-id", id);
421
+ const registered = {
422
+ id,
423
+ element,
424
+ type,
425
+ label: options.label,
426
+ actions,
427
+ customActions: options.customActions,
428
+ getState: () => getElementState(element),
429
+ getIdentifier: () => createElementIdentifier(element),
430
+ registeredAt: Date.now(),
431
+ mounted: true
432
+ };
433
+ this.elements.set(id, registered);
434
+ this.emit("element:registered", { id, type, label: options.label });
435
+ return registered;
436
+ }
437
+ /**
438
+ * Unregister an element
439
+ */
440
+ unregisterElement(id) {
441
+ const registered = this.elements.get(id);
442
+ if (registered) {
443
+ registered.mounted = false;
444
+ registered.element.removeAttribute("data-ui-id");
445
+ this.elements.delete(id);
446
+ this.emit("element:unregistered", { id });
447
+ return true;
448
+ }
449
+ return false;
450
+ }
451
+ /**
452
+ * Get a registered element
453
+ */
454
+ getElement(id) {
455
+ return this.elements.get(id);
456
+ }
457
+ /**
458
+ * Get all registered elements
459
+ */
460
+ getAllElements() {
461
+ return Array.from(this.elements.values());
462
+ }
463
+ /**
464
+ * Find element by DOM element reference
465
+ */
466
+ findByDOMElement(element) {
467
+ for (const registered of this.elements.values()) {
468
+ if (registered.element === element) {
469
+ return registered;
470
+ }
471
+ }
472
+ return void 0;
473
+ }
474
+ /**
475
+ * Register a component
476
+ */
477
+ registerComponent(id, options) {
478
+ const registered = {
479
+ id,
480
+ name: options.name,
481
+ description: options.description,
482
+ actions: options.actions?.map((a) => ({
483
+ id: a.id,
484
+ label: a.label,
485
+ description: a.description,
486
+ handler: a.handler
487
+ })) ?? [],
488
+ elementIds: options.elementIds,
489
+ registeredAt: Date.now(),
490
+ mounted: true
491
+ };
492
+ this.components.set(id, registered);
493
+ this.emit("component:registered", { id, name: options.name });
494
+ return registered;
495
+ }
496
+ /**
497
+ * Unregister a component
498
+ */
499
+ unregisterComponent(id) {
500
+ const component = this.components.get(id);
501
+ if (component) {
502
+ component.mounted = false;
503
+ this.components.delete(id);
504
+ this.emit("component:unregistered", { id });
505
+ return true;
506
+ }
507
+ return false;
508
+ }
509
+ /**
510
+ * Get a registered component
511
+ */
512
+ getComponent(id) {
513
+ return this.components.get(id);
514
+ }
515
+ /**
516
+ * Get all registered components
517
+ */
518
+ getAllComponents() {
519
+ return Array.from(this.components.values());
520
+ }
521
+ /**
522
+ * Register a workflow
523
+ */
524
+ registerWorkflow(workflow) {
525
+ this.workflows.set(workflow.id, workflow);
526
+ return workflow;
527
+ }
528
+ /**
529
+ * Unregister a workflow
530
+ */
531
+ unregisterWorkflow(id) {
532
+ return this.workflows.delete(id);
533
+ }
534
+ /**
535
+ * Get a workflow
536
+ */
537
+ getWorkflow(id) {
538
+ return this.workflows.get(id);
539
+ }
540
+ /**
541
+ * Get all workflows
542
+ */
543
+ getAllWorkflows() {
544
+ return Array.from(this.workflows.values());
545
+ }
546
+ // ==========================================================================
547
+ // State Management
548
+ // ==========================================================================
549
+ /**
550
+ * Register a state
551
+ */
552
+ registerState(state) {
553
+ this.states.set(state.id, state);
554
+ this.emit("element:registered", { id: state.id, type: "state", name: state.name });
555
+ return state;
556
+ }
557
+ /**
558
+ * Unregister a state
559
+ */
560
+ unregisterState(id) {
561
+ const state = this.states.get(id);
562
+ if (state) {
563
+ this.activeStates.delete(id);
564
+ this.states.delete(id);
565
+ this.emit("element:unregistered", { id, type: "state" });
566
+ return true;
567
+ }
568
+ return false;
569
+ }
570
+ /**
571
+ * Get a registered state
572
+ */
573
+ getState(id) {
574
+ return this.states.get(id);
575
+ }
576
+ /**
577
+ * Get all registered states
578
+ */
579
+ getAllStates() {
580
+ return Array.from(this.states.values());
581
+ }
582
+ /**
583
+ * Register a state group
584
+ */
585
+ registerStateGroup(group) {
586
+ this.stateGroups.set(group.id, group);
587
+ return group;
588
+ }
589
+ /**
590
+ * Unregister a state group
591
+ */
592
+ unregisterStateGroup(id) {
593
+ return this.stateGroups.delete(id);
594
+ }
595
+ /**
596
+ * Get a state group
597
+ */
598
+ getStateGroup(id) {
599
+ return this.stateGroups.get(id);
600
+ }
601
+ /**
602
+ * Get all state groups
603
+ */
604
+ getAllStateGroups() {
605
+ return Array.from(this.stateGroups.values());
606
+ }
607
+ /**
608
+ * Register a transition
609
+ */
610
+ registerTransition(transition) {
611
+ this.transitions.set(transition.id, transition);
612
+ return transition;
613
+ }
614
+ /**
615
+ * Unregister a transition
616
+ */
617
+ unregisterTransition(id) {
618
+ return this.transitions.delete(id);
619
+ }
620
+ /**
621
+ * Get a transition
622
+ */
623
+ getTransition(id) {
624
+ return this.transitions.get(id);
625
+ }
626
+ /**
627
+ * Get all transitions
628
+ */
629
+ getAllTransitions() {
630
+ return Array.from(this.transitions.values());
631
+ }
632
+ /**
633
+ * Get currently active states
634
+ */
635
+ getActiveStates() {
636
+ return Array.from(this.activeStates);
637
+ }
638
+ /**
639
+ * Check if a state is active
640
+ */
641
+ isStateActive(id) {
642
+ return this.activeStates.has(id);
643
+ }
644
+ /**
645
+ * Activate a state
646
+ */
647
+ activateState(id) {
648
+ const state = this.states.get(id);
649
+ if (!state) {
650
+ return false;
651
+ }
652
+ for (const activeId of this.activeStates) {
653
+ const activeState = this.states.get(activeId);
654
+ if (activeState?.blocking && activeState.id !== id) {
655
+ return false;
656
+ }
657
+ if (activeState?.blocks?.includes(id)) {
658
+ return false;
659
+ }
660
+ }
661
+ const wasActive = this.activeStates.has(id);
662
+ this.activeStates.add(id);
663
+ if (!wasActive) {
664
+ this.emit("element:stateChanged", {
665
+ stateId: id,
666
+ active: true,
667
+ activeStates: this.getActiveStates()
668
+ });
669
+ }
670
+ return true;
671
+ }
672
+ /**
673
+ * Deactivate a state
674
+ */
675
+ deactivateState(id) {
676
+ const wasActive = this.activeStates.has(id);
677
+ this.activeStates.delete(id);
678
+ if (wasActive) {
679
+ this.emit("element:stateChanged", {
680
+ stateId: id,
681
+ active: false,
682
+ activeStates: this.getActiveStates()
683
+ });
684
+ }
685
+ return wasActive;
686
+ }
687
+ /**
688
+ * Activate multiple states
689
+ */
690
+ activateStates(ids) {
691
+ const activated = [];
692
+ for (const id of ids) {
693
+ if (this.activateState(id)) {
694
+ activated.push(id);
695
+ }
696
+ }
697
+ return activated;
698
+ }
699
+ /**
700
+ * Deactivate multiple states
701
+ */
702
+ deactivateStates(ids) {
703
+ const deactivated = [];
704
+ for (const id of ids) {
705
+ if (this.deactivateState(id)) {
706
+ deactivated.push(id);
707
+ }
708
+ }
709
+ return deactivated;
710
+ }
711
+ /**
712
+ * Activate a state group (all states in the group)
713
+ */
714
+ activateStateGroup(groupId) {
715
+ const group = this.stateGroups.get(groupId);
716
+ if (!group) return [];
717
+ return this.activateStates(group.states);
718
+ }
719
+ /**
720
+ * Deactivate a state group (all states in the group)
721
+ */
722
+ deactivateStateGroup(groupId) {
723
+ const group = this.stateGroups.get(groupId);
724
+ if (!group) return [];
725
+ return this.deactivateStates(group.states);
726
+ }
727
+ /**
728
+ * Check if a transition can be executed from current state
729
+ */
730
+ canExecuteTransition(transitionId) {
731
+ const transition = this.transitions.get(transitionId);
732
+ if (!transition) return false;
733
+ return transition.fromStates.some((stateId) => this.activeStates.has(stateId));
734
+ }
735
+ /**
736
+ * Execute a transition
737
+ */
738
+ async executeTransition(transitionId) {
739
+ const startTime = performance.now();
740
+ const transition = this.transitions.get(transitionId);
741
+ if (!transition) {
742
+ return {
743
+ success: false,
744
+ activatedStates: [],
745
+ deactivatedStates: [],
746
+ error: `Transition not found: ${transitionId}`,
747
+ durationMs: performance.now() - startTime
748
+ };
749
+ }
750
+ if (!this.canExecuteTransition(transitionId)) {
751
+ return {
752
+ success: false,
753
+ activatedStates: [],
754
+ deactivatedStates: [],
755
+ error: "Precondition not met: none of the fromStates are active",
756
+ failedPhase: "precondition",
757
+ durationMs: performance.now() - startTime
758
+ };
759
+ }
760
+ try {
761
+ const deactivated = this.deactivateStates(transition.exitStates);
762
+ if (transition.exitGroups) {
763
+ for (const groupId of transition.exitGroups) {
764
+ deactivated.push(...this.deactivateStateGroup(groupId));
765
+ }
766
+ }
767
+ const activated = this.activateStates(transition.activateStates);
768
+ if (transition.activateGroups) {
769
+ for (const groupId of transition.activateGroups) {
770
+ activated.push(...this.activateStateGroup(groupId));
771
+ }
772
+ }
773
+ return {
774
+ success: true,
775
+ activatedStates: activated,
776
+ deactivatedStates: deactivated,
777
+ durationMs: performance.now() - startTime
778
+ };
779
+ } catch (error) {
780
+ return {
781
+ success: false,
782
+ activatedStates: [],
783
+ deactivatedStates: [],
784
+ error: error instanceof Error ? error.message : String(error),
785
+ failedPhase: "execution",
786
+ durationMs: performance.now() - startTime
787
+ };
788
+ }
789
+ }
790
+ /**
791
+ * Find a path from current state to target states
792
+ *
793
+ * Uses a simple BFS algorithm for pathfinding.
794
+ * For more advanced pathfinding (Dijkstra, A*), use the Python state manager service.
795
+ */
796
+ findPath(targetStates) {
797
+ if (targetStates.every((t) => this.activeStates.has(t))) {
798
+ return {
799
+ found: true,
800
+ transitions: [],
801
+ totalCost: 0,
802
+ targetStates,
803
+ estimatedSteps: 0
804
+ };
805
+ }
806
+ const queue = [
807
+ { activeStates: new Set(this.activeStates), path: [], cost: 0 }
808
+ ];
809
+ const visited = /* @__PURE__ */ new Set();
810
+ while (queue.length > 0) {
811
+ const current = queue.shift();
812
+ const stateKey = Array.from(current.activeStates).sort().join(",");
813
+ if (visited.has(stateKey)) continue;
814
+ visited.add(stateKey);
815
+ if (targetStates.every((t) => current.activeStates.has(t))) {
816
+ return {
817
+ found: true,
818
+ transitions: current.path,
819
+ totalCost: current.cost,
820
+ targetStates,
821
+ estimatedSteps: current.path.length
822
+ };
823
+ }
824
+ for (const transition of this.transitions.values()) {
825
+ const canExecute = transition.fromStates.some((s) => current.activeStates.has(s));
826
+ if (!canExecute) continue;
827
+ const newActive = new Set(current.activeStates);
828
+ for (const s of transition.exitStates) newActive.delete(s);
829
+ for (const s of transition.activateStates) newActive.add(s);
830
+ const newCost = current.cost + (transition.pathCost ?? 1);
831
+ queue.push({
832
+ activeStates: newActive,
833
+ path: [...current.path, transition.id],
834
+ cost: newCost
835
+ });
836
+ }
837
+ }
838
+ return {
839
+ found: false,
840
+ transitions: [],
841
+ totalCost: 0,
842
+ targetStates,
843
+ estimatedSteps: 0
844
+ };
845
+ }
846
+ /**
847
+ * Navigate to target states using pathfinding
848
+ */
849
+ async navigateTo(targetStates) {
850
+ const startTime = performance.now();
851
+ const path = this.findPath(targetStates);
852
+ if (!path.found) {
853
+ return {
854
+ success: false,
855
+ path,
856
+ executedTransitions: [],
857
+ finalActiveStates: this.getActiveStates(),
858
+ error: `No path found to target states: ${targetStates.join(", ")}`,
859
+ durationMs: performance.now() - startTime
860
+ };
861
+ }
862
+ const executedTransitions = [];
863
+ for (const transitionId of path.transitions) {
864
+ const result = await this.executeTransition(transitionId);
865
+ if (!result.success) {
866
+ return {
867
+ success: false,
868
+ path,
869
+ executedTransitions,
870
+ finalActiveStates: this.getActiveStates(),
871
+ error: result.error,
872
+ durationMs: performance.now() - startTime
873
+ };
874
+ }
875
+ executedTransitions.push(transitionId);
876
+ }
877
+ return {
878
+ success: true,
879
+ path,
880
+ executedTransitions,
881
+ finalActiveStates: this.getActiveStates(),
882
+ durationMs: performance.now() - startTime
883
+ };
884
+ }
885
+ /**
886
+ * Create a state snapshot
887
+ */
888
+ createStateSnapshot() {
889
+ return {
890
+ timestamp: Date.now(),
891
+ activeStates: this.getActiveStates(),
892
+ states: this.getAllStates(),
893
+ groups: this.getAllStateGroups(),
894
+ transitions: this.getAllTransitions()
895
+ };
896
+ }
897
+ /**
898
+ * Create a snapshot of the current state
899
+ */
900
+ createSnapshot() {
901
+ return {
902
+ timestamp: Date.now(),
903
+ elements: this.getAllElements().map((el) => ({
904
+ id: el.id,
905
+ type: el.type,
906
+ label: el.label,
907
+ identifier: el.getIdentifier(),
908
+ state: el.getState(),
909
+ actions: el.actions,
910
+ customActions: el.customActions ? Object.keys(el.customActions) : void 0
911
+ })),
912
+ components: this.getAllComponents().map((comp) => ({
913
+ id: comp.id,
914
+ name: comp.name,
915
+ description: comp.description,
916
+ actions: comp.actions.map((a) => a.id),
917
+ elementIds: comp.elementIds
918
+ })),
919
+ workflows: this.getAllWorkflows().map((wf) => ({
920
+ id: wf.id,
921
+ name: wf.name,
922
+ description: wf.description,
923
+ stepCount: wf.steps.length
924
+ }))
925
+ };
926
+ }
927
+ /**
928
+ * Clear all registrations
929
+ */
930
+ clear() {
931
+ this.elements.clear();
932
+ this.components.clear();
933
+ this.workflows.clear();
934
+ this.eventListeners.clear();
935
+ this.states.clear();
936
+ this.stateGroups.clear();
937
+ this.transitions.clear();
938
+ this.activeStates.clear();
939
+ }
940
+ /**
941
+ * Get registry statistics
942
+ */
943
+ getStats() {
944
+ const elements = this.getAllElements();
945
+ const components = this.getAllComponents();
946
+ return {
947
+ elementCount: elements.length,
948
+ componentCount: components.length,
949
+ workflowCount: this.workflows.size,
950
+ mountedElementCount: elements.filter((e) => e.mounted).length,
951
+ mountedComponentCount: components.filter((c) => c.mounted).length,
952
+ stateCount: this.states.size,
953
+ stateGroupCount: this.stateGroups.size,
954
+ transitionCount: this.transitions.size,
955
+ activeStateCount: this.activeStates.size
956
+ };
957
+ }
958
+ };
959
+ var globalRegistry = null;
960
+ function getGlobalRegistry() {
961
+ if (!globalRegistry) {
962
+ globalRegistry = new UIBridgeRegistry();
963
+ }
964
+ return globalRegistry;
965
+ }
966
+ function setGlobalRegistry(registry) {
967
+ globalRegistry = registry;
968
+ }
969
+ function resetGlobalRegistry() {
970
+ globalRegistry?.clear();
971
+ globalRegistry = null;
972
+ }
973
+
974
+ // src/core/websocket-client.ts
975
+ function generateId() {
976
+ return `${Date.now()}-${Math.random().toString(36).slice(2, 11)}`;
977
+ }
978
+ var UIBridgeWSClient = class {
979
+ constructor(config) {
980
+ this.ws = null;
981
+ this.state = "disconnected";
982
+ this.clientId = null;
983
+ this.reconnectAttempts = 0;
984
+ this.reconnectTimer = null;
985
+ this.pingTimer = null;
986
+ this.pendingRequests = /* @__PURE__ */ new Map();
987
+ // Event listeners
988
+ this.connectionListeners = /* @__PURE__ */ new Set();
989
+ this.eventListeners = /* @__PURE__ */ new Map();
990
+ this.errorListeners = /* @__PURE__ */ new Set();
991
+ // Current subscriptions
992
+ this.subscriptions = {};
993
+ this.config = {
994
+ url: config.url,
995
+ autoReconnect: config.autoReconnect ?? true,
996
+ reconnectDelay: config.reconnectDelay ?? 1e3,
997
+ maxReconnectAttempts: config.maxReconnectAttempts ?? 10,
998
+ pingInterval: config.pingInterval ?? 3e4,
999
+ connectionTimeout: config.connectionTimeout ?? 1e4
1000
+ };
1001
+ }
1002
+ /**
1003
+ * Get current connection state
1004
+ */
1005
+ get connectionState() {
1006
+ return this.state;
1007
+ }
1008
+ /**
1009
+ * Get assigned client ID
1010
+ */
1011
+ get id() {
1012
+ return this.clientId;
1013
+ }
1014
+ /**
1015
+ * Connect to the WebSocket server
1016
+ */
1017
+ connect() {
1018
+ return new Promise((resolve, reject) => {
1019
+ if (this.ws && this.state === "connected") {
1020
+ resolve();
1021
+ return;
1022
+ }
1023
+ this.setState("connecting");
1024
+ try {
1025
+ this.ws = new WebSocket(this.config.url);
1026
+ } catch (error) {
1027
+ this.setState("disconnected");
1028
+ reject(error);
1029
+ return;
1030
+ }
1031
+ const connectionTimeout = setTimeout(() => {
1032
+ if (this.state === "connecting") {
1033
+ this.ws?.close();
1034
+ this.setState("disconnected");
1035
+ reject(new Error("Connection timeout"));
1036
+ }
1037
+ }, this.config.connectionTimeout);
1038
+ this.ws.onopen = () => {
1039
+ clearTimeout(connectionTimeout);
1040
+ };
1041
+ this.ws.onmessage = (event) => {
1042
+ try {
1043
+ const message = JSON.parse(event.data);
1044
+ this.handleMessage(message);
1045
+ if (message.type === "welcome") {
1046
+ clearTimeout(connectionTimeout);
1047
+ this.reconnectAttempts = 0;
1048
+ this.setState("connected");
1049
+ this.startPingInterval();
1050
+ if (this.subscriptions.events?.length || this.subscriptions.elementIds?.length || this.subscriptions.componentIds?.length) {
1051
+ this.subscribe(this.subscriptions);
1052
+ }
1053
+ resolve();
1054
+ }
1055
+ } catch (error) {
1056
+ console.error("Failed to parse WebSocket message:", error);
1057
+ }
1058
+ };
1059
+ this.ws.onerror = (_event) => {
1060
+ clearTimeout(connectionTimeout);
1061
+ const error = new Error("WebSocket error");
1062
+ this.notifyError(error);
1063
+ if (this.state === "connecting") {
1064
+ reject(error);
1065
+ }
1066
+ };
1067
+ this.ws.onclose = () => {
1068
+ clearTimeout(connectionTimeout);
1069
+ this.stopPingInterval();
1070
+ this.clientId = null;
1071
+ const wasConnected = this.state === "connected";
1072
+ this.setState("disconnected");
1073
+ for (const [_id, pending] of this.pendingRequests) {
1074
+ clearTimeout(pending.timeout);
1075
+ pending.reject(new Error("Connection closed"));
1076
+ }
1077
+ this.pendingRequests.clear();
1078
+ if (wasConnected && this.config.autoReconnect && (this.config.maxReconnectAttempts === 0 || this.reconnectAttempts < this.config.maxReconnectAttempts)) {
1079
+ this.scheduleReconnect();
1080
+ }
1081
+ };
1082
+ });
1083
+ }
1084
+ /**
1085
+ * Disconnect from the server
1086
+ */
1087
+ disconnect() {
1088
+ if (this.reconnectTimer) {
1089
+ clearTimeout(this.reconnectTimer);
1090
+ this.reconnectTimer = null;
1091
+ }
1092
+ this.stopPingInterval();
1093
+ if (this.ws) {
1094
+ this.ws.close();
1095
+ this.ws = null;
1096
+ }
1097
+ this.setState("disconnected");
1098
+ }
1099
+ /**
1100
+ * Subscribe to events
1101
+ */
1102
+ async subscribe(options) {
1103
+ this.subscriptions = { ...this.subscriptions, ...options };
1104
+ const response = await this.sendRequest({
1105
+ id: generateId(),
1106
+ type: "subscribe",
1107
+ timestamp: Date.now(),
1108
+ payload: options
1109
+ });
1110
+ return response.events;
1111
+ }
1112
+ /**
1113
+ * Unsubscribe from events
1114
+ */
1115
+ async unsubscribe(events) {
1116
+ if (events) {
1117
+ this.subscriptions.events = this.subscriptions.events?.filter((e) => !events.includes(e));
1118
+ } else {
1119
+ this.subscriptions = {};
1120
+ }
1121
+ const response = await this.sendRequest({
1122
+ id: generateId(),
1123
+ type: "unsubscribe",
1124
+ timestamp: Date.now(),
1125
+ payload: { events }
1126
+ });
1127
+ return response.events;
1128
+ }
1129
+ /**
1130
+ * Find elements
1131
+ */
1132
+ async find(options) {
1133
+ const response = await this.sendRequest({
1134
+ id: generateId(),
1135
+ type: "find",
1136
+ timestamp: Date.now(),
1137
+ payload: options
1138
+ });
1139
+ return response.elements;
1140
+ }
1141
+ /**
1142
+ * Discover elements
1143
+ * @deprecated Use find() instead
1144
+ */
1145
+ async discover(options) {
1146
+ return this.find(options);
1147
+ }
1148
+ /**
1149
+ * Get element details
1150
+ */
1151
+ async getElement(elementId, includeState = true) {
1152
+ const response = await this.sendRequest({
1153
+ id: generateId(),
1154
+ type: "getElement",
1155
+ timestamp: Date.now(),
1156
+ payload: { elementId, includeState }
1157
+ });
1158
+ return response.element;
1159
+ }
1160
+ /**
1161
+ * Get full snapshot
1162
+ */
1163
+ async getSnapshot() {
1164
+ const response = await this.sendRequest({
1165
+ id: generateId(),
1166
+ type: "getSnapshot",
1167
+ timestamp: Date.now()
1168
+ });
1169
+ return response;
1170
+ }
1171
+ /**
1172
+ * Execute action on an element
1173
+ */
1174
+ async executeAction(elementId, action) {
1175
+ const response = await this.sendRequest({
1176
+ id: generateId(),
1177
+ type: "executeAction",
1178
+ timestamp: Date.now(),
1179
+ payload: { elementId, action }
1180
+ });
1181
+ return response;
1182
+ }
1183
+ /**
1184
+ * Execute component action
1185
+ */
1186
+ async executeComponentAction(componentId, action, params) {
1187
+ const response = await this.sendRequest({
1188
+ id: generateId(),
1189
+ type: "executeComponentAction",
1190
+ timestamp: Date.now(),
1191
+ payload: { componentId, action, params }
1192
+ });
1193
+ return response;
1194
+ }
1195
+ /**
1196
+ * Execute workflow with optional progress streaming
1197
+ */
1198
+ async executeWorkflow(workflowId, params, onProgress) {
1199
+ const id = generateId();
1200
+ const progressHandler = onProgress ? (message) => {
1201
+ if (message.type === "workflowProgress" && message.requestId === id) {
1202
+ onProgress({
1203
+ currentStep: message.payload.currentStep,
1204
+ totalSteps: message.payload.totalSteps,
1205
+ step: {
1206
+ id: message.payload.step.id,
1207
+ status: message.payload.step.status
1208
+ }
1209
+ });
1210
+ }
1211
+ } : void 0;
1212
+ const response = await this.sendRequest(
1213
+ {
1214
+ id,
1215
+ type: "executeWorkflow",
1216
+ timestamp: Date.now(),
1217
+ payload: { workflowId, params, streamProgress: !!onProgress }
1218
+ },
1219
+ progressHandler
1220
+ );
1221
+ return response;
1222
+ }
1223
+ /**
1224
+ * Add connection state listener
1225
+ */
1226
+ onConnectionChange(listener) {
1227
+ this.connectionListeners.add(listener);
1228
+ return () => this.connectionListeners.delete(listener);
1229
+ }
1230
+ /**
1231
+ * Add event listener
1232
+ */
1233
+ onEvent(eventType, listener) {
1234
+ if (!this.eventListeners.has(eventType)) {
1235
+ this.eventListeners.set(eventType, /* @__PURE__ */ new Set());
1236
+ }
1237
+ this.eventListeners.get(eventType).add(listener);
1238
+ return () => this.eventListeners.get(eventType)?.delete(listener);
1239
+ }
1240
+ /**
1241
+ * Add error listener
1242
+ */
1243
+ onError(listener) {
1244
+ this.errorListeners.add(listener);
1245
+ return () => this.errorListeners.delete(listener);
1246
+ }
1247
+ // Private methods
1248
+ setState(state) {
1249
+ this.state = state;
1250
+ for (const listener of this.connectionListeners) {
1251
+ try {
1252
+ listener(state);
1253
+ } catch (error) {
1254
+ console.error("Connection listener error:", error);
1255
+ }
1256
+ }
1257
+ }
1258
+ handleMessage(message) {
1259
+ switch (message.type) {
1260
+ case "welcome":
1261
+ this.clientId = message.payload.clientId;
1262
+ break;
1263
+ case "pong":
1264
+ break;
1265
+ case "subscribed":
1266
+ case "unsubscribed":
1267
+ break;
1268
+ case "event":
1269
+ this.notifyEvent(message.payload);
1270
+ break;
1271
+ case "response":
1272
+ this.handleResponse(message);
1273
+ break;
1274
+ case "error":
1275
+ if (message.requestId) {
1276
+ this.handleResponse({
1277
+ ...message,
1278
+ type: "response",
1279
+ requestId: message.requestId,
1280
+ payload: {
1281
+ success: false,
1282
+ error: message.payload.message
1283
+ }
1284
+ });
1285
+ } else {
1286
+ this.notifyError(new Error(message.payload.message));
1287
+ }
1288
+ break;
1289
+ }
1290
+ }
1291
+ handleResponse(message) {
1292
+ const pending = this.pendingRequests.get(message.requestId);
1293
+ if (!pending) return;
1294
+ clearTimeout(pending.timeout);
1295
+ this.pendingRequests.delete(message.requestId);
1296
+ if (message.type === "response") {
1297
+ if (message.payload.success) {
1298
+ pending.resolve(message.payload.data);
1299
+ } else {
1300
+ pending.reject(new Error(message.payload.error || "Request failed"));
1301
+ }
1302
+ }
1303
+ }
1304
+ notifyEvent(event) {
1305
+ const typeListeners = this.eventListeners.get(event.type);
1306
+ if (typeListeners) {
1307
+ for (const listener of typeListeners) {
1308
+ try {
1309
+ listener(event);
1310
+ } catch (error) {
1311
+ console.error("Event listener error:", error);
1312
+ }
1313
+ }
1314
+ }
1315
+ const wildcardListeners = this.eventListeners.get("*");
1316
+ if (wildcardListeners) {
1317
+ for (const listener of wildcardListeners) {
1318
+ try {
1319
+ listener(event);
1320
+ } catch (error) {
1321
+ console.error("Event listener error:", error);
1322
+ }
1323
+ }
1324
+ }
1325
+ }
1326
+ notifyError(error) {
1327
+ for (const listener of this.errorListeners) {
1328
+ try {
1329
+ listener(error);
1330
+ } catch (e) {
1331
+ console.error("Error listener error:", e);
1332
+ }
1333
+ }
1334
+ }
1335
+ sendRequest(message, progressHandler) {
1336
+ return new Promise((resolve, reject) => {
1337
+ if (!this.ws || this.state !== "connected") {
1338
+ reject(new Error("Not connected"));
1339
+ return;
1340
+ }
1341
+ const timeout = setTimeout(() => {
1342
+ this.pendingRequests.delete(message.id);
1343
+ reject(new Error("Request timeout"));
1344
+ }, 3e4);
1345
+ this.pendingRequests.set(message.id, {
1346
+ resolve,
1347
+ reject,
1348
+ timeout
1349
+ });
1350
+ if (progressHandler && this.ws) {
1351
+ const originalHandler = this.ws.onmessage;
1352
+ const wsRef = this.ws;
1353
+ const wrappedHandler = (event) => {
1354
+ try {
1355
+ const msg = JSON.parse(event.data);
1356
+ if (msg.type === "workflowProgress") {
1357
+ progressHandler(msg);
1358
+ }
1359
+ } catch {
1360
+ }
1361
+ if (originalHandler) {
1362
+ originalHandler.call(wsRef, event);
1363
+ }
1364
+ };
1365
+ this.ws.onmessage = wrappedHandler;
1366
+ }
1367
+ this.ws.send(JSON.stringify(message));
1368
+ });
1369
+ }
1370
+ scheduleReconnect() {
1371
+ if (this.reconnectTimer) return;
1372
+ this.setState("reconnecting");
1373
+ this.reconnectAttempts++;
1374
+ const delay = Math.min(
1375
+ this.config.reconnectDelay * Math.pow(2, this.reconnectAttempts - 1),
1376
+ 3e4
1377
+ );
1378
+ this.reconnectTimer = setTimeout(() => {
1379
+ this.reconnectTimer = null;
1380
+ this.connect().catch(() => {
1381
+ });
1382
+ }, delay);
1383
+ }
1384
+ startPingInterval() {
1385
+ if (this.config.pingInterval <= 0) return;
1386
+ this.pingTimer = setInterval(() => {
1387
+ if (this.ws && this.state === "connected") {
1388
+ this.ws.send(
1389
+ JSON.stringify({
1390
+ id: generateId(),
1391
+ type: "ping",
1392
+ timestamp: Date.now()
1393
+ })
1394
+ );
1395
+ }
1396
+ }, this.config.pingInterval);
1397
+ }
1398
+ stopPingInterval() {
1399
+ if (this.pingTimer) {
1400
+ clearInterval(this.pingTimer);
1401
+ this.pingTimer = null;
1402
+ }
1403
+ }
1404
+ };
1405
+ function createWSClient(config) {
1406
+ return new UIBridgeWSClient(config);
1407
+ }
1408
+
1409
+ exports.ID_ATTRIBUTES = ID_ATTRIBUTES;
1410
+ exports.UIBridgeRegistry = UIBridgeRegistry;
1411
+ exports.UIBridgeWSClient = UIBridgeWSClient;
1412
+ exports.createElementIdentifier = createElementIdentifier;
1413
+ exports.createWSClient = createWSClient;
1414
+ exports.elementMatchesIdentifier = elementMatchesIdentifier;
1415
+ exports.findAllElementsByIdentifier = findAllElementsByIdentifier;
1416
+ exports.findElementByIdentifier = findElementByIdentifier;
1417
+ exports.generateCSSSelector = generateCSSSelector;
1418
+ exports.generateXPath = generateXPath;
1419
+ exports.getBestIdentifier = getBestIdentifier;
1420
+ exports.getGlobalRegistry = getGlobalRegistry;
1421
+ exports.resetGlobalRegistry = resetGlobalRegistry;
1422
+ exports.setGlobalRegistry = setGlobalRegistry;
1423
+ //# sourceMappingURL=index.js.map
1424
+ //# sourceMappingURL=index.js.map