@qontinui/ui-bridge 0.1.1 → 0.3.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.
Files changed (112) hide show
  1. package/dist/ai/index.d.mts +893 -0
  2. package/dist/ai/index.d.ts +893 -0
  3. package/dist/ai/index.js +3897 -0
  4. package/dist/ai/index.js.map +1 -0
  5. package/dist/ai/index.mjs +3839 -0
  6. package/dist/ai/index.mjs.map +1 -0
  7. package/dist/babel-plugin/index.js +515 -0
  8. package/dist/babel-plugin/index.js.map +1 -0
  9. package/dist/babel-plugin/index.mjs +499 -0
  10. package/dist/babel-plugin/index.mjs.map +1 -0
  11. package/dist/control/index.d.mts +5 -4
  12. package/dist/control/index.d.ts +5 -4
  13. package/dist/core/index.d.mts +115 -42
  14. package/dist/core/index.d.ts +115 -42
  15. package/dist/core/index.js +0 -983
  16. package/dist/core/index.js.map +1 -1
  17. package/dist/core/index.mjs +1 -972
  18. package/dist/core/index.mjs.map +1 -1
  19. package/dist/debug/index.d.mts +3 -3
  20. package/dist/debug/index.d.ts +3 -3
  21. package/dist/index.d.mts +8 -7
  22. package/dist/index.d.ts +8 -7
  23. package/dist/index.js +8249 -4163
  24. package/dist/index.js.map +1 -1
  25. package/dist/index.mjs +8193 -4152
  26. package/dist/index.mjs.map +1 -1
  27. package/dist/{metrics-QCnK0EFw.d.ts → metrics-BfiT_rhZ.d.ts} +2 -2
  28. package/dist/{metrics-BCG7z7Aq.d.mts → metrics-DTA2bwG7.d.mts} +2 -2
  29. package/dist/native/control/index.js +453 -0
  30. package/dist/native/control/index.js.map +1 -0
  31. package/dist/native/control/index.mjs +450 -0
  32. package/dist/native/control/index.mjs.map +1 -0
  33. package/dist/native/core/index.js +486 -0
  34. package/dist/native/core/index.js.map +1 -0
  35. package/dist/native/core/index.mjs +475 -0
  36. package/dist/native/core/index.mjs.map +1 -0
  37. package/dist/native/debug/index.js +451 -0
  38. package/dist/native/debug/index.js.map +1 -0
  39. package/dist/native/debug/index.mjs +449 -0
  40. package/dist/native/debug/index.mjs.map +1 -0
  41. package/dist/native/index.js +2274 -0
  42. package/dist/native/index.js.map +1 -0
  43. package/dist/native/index.mjs +2246 -0
  44. package/dist/native/index.mjs.map +1 -0
  45. package/dist/native/react/index.js +1401 -0
  46. package/dist/native/react/index.js.map +1 -0
  47. package/dist/native/react/index.mjs +1389 -0
  48. package/dist/native/react/index.mjs.map +1 -0
  49. package/dist/native/server/index.js +415 -0
  50. package/dist/native/server/index.js.map +1 -0
  51. package/dist/native/server/index.mjs +410 -0
  52. package/dist/native/server/index.mjs.map +1 -0
  53. package/dist/react/index.d.mts +20 -6
  54. package/dist/react/index.d.ts +20 -6
  55. package/dist/react/index.js +629 -14
  56. package/dist/react/index.js.map +1 -1
  57. package/dist/react/index.mjs +629 -14
  58. package/dist/react/index.mjs.map +1 -1
  59. package/dist/{registry-CT6BVVKr.d.mts → registry-BKLEm-yk.d.ts} +29 -14
  60. package/dist/{registry-D4mQ01B3.d.ts → registry-BmZgyCz8.d.mts} +29 -14
  61. package/dist/render-log/index.d.mts +1 -1
  62. package/dist/render-log/index.d.ts +1 -1
  63. package/dist/server/express.d.mts +36 -0
  64. package/dist/server/express.d.ts +36 -0
  65. package/dist/server/express.js +196 -0
  66. package/dist/server/express.js.map +1 -0
  67. package/dist/server/express.mjs +192 -0
  68. package/dist/server/express.mjs.map +1 -0
  69. package/dist/server/handlers.d.mts +93 -0
  70. package/dist/server/handlers.d.ts +93 -0
  71. package/dist/server/handlers.js +4278 -0
  72. package/dist/server/handlers.js.map +1 -0
  73. package/dist/server/handlers.mjs +4275 -0
  74. package/dist/server/handlers.mjs.map +1 -0
  75. package/dist/server/index.d.mts +10 -0
  76. package/dist/server/index.d.ts +10 -0
  77. package/dist/server/index.js +5352 -0
  78. package/dist/server/index.js.map +1 -0
  79. package/dist/server/index.mjs +5337 -0
  80. package/dist/server/index.mjs.map +1 -0
  81. package/dist/server/nextjs.d.mts +126 -0
  82. package/dist/server/nextjs.d.ts +126 -0
  83. package/dist/server/nextjs.js +287 -0
  84. package/dist/server/nextjs.js.map +1 -0
  85. package/dist/server/nextjs.mjs +282 -0
  86. package/dist/server/nextjs.mjs.map +1 -0
  87. package/dist/server/standalone.d.mts +6 -0
  88. package/dist/server/standalone.d.ts +6 -0
  89. package/dist/server/standalone.js +719 -0
  90. package/dist/server/standalone.js.map +1 -0
  91. package/dist/server/standalone.mjs +715 -0
  92. package/dist/server/standalone.mjs.map +1 -0
  93. package/dist/standalone-BURj8J3G.d.ts +212 -0
  94. package/dist/standalone-Dwmel29d.d.mts +212 -0
  95. package/dist/swc-plugin/index.d.mts +79 -0
  96. package/dist/swc-plugin/index.d.ts +79 -0
  97. package/dist/swc-plugin/index.js +15 -0
  98. package/dist/swc-plugin/index.js.map +1 -0
  99. package/dist/swc-plugin/index.mjs +9 -0
  100. package/dist/swc-plugin/index.mjs.map +1 -0
  101. package/dist/types-B5Q0GVo0.d.mts +646 -0
  102. package/dist/{types-DdJD9yw5.d.mts → types-B7J7noLK.d.mts} +1 -1
  103. package/dist/{types-BDkXy5si.d.ts → types-BkNRILUa.d.ts} +1 -1
  104. package/dist/types-CEQLnFMv.d.mts +156 -0
  105. package/dist/types-CHnlwiTK.d.ts +156 -0
  106. package/dist/types-DfPqwU-i.d.ts +646 -0
  107. package/dist/{types-BpvpStn3.d.mts → types-jKVgTI6_.d.mts} +364 -160
  108. package/dist/{types-BpvpStn3.d.ts → types-jKVgTI6_.d.ts} +364 -160
  109. package/package.json +111 -3
  110. package/swc-plugin-wasm/ui_bridge_swc_plugin.wasm +0 -0
  111. package/dist/websocket-client-B2LC9CYc.d.mts +0 -124
  112. package/dist/websocket-client-DupH0X7B.d.ts +0 -124
@@ -1,974 +1,3 @@
1
- // src/core/element-identifier.ts
2
- var ID_ATTRIBUTES = ["data-ui-id", "data-testid", "data-awas-element", "id"];
3
- function generateXPath(element) {
4
- if (element.id) {
5
- return `//*[@id="${element.id}"]`;
6
- }
7
- const parts = [];
8
- let current = element;
9
- while (current && current.nodeType === Node.ELEMENT_NODE) {
10
- let selector = current.nodeName.toLowerCase();
11
- const uiId = current.getAttribute("data-ui-id");
12
- if (uiId) {
13
- selector += `[@data-ui-id="${uiId}"]`;
14
- parts.unshift(selector);
15
- break;
16
- }
17
- const testId = current.getAttribute("data-testid");
18
- if (testId) {
19
- selector += `[@data-testid="${testId}"]`;
20
- parts.unshift(selector);
21
- break;
22
- }
23
- const id = current.id;
24
- if (id) {
25
- selector += `[@id="${id}"]`;
26
- parts.unshift(selector);
27
- break;
28
- }
29
- const parentEl = current.parentElement;
30
- if (parentEl) {
31
- const currentEl = current;
32
- const siblings = Array.from(parentEl.children).filter(
33
- (child) => child.nodeName === currentEl.nodeName
34
- );
35
- if (siblings.length > 1) {
36
- const index = siblings.indexOf(currentEl) + 1;
37
- selector += `[${index}]`;
38
- }
39
- }
40
- parts.unshift(selector);
41
- current = parentEl;
42
- }
43
- return "/" + parts.join("/");
44
- }
45
- function generateCSSSelector(element) {
46
- const uiId = element.getAttribute("data-ui-id");
47
- if (uiId) {
48
- return `[data-ui-id="${uiId}"]`;
49
- }
50
- const testId = element.getAttribute("data-testid");
51
- if (testId) {
52
- return `[data-testid="${testId}"]`;
53
- }
54
- const awasId = element.getAttribute("data-awas-element");
55
- if (awasId) {
56
- return `[data-awas-element="${awasId}"]`;
57
- }
58
- if (element.id) {
59
- return `#${CSS.escape(element.id)}`;
60
- }
61
- const path = [];
62
- let current = element;
63
- while (current && current.nodeType === Node.ELEMENT_NODE) {
64
- let selector = current.nodeName.toLowerCase();
65
- const parentUiId = current.getAttribute("data-ui-id");
66
- if (parentUiId && current !== element) {
67
- path.unshift(`[data-ui-id="${parentUiId}"]`);
68
- break;
69
- }
70
- const parentTestId = current.getAttribute("data-testid");
71
- if (parentTestId && current !== element) {
72
- path.unshift(`[data-testid="${parentTestId}"]`);
73
- break;
74
- }
75
- if (current.id) {
76
- path.unshift(`#${CSS.escape(current.id)}`);
77
- break;
78
- }
79
- const parentEl = current.parentElement;
80
- if (parentEl) {
81
- const currentEl = current;
82
- const siblings = Array.from(parentEl.children);
83
- const sameTagSiblings = siblings.filter(
84
- (s) => s.nodeName === currentEl.nodeName
85
- );
86
- if (sameTagSiblings.length > 1) {
87
- const index = siblings.indexOf(currentEl) + 1;
88
- selector += `:nth-child(${index})`;
89
- }
90
- }
91
- path.unshift(selector);
92
- current = current.parentElement;
93
- }
94
- return path.join(" > ");
95
- }
96
- function getBestIdentifier(element) {
97
- const uiId = element.getAttribute("data-ui-id");
98
- if (uiId) return uiId;
99
- const testId = element.getAttribute("data-testid");
100
- if (testId) return testId;
101
- const awasId = element.getAttribute("data-awas-element");
102
- if (awasId) return awasId;
103
- if (element.id) return element.id;
104
- return generateCSSSelector(element);
105
- }
106
- function createElementIdentifier(element) {
107
- return {
108
- uiId: element.getAttribute("data-ui-id") || void 0,
109
- testId: element.getAttribute("data-testid") || void 0,
110
- awasId: element.getAttribute("data-awas-element") || void 0,
111
- htmlId: element.id || void 0,
112
- xpath: generateXPath(element),
113
- selector: generateCSSSelector(element)
114
- };
115
- }
116
- function findElementByIdentifier(identifier, root = document) {
117
- if (typeof identifier === "string") {
118
- const byUiId = root.querySelector(`[data-ui-id="${identifier}"]`);
119
- if (byUiId) return byUiId;
120
- const byTestId = root.querySelector(`[data-testid="${identifier}"]`);
121
- if (byTestId) return byTestId;
122
- const byAwasId = root.querySelector(`[data-awas-element="${identifier}"]`);
123
- if (byAwasId) return byAwasId;
124
- const byId = root.querySelector(`#${CSS.escape(identifier)}`);
125
- if (byId) return byId;
126
- try {
127
- const bySelector = root.querySelector(identifier);
128
- if (bySelector) return bySelector;
129
- } catch {
130
- }
131
- try {
132
- const result = document.evaluate(
133
- identifier,
134
- root,
135
- null,
136
- XPathResult.FIRST_ORDERED_NODE_TYPE,
137
- null
138
- );
139
- if (result.singleNodeValue instanceof HTMLElement) {
140
- return result.singleNodeValue;
141
- }
142
- } catch {
143
- }
144
- return null;
145
- }
146
- if (identifier.uiId) {
147
- const el = root.querySelector(`[data-ui-id="${identifier.uiId}"]`);
148
- if (el) return el;
149
- }
150
- if (identifier.testId) {
151
- const el = root.querySelector(`[data-testid="${identifier.testId}"]`);
152
- if (el) return el;
153
- }
154
- if (identifier.awasId) {
155
- const el = root.querySelector(`[data-awas-element="${identifier.awasId}"]`);
156
- if (el) return el;
157
- }
158
- if (identifier.htmlId) {
159
- const el = root.querySelector(`#${CSS.escape(identifier.htmlId)}`);
160
- if (el) return el;
161
- }
162
- if (identifier.selector) {
163
- try {
164
- const el = root.querySelector(identifier.selector);
165
- if (el) return el;
166
- } catch {
167
- }
168
- }
169
- if (identifier.xpath) {
170
- try {
171
- const result = document.evaluate(
172
- identifier.xpath,
173
- root,
174
- null,
175
- XPathResult.FIRST_ORDERED_NODE_TYPE,
176
- null
177
- );
178
- if (result.singleNodeValue instanceof HTMLElement) {
179
- return result.singleNodeValue;
180
- }
181
- } catch {
182
- }
183
- }
184
- return null;
185
- }
186
- function findAllElementsByIdentifier(pattern, root = document) {
187
- const results = [];
188
- try {
189
- const elements = root.querySelectorAll(pattern);
190
- results.push(...Array.from(elements));
191
- if (results.length > 0) return results;
192
- } catch {
193
- }
194
- const partials = [
195
- `[data-ui-id*="${pattern}"]`,
196
- `[data-testid*="${pattern}"]`,
197
- `[data-awas-element*="${pattern}"]`,
198
- `[id*="${pattern}"]`
199
- ];
200
- for (const selector of partials) {
201
- try {
202
- const elements = root.querySelectorAll(selector);
203
- for (const el of elements) {
204
- if (!results.includes(el)) {
205
- results.push(el);
206
- }
207
- }
208
- } catch {
209
- }
210
- }
211
- return results;
212
- }
213
- function elementMatchesIdentifier(element, identifier) {
214
- if (typeof identifier === "string") {
215
- return element.getAttribute("data-ui-id") === identifier || element.getAttribute("data-testid") === identifier || element.getAttribute("data-awas-element") === identifier || element.id === identifier || element.matches(identifier);
216
- }
217
- 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;
218
- }
219
-
220
- // src/core/registry.ts
221
- function getElementState(element) {
222
- const rect = element.getBoundingClientRect();
223
- const computedStyle = window.getComputedStyle(element);
224
- const state = {
225
- visible: isElementVisible(element, rect, computedStyle),
226
- enabled: !isElementDisabled(element),
227
- focused: document.activeElement === element,
228
- rect: {
229
- x: rect.x,
230
- y: rect.y,
231
- width: rect.width,
232
- height: rect.height,
233
- top: rect.top,
234
- right: rect.right,
235
- bottom: rect.bottom,
236
- left: rect.left
237
- },
238
- textContent: element.textContent?.trim() || void 0,
239
- computedStyles: {
240
- display: computedStyle.display,
241
- visibility: computedStyle.visibility,
242
- opacity: computedStyle.opacity,
243
- pointerEvents: computedStyle.pointerEvents
244
- }
245
- };
246
- if (element instanceof HTMLInputElement) {
247
- state.value = element.value;
248
- if (element.type === "checkbox" || element.type === "radio") {
249
- state.checked = element.checked;
250
- }
251
- } else if (element instanceof HTMLTextAreaElement) {
252
- state.value = element.value;
253
- } else if (element instanceof HTMLSelectElement) {
254
- state.value = element.value;
255
- state.selectedOptions = Array.from(element.selectedOptions).map((opt) => opt.value);
256
- }
257
- return state;
258
- }
259
- function isElementVisible(element, rect, style) {
260
- if (rect.width === 0 || rect.height === 0) return false;
261
- if (style.display === "none") return false;
262
- if (style.visibility === "hidden") return false;
263
- if (parseFloat(style.opacity) === 0) return false;
264
- const inViewport = rect.top < window.innerHeight && rect.bottom > 0 && rect.left < window.innerWidth && rect.right > 0;
265
- return inViewport;
266
- }
267
- function isElementDisabled(element) {
268
- if ("disabled" in element && element.disabled) {
269
- return true;
270
- }
271
- if (element.getAttribute("aria-disabled") === "true") {
272
- return true;
273
- }
274
- return false;
275
- }
276
- function inferActions(type) {
277
- const baseActions = ["focus", "blur", "hover"];
278
- switch (type) {
279
- case "button":
280
- return [...baseActions, "click", "doubleClick", "rightClick"];
281
- case "input":
282
- return [...baseActions, "click", "type", "clear"];
283
- case "textarea":
284
- return [...baseActions, "click", "type", "clear"];
285
- case "select":
286
- return [...baseActions, "click", "select"];
287
- case "checkbox":
288
- return [...baseActions, "click", "check", "uncheck", "toggle"];
289
- case "radio":
290
- return [...baseActions, "click", "check"];
291
- case "link":
292
- return [...baseActions, "click"];
293
- case "form":
294
- return ["focus", "blur"];
295
- case "menu":
296
- case "menuitem":
297
- return [...baseActions, "click"];
298
- case "tab":
299
- return [...baseActions, "click"];
300
- case "dialog":
301
- return ["focus", "blur"];
302
- case "custom":
303
- default:
304
- return [...baseActions, "click"];
305
- }
306
- }
307
- function inferElementType(element) {
308
- const tagName = element.tagName.toLowerCase();
309
- const role = element.getAttribute("role");
310
- if (role) {
311
- switch (role) {
312
- case "button":
313
- return "button";
314
- case "textbox":
315
- return "input";
316
- case "checkbox":
317
- return "checkbox";
318
- case "radio":
319
- return "radio";
320
- case "link":
321
- return "link";
322
- case "listbox":
323
- case "combobox":
324
- return "select";
325
- case "menu":
326
- return "menu";
327
- case "menuitem":
328
- return "menuitem";
329
- case "tab":
330
- return "tab";
331
- case "dialog":
332
- return "dialog";
333
- }
334
- }
335
- switch (tagName) {
336
- case "button":
337
- return "button";
338
- case "input": {
339
- const inputType = element.type;
340
- if (inputType === "checkbox") return "checkbox";
341
- if (inputType === "radio") return "radio";
342
- if (inputType === "submit" || inputType === "button") return "button";
343
- return "input";
344
- }
345
- case "textarea":
346
- return "textarea";
347
- case "select":
348
- return "select";
349
- case "a":
350
- return "link";
351
- case "form":
352
- return "form";
353
- default:
354
- return "custom";
355
- }
356
- }
357
- var UIBridgeRegistry = class {
358
- constructor(options = {}) {
359
- this.elements = /* @__PURE__ */ new Map();
360
- this.components = /* @__PURE__ */ new Map();
361
- this.workflows = /* @__PURE__ */ new Map();
362
- this.eventListeners = /* @__PURE__ */ new Map();
363
- // State management
364
- this.states = /* @__PURE__ */ new Map();
365
- this.stateGroups = /* @__PURE__ */ new Map();
366
- this.transitions = /* @__PURE__ */ new Map();
367
- this.activeStates = /* @__PURE__ */ new Set();
368
- this.options = options;
369
- }
370
- /**
371
- * Emit an event
372
- */
373
- emit(type, data) {
374
- const event = {
375
- type,
376
- timestamp: Date.now(),
377
- data
378
- };
379
- this.options.onEvent?.(event);
380
- const listeners = this.eventListeners.get(type);
381
- if (listeners) {
382
- for (const listener of listeners) {
383
- try {
384
- listener(event);
385
- } catch (error) {
386
- console.error(`Error in event listener for ${type}:`, error);
387
- }
388
- }
389
- }
390
- if (this.options.verbose) {
391
- console.log("[UIBridge]", type, data);
392
- }
393
- }
394
- /**
395
- * Register an event listener
396
- */
397
- on(type, listener) {
398
- if (!this.eventListeners.has(type)) {
399
- this.eventListeners.set(type, /* @__PURE__ */ new Set());
400
- }
401
- this.eventListeners.get(type).add(listener);
402
- return () => {
403
- this.eventListeners.get(type)?.delete(listener);
404
- };
405
- }
406
- /**
407
- * Remove an event listener
408
- */
409
- off(type, listener) {
410
- this.eventListeners.get(type)?.delete(listener);
411
- }
412
- /**
413
- * Register an element
414
- */
415
- registerElement(id, element, options = {}) {
416
- const type = options.type ?? inferElementType(element);
417
- const actions = options.actions ?? inferActions(type);
418
- element.setAttribute("data-ui-id", id);
419
- const registered = {
420
- id,
421
- element,
422
- type,
423
- label: options.label,
424
- actions,
425
- customActions: options.customActions,
426
- getState: () => getElementState(element),
427
- getIdentifier: () => createElementIdentifier(element),
428
- registeredAt: Date.now(),
429
- mounted: true
430
- };
431
- this.elements.set(id, registered);
432
- this.emit("element:registered", { id, type, label: options.label });
433
- return registered;
434
- }
435
- /**
436
- * Unregister an element
437
- */
438
- unregisterElement(id) {
439
- const registered = this.elements.get(id);
440
- if (registered) {
441
- registered.mounted = false;
442
- registered.element.removeAttribute("data-ui-id");
443
- this.elements.delete(id);
444
- this.emit("element:unregistered", { id });
445
- return true;
446
- }
447
- return false;
448
- }
449
- /**
450
- * Get a registered element
451
- */
452
- getElement(id) {
453
- return this.elements.get(id);
454
- }
455
- /**
456
- * Get all registered elements
457
- */
458
- getAllElements() {
459
- return Array.from(this.elements.values());
460
- }
461
- /**
462
- * Find element by DOM element reference
463
- */
464
- findByDOMElement(element) {
465
- for (const registered of this.elements.values()) {
466
- if (registered.element === element) {
467
- return registered;
468
- }
469
- }
470
- return void 0;
471
- }
472
- /**
473
- * Register a component
474
- */
475
- registerComponent(id, options) {
476
- const registered = {
477
- id,
478
- name: options.name,
479
- description: options.description,
480
- actions: options.actions?.map((a) => ({
481
- id: a.id,
482
- label: a.label,
483
- description: a.description,
484
- handler: a.handler
485
- })) ?? [],
486
- elementIds: options.elementIds,
487
- registeredAt: Date.now(),
488
- mounted: true
489
- };
490
- this.components.set(id, registered);
491
- this.emit("component:registered", { id, name: options.name });
492
- return registered;
493
- }
494
- /**
495
- * Unregister a component
496
- */
497
- unregisterComponent(id) {
498
- const component = this.components.get(id);
499
- if (component) {
500
- component.mounted = false;
501
- this.components.delete(id);
502
- this.emit("component:unregistered", { id });
503
- return true;
504
- }
505
- return false;
506
- }
507
- /**
508
- * Get a registered component
509
- */
510
- getComponent(id) {
511
- return this.components.get(id);
512
- }
513
- /**
514
- * Get all registered components
515
- */
516
- getAllComponents() {
517
- return Array.from(this.components.values());
518
- }
519
- /**
520
- * Register a workflow
521
- */
522
- registerWorkflow(workflow) {
523
- this.workflows.set(workflow.id, workflow);
524
- return workflow;
525
- }
526
- /**
527
- * Unregister a workflow
528
- */
529
- unregisterWorkflow(id) {
530
- return this.workflows.delete(id);
531
- }
532
- /**
533
- * Get a workflow
534
- */
535
- getWorkflow(id) {
536
- return this.workflows.get(id);
537
- }
538
- /**
539
- * Get all workflows
540
- */
541
- getAllWorkflows() {
542
- return Array.from(this.workflows.values());
543
- }
544
- // ==========================================================================
545
- // State Management
546
- // ==========================================================================
547
- /**
548
- * Register a state
549
- */
550
- registerState(state) {
551
- this.states.set(state.id, state);
552
- this.emit("element:registered", { id: state.id, type: "state", name: state.name });
553
- return state;
554
- }
555
- /**
556
- * Unregister a state
557
- */
558
- unregisterState(id) {
559
- const state = this.states.get(id);
560
- if (state) {
561
- this.activeStates.delete(id);
562
- this.states.delete(id);
563
- this.emit("element:unregistered", { id, type: "state" });
564
- return true;
565
- }
566
- return false;
567
- }
568
- /**
569
- * Get a registered state
570
- */
571
- getState(id) {
572
- return this.states.get(id);
573
- }
574
- /**
575
- * Get all registered states
576
- */
577
- getAllStates() {
578
- return Array.from(this.states.values());
579
- }
580
- /**
581
- * Register a state group
582
- */
583
- registerStateGroup(group) {
584
- this.stateGroups.set(group.id, group);
585
- return group;
586
- }
587
- /**
588
- * Unregister a state group
589
- */
590
- unregisterStateGroup(id) {
591
- return this.stateGroups.delete(id);
592
- }
593
- /**
594
- * Get a state group
595
- */
596
- getStateGroup(id) {
597
- return this.stateGroups.get(id);
598
- }
599
- /**
600
- * Get all state groups
601
- */
602
- getAllStateGroups() {
603
- return Array.from(this.stateGroups.values());
604
- }
605
- /**
606
- * Register a transition
607
- */
608
- registerTransition(transition) {
609
- this.transitions.set(transition.id, transition);
610
- return transition;
611
- }
612
- /**
613
- * Unregister a transition
614
- */
615
- unregisterTransition(id) {
616
- return this.transitions.delete(id);
617
- }
618
- /**
619
- * Get a transition
620
- */
621
- getTransition(id) {
622
- return this.transitions.get(id);
623
- }
624
- /**
625
- * Get all transitions
626
- */
627
- getAllTransitions() {
628
- return Array.from(this.transitions.values());
629
- }
630
- /**
631
- * Get currently active states
632
- */
633
- getActiveStates() {
634
- return Array.from(this.activeStates);
635
- }
636
- /**
637
- * Check if a state is active
638
- */
639
- isStateActive(id) {
640
- return this.activeStates.has(id);
641
- }
642
- /**
643
- * Activate a state
644
- */
645
- activateState(id) {
646
- const state = this.states.get(id);
647
- if (!state) {
648
- return false;
649
- }
650
- for (const activeId of this.activeStates) {
651
- const activeState = this.states.get(activeId);
652
- if (activeState?.blocking && activeState.id !== id) {
653
- return false;
654
- }
655
- if (activeState?.blocks?.includes(id)) {
656
- return false;
657
- }
658
- }
659
- const wasActive = this.activeStates.has(id);
660
- this.activeStates.add(id);
661
- if (!wasActive) {
662
- this.emit("element:stateChanged", {
663
- stateId: id,
664
- active: true,
665
- activeStates: this.getActiveStates()
666
- });
667
- }
668
- return true;
669
- }
670
- /**
671
- * Deactivate a state
672
- */
673
- deactivateState(id) {
674
- const wasActive = this.activeStates.has(id);
675
- this.activeStates.delete(id);
676
- if (wasActive) {
677
- this.emit("element:stateChanged", {
678
- stateId: id,
679
- active: false,
680
- activeStates: this.getActiveStates()
681
- });
682
- }
683
- return wasActive;
684
- }
685
- /**
686
- * Activate multiple states
687
- */
688
- activateStates(ids) {
689
- const activated = [];
690
- for (const id of ids) {
691
- if (this.activateState(id)) {
692
- activated.push(id);
693
- }
694
- }
695
- return activated;
696
- }
697
- /**
698
- * Deactivate multiple states
699
- */
700
- deactivateStates(ids) {
701
- const deactivated = [];
702
- for (const id of ids) {
703
- if (this.deactivateState(id)) {
704
- deactivated.push(id);
705
- }
706
- }
707
- return deactivated;
708
- }
709
- /**
710
- * Activate a state group (all states in the group)
711
- */
712
- activateStateGroup(groupId) {
713
- const group = this.stateGroups.get(groupId);
714
- if (!group) return [];
715
- return this.activateStates(group.states);
716
- }
717
- /**
718
- * Deactivate a state group (all states in the group)
719
- */
720
- deactivateStateGroup(groupId) {
721
- const group = this.stateGroups.get(groupId);
722
- if (!group) return [];
723
- return this.deactivateStates(group.states);
724
- }
725
- /**
726
- * Check if a transition can be executed from current state
727
- */
728
- canExecuteTransition(transitionId) {
729
- const transition = this.transitions.get(transitionId);
730
- if (!transition) return false;
731
- return transition.fromStates.some((stateId) => this.activeStates.has(stateId));
732
- }
733
- /**
734
- * Execute a transition
735
- */
736
- async executeTransition(transitionId) {
737
- const startTime = performance.now();
738
- const transition = this.transitions.get(transitionId);
739
- if (!transition) {
740
- return {
741
- success: false,
742
- activatedStates: [],
743
- deactivatedStates: [],
744
- error: `Transition not found: ${transitionId}`,
745
- durationMs: performance.now() - startTime
746
- };
747
- }
748
- if (!this.canExecuteTransition(transitionId)) {
749
- return {
750
- success: false,
751
- activatedStates: [],
752
- deactivatedStates: [],
753
- error: "Precondition not met: none of the fromStates are active",
754
- failedPhase: "precondition",
755
- durationMs: performance.now() - startTime
756
- };
757
- }
758
- try {
759
- const deactivated = this.deactivateStates(transition.exitStates);
760
- if (transition.exitGroups) {
761
- for (const groupId of transition.exitGroups) {
762
- deactivated.push(...this.deactivateStateGroup(groupId));
763
- }
764
- }
765
- const activated = this.activateStates(transition.activateStates);
766
- if (transition.activateGroups) {
767
- for (const groupId of transition.activateGroups) {
768
- activated.push(...this.activateStateGroup(groupId));
769
- }
770
- }
771
- return {
772
- success: true,
773
- activatedStates: activated,
774
- deactivatedStates: deactivated,
775
- durationMs: performance.now() - startTime
776
- };
777
- } catch (error) {
778
- return {
779
- success: false,
780
- activatedStates: [],
781
- deactivatedStates: [],
782
- error: error instanceof Error ? error.message : String(error),
783
- failedPhase: "execution",
784
- durationMs: performance.now() - startTime
785
- };
786
- }
787
- }
788
- /**
789
- * Find a path from current state to target states
790
- *
791
- * Uses a simple BFS algorithm for pathfinding.
792
- * For more advanced pathfinding (Dijkstra, A*), use the Python state manager service.
793
- */
794
- findPath(targetStates) {
795
- if (targetStates.every((t) => this.activeStates.has(t))) {
796
- return {
797
- found: true,
798
- transitions: [],
799
- totalCost: 0,
800
- targetStates,
801
- estimatedSteps: 0
802
- };
803
- }
804
- const queue = [
805
- { activeStates: new Set(this.activeStates), path: [], cost: 0 }
806
- ];
807
- const visited = /* @__PURE__ */ new Set();
808
- while (queue.length > 0) {
809
- const current = queue.shift();
810
- const stateKey = Array.from(current.activeStates).sort().join(",");
811
- if (visited.has(stateKey)) continue;
812
- visited.add(stateKey);
813
- if (targetStates.every((t) => current.activeStates.has(t))) {
814
- return {
815
- found: true,
816
- transitions: current.path,
817
- totalCost: current.cost,
818
- targetStates,
819
- estimatedSteps: current.path.length
820
- };
821
- }
822
- for (const transition of this.transitions.values()) {
823
- const canExecute = transition.fromStates.some((s) => current.activeStates.has(s));
824
- if (!canExecute) continue;
825
- const newActive = new Set(current.activeStates);
826
- for (const s of transition.exitStates) newActive.delete(s);
827
- for (const s of transition.activateStates) newActive.add(s);
828
- const newCost = current.cost + (transition.pathCost ?? 1);
829
- queue.push({
830
- activeStates: newActive,
831
- path: [...current.path, transition.id],
832
- cost: newCost
833
- });
834
- }
835
- }
836
- return {
837
- found: false,
838
- transitions: [],
839
- totalCost: 0,
840
- targetStates,
841
- estimatedSteps: 0
842
- };
843
- }
844
- /**
845
- * Navigate to target states using pathfinding
846
- */
847
- async navigateTo(targetStates) {
848
- const startTime = performance.now();
849
- const path = this.findPath(targetStates);
850
- if (!path.found) {
851
- return {
852
- success: false,
853
- path,
854
- executedTransitions: [],
855
- finalActiveStates: this.getActiveStates(),
856
- error: `No path found to target states: ${targetStates.join(", ")}`,
857
- durationMs: performance.now() - startTime
858
- };
859
- }
860
- const executedTransitions = [];
861
- for (const transitionId of path.transitions) {
862
- const result = await this.executeTransition(transitionId);
863
- if (!result.success) {
864
- return {
865
- success: false,
866
- path,
867
- executedTransitions,
868
- finalActiveStates: this.getActiveStates(),
869
- error: result.error,
870
- durationMs: performance.now() - startTime
871
- };
872
- }
873
- executedTransitions.push(transitionId);
874
- }
875
- return {
876
- success: true,
877
- path,
878
- executedTransitions,
879
- finalActiveStates: this.getActiveStates(),
880
- durationMs: performance.now() - startTime
881
- };
882
- }
883
- /**
884
- * Create a state snapshot
885
- */
886
- createStateSnapshot() {
887
- return {
888
- timestamp: Date.now(),
889
- activeStates: this.getActiveStates(),
890
- states: this.getAllStates(),
891
- groups: this.getAllStateGroups(),
892
- transitions: this.getAllTransitions()
893
- };
894
- }
895
- /**
896
- * Create a snapshot of the current state
897
- */
898
- createSnapshot() {
899
- return {
900
- timestamp: Date.now(),
901
- elements: this.getAllElements().map((el) => ({
902
- id: el.id,
903
- type: el.type,
904
- label: el.label,
905
- identifier: el.getIdentifier(),
906
- state: el.getState(),
907
- actions: el.actions,
908
- customActions: el.customActions ? Object.keys(el.customActions) : void 0
909
- })),
910
- components: this.getAllComponents().map((comp) => ({
911
- id: comp.id,
912
- name: comp.name,
913
- description: comp.description,
914
- actions: comp.actions.map((a) => a.id),
915
- elementIds: comp.elementIds
916
- })),
917
- workflows: this.getAllWorkflows().map((wf) => ({
918
- id: wf.id,
919
- name: wf.name,
920
- description: wf.description,
921
- stepCount: wf.steps.length
922
- }))
923
- };
924
- }
925
- /**
926
- * Clear all registrations
927
- */
928
- clear() {
929
- this.elements.clear();
930
- this.components.clear();
931
- this.workflows.clear();
932
- this.eventListeners.clear();
933
- this.states.clear();
934
- this.stateGroups.clear();
935
- this.transitions.clear();
936
- this.activeStates.clear();
937
- }
938
- /**
939
- * Get registry statistics
940
- */
941
- getStats() {
942
- const elements = this.getAllElements();
943
- const components = this.getAllComponents();
944
- return {
945
- elementCount: elements.length,
946
- componentCount: components.length,
947
- workflowCount: this.workflows.size,
948
- mountedElementCount: elements.filter((e) => e.mounted).length,
949
- mountedComponentCount: components.filter((c) => c.mounted).length,
950
- stateCount: this.states.size,
951
- stateGroupCount: this.stateGroups.size,
952
- transitionCount: this.transitions.size,
953
- activeStateCount: this.activeStates.size
954
- };
955
- }
956
- };
957
- var globalRegistry = null;
958
- function getGlobalRegistry() {
959
- if (!globalRegistry) {
960
- globalRegistry = new UIBridgeRegistry();
961
- }
962
- return globalRegistry;
963
- }
964
- function setGlobalRegistry(registry) {
965
- globalRegistry = registry;
966
- }
967
- function resetGlobalRegistry() {
968
- globalRegistry?.clear();
969
- globalRegistry = null;
970
- }
971
-
972
1
  // src/core/websocket-client.ts
973
2
  function generateId() {
974
3
  return `${Date.now()}-${Math.random().toString(36).slice(2, 11)}`;
@@ -1404,6 +433,6 @@ function createWSClient(config) {
1404
433
  return new UIBridgeWSClient(config);
1405
434
  }
1406
435
 
1407
- export { ID_ATTRIBUTES, UIBridgeRegistry, UIBridgeWSClient, createElementIdentifier, createWSClient, elementMatchesIdentifier, findAllElementsByIdentifier, findElementByIdentifier, generateCSSSelector, generateXPath, getBestIdentifier, getGlobalRegistry, resetGlobalRegistry, setGlobalRegistry };
436
+ export { UIBridgeWSClient, createWSClient };
1408
437
  //# sourceMappingURL=index.mjs.map
1409
438
  //# sourceMappingURL=index.mjs.map