@qontinui/ui-bridge 0.2.0 → 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 (108) hide show
  1. package/dist/ai/index.d.mts +4 -4
  2. package/dist/ai/index.d.ts +4 -4
  3. package/dist/babel-plugin/index.js +515 -0
  4. package/dist/babel-plugin/index.js.map +1 -0
  5. package/dist/babel-plugin/index.mjs +499 -0
  6. package/dist/babel-plugin/index.mjs.map +1 -0
  7. package/dist/control/index.d.mts +5 -5
  8. package/dist/control/index.d.ts +5 -5
  9. package/dist/core/index.d.mts +115 -44
  10. package/dist/core/index.d.ts +115 -44
  11. package/dist/core/index.js +0 -1560
  12. package/dist/core/index.js.map +1 -1
  13. package/dist/core/index.mjs +1 -1549
  14. package/dist/core/index.mjs.map +1 -1
  15. package/dist/debug/index.d.mts +3 -3
  16. package/dist/debug/index.d.ts +3 -3
  17. package/dist/index.d.mts +7 -8
  18. package/dist/index.d.ts +7 -8
  19. package/dist/index.js +859 -873
  20. package/dist/index.js.map +1 -1
  21. package/dist/index.mjs +860 -862
  22. package/dist/index.mjs.map +1 -1
  23. package/dist/{metrics-C9XRi_mL.d.ts → metrics-BfiT_rhZ.d.ts} +2 -2
  24. package/dist/{metrics-NC3csD0R.d.mts → metrics-DTA2bwG7.d.mts} +2 -2
  25. package/dist/native/control/index.js +453 -0
  26. package/dist/native/control/index.js.map +1 -0
  27. package/dist/native/control/index.mjs +450 -0
  28. package/dist/native/control/index.mjs.map +1 -0
  29. package/dist/native/core/index.js +486 -0
  30. package/dist/native/core/index.js.map +1 -0
  31. package/dist/native/core/index.mjs +475 -0
  32. package/dist/native/core/index.mjs.map +1 -0
  33. package/dist/native/debug/index.js +451 -0
  34. package/dist/native/debug/index.js.map +1 -0
  35. package/dist/native/debug/index.mjs +449 -0
  36. package/dist/native/debug/index.mjs.map +1 -0
  37. package/dist/native/index.js +2274 -0
  38. package/dist/native/index.js.map +1 -0
  39. package/dist/native/index.mjs +2246 -0
  40. package/dist/native/index.mjs.map +1 -0
  41. package/dist/native/react/index.js +1401 -0
  42. package/dist/native/react/index.js.map +1 -0
  43. package/dist/native/react/index.mjs +1389 -0
  44. package/dist/native/react/index.mjs.map +1 -0
  45. package/dist/native/server/index.js +415 -0
  46. package/dist/native/server/index.js.map +1 -0
  47. package/dist/native/server/index.mjs +410 -0
  48. package/dist/native/server/index.mjs.map +1 -0
  49. package/dist/react/index.d.mts +20 -7
  50. package/dist/react/index.d.ts +20 -7
  51. package/dist/react/index.js +42 -4
  52. package/dist/react/index.js.map +1 -1
  53. package/dist/react/index.mjs +42 -4
  54. package/dist/react/index.mjs.map +1 -1
  55. package/dist/{registry-CIEDjbQ9.d.ts → registry-BKLEm-yk.d.ts} +9 -15
  56. package/dist/{registry-SsSDq46X.d.mts → registry-BmZgyCz8.d.mts} +9 -15
  57. package/dist/render-log/index.d.mts +1 -1
  58. package/dist/render-log/index.d.ts +1 -1
  59. package/dist/server/express.d.mts +36 -0
  60. package/dist/server/express.d.ts +36 -0
  61. package/dist/server/express.js +196 -0
  62. package/dist/server/express.js.map +1 -0
  63. package/dist/server/express.mjs +192 -0
  64. package/dist/server/express.mjs.map +1 -0
  65. package/dist/server/handlers.d.mts +93 -0
  66. package/dist/server/handlers.d.ts +93 -0
  67. package/dist/server/handlers.js +4278 -0
  68. package/dist/server/handlers.js.map +1 -0
  69. package/dist/server/handlers.mjs +4275 -0
  70. package/dist/server/handlers.mjs.map +1 -0
  71. package/dist/server/index.d.mts +10 -0
  72. package/dist/server/index.d.ts +10 -0
  73. package/dist/server/index.js +5352 -0
  74. package/dist/server/index.js.map +1 -0
  75. package/dist/server/index.mjs +5337 -0
  76. package/dist/server/index.mjs.map +1 -0
  77. package/dist/server/nextjs.d.mts +126 -0
  78. package/dist/server/nextjs.d.ts +126 -0
  79. package/dist/server/nextjs.js +287 -0
  80. package/dist/server/nextjs.js.map +1 -0
  81. package/dist/server/nextjs.mjs +282 -0
  82. package/dist/server/nextjs.mjs.map +1 -0
  83. package/dist/server/standalone.d.mts +6 -0
  84. package/dist/server/standalone.d.ts +6 -0
  85. package/dist/server/standalone.js +719 -0
  86. package/dist/server/standalone.js.map +1 -0
  87. package/dist/server/standalone.mjs +715 -0
  88. package/dist/server/standalone.mjs.map +1 -0
  89. package/dist/standalone-BURj8J3G.d.ts +212 -0
  90. package/dist/standalone-Dwmel29d.d.mts +212 -0
  91. package/dist/swc-plugin/index.d.mts +79 -0
  92. package/dist/swc-plugin/index.d.ts +79 -0
  93. package/dist/swc-plugin/index.js +15 -0
  94. package/dist/swc-plugin/index.js.map +1 -0
  95. package/dist/swc-plugin/index.mjs +9 -0
  96. package/dist/swc-plugin/index.mjs.map +1 -0
  97. package/dist/{types-CFT3Dnx4.d.mts → types-B5Q0GVo0.d.mts} +115 -3
  98. package/dist/{types-Dr6tH-bm.d.mts → types-B7J7noLK.d.mts} +1 -1
  99. package/dist/{types-oCTrRxSw.d.ts → types-BkNRILUa.d.ts} +1 -1
  100. package/dist/types-CEQLnFMv.d.mts +156 -0
  101. package/dist/types-CHnlwiTK.d.ts +156 -0
  102. package/dist/{types-BvCfFuEV.d.ts → types-DfPqwU-i.d.ts} +115 -3
  103. package/dist/{types-CPMbN_Iw.d.mts → types-jKVgTI6_.d.mts} +356 -160
  104. package/dist/{types-CPMbN_Iw.d.ts → types-jKVgTI6_.d.ts} +356 -160
  105. package/package.json +106 -3
  106. package/swc-plugin-wasm/ui_bridge_swc_plugin.wasm +0 -0
  107. package/dist/websocket-client-CX4QJesI.d.ts +0 -124
  108. package/dist/websocket-client-C_Na0OSp.d.mts +0 -124
package/dist/index.mjs CHANGED
@@ -1,8 +1,442 @@
1
1
  import { createContext, useRef, useState, useMemo, useEffect, useCallback, useContext } from 'react';
2
2
  import { jsx, Fragment, jsxs } from 'react/jsx-runtime';
3
3
 
4
+ // src/core/websocket-client.ts
5
+ function generateId() {
6
+ return `${Date.now()}-${Math.random().toString(36).slice(2, 11)}`;
7
+ }
8
+ var UIBridgeWSClient = class {
9
+ constructor(config) {
10
+ this.ws = null;
11
+ this.state = "disconnected";
12
+ this.clientId = null;
13
+ this.reconnectAttempts = 0;
14
+ this.reconnectTimer = null;
15
+ this.pingTimer = null;
16
+ this.pendingRequests = /* @__PURE__ */ new Map();
17
+ // Event listeners
18
+ this.connectionListeners = /* @__PURE__ */ new Set();
19
+ this.eventListeners = /* @__PURE__ */ new Map();
20
+ this.errorListeners = /* @__PURE__ */ new Set();
21
+ // Current subscriptions
22
+ this.subscriptions = {};
23
+ this.config = {
24
+ url: config.url,
25
+ autoReconnect: config.autoReconnect ?? true,
26
+ reconnectDelay: config.reconnectDelay ?? 1e3,
27
+ maxReconnectAttempts: config.maxReconnectAttempts ?? 10,
28
+ pingInterval: config.pingInterval ?? 3e4,
29
+ connectionTimeout: config.connectionTimeout ?? 1e4
30
+ };
31
+ }
32
+ /**
33
+ * Get current connection state
34
+ */
35
+ get connectionState() {
36
+ return this.state;
37
+ }
38
+ /**
39
+ * Get assigned client ID
40
+ */
41
+ get id() {
42
+ return this.clientId;
43
+ }
44
+ /**
45
+ * Connect to the WebSocket server
46
+ */
47
+ connect() {
48
+ return new Promise((resolve, reject) => {
49
+ if (this.ws && this.state === "connected") {
50
+ resolve();
51
+ return;
52
+ }
53
+ this.setState("connecting");
54
+ try {
55
+ this.ws = new WebSocket(this.config.url);
56
+ } catch (error) {
57
+ this.setState("disconnected");
58
+ reject(error);
59
+ return;
60
+ }
61
+ const connectionTimeout = setTimeout(() => {
62
+ if (this.state === "connecting") {
63
+ this.ws?.close();
64
+ this.setState("disconnected");
65
+ reject(new Error("Connection timeout"));
66
+ }
67
+ }, this.config.connectionTimeout);
68
+ this.ws.onopen = () => {
69
+ clearTimeout(connectionTimeout);
70
+ };
71
+ this.ws.onmessage = (event) => {
72
+ try {
73
+ const message = JSON.parse(event.data);
74
+ this.handleMessage(message);
75
+ if (message.type === "welcome") {
76
+ clearTimeout(connectionTimeout);
77
+ this.reconnectAttempts = 0;
78
+ this.setState("connected");
79
+ this.startPingInterval();
80
+ if (this.subscriptions.events?.length || this.subscriptions.elementIds?.length || this.subscriptions.componentIds?.length) {
81
+ this.subscribe(this.subscriptions);
82
+ }
83
+ resolve();
84
+ }
85
+ } catch (error) {
86
+ console.error("Failed to parse WebSocket message:", error);
87
+ }
88
+ };
89
+ this.ws.onerror = (_event) => {
90
+ clearTimeout(connectionTimeout);
91
+ const error = new Error("WebSocket error");
92
+ this.notifyError(error);
93
+ if (this.state === "connecting") {
94
+ reject(error);
95
+ }
96
+ };
97
+ this.ws.onclose = () => {
98
+ clearTimeout(connectionTimeout);
99
+ this.stopPingInterval();
100
+ this.clientId = null;
101
+ const wasConnected = this.state === "connected";
102
+ this.setState("disconnected");
103
+ for (const [_id, pending] of this.pendingRequests) {
104
+ clearTimeout(pending.timeout);
105
+ pending.reject(new Error("Connection closed"));
106
+ }
107
+ this.pendingRequests.clear();
108
+ if (wasConnected && this.config.autoReconnect && (this.config.maxReconnectAttempts === 0 || this.reconnectAttempts < this.config.maxReconnectAttempts)) {
109
+ this.scheduleReconnect();
110
+ }
111
+ };
112
+ });
113
+ }
114
+ /**
115
+ * Disconnect from the server
116
+ */
117
+ disconnect() {
118
+ if (this.reconnectTimer) {
119
+ clearTimeout(this.reconnectTimer);
120
+ this.reconnectTimer = null;
121
+ }
122
+ this.stopPingInterval();
123
+ if (this.ws) {
124
+ this.ws.close();
125
+ this.ws = null;
126
+ }
127
+ this.setState("disconnected");
128
+ }
129
+ /**
130
+ * Subscribe to events
131
+ */
132
+ async subscribe(options) {
133
+ this.subscriptions = { ...this.subscriptions, ...options };
134
+ const response = await this.sendRequest({
135
+ id: generateId(),
136
+ type: "subscribe",
137
+ timestamp: Date.now(),
138
+ payload: options
139
+ });
140
+ return response.events;
141
+ }
142
+ /**
143
+ * Unsubscribe from events
144
+ */
145
+ async unsubscribe(events) {
146
+ if (events) {
147
+ this.subscriptions.events = this.subscriptions.events?.filter((e) => !events.includes(e));
148
+ } else {
149
+ this.subscriptions = {};
150
+ }
151
+ const response = await this.sendRequest({
152
+ id: generateId(),
153
+ type: "unsubscribe",
154
+ timestamp: Date.now(),
155
+ payload: { events }
156
+ });
157
+ return response.events;
158
+ }
159
+ /**
160
+ * Find elements
161
+ */
162
+ async find(options) {
163
+ const response = await this.sendRequest({
164
+ id: generateId(),
165
+ type: "find",
166
+ timestamp: Date.now(),
167
+ payload: options
168
+ });
169
+ return response.elements;
170
+ }
171
+ /**
172
+ * Discover elements
173
+ * @deprecated Use find() instead
174
+ */
175
+ async discover(options) {
176
+ return this.find(options);
177
+ }
178
+ /**
179
+ * Get element details
180
+ */
181
+ async getElement(elementId, includeState = true) {
182
+ const response = await this.sendRequest({
183
+ id: generateId(),
184
+ type: "getElement",
185
+ timestamp: Date.now(),
186
+ payload: { elementId, includeState }
187
+ });
188
+ return response.element;
189
+ }
190
+ /**
191
+ * Get full snapshot
192
+ */
193
+ async getSnapshot() {
194
+ const response = await this.sendRequest({
195
+ id: generateId(),
196
+ type: "getSnapshot",
197
+ timestamp: Date.now()
198
+ });
199
+ return response;
200
+ }
201
+ /**
202
+ * Execute action on an element
203
+ */
204
+ async executeAction(elementId, action) {
205
+ const response = await this.sendRequest({
206
+ id: generateId(),
207
+ type: "executeAction",
208
+ timestamp: Date.now(),
209
+ payload: { elementId, action }
210
+ });
211
+ return response;
212
+ }
213
+ /**
214
+ * Execute component action
215
+ */
216
+ async executeComponentAction(componentId, action, params) {
217
+ const response = await this.sendRequest({
218
+ id: generateId(),
219
+ type: "executeComponentAction",
220
+ timestamp: Date.now(),
221
+ payload: { componentId, action, params }
222
+ });
223
+ return response;
224
+ }
225
+ /**
226
+ * Execute workflow with optional progress streaming
227
+ */
228
+ async executeWorkflow(workflowId, params, onProgress) {
229
+ const id = generateId();
230
+ const progressHandler = onProgress ? (message) => {
231
+ if (message.type === "workflowProgress" && message.requestId === id) {
232
+ onProgress({
233
+ currentStep: message.payload.currentStep,
234
+ totalSteps: message.payload.totalSteps,
235
+ step: {
236
+ id: message.payload.step.id,
237
+ status: message.payload.step.status
238
+ }
239
+ });
240
+ }
241
+ } : void 0;
242
+ const response = await this.sendRequest(
243
+ {
244
+ id,
245
+ type: "executeWorkflow",
246
+ timestamp: Date.now(),
247
+ payload: { workflowId, params, streamProgress: !!onProgress }
248
+ },
249
+ progressHandler
250
+ );
251
+ return response;
252
+ }
253
+ /**
254
+ * Add connection state listener
255
+ */
256
+ onConnectionChange(listener) {
257
+ this.connectionListeners.add(listener);
258
+ return () => this.connectionListeners.delete(listener);
259
+ }
260
+ /**
261
+ * Add event listener
262
+ */
263
+ onEvent(eventType, listener) {
264
+ if (!this.eventListeners.has(eventType)) {
265
+ this.eventListeners.set(eventType, /* @__PURE__ */ new Set());
266
+ }
267
+ this.eventListeners.get(eventType).add(listener);
268
+ return () => this.eventListeners.get(eventType)?.delete(listener);
269
+ }
270
+ /**
271
+ * Add error listener
272
+ */
273
+ onError(listener) {
274
+ this.errorListeners.add(listener);
275
+ return () => this.errorListeners.delete(listener);
276
+ }
277
+ // Private methods
278
+ setState(state) {
279
+ this.state = state;
280
+ for (const listener of this.connectionListeners) {
281
+ try {
282
+ listener(state);
283
+ } catch (error) {
284
+ console.error("Connection listener error:", error);
285
+ }
286
+ }
287
+ }
288
+ handleMessage(message) {
289
+ switch (message.type) {
290
+ case "welcome":
291
+ this.clientId = message.payload.clientId;
292
+ break;
293
+ case "pong":
294
+ break;
295
+ case "subscribed":
296
+ case "unsubscribed":
297
+ break;
298
+ case "event":
299
+ this.notifyEvent(message.payload);
300
+ break;
301
+ case "response":
302
+ this.handleResponse(message);
303
+ break;
304
+ case "error":
305
+ if (message.requestId) {
306
+ this.handleResponse({
307
+ ...message,
308
+ type: "response",
309
+ requestId: message.requestId,
310
+ payload: {
311
+ success: false,
312
+ error: message.payload.message
313
+ }
314
+ });
315
+ } else {
316
+ this.notifyError(new Error(message.payload.message));
317
+ }
318
+ break;
319
+ }
320
+ }
321
+ handleResponse(message) {
322
+ const pending = this.pendingRequests.get(message.requestId);
323
+ if (!pending) return;
324
+ clearTimeout(pending.timeout);
325
+ this.pendingRequests.delete(message.requestId);
326
+ if (message.type === "response") {
327
+ if (message.payload.success) {
328
+ pending.resolve(message.payload.data);
329
+ } else {
330
+ pending.reject(new Error(message.payload.error || "Request failed"));
331
+ }
332
+ }
333
+ }
334
+ notifyEvent(event) {
335
+ const typeListeners = this.eventListeners.get(event.type);
336
+ if (typeListeners) {
337
+ for (const listener of typeListeners) {
338
+ try {
339
+ listener(event);
340
+ } catch (error) {
341
+ console.error("Event listener error:", error);
342
+ }
343
+ }
344
+ }
345
+ const wildcardListeners = this.eventListeners.get("*");
346
+ if (wildcardListeners) {
347
+ for (const listener of wildcardListeners) {
348
+ try {
349
+ listener(event);
350
+ } catch (error) {
351
+ console.error("Event listener error:", error);
352
+ }
353
+ }
354
+ }
355
+ }
356
+ notifyError(error) {
357
+ for (const listener of this.errorListeners) {
358
+ try {
359
+ listener(error);
360
+ } catch (e) {
361
+ console.error("Error listener error:", e);
362
+ }
363
+ }
364
+ }
365
+ sendRequest(message, progressHandler) {
366
+ return new Promise((resolve, reject) => {
367
+ if (!this.ws || this.state !== "connected") {
368
+ reject(new Error("Not connected"));
369
+ return;
370
+ }
371
+ const timeout = setTimeout(() => {
372
+ this.pendingRequests.delete(message.id);
373
+ reject(new Error("Request timeout"));
374
+ }, 3e4);
375
+ this.pendingRequests.set(message.id, {
376
+ resolve,
377
+ reject,
378
+ timeout
379
+ });
380
+ if (progressHandler && this.ws) {
381
+ const originalHandler = this.ws.onmessage;
382
+ const wsRef = this.ws;
383
+ const wrappedHandler = (event) => {
384
+ try {
385
+ const msg = JSON.parse(event.data);
386
+ if (msg.type === "workflowProgress") {
387
+ progressHandler(msg);
388
+ }
389
+ } catch {
390
+ }
391
+ if (originalHandler) {
392
+ originalHandler.call(wsRef, event);
393
+ }
394
+ };
395
+ this.ws.onmessage = wrappedHandler;
396
+ }
397
+ this.ws.send(JSON.stringify(message));
398
+ });
399
+ }
400
+ scheduleReconnect() {
401
+ if (this.reconnectTimer) return;
402
+ this.setState("reconnecting");
403
+ this.reconnectAttempts++;
404
+ const delay = Math.min(
405
+ this.config.reconnectDelay * Math.pow(2, this.reconnectAttempts - 1),
406
+ 3e4
407
+ );
408
+ this.reconnectTimer = setTimeout(() => {
409
+ this.reconnectTimer = null;
410
+ this.connect().catch(() => {
411
+ });
412
+ }, delay);
413
+ }
414
+ startPingInterval() {
415
+ if (this.config.pingInterval <= 0) return;
416
+ this.pingTimer = setInterval(() => {
417
+ if (this.ws && this.state === "connected") {
418
+ this.ws.send(
419
+ JSON.stringify({
420
+ id: generateId(),
421
+ type: "ping",
422
+ timestamp: Date.now()
423
+ })
424
+ );
425
+ }
426
+ }, this.config.pingInterval);
427
+ }
428
+ stopPingInterval() {
429
+ if (this.pingTimer) {
430
+ clearInterval(this.pingTimer);
431
+ this.pingTimer = null;
432
+ }
433
+ }
434
+ };
435
+ function createWSClient(config) {
436
+ return new UIBridgeWSClient(config);
437
+ }
438
+
4
439
  // src/core/element-identifier.ts
5
- var ID_ATTRIBUTES = ["data-ui-id", "data-testid", "data-awas-element", "id"];
6
440
  function generateXPath(element) {
7
441
  if (element.id) {
8
442
  return `//*[@id="${element.id}"]`;
@@ -186,39 +620,6 @@ function findElementByIdentifier(identifier, root = document) {
186
620
  }
187
621
  return null;
188
622
  }
189
- function findAllElementsByIdentifier(pattern, root = document) {
190
- const results = [];
191
- try {
192
- const elements = root.querySelectorAll(pattern);
193
- results.push(...Array.from(elements));
194
- if (results.length > 0) return results;
195
- } catch {
196
- }
197
- const partials = [
198
- `[data-ui-id*="${pattern}"]`,
199
- `[data-testid*="${pattern}"]`,
200
- `[data-awas-element*="${pattern}"]`,
201
- `[id*="${pattern}"]`
202
- ];
203
- for (const selector of partials) {
204
- try {
205
- const elements = root.querySelectorAll(selector);
206
- for (const el of elements) {
207
- if (!results.includes(el)) {
208
- results.push(el);
209
- }
210
- }
211
- } catch {
212
- }
213
- }
214
- return results;
215
- }
216
- function elementMatchesIdentifier(element, identifier) {
217
- if (typeof identifier === "string") {
218
- return element.getAttribute("data-ui-id") === identifier || element.getAttribute("data-testid") === identifier || element.getAttribute("data-awas-element") === identifier || element.id === identifier || element.matches(identifier);
219
- }
220
- 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;
221
- }
222
623
 
223
624
  // src/ai/fuzzy-matcher.ts
224
625
  var DEFAULT_FUZZY_CONFIG = {
@@ -1258,937 +1659,512 @@ var UIBridgeRegistry = class {
1258
1659
  }
1259
1660
  /**
1260
1661
  * Register a component
1261
- */
1262
- registerComponent(id, options) {
1263
- const registered = {
1264
- id,
1265
- name: options.name,
1266
- description: options.description,
1267
- actions: options.actions?.map((a) => ({
1268
- id: a.id,
1269
- label: a.label,
1270
- description: a.description,
1271
- handler: a.handler
1272
- })) ?? [],
1273
- elementIds: options.elementIds,
1274
- registeredAt: Date.now(),
1275
- mounted: true
1276
- };
1277
- this.components.set(id, registered);
1278
- this.emit("component:registered", { id, name: options.name });
1279
- return registered;
1280
- }
1281
- /**
1282
- * Unregister a component
1283
- */
1284
- unregisterComponent(id) {
1285
- const component = this.components.get(id);
1286
- if (component) {
1287
- component.mounted = false;
1288
- this.components.delete(id);
1289
- this.emit("component:unregistered", { id });
1290
- return true;
1291
- }
1292
- return false;
1293
- }
1294
- /**
1295
- * Get a registered component
1296
- */
1297
- getComponent(id) {
1298
- return this.components.get(id);
1299
- }
1300
- /**
1301
- * Get all registered components
1302
- */
1303
- getAllComponents() {
1304
- return Array.from(this.components.values());
1305
- }
1306
- /**
1307
- * Register a workflow
1308
- */
1309
- registerWorkflow(workflow) {
1310
- this.workflows.set(workflow.id, workflow);
1311
- return workflow;
1312
- }
1313
- /**
1314
- * Unregister a workflow
1315
- */
1316
- unregisterWorkflow(id) {
1317
- return this.workflows.delete(id);
1318
- }
1319
- /**
1320
- * Get a workflow
1321
- */
1322
- getWorkflow(id) {
1323
- return this.workflows.get(id);
1324
- }
1325
- /**
1326
- * Get all workflows
1327
- */
1328
- getAllWorkflows() {
1329
- return Array.from(this.workflows.values());
1330
- }
1331
- // ==========================================================================
1332
- // State Management
1333
- // ==========================================================================
1334
- /**
1335
- * Register a state
1336
- */
1337
- registerState(state) {
1338
- this.states.set(state.id, state);
1339
- this.emit("element:registered", { id: state.id, type: "state", name: state.name });
1340
- return state;
1341
- }
1342
- /**
1343
- * Unregister a state
1344
- */
1345
- unregisterState(id) {
1346
- const state = this.states.get(id);
1347
- if (state) {
1348
- this.activeStates.delete(id);
1349
- this.states.delete(id);
1350
- this.emit("element:unregistered", { id, type: "state" });
1351
- return true;
1352
- }
1353
- return false;
1354
- }
1355
- /**
1356
- * Get a registered state
1357
- */
1358
- getState(id) {
1359
- return this.states.get(id);
1360
- }
1361
- /**
1362
- * Get all registered states
1363
- */
1364
- getAllStates() {
1365
- return Array.from(this.states.values());
1366
- }
1367
- /**
1368
- * Register a state group
1369
- */
1370
- registerStateGroup(group) {
1371
- this.stateGroups.set(group.id, group);
1372
- return group;
1373
- }
1374
- /**
1375
- * Unregister a state group
1376
- */
1377
- unregisterStateGroup(id) {
1378
- return this.stateGroups.delete(id);
1379
- }
1380
- /**
1381
- * Get a state group
1382
- */
1383
- getStateGroup(id) {
1384
- return this.stateGroups.get(id);
1385
- }
1386
- /**
1387
- * Get all state groups
1388
- */
1389
- getAllStateGroups() {
1390
- return Array.from(this.stateGroups.values());
1391
- }
1392
- /**
1393
- * Register a transition
1394
- */
1395
- registerTransition(transition) {
1396
- this.transitions.set(transition.id, transition);
1397
- return transition;
1398
- }
1399
- /**
1400
- * Unregister a transition
1401
- */
1402
- unregisterTransition(id) {
1403
- return this.transitions.delete(id);
1404
- }
1405
- /**
1406
- * Get a transition
1407
- */
1408
- getTransition(id) {
1409
- return this.transitions.get(id);
1410
- }
1411
- /**
1412
- * Get all transitions
1413
- */
1414
- getAllTransitions() {
1415
- return Array.from(this.transitions.values());
1416
- }
1417
- /**
1418
- * Get currently active states
1419
- */
1420
- getActiveStates() {
1421
- return Array.from(this.activeStates);
1422
- }
1423
- /**
1424
- * Check if a state is active
1425
- */
1426
- isStateActive(id) {
1427
- return this.activeStates.has(id);
1428
- }
1429
- /**
1430
- * Activate a state
1431
- */
1432
- activateState(id) {
1433
- const state = this.states.get(id);
1434
- if (!state) {
1435
- return false;
1436
- }
1437
- for (const activeId of this.activeStates) {
1438
- const activeState = this.states.get(activeId);
1439
- if (activeState?.blocking && activeState.id !== id) {
1440
- return false;
1441
- }
1442
- if (activeState?.blocks?.includes(id)) {
1443
- return false;
1444
- }
1445
- }
1446
- const wasActive = this.activeStates.has(id);
1447
- this.activeStates.add(id);
1448
- if (!wasActive) {
1449
- this.emit("element:stateChanged", {
1450
- stateId: id,
1451
- active: true,
1452
- activeStates: this.getActiveStates()
1453
- });
1454
- }
1455
- return true;
1662
+ */
1663
+ registerComponent(id, options) {
1664
+ const registered = {
1665
+ id,
1666
+ name: options.name,
1667
+ description: options.description,
1668
+ actions: options.actions?.map((a) => ({
1669
+ id: a.id,
1670
+ label: a.label,
1671
+ description: a.description,
1672
+ handler: a.handler
1673
+ })) ?? [],
1674
+ elementIds: options.elementIds,
1675
+ registeredAt: Date.now(),
1676
+ mounted: true,
1677
+ getState: options.getState,
1678
+ getComputed: options.getComputed
1679
+ };
1680
+ this.components.set(id, registered);
1681
+ this.emit("component:registered", { id, name: options.name });
1682
+ return registered;
1456
1683
  }
1457
1684
  /**
1458
- * Deactivate a state
1685
+ * Unregister a component
1459
1686
  */
1460
- deactivateState(id) {
1461
- const wasActive = this.activeStates.has(id);
1462
- this.activeStates.delete(id);
1463
- if (wasActive) {
1464
- this.emit("element:stateChanged", {
1465
- stateId: id,
1466
- active: false,
1467
- activeStates: this.getActiveStates()
1468
- });
1687
+ unregisterComponent(id) {
1688
+ const component = this.components.get(id);
1689
+ if (component) {
1690
+ component.mounted = false;
1691
+ this.components.delete(id);
1692
+ this.emit("component:unregistered", { id });
1693
+ return true;
1469
1694
  }
1470
- return wasActive;
1695
+ return false;
1471
1696
  }
1472
1697
  /**
1473
- * Activate multiple states
1698
+ * Get a registered component
1474
1699
  */
1475
- activateStates(ids) {
1476
- const activated = [];
1477
- for (const id of ids) {
1478
- if (this.activateState(id)) {
1479
- activated.push(id);
1480
- }
1481
- }
1482
- return activated;
1700
+ getComponent(id) {
1701
+ return this.components.get(id);
1483
1702
  }
1484
1703
  /**
1485
- * Deactivate multiple states
1704
+ * Get all registered components
1486
1705
  */
1487
- deactivateStates(ids) {
1488
- const deactivated = [];
1489
- for (const id of ids) {
1490
- if (this.deactivateState(id)) {
1491
- deactivated.push(id);
1492
- }
1493
- }
1494
- return deactivated;
1706
+ getAllComponents() {
1707
+ return Array.from(this.components.values());
1495
1708
  }
1496
1709
  /**
1497
- * Activate a state group (all states in the group)
1710
+ * Get the current state and computed properties of a component
1498
1711
  */
1499
- activateStateGroup(groupId) {
1500
- const group = this.stateGroups.get(groupId);
1501
- if (!group) return [];
1502
- return this.activateStates(group.states);
1712
+ getComponentState(id) {
1713
+ const component = this.components.get(id);
1714
+ if (!component || !component.mounted) {
1715
+ return null;
1716
+ }
1717
+ return {
1718
+ state: component.getState?.() ?? {},
1719
+ computed: component.getComputed?.() ?? {},
1720
+ timestamp: Date.now()
1721
+ };
1503
1722
  }
1504
1723
  /**
1505
- * Deactivate a state group (all states in the group)
1724
+ * Register a workflow
1506
1725
  */
1507
- deactivateStateGroup(groupId) {
1508
- const group = this.stateGroups.get(groupId);
1509
- if (!group) return [];
1510
- return this.deactivateStates(group.states);
1726
+ registerWorkflow(workflow) {
1727
+ this.workflows.set(workflow.id, workflow);
1728
+ return workflow;
1511
1729
  }
1512
1730
  /**
1513
- * Check if a transition can be executed from current state
1731
+ * Unregister a workflow
1514
1732
  */
1515
- canExecuteTransition(transitionId) {
1516
- const transition = this.transitions.get(transitionId);
1517
- if (!transition) return false;
1518
- return transition.fromStates.some((stateId) => this.activeStates.has(stateId));
1733
+ unregisterWorkflow(id) {
1734
+ return this.workflows.delete(id);
1519
1735
  }
1520
1736
  /**
1521
- * Execute a transition
1737
+ * Get a workflow
1522
1738
  */
1523
- async executeTransition(transitionId) {
1524
- const startTime = performance.now();
1525
- const transition = this.transitions.get(transitionId);
1526
- if (!transition) {
1527
- return {
1528
- success: false,
1529
- activatedStates: [],
1530
- deactivatedStates: [],
1531
- error: `Transition not found: ${transitionId}`,
1532
- durationMs: performance.now() - startTime
1533
- };
1534
- }
1535
- if (!this.canExecuteTransition(transitionId)) {
1536
- return {
1537
- success: false,
1538
- activatedStates: [],
1539
- deactivatedStates: [],
1540
- error: "Precondition not met: none of the fromStates are active",
1541
- failedPhase: "precondition",
1542
- durationMs: performance.now() - startTime
1543
- };
1544
- }
1545
- try {
1546
- const deactivated = this.deactivateStates(transition.exitStates);
1547
- if (transition.exitGroups) {
1548
- for (const groupId of transition.exitGroups) {
1549
- deactivated.push(...this.deactivateStateGroup(groupId));
1550
- }
1551
- }
1552
- const activated = this.activateStates(transition.activateStates);
1553
- if (transition.activateGroups) {
1554
- for (const groupId of transition.activateGroups) {
1555
- activated.push(...this.activateStateGroup(groupId));
1556
- }
1557
- }
1558
- return {
1559
- success: true,
1560
- activatedStates: activated,
1561
- deactivatedStates: deactivated,
1562
- durationMs: performance.now() - startTime
1563
- };
1564
- } catch (error) {
1565
- return {
1566
- success: false,
1567
- activatedStates: [],
1568
- deactivatedStates: [],
1569
- error: error instanceof Error ? error.message : String(error),
1570
- failedPhase: "execution",
1571
- durationMs: performance.now() - startTime
1572
- };
1573
- }
1739
+ getWorkflow(id) {
1740
+ return this.workflows.get(id);
1574
1741
  }
1575
1742
  /**
1576
- * Find a path from current state to target states
1577
- *
1578
- * Uses a simple BFS algorithm for pathfinding.
1579
- * For more advanced pathfinding (Dijkstra, A*), use the Python state manager service.
1743
+ * Get all workflows
1580
1744
  */
1581
- findPath(targetStates) {
1582
- if (targetStates.every((t) => this.activeStates.has(t))) {
1583
- return {
1584
- found: true,
1585
- transitions: [],
1586
- totalCost: 0,
1587
- targetStates,
1588
- estimatedSteps: 0
1589
- };
1590
- }
1591
- const queue = [
1592
- { activeStates: new Set(this.activeStates), path: [], cost: 0 }
1593
- ];
1594
- const visited = /* @__PURE__ */ new Set();
1595
- while (queue.length > 0) {
1596
- const current = queue.shift();
1597
- const stateKey = Array.from(current.activeStates).sort().join(",");
1598
- if (visited.has(stateKey)) continue;
1599
- visited.add(stateKey);
1600
- if (targetStates.every((t) => current.activeStates.has(t))) {
1601
- return {
1602
- found: true,
1603
- transitions: current.path,
1604
- totalCost: current.cost,
1605
- targetStates,
1606
- estimatedSteps: current.path.length
1607
- };
1608
- }
1609
- for (const transition of this.transitions.values()) {
1610
- const canExecute = transition.fromStates.some((s) => current.activeStates.has(s));
1611
- if (!canExecute) continue;
1612
- const newActive = new Set(current.activeStates);
1613
- for (const s of transition.exitStates) newActive.delete(s);
1614
- for (const s of transition.activateStates) newActive.add(s);
1615
- const newCost = current.cost + (transition.pathCost ?? 1);
1616
- queue.push({
1617
- activeStates: newActive,
1618
- path: [...current.path, transition.id],
1619
- cost: newCost
1620
- });
1621
- }
1622
- }
1623
- return {
1624
- found: false,
1625
- transitions: [],
1626
- totalCost: 0,
1627
- targetStates,
1628
- estimatedSteps: 0
1629
- };
1745
+ getAllWorkflows() {
1746
+ return Array.from(this.workflows.values());
1630
1747
  }
1748
+ // ==========================================================================
1749
+ // State Management
1750
+ // ==========================================================================
1631
1751
  /**
1632
- * Navigate to target states using pathfinding
1752
+ * Register a state
1633
1753
  */
1634
- async navigateTo(targetStates) {
1635
- const startTime = performance.now();
1636
- const path = this.findPath(targetStates);
1637
- if (!path.found) {
1638
- return {
1639
- success: false,
1640
- path,
1641
- executedTransitions: [],
1642
- finalActiveStates: this.getActiveStates(),
1643
- error: `No path found to target states: ${targetStates.join(", ")}`,
1644
- durationMs: performance.now() - startTime
1645
- };
1646
- }
1647
- const executedTransitions = [];
1648
- for (const transitionId of path.transitions) {
1649
- const result = await this.executeTransition(transitionId);
1650
- if (!result.success) {
1651
- return {
1652
- success: false,
1653
- path,
1654
- executedTransitions,
1655
- finalActiveStates: this.getActiveStates(),
1656
- error: result.error,
1657
- durationMs: performance.now() - startTime
1658
- };
1659
- }
1660
- executedTransitions.push(transitionId);
1661
- }
1662
- return {
1663
- success: true,
1664
- path,
1665
- executedTransitions,
1666
- finalActiveStates: this.getActiveStates(),
1667
- durationMs: performance.now() - startTime
1668
- };
1754
+ registerState(state) {
1755
+ this.states.set(state.id, state);
1756
+ this.emit("element:registered", { id: state.id, type: "state", name: state.name });
1757
+ return state;
1669
1758
  }
1670
1759
  /**
1671
- * Create a state snapshot
1760
+ * Unregister a state
1672
1761
  */
1673
- createStateSnapshot() {
1674
- return {
1675
- timestamp: Date.now(),
1676
- activeStates: this.getActiveStates(),
1677
- states: this.getAllStates(),
1678
- groups: this.getAllStateGroups(),
1679
- transitions: this.getAllTransitions()
1680
- };
1762
+ unregisterState(id) {
1763
+ const state = this.states.get(id);
1764
+ if (state) {
1765
+ this.activeStates.delete(id);
1766
+ this.states.delete(id);
1767
+ this.emit("element:unregistered", { id, type: "state" });
1768
+ return true;
1769
+ }
1770
+ return false;
1681
1771
  }
1682
1772
  /**
1683
- * Create a snapshot of the current state
1773
+ * Get a registered state
1684
1774
  */
1685
- createSnapshot() {
1686
- return {
1687
- timestamp: Date.now(),
1688
- elements: this.getAllElements().map((el) => ({
1689
- id: el.id,
1690
- type: el.type,
1691
- label: el.label,
1692
- identifier: el.getIdentifier(),
1693
- state: el.getState(),
1694
- actions: el.actions,
1695
- customActions: el.customActions ? Object.keys(el.customActions) : void 0
1696
- })),
1697
- components: this.getAllComponents().map((comp) => ({
1698
- id: comp.id,
1699
- name: comp.name,
1700
- description: comp.description,
1701
- actions: comp.actions.map((a) => a.id),
1702
- elementIds: comp.elementIds
1703
- })),
1704
- workflows: this.getAllWorkflows().map((wf) => ({
1705
- id: wf.id,
1706
- name: wf.name,
1707
- description: wf.description,
1708
- stepCount: wf.steps.length
1709
- }))
1710
- };
1775
+ getState(id) {
1776
+ return this.states.get(id);
1711
1777
  }
1712
1778
  /**
1713
- * Clear all registrations
1779
+ * Get all registered states
1714
1780
  */
1715
- clear() {
1716
- this.elements.clear();
1717
- this.components.clear();
1718
- this.workflows.clear();
1719
- this.eventListeners.clear();
1720
- this.states.clear();
1721
- this.stateGroups.clear();
1722
- this.transitions.clear();
1723
- this.activeStates.clear();
1781
+ getAllStates() {
1782
+ return Array.from(this.states.values());
1724
1783
  }
1725
1784
  /**
1726
- * Get registry statistics
1785
+ * Register a state group
1727
1786
  */
1728
- getStats() {
1729
- const elements = this.getAllElements();
1730
- const components = this.getAllComponents();
1731
- return {
1732
- elementCount: elements.length,
1733
- componentCount: components.length,
1734
- workflowCount: this.workflows.size,
1735
- mountedElementCount: elements.filter((e) => e.mounted).length,
1736
- mountedComponentCount: components.filter((c) => c.mounted).length,
1737
- stateCount: this.states.size,
1738
- stateGroupCount: this.stateGroups.size,
1739
- transitionCount: this.transitions.size,
1740
- activeStateCount: this.activeStates.size
1741
- };
1742
- }
1743
- };
1744
- var globalRegistry = null;
1745
- function getGlobalRegistry() {
1746
- if (!globalRegistry) {
1747
- globalRegistry = new UIBridgeRegistry();
1748
- }
1749
- return globalRegistry;
1750
- }
1751
- function setGlobalRegistry(registry) {
1752
- globalRegistry = registry;
1753
- }
1754
- function resetGlobalRegistry() {
1755
- globalRegistry?.clear();
1756
- globalRegistry = null;
1757
- }
1758
-
1759
- // src/core/websocket-client.ts
1760
- function generateId() {
1761
- return `${Date.now()}-${Math.random().toString(36).slice(2, 11)}`;
1762
- }
1763
- var UIBridgeWSClient = class {
1764
- constructor(config) {
1765
- this.ws = null;
1766
- this.state = "disconnected";
1767
- this.clientId = null;
1768
- this.reconnectAttempts = 0;
1769
- this.reconnectTimer = null;
1770
- this.pingTimer = null;
1771
- this.pendingRequests = /* @__PURE__ */ new Map();
1772
- // Event listeners
1773
- this.connectionListeners = /* @__PURE__ */ new Set();
1774
- this.eventListeners = /* @__PURE__ */ new Map();
1775
- this.errorListeners = /* @__PURE__ */ new Set();
1776
- // Current subscriptions
1777
- this.subscriptions = {};
1778
- this.config = {
1779
- url: config.url,
1780
- autoReconnect: config.autoReconnect ?? true,
1781
- reconnectDelay: config.reconnectDelay ?? 1e3,
1782
- maxReconnectAttempts: config.maxReconnectAttempts ?? 10,
1783
- pingInterval: config.pingInterval ?? 3e4,
1784
- connectionTimeout: config.connectionTimeout ?? 1e4
1785
- };
1787
+ registerStateGroup(group) {
1788
+ this.stateGroups.set(group.id, group);
1789
+ return group;
1786
1790
  }
1787
1791
  /**
1788
- * Get current connection state
1792
+ * Unregister a state group
1789
1793
  */
1790
- get connectionState() {
1791
- return this.state;
1794
+ unregisterStateGroup(id) {
1795
+ return this.stateGroups.delete(id);
1792
1796
  }
1793
1797
  /**
1794
- * Get assigned client ID
1798
+ * Get a state group
1795
1799
  */
1796
- get id() {
1797
- return this.clientId;
1800
+ getStateGroup(id) {
1801
+ return this.stateGroups.get(id);
1798
1802
  }
1799
1803
  /**
1800
- * Connect to the WebSocket server
1804
+ * Get all state groups
1801
1805
  */
1802
- connect() {
1803
- return new Promise((resolve, reject) => {
1804
- if (this.ws && this.state === "connected") {
1805
- resolve();
1806
- return;
1807
- }
1808
- this.setState("connecting");
1809
- try {
1810
- this.ws = new WebSocket(this.config.url);
1811
- } catch (error) {
1812
- this.setState("disconnected");
1813
- reject(error);
1814
- return;
1815
- }
1816
- const connectionTimeout = setTimeout(() => {
1817
- if (this.state === "connecting") {
1818
- this.ws?.close();
1819
- this.setState("disconnected");
1820
- reject(new Error("Connection timeout"));
1821
- }
1822
- }, this.config.connectionTimeout);
1823
- this.ws.onopen = () => {
1824
- clearTimeout(connectionTimeout);
1825
- };
1826
- this.ws.onmessage = (event) => {
1827
- try {
1828
- const message = JSON.parse(event.data);
1829
- this.handleMessage(message);
1830
- if (message.type === "welcome") {
1831
- clearTimeout(connectionTimeout);
1832
- this.reconnectAttempts = 0;
1833
- this.setState("connected");
1834
- this.startPingInterval();
1835
- if (this.subscriptions.events?.length || this.subscriptions.elementIds?.length || this.subscriptions.componentIds?.length) {
1836
- this.subscribe(this.subscriptions);
1837
- }
1838
- resolve();
1839
- }
1840
- } catch (error) {
1841
- console.error("Failed to parse WebSocket message:", error);
1842
- }
1843
- };
1844
- this.ws.onerror = (_event) => {
1845
- clearTimeout(connectionTimeout);
1846
- const error = new Error("WebSocket error");
1847
- this.notifyError(error);
1848
- if (this.state === "connecting") {
1849
- reject(error);
1850
- }
1851
- };
1852
- this.ws.onclose = () => {
1853
- clearTimeout(connectionTimeout);
1854
- this.stopPingInterval();
1855
- this.clientId = null;
1856
- const wasConnected = this.state === "connected";
1857
- this.setState("disconnected");
1858
- for (const [_id, pending] of this.pendingRequests) {
1859
- clearTimeout(pending.timeout);
1860
- pending.reject(new Error("Connection closed"));
1861
- }
1862
- this.pendingRequests.clear();
1863
- if (wasConnected && this.config.autoReconnect && (this.config.maxReconnectAttempts === 0 || this.reconnectAttempts < this.config.maxReconnectAttempts)) {
1864
- this.scheduleReconnect();
1865
- }
1866
- };
1867
- });
1806
+ getAllStateGroups() {
1807
+ return Array.from(this.stateGroups.values());
1868
1808
  }
1869
1809
  /**
1870
- * Disconnect from the server
1810
+ * Register a transition
1871
1811
  */
1872
- disconnect() {
1873
- if (this.reconnectTimer) {
1874
- clearTimeout(this.reconnectTimer);
1875
- this.reconnectTimer = null;
1876
- }
1877
- this.stopPingInterval();
1878
- if (this.ws) {
1879
- this.ws.close();
1880
- this.ws = null;
1881
- }
1882
- this.setState("disconnected");
1812
+ registerTransition(transition) {
1813
+ this.transitions.set(transition.id, transition);
1814
+ return transition;
1883
1815
  }
1884
1816
  /**
1885
- * Subscribe to events
1817
+ * Unregister a transition
1886
1818
  */
1887
- async subscribe(options) {
1888
- this.subscriptions = { ...this.subscriptions, ...options };
1889
- const response = await this.sendRequest({
1890
- id: generateId(),
1891
- type: "subscribe",
1892
- timestamp: Date.now(),
1893
- payload: options
1894
- });
1895
- return response.events;
1819
+ unregisterTransition(id) {
1820
+ return this.transitions.delete(id);
1896
1821
  }
1897
1822
  /**
1898
- * Unsubscribe from events
1823
+ * Get a transition
1899
1824
  */
1900
- async unsubscribe(events) {
1901
- if (events) {
1902
- this.subscriptions.events = this.subscriptions.events?.filter((e) => !events.includes(e));
1903
- } else {
1904
- this.subscriptions = {};
1905
- }
1906
- const response = await this.sendRequest({
1907
- id: generateId(),
1908
- type: "unsubscribe",
1909
- timestamp: Date.now(),
1910
- payload: { events }
1911
- });
1912
- return response.events;
1825
+ getTransition(id) {
1826
+ return this.transitions.get(id);
1913
1827
  }
1914
1828
  /**
1915
- * Find elements
1829
+ * Get all transitions
1916
1830
  */
1917
- async find(options) {
1918
- const response = await this.sendRequest({
1919
- id: generateId(),
1920
- type: "find",
1921
- timestamp: Date.now(),
1922
- payload: options
1923
- });
1924
- return response.elements;
1831
+ getAllTransitions() {
1832
+ return Array.from(this.transitions.values());
1925
1833
  }
1926
1834
  /**
1927
- * Discover elements
1928
- * @deprecated Use find() instead
1835
+ * Get currently active states
1929
1836
  */
1930
- async discover(options) {
1931
- return this.find(options);
1837
+ getActiveStates() {
1838
+ return Array.from(this.activeStates);
1932
1839
  }
1933
1840
  /**
1934
- * Get element details
1841
+ * Check if a state is active
1935
1842
  */
1936
- async getElement(elementId, includeState = true) {
1937
- const response = await this.sendRequest({
1938
- id: generateId(),
1939
- type: "getElement",
1940
- timestamp: Date.now(),
1941
- payload: { elementId, includeState }
1942
- });
1943
- return response.element;
1843
+ isStateActive(id) {
1844
+ return this.activeStates.has(id);
1944
1845
  }
1945
1846
  /**
1946
- * Get full snapshot
1847
+ * Activate a state
1947
1848
  */
1948
- async getSnapshot() {
1949
- const response = await this.sendRequest({
1950
- id: generateId(),
1951
- type: "getSnapshot",
1952
- timestamp: Date.now()
1953
- });
1954
- return response;
1849
+ activateState(id) {
1850
+ const state = this.states.get(id);
1851
+ if (!state) {
1852
+ return false;
1853
+ }
1854
+ for (const activeId of this.activeStates) {
1855
+ const activeState = this.states.get(activeId);
1856
+ if (activeState?.blocking && activeState.id !== id) {
1857
+ return false;
1858
+ }
1859
+ if (activeState?.blocks?.includes(id)) {
1860
+ return false;
1861
+ }
1862
+ }
1863
+ const wasActive = this.activeStates.has(id);
1864
+ this.activeStates.add(id);
1865
+ if (!wasActive) {
1866
+ this.emit("element:stateChanged", {
1867
+ stateId: id,
1868
+ active: true,
1869
+ activeStates: this.getActiveStates()
1870
+ });
1871
+ }
1872
+ return true;
1955
1873
  }
1956
1874
  /**
1957
- * Execute action on an element
1875
+ * Deactivate a state
1958
1876
  */
1959
- async executeAction(elementId, action) {
1960
- const response = await this.sendRequest({
1961
- id: generateId(),
1962
- type: "executeAction",
1963
- timestamp: Date.now(),
1964
- payload: { elementId, action }
1965
- });
1966
- return response;
1877
+ deactivateState(id) {
1878
+ const wasActive = this.activeStates.has(id);
1879
+ this.activeStates.delete(id);
1880
+ if (wasActive) {
1881
+ this.emit("element:stateChanged", {
1882
+ stateId: id,
1883
+ active: false,
1884
+ activeStates: this.getActiveStates()
1885
+ });
1886
+ }
1887
+ return wasActive;
1967
1888
  }
1968
1889
  /**
1969
- * Execute component action
1890
+ * Activate multiple states
1970
1891
  */
1971
- async executeComponentAction(componentId, action, params) {
1972
- const response = await this.sendRequest({
1973
- id: generateId(),
1974
- type: "executeComponentAction",
1975
- timestamp: Date.now(),
1976
- payload: { componentId, action, params }
1977
- });
1978
- return response;
1892
+ activateStates(ids) {
1893
+ const activated = [];
1894
+ for (const id of ids) {
1895
+ if (this.activateState(id)) {
1896
+ activated.push(id);
1897
+ }
1898
+ }
1899
+ return activated;
1979
1900
  }
1980
1901
  /**
1981
- * Execute workflow with optional progress streaming
1902
+ * Deactivate multiple states
1982
1903
  */
1983
- async executeWorkflow(workflowId, params, onProgress) {
1984
- const id = generateId();
1985
- const progressHandler = onProgress ? (message) => {
1986
- if (message.type === "workflowProgress" && message.requestId === id) {
1987
- onProgress({
1988
- currentStep: message.payload.currentStep,
1989
- totalSteps: message.payload.totalSteps,
1990
- step: {
1991
- id: message.payload.step.id,
1992
- status: message.payload.step.status
1993
- }
1994
- });
1904
+ deactivateStates(ids) {
1905
+ const deactivated = [];
1906
+ for (const id of ids) {
1907
+ if (this.deactivateState(id)) {
1908
+ deactivated.push(id);
1995
1909
  }
1996
- } : void 0;
1997
- const response = await this.sendRequest(
1998
- {
1999
- id,
2000
- type: "executeWorkflow",
2001
- timestamp: Date.now(),
2002
- payload: { workflowId, params, streamProgress: !!onProgress }
2003
- },
2004
- progressHandler
2005
- );
2006
- return response;
1910
+ }
1911
+ return deactivated;
2007
1912
  }
2008
1913
  /**
2009
- * Add connection state listener
1914
+ * Activate a state group (all states in the group)
2010
1915
  */
2011
- onConnectionChange(listener) {
2012
- this.connectionListeners.add(listener);
2013
- return () => this.connectionListeners.delete(listener);
1916
+ activateStateGroup(groupId) {
1917
+ const group = this.stateGroups.get(groupId);
1918
+ if (!group) return [];
1919
+ return this.activateStates(group.states);
2014
1920
  }
2015
1921
  /**
2016
- * Add event listener
1922
+ * Deactivate a state group (all states in the group)
2017
1923
  */
2018
- onEvent(eventType, listener) {
2019
- if (!this.eventListeners.has(eventType)) {
2020
- this.eventListeners.set(eventType, /* @__PURE__ */ new Set());
2021
- }
2022
- this.eventListeners.get(eventType).add(listener);
2023
- return () => this.eventListeners.get(eventType)?.delete(listener);
1924
+ deactivateStateGroup(groupId) {
1925
+ const group = this.stateGroups.get(groupId);
1926
+ if (!group) return [];
1927
+ return this.deactivateStates(group.states);
2024
1928
  }
2025
1929
  /**
2026
- * Add error listener
1930
+ * Check if a transition can be executed from current state
2027
1931
  */
2028
- onError(listener) {
2029
- this.errorListeners.add(listener);
2030
- return () => this.errorListeners.delete(listener);
1932
+ canExecuteTransition(transitionId) {
1933
+ const transition = this.transitions.get(transitionId);
1934
+ if (!transition) return false;
1935
+ return transition.fromStates.some((stateId) => this.activeStates.has(stateId));
2031
1936
  }
2032
- // Private methods
2033
- setState(state) {
2034
- this.state = state;
2035
- for (const listener of this.connectionListeners) {
2036
- try {
2037
- listener(state);
2038
- } catch (error) {
2039
- console.error("Connection listener error:", error);
2040
- }
1937
+ /**
1938
+ * Execute a transition
1939
+ */
1940
+ async executeTransition(transitionId) {
1941
+ const startTime = performance.now();
1942
+ const transition = this.transitions.get(transitionId);
1943
+ if (!transition) {
1944
+ return {
1945
+ success: false,
1946
+ activatedStates: [],
1947
+ deactivatedStates: [],
1948
+ error: `Transition not found: ${transitionId}`,
1949
+ durationMs: performance.now() - startTime
1950
+ };
2041
1951
  }
2042
- }
2043
- handleMessage(message) {
2044
- switch (message.type) {
2045
- case "welcome":
2046
- this.clientId = message.payload.clientId;
2047
- break;
2048
- case "pong":
2049
- break;
2050
- case "subscribed":
2051
- case "unsubscribed":
2052
- break;
2053
- case "event":
2054
- this.notifyEvent(message.payload);
2055
- break;
2056
- case "response":
2057
- this.handleResponse(message);
2058
- break;
2059
- case "error":
2060
- if (message.requestId) {
2061
- this.handleResponse({
2062
- ...message,
2063
- type: "response",
2064
- requestId: message.requestId,
2065
- payload: {
2066
- success: false,
2067
- error: message.payload.message
2068
- }
2069
- });
2070
- } else {
2071
- this.notifyError(new Error(message.payload.message));
1952
+ if (!this.canExecuteTransition(transitionId)) {
1953
+ return {
1954
+ success: false,
1955
+ activatedStates: [],
1956
+ deactivatedStates: [],
1957
+ error: "Precondition not met: none of the fromStates are active",
1958
+ failedPhase: "precondition",
1959
+ durationMs: performance.now() - startTime
1960
+ };
1961
+ }
1962
+ try {
1963
+ const deactivated = this.deactivateStates(transition.exitStates);
1964
+ if (transition.exitGroups) {
1965
+ for (const groupId of transition.exitGroups) {
1966
+ deactivated.push(...this.deactivateStateGroup(groupId));
2072
1967
  }
2073
- break;
1968
+ }
1969
+ const activated = this.activateStates(transition.activateStates);
1970
+ if (transition.activateGroups) {
1971
+ for (const groupId of transition.activateGroups) {
1972
+ activated.push(...this.activateStateGroup(groupId));
1973
+ }
1974
+ }
1975
+ return {
1976
+ success: true,
1977
+ activatedStates: activated,
1978
+ deactivatedStates: deactivated,
1979
+ durationMs: performance.now() - startTime
1980
+ };
1981
+ } catch (error) {
1982
+ return {
1983
+ success: false,
1984
+ activatedStates: [],
1985
+ deactivatedStates: [],
1986
+ error: error instanceof Error ? error.message : String(error),
1987
+ failedPhase: "execution",
1988
+ durationMs: performance.now() - startTime
1989
+ };
2074
1990
  }
2075
1991
  }
2076
- handleResponse(message) {
2077
- const pending = this.pendingRequests.get(message.requestId);
2078
- if (!pending) return;
2079
- clearTimeout(pending.timeout);
2080
- this.pendingRequests.delete(message.requestId);
2081
- if (message.type === "response") {
2082
- if (message.payload.success) {
2083
- pending.resolve(message.payload.data);
2084
- } else {
2085
- pending.reject(new Error(message.payload.error || "Request failed"));
2086
- }
1992
+ /**
1993
+ * Find a path from current state to target states
1994
+ *
1995
+ * Uses a simple BFS algorithm for pathfinding.
1996
+ * For more advanced pathfinding (Dijkstra, A*), use the Python state manager service.
1997
+ */
1998
+ findPath(targetStates) {
1999
+ if (targetStates.every((t) => this.activeStates.has(t))) {
2000
+ return {
2001
+ found: true,
2002
+ transitions: [],
2003
+ totalCost: 0,
2004
+ targetStates,
2005
+ estimatedSteps: 0
2006
+ };
2087
2007
  }
2088
- }
2089
- notifyEvent(event) {
2090
- const typeListeners = this.eventListeners.get(event.type);
2091
- if (typeListeners) {
2092
- for (const listener of typeListeners) {
2093
- try {
2094
- listener(event);
2095
- } catch (error) {
2096
- console.error("Event listener error:", error);
2097
- }
2008
+ const queue = [
2009
+ { activeStates: new Set(this.activeStates), path: [], cost: 0 }
2010
+ ];
2011
+ const visited = /* @__PURE__ */ new Set();
2012
+ while (queue.length > 0) {
2013
+ const current = queue.shift();
2014
+ const stateKey = Array.from(current.activeStates).sort().join(",");
2015
+ if (visited.has(stateKey)) continue;
2016
+ visited.add(stateKey);
2017
+ if (targetStates.every((t) => current.activeStates.has(t))) {
2018
+ return {
2019
+ found: true,
2020
+ transitions: current.path,
2021
+ totalCost: current.cost,
2022
+ targetStates,
2023
+ estimatedSteps: current.path.length
2024
+ };
2098
2025
  }
2099
- }
2100
- const wildcardListeners = this.eventListeners.get("*");
2101
- if (wildcardListeners) {
2102
- for (const listener of wildcardListeners) {
2103
- try {
2104
- listener(event);
2105
- } catch (error) {
2106
- console.error("Event listener error:", error);
2107
- }
2026
+ for (const transition of this.transitions.values()) {
2027
+ const canExecute = transition.fromStates.some((s) => current.activeStates.has(s));
2028
+ if (!canExecute) continue;
2029
+ const newActive = new Set(current.activeStates);
2030
+ for (const s of transition.exitStates) newActive.delete(s);
2031
+ for (const s of transition.activateStates) newActive.add(s);
2032
+ const newCost = current.cost + (transition.pathCost ?? 1);
2033
+ queue.push({
2034
+ activeStates: newActive,
2035
+ path: [...current.path, transition.id],
2036
+ cost: newCost
2037
+ });
2108
2038
  }
2109
2039
  }
2040
+ return {
2041
+ found: false,
2042
+ transitions: [],
2043
+ totalCost: 0,
2044
+ targetStates,
2045
+ estimatedSteps: 0
2046
+ };
2110
2047
  }
2111
- notifyError(error) {
2112
- for (const listener of this.errorListeners) {
2113
- try {
2114
- listener(error);
2115
- } catch (e) {
2116
- console.error("Error listener error:", e);
2117
- }
2048
+ /**
2049
+ * Navigate to target states using pathfinding
2050
+ */
2051
+ async navigateTo(targetStates) {
2052
+ const startTime = performance.now();
2053
+ const path = this.findPath(targetStates);
2054
+ if (!path.found) {
2055
+ return {
2056
+ success: false,
2057
+ path,
2058
+ executedTransitions: [],
2059
+ finalActiveStates: this.getActiveStates(),
2060
+ error: `No path found to target states: ${targetStates.join(", ")}`,
2061
+ durationMs: performance.now() - startTime
2062
+ };
2118
2063
  }
2119
- }
2120
- sendRequest(message, progressHandler) {
2121
- return new Promise((resolve, reject) => {
2122
- if (!this.ws || this.state !== "connected") {
2123
- reject(new Error("Not connected"));
2124
- return;
2125
- }
2126
- const timeout = setTimeout(() => {
2127
- this.pendingRequests.delete(message.id);
2128
- reject(new Error("Request timeout"));
2129
- }, 3e4);
2130
- this.pendingRequests.set(message.id, {
2131
- resolve,
2132
- reject,
2133
- timeout
2134
- });
2135
- if (progressHandler && this.ws) {
2136
- const originalHandler = this.ws.onmessage;
2137
- const wsRef = this.ws;
2138
- const wrappedHandler = (event) => {
2139
- try {
2140
- const msg = JSON.parse(event.data);
2141
- if (msg.type === "workflowProgress") {
2142
- progressHandler(msg);
2143
- }
2144
- } catch {
2145
- }
2146
- if (originalHandler) {
2147
- originalHandler.call(wsRef, event);
2148
- }
2064
+ const executedTransitions = [];
2065
+ for (const transitionId of path.transitions) {
2066
+ const result = await this.executeTransition(transitionId);
2067
+ if (!result.success) {
2068
+ return {
2069
+ success: false,
2070
+ path,
2071
+ executedTransitions,
2072
+ finalActiveStates: this.getActiveStates(),
2073
+ error: result.error,
2074
+ durationMs: performance.now() - startTime
2149
2075
  };
2150
- this.ws.onmessage = wrappedHandler;
2151
2076
  }
2152
- this.ws.send(JSON.stringify(message));
2153
- });
2077
+ executedTransitions.push(transitionId);
2078
+ }
2079
+ return {
2080
+ success: true,
2081
+ path,
2082
+ executedTransitions,
2083
+ finalActiveStates: this.getActiveStates(),
2084
+ durationMs: performance.now() - startTime
2085
+ };
2154
2086
  }
2155
- scheduleReconnect() {
2156
- if (this.reconnectTimer) return;
2157
- this.setState("reconnecting");
2158
- this.reconnectAttempts++;
2159
- const delay = Math.min(
2160
- this.config.reconnectDelay * Math.pow(2, this.reconnectAttempts - 1),
2161
- 3e4
2162
- );
2163
- this.reconnectTimer = setTimeout(() => {
2164
- this.reconnectTimer = null;
2165
- this.connect().catch(() => {
2166
- });
2167
- }, delay);
2087
+ /**
2088
+ * Create a state snapshot
2089
+ */
2090
+ createStateSnapshot() {
2091
+ return {
2092
+ timestamp: Date.now(),
2093
+ activeStates: this.getActiveStates(),
2094
+ states: this.getAllStates(),
2095
+ groups: this.getAllStateGroups(),
2096
+ transitions: this.getAllTransitions()
2097
+ };
2168
2098
  }
2169
- startPingInterval() {
2170
- if (this.config.pingInterval <= 0) return;
2171
- this.pingTimer = setInterval(() => {
2172
- if (this.ws && this.state === "connected") {
2173
- this.ws.send(
2174
- JSON.stringify({
2175
- id: generateId(),
2176
- type: "ping",
2177
- timestamp: Date.now()
2178
- })
2179
- );
2180
- }
2181
- }, this.config.pingInterval);
2099
+ /**
2100
+ * Create a snapshot of the current state
2101
+ */
2102
+ createSnapshot() {
2103
+ return {
2104
+ timestamp: Date.now(),
2105
+ elements: this.getAllElements().map((el) => ({
2106
+ id: el.id,
2107
+ type: el.type,
2108
+ label: el.label,
2109
+ identifier: el.getIdentifier(),
2110
+ state: el.getState(),
2111
+ actions: el.actions,
2112
+ customActions: el.customActions ? Object.keys(el.customActions) : void 0
2113
+ })),
2114
+ components: this.getAllComponents().map((comp) => ({
2115
+ id: comp.id,
2116
+ name: comp.name,
2117
+ description: comp.description,
2118
+ actions: comp.actions.map((a) => a.id),
2119
+ elementIds: comp.elementIds
2120
+ })),
2121
+ workflows: this.getAllWorkflows().map((wf) => ({
2122
+ id: wf.id,
2123
+ name: wf.name,
2124
+ description: wf.description,
2125
+ stepCount: wf.steps.length
2126
+ }))
2127
+ };
2182
2128
  }
2183
- stopPingInterval() {
2184
- if (this.pingTimer) {
2185
- clearInterval(this.pingTimer);
2186
- this.pingTimer = null;
2187
- }
2129
+ /**
2130
+ * Clear all registrations
2131
+ */
2132
+ clear() {
2133
+ this.elements.clear();
2134
+ this.components.clear();
2135
+ this.workflows.clear();
2136
+ this.eventListeners.clear();
2137
+ this.states.clear();
2138
+ this.stateGroups.clear();
2139
+ this.transitions.clear();
2140
+ this.activeStates.clear();
2141
+ }
2142
+ /**
2143
+ * Get registry statistics
2144
+ */
2145
+ getStats() {
2146
+ const elements = this.getAllElements();
2147
+ const components = this.getAllComponents();
2148
+ return {
2149
+ elementCount: elements.length,
2150
+ componentCount: components.length,
2151
+ workflowCount: this.workflows.size,
2152
+ mountedElementCount: elements.filter((e) => e.mounted).length,
2153
+ mountedComponentCount: components.filter((c) => c.mounted).length,
2154
+ stateCount: this.states.size,
2155
+ stateGroupCount: this.stateGroups.size,
2156
+ transitionCount: this.transitions.size,
2157
+ activeStateCount: this.activeStates.size
2158
+ };
2188
2159
  }
2189
2160
  };
2190
- function createWSClient(config) {
2191
- return new UIBridgeWSClient(config);
2161
+ var globalRegistry = null;
2162
+ function setGlobalRegistry(registry) {
2163
+ globalRegistry = registry;
2164
+ }
2165
+ function resetGlobalRegistry() {
2166
+ globalRegistry?.clear();
2167
+ globalRegistry = null;
2192
2168
  }
2193
2169
 
2194
2170
  // src/control/action-executor.ts
@@ -4093,11 +4069,31 @@ function useUIComponent(options) {
4093
4069
  const registeredRef = useRef(false);
4094
4070
  const actionsRef = useRef(options.actions || []);
4095
4071
  const elementIdsRef = useRef(options.elementIds || []);
4072
+ const stateRef = useRef(options.state);
4073
+ const computedRef = useRef(options.computed);
4096
4074
  const { id, name, description, autoRegister = true } = options;
4097
4075
  useEffect(() => {
4098
4076
  actionsRef.current = options.actions || [];
4099
4077
  elementIdsRef.current = options.elementIds || [];
4100
- }, [options.actions, options.elementIds]);
4078
+ stateRef.current = options.state;
4079
+ computedRef.current = options.computed;
4080
+ }, [options.actions, options.elementIds, options.state, options.computed]);
4081
+ const createGetComputed = useCallback(() => {
4082
+ return () => {
4083
+ const computed = computedRef.current;
4084
+ if (!computed) return {};
4085
+ const result = {};
4086
+ for (const [key, def] of Object.entries(computed)) {
4087
+ try {
4088
+ const getter = typeof def === "function" ? def : def.getter;
4089
+ result[key] = getter();
4090
+ } catch {
4091
+ result[key] = void 0;
4092
+ }
4093
+ }
4094
+ return result;
4095
+ };
4096
+ }, []);
4101
4097
  const register = useCallback(() => {
4102
4098
  if (!bridge || registeredRef.current) return;
4103
4099
  bridge.registry.registerComponent(id, {
@@ -4109,10 +4105,12 @@ function useUIComponent(options) {
4109
4105
  description: a.description,
4110
4106
  handler: a.handler
4111
4107
  })),
4112
- elementIds: elementIdsRef.current
4108
+ elementIds: elementIdsRef.current,
4109
+ getState: stateRef.current,
4110
+ getComputed: createGetComputed()
4113
4111
  });
4114
4112
  registeredRef.current = true;
4115
- }, [bridge, id, name, description]);
4113
+ }, [bridge, id, name, description, createGetComputed]);
4116
4114
  const unregister = useCallback(() => {
4117
4115
  if (!bridge || !registeredRef.current) return;
4118
4116
  bridge.registry.unregisterComponent(id);
@@ -8703,6 +8701,6 @@ function describeDiff(diff) {
8703
8701
  return parts.join(", ");
8704
8702
  }
8705
8703
 
8706
- export { AssertionExecutor, AutoRegisterProvider, DEFAULT_ALIAS_CONFIG, DEFAULT_ASSERTION_CONFIG, DEFAULT_DIFF_CONFIG, DEFAULT_EXECUTOR_CONFIG, DEFAULT_FUZZY_CONFIG, DEFAULT_SEARCH_CONFIG, DEFAULT_SNAPSHOT_CONFIG, DOMChangeObserver, DefaultActionExecutor, DefaultWorkflowEngine, ErrorCodes, ID_ATTRIBUTES, InMemoryRenderLogStorage, InfoPanel, Inspector, InspectorOverlay, MetricsCollector, NLActionExecutor, RenderLogManager, SearchEngine, SemanticDiffManager, SemanticSnapshotManager, UIBridgeProvider, UIBridgeRegistry, UIBridgeWSClient, areSynonyms, captureDOMSnapshot, captureInteractiveElements, computeDiff, createActionExecutor, createAssertionExecutor, createDiffManager, createElementIdentifier, createErrorContext, createMetricsCollector, createNLActionExecutor, createRenderLogManager, createSearchEngine, createSimpleError, createSnapshotManager, createWSClient, createWorkflowEngine, describeAction, describeDiff, elementMatchesIdentifier, extractModifiers, findAllElementsByIdentifier, findAllMatches, findBestMatch, findElementByIdentifier, formatDuration, formatErrorContext, formatPercentage, fuzzyContains, fuzzyMatch, generateAliases, generateCSSSelector, generateDescription, generateDiffSummary, generateElementDescription, generateNgrams, generatePageSummary, generatePurpose, generateSnapshotSummary, generateSuggestedActions, generateXPath, getBestIdentifier, getBestRecoverySuggestion, getGlobalRegistry, getSynonyms, hasSignificantChanges, inferPageType, isRecoverableError, jaroSimilarity, jaroWinklerSimilarity, levenshteinDistance, levenshteinSimilarity, ngramSimilarity, normalizeString, parseNLInstruction, parseNLInstructions, resetGlobalRegistry, setGlobalRegistry, splitCompoundInstruction, tokenSimilarity, tokenize, useActiveStates, useAutoRegister, useAvailableTransitions, useCanNavigateTo, useInspector, useNavigationPath, useStateSnapshot, useTransitions, useUIBridge, useUIBridgeContext, useUIBridgeOptional, useUIBridgeRequired, useUIComponent, useUIComponentAction, useUIElement, useUIElementRef, useUINavigation, useUIState, useUIStateGroup, useUITransition, validateParsedAction, wordSimilarity };
8704
+ export { AssertionExecutor, AutoRegisterProvider, DEFAULT_ALIAS_CONFIG, DEFAULT_ASSERTION_CONFIG, DEFAULT_DIFF_CONFIG, DEFAULT_EXECUTOR_CONFIG, DEFAULT_FUZZY_CONFIG, DEFAULT_SEARCH_CONFIG, DEFAULT_SNAPSHOT_CONFIG, DOMChangeObserver, DefaultActionExecutor, DefaultWorkflowEngine, ErrorCodes, InMemoryRenderLogStorage, InfoPanel, Inspector, InspectorOverlay, MetricsCollector, NLActionExecutor, RenderLogManager, SearchEngine, SemanticDiffManager, SemanticSnapshotManager, UIBridgeProvider, UIBridgeWSClient, areSynonyms, captureDOMSnapshot, captureInteractiveElements, computeDiff, createActionExecutor, createAssertionExecutor, createDiffManager, createErrorContext, createMetricsCollector, createNLActionExecutor, createRenderLogManager, createSearchEngine, createSimpleError, createSnapshotManager, createWSClient, createWorkflowEngine, describeAction, describeDiff, extractModifiers, findAllMatches, findBestMatch, formatDuration, formatErrorContext, formatPercentage, fuzzyContains, fuzzyMatch, generateAliases, generateDescription, generateDiffSummary, generateElementDescription, generateNgrams, generatePageSummary, generatePurpose, generateSnapshotSummary, generateSuggestedActions, getBestRecoverySuggestion, getSynonyms, hasSignificantChanges, inferPageType, isRecoverableError, jaroSimilarity, jaroWinklerSimilarity, levenshteinDistance, levenshteinSimilarity, ngramSimilarity, normalizeString, parseNLInstruction, parseNLInstructions, splitCompoundInstruction, tokenSimilarity, tokenize, useActiveStates, useAutoRegister, useAvailableTransitions, useCanNavigateTo, useInspector, useNavigationPath, useStateSnapshot, useTransitions, useUIBridge, useUIBridgeContext, useUIBridgeOptional, useUIBridgeRequired, useUIComponent, useUIComponentAction, useUIElement, useUIElementRef, useUINavigation, useUIState, useUIStateGroup, useUITransition, validateParsedAction, wordSimilarity };
8707
8705
  //# sourceMappingURL=index.mjs.map
8708
8706
  //# sourceMappingURL=index.mjs.map