@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.
- package/dist/ai/index.d.mts +4 -4
- package/dist/ai/index.d.ts +4 -4
- package/dist/babel-plugin/index.js +515 -0
- package/dist/babel-plugin/index.js.map +1 -0
- package/dist/babel-plugin/index.mjs +499 -0
- package/dist/babel-plugin/index.mjs.map +1 -0
- package/dist/control/index.d.mts +5 -5
- package/dist/control/index.d.ts +5 -5
- package/dist/core/index.d.mts +115 -44
- package/dist/core/index.d.ts +115 -44
- package/dist/core/index.js +0 -1560
- package/dist/core/index.js.map +1 -1
- package/dist/core/index.mjs +1 -1549
- package/dist/core/index.mjs.map +1 -1
- package/dist/debug/index.d.mts +3 -3
- package/dist/debug/index.d.ts +3 -3
- package/dist/index.d.mts +7 -8
- package/dist/index.d.ts +7 -8
- package/dist/index.js +859 -873
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +860 -862
- package/dist/index.mjs.map +1 -1
- package/dist/{metrics-C9XRi_mL.d.ts → metrics-BfiT_rhZ.d.ts} +2 -2
- package/dist/{metrics-NC3csD0R.d.mts → metrics-DTA2bwG7.d.mts} +2 -2
- package/dist/native/control/index.js +453 -0
- package/dist/native/control/index.js.map +1 -0
- package/dist/native/control/index.mjs +450 -0
- package/dist/native/control/index.mjs.map +1 -0
- package/dist/native/core/index.js +486 -0
- package/dist/native/core/index.js.map +1 -0
- package/dist/native/core/index.mjs +475 -0
- package/dist/native/core/index.mjs.map +1 -0
- package/dist/native/debug/index.js +451 -0
- package/dist/native/debug/index.js.map +1 -0
- package/dist/native/debug/index.mjs +449 -0
- package/dist/native/debug/index.mjs.map +1 -0
- package/dist/native/index.js +2274 -0
- package/dist/native/index.js.map +1 -0
- package/dist/native/index.mjs +2246 -0
- package/dist/native/index.mjs.map +1 -0
- package/dist/native/react/index.js +1401 -0
- package/dist/native/react/index.js.map +1 -0
- package/dist/native/react/index.mjs +1389 -0
- package/dist/native/react/index.mjs.map +1 -0
- package/dist/native/server/index.js +415 -0
- package/dist/native/server/index.js.map +1 -0
- package/dist/native/server/index.mjs +410 -0
- package/dist/native/server/index.mjs.map +1 -0
- package/dist/react/index.d.mts +20 -7
- package/dist/react/index.d.ts +20 -7
- package/dist/react/index.js +42 -4
- package/dist/react/index.js.map +1 -1
- package/dist/react/index.mjs +42 -4
- package/dist/react/index.mjs.map +1 -1
- package/dist/{registry-CIEDjbQ9.d.ts → registry-BKLEm-yk.d.ts} +9 -15
- package/dist/{registry-SsSDq46X.d.mts → registry-BmZgyCz8.d.mts} +9 -15
- package/dist/render-log/index.d.mts +1 -1
- package/dist/render-log/index.d.ts +1 -1
- package/dist/server/express.d.mts +36 -0
- package/dist/server/express.d.ts +36 -0
- package/dist/server/express.js +196 -0
- package/dist/server/express.js.map +1 -0
- package/dist/server/express.mjs +192 -0
- package/dist/server/express.mjs.map +1 -0
- package/dist/server/handlers.d.mts +93 -0
- package/dist/server/handlers.d.ts +93 -0
- package/dist/server/handlers.js +4278 -0
- package/dist/server/handlers.js.map +1 -0
- package/dist/server/handlers.mjs +4275 -0
- package/dist/server/handlers.mjs.map +1 -0
- package/dist/server/index.d.mts +10 -0
- package/dist/server/index.d.ts +10 -0
- package/dist/server/index.js +5352 -0
- package/dist/server/index.js.map +1 -0
- package/dist/server/index.mjs +5337 -0
- package/dist/server/index.mjs.map +1 -0
- package/dist/server/nextjs.d.mts +126 -0
- package/dist/server/nextjs.d.ts +126 -0
- package/dist/server/nextjs.js +287 -0
- package/dist/server/nextjs.js.map +1 -0
- package/dist/server/nextjs.mjs +282 -0
- package/dist/server/nextjs.mjs.map +1 -0
- package/dist/server/standalone.d.mts +6 -0
- package/dist/server/standalone.d.ts +6 -0
- package/dist/server/standalone.js +719 -0
- package/dist/server/standalone.js.map +1 -0
- package/dist/server/standalone.mjs +715 -0
- package/dist/server/standalone.mjs.map +1 -0
- package/dist/standalone-BURj8J3G.d.ts +212 -0
- package/dist/standalone-Dwmel29d.d.mts +212 -0
- package/dist/swc-plugin/index.d.mts +79 -0
- package/dist/swc-plugin/index.d.ts +79 -0
- package/dist/swc-plugin/index.js +15 -0
- package/dist/swc-plugin/index.js.map +1 -0
- package/dist/swc-plugin/index.mjs +9 -0
- package/dist/swc-plugin/index.mjs.map +1 -0
- package/dist/{types-CFT3Dnx4.d.mts → types-B5Q0GVo0.d.mts} +115 -3
- package/dist/{types-Dr6tH-bm.d.mts → types-B7J7noLK.d.mts} +1 -1
- package/dist/{types-oCTrRxSw.d.ts → types-BkNRILUa.d.ts} +1 -1
- package/dist/types-CEQLnFMv.d.mts +156 -0
- package/dist/types-CHnlwiTK.d.ts +156 -0
- package/dist/{types-BvCfFuEV.d.ts → types-DfPqwU-i.d.ts} +115 -3
- package/dist/{types-CPMbN_Iw.d.mts → types-jKVgTI6_.d.mts} +356 -160
- package/dist/{types-CPMbN_Iw.d.ts → types-jKVgTI6_.d.ts} +356 -160
- package/package.json +106 -3
- package/swc-plugin-wasm/ui_bridge_swc_plugin.wasm +0 -0
- package/dist/websocket-client-CX4QJesI.d.ts +0 -124
- package/dist/websocket-client-C_Na0OSp.d.mts +0 -124
|
@@ -0,0 +1,486 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// src/native/core/registry.ts
|
|
4
|
+
function inferActions(type) {
|
|
5
|
+
const baseActions = ["focus", "blur"];
|
|
6
|
+
switch (type) {
|
|
7
|
+
case "button":
|
|
8
|
+
case "touchable":
|
|
9
|
+
case "pressable":
|
|
10
|
+
return [...baseActions, "press", "longPress", "doubleTap"];
|
|
11
|
+
case "input":
|
|
12
|
+
return [...baseActions, "press", "type", "clear"];
|
|
13
|
+
case "text":
|
|
14
|
+
return [...baseActions, "press", "longPress"];
|
|
15
|
+
case "view":
|
|
16
|
+
return [...baseActions, "press"];
|
|
17
|
+
case "scroll":
|
|
18
|
+
return [...baseActions, "scroll", "swipe"];
|
|
19
|
+
case "list":
|
|
20
|
+
return [...baseActions, "scroll", "swipe"];
|
|
21
|
+
case "listItem":
|
|
22
|
+
return [...baseActions, "press", "longPress", "swipe"];
|
|
23
|
+
case "switch":
|
|
24
|
+
case "checkbox":
|
|
25
|
+
return [...baseActions, "press", "toggle"];
|
|
26
|
+
case "radio":
|
|
27
|
+
return [...baseActions, "press"];
|
|
28
|
+
case "image":
|
|
29
|
+
return [...baseActions, "press", "longPress"];
|
|
30
|
+
case "modal":
|
|
31
|
+
return ["focus", "blur"];
|
|
32
|
+
case "custom":
|
|
33
|
+
default:
|
|
34
|
+
return [...baseActions, "press"];
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
var NativeUIBridgeRegistry = class {
|
|
38
|
+
constructor(config = {}) {
|
|
39
|
+
this.elements = /* @__PURE__ */ new Map();
|
|
40
|
+
this.components = /* @__PURE__ */ new Map();
|
|
41
|
+
this.workflows = /* @__PURE__ */ new Map();
|
|
42
|
+
this.eventListeners = /* @__PURE__ */ new Map();
|
|
43
|
+
this.config = config;
|
|
44
|
+
}
|
|
45
|
+
// ============================================================================
|
|
46
|
+
// Element Management
|
|
47
|
+
// ============================================================================
|
|
48
|
+
/**
|
|
49
|
+
* Register a native element
|
|
50
|
+
*/
|
|
51
|
+
registerElement(id, ref, options = {}) {
|
|
52
|
+
const {
|
|
53
|
+
type = "custom",
|
|
54
|
+
label,
|
|
55
|
+
actions = inferActions(type),
|
|
56
|
+
customActions,
|
|
57
|
+
props,
|
|
58
|
+
treePath = id,
|
|
59
|
+
testId,
|
|
60
|
+
accessibilityLabel
|
|
61
|
+
} = options;
|
|
62
|
+
const getState = () => {
|
|
63
|
+
const element = ref.current;
|
|
64
|
+
if (!element) {
|
|
65
|
+
return {
|
|
66
|
+
mounted: false,
|
|
67
|
+
visible: false,
|
|
68
|
+
enabled: false,
|
|
69
|
+
focused: false,
|
|
70
|
+
layout: null
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
const stored = this.elements.get(id);
|
|
74
|
+
if (stored && stored.getState !== getState) {
|
|
75
|
+
return stored.getState();
|
|
76
|
+
}
|
|
77
|
+
return {
|
|
78
|
+
mounted: true,
|
|
79
|
+
visible: true,
|
|
80
|
+
enabled: true,
|
|
81
|
+
focused: false,
|
|
82
|
+
layout: null
|
|
83
|
+
};
|
|
84
|
+
};
|
|
85
|
+
const getIdentifier = () => ({
|
|
86
|
+
uiId: id,
|
|
87
|
+
testId: testId || id,
|
|
88
|
+
accessibilityLabel,
|
|
89
|
+
treePath
|
|
90
|
+
});
|
|
91
|
+
const registered = {
|
|
92
|
+
id,
|
|
93
|
+
ref,
|
|
94
|
+
type,
|
|
95
|
+
label,
|
|
96
|
+
actions,
|
|
97
|
+
customActions,
|
|
98
|
+
props,
|
|
99
|
+
getState,
|
|
100
|
+
getIdentifier,
|
|
101
|
+
registeredAt: Date.now(),
|
|
102
|
+
mounted: true
|
|
103
|
+
};
|
|
104
|
+
this.elements.set(id, registered);
|
|
105
|
+
this.emit("element:registered", { id, type, label });
|
|
106
|
+
if (this.config.verbose) {
|
|
107
|
+
console.log(`[ui-bridge-native] Registered element: ${id} (${type})`);
|
|
108
|
+
}
|
|
109
|
+
return registered;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Unregister an element
|
|
113
|
+
*/
|
|
114
|
+
unregisterElement(id) {
|
|
115
|
+
const element = this.elements.get(id);
|
|
116
|
+
if (element) {
|
|
117
|
+
this.elements.delete(id);
|
|
118
|
+
this.emit("element:unregistered", { id });
|
|
119
|
+
if (this.config.verbose) {
|
|
120
|
+
console.log(`[ui-bridge-native] Unregistered element: ${id}`);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Get a registered element
|
|
126
|
+
*/
|
|
127
|
+
getElement(id) {
|
|
128
|
+
return this.elements.get(id);
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Get all registered elements
|
|
132
|
+
*/
|
|
133
|
+
getAllElements() {
|
|
134
|
+
return Array.from(this.elements.values());
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Update element state
|
|
138
|
+
*/
|
|
139
|
+
updateElementState(id, state) {
|
|
140
|
+
const element = this.elements.get(id);
|
|
141
|
+
if (element) {
|
|
142
|
+
const currentState = element.getState();
|
|
143
|
+
const newState = { ...currentState, ...state };
|
|
144
|
+
const updated = {
|
|
145
|
+
...element,
|
|
146
|
+
getState: () => newState
|
|
147
|
+
};
|
|
148
|
+
this.elements.set(id, updated);
|
|
149
|
+
this.emit("element:stateChanged", { id, state: newState });
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Update element props (for action execution)
|
|
154
|
+
*/
|
|
155
|
+
updateElementProps(id, props) {
|
|
156
|
+
const element = this.elements.get(id);
|
|
157
|
+
if (element) {
|
|
158
|
+
const updated = {
|
|
159
|
+
...element,
|
|
160
|
+
props: { ...element.props, ...props }
|
|
161
|
+
};
|
|
162
|
+
this.elements.set(id, updated);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Find element by testID
|
|
167
|
+
*/
|
|
168
|
+
findByTestId(testId) {
|
|
169
|
+
for (const element of this.elements.values()) {
|
|
170
|
+
const identifier = element.getIdentifier();
|
|
171
|
+
if (identifier.testId === testId) {
|
|
172
|
+
return element;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
return void 0;
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Find elements by type
|
|
179
|
+
*/
|
|
180
|
+
findByType(type) {
|
|
181
|
+
return Array.from(this.elements.values()).filter((e) => e.type === type);
|
|
182
|
+
}
|
|
183
|
+
// ============================================================================
|
|
184
|
+
// Component Management
|
|
185
|
+
// ============================================================================
|
|
186
|
+
/**
|
|
187
|
+
* Register a component
|
|
188
|
+
*/
|
|
189
|
+
registerComponent(id, options) {
|
|
190
|
+
const { name, description, actions = [], elementIds } = options;
|
|
191
|
+
const registered = {
|
|
192
|
+
id,
|
|
193
|
+
name,
|
|
194
|
+
description,
|
|
195
|
+
actions: actions.map((a) => ({
|
|
196
|
+
id: a.id,
|
|
197
|
+
label: a.label,
|
|
198
|
+
description: a.description,
|
|
199
|
+
handler: a.handler
|
|
200
|
+
})),
|
|
201
|
+
elementIds,
|
|
202
|
+
registeredAt: Date.now(),
|
|
203
|
+
mounted: true
|
|
204
|
+
};
|
|
205
|
+
this.components.set(id, registered);
|
|
206
|
+
this.emit("component:registered", { id, name });
|
|
207
|
+
if (this.config.verbose) {
|
|
208
|
+
console.log(`[ui-bridge-native] Registered component: ${id} (${name})`);
|
|
209
|
+
}
|
|
210
|
+
return registered;
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Unregister a component
|
|
214
|
+
*/
|
|
215
|
+
unregisterComponent(id) {
|
|
216
|
+
const component = this.components.get(id);
|
|
217
|
+
if (component) {
|
|
218
|
+
this.components.delete(id);
|
|
219
|
+
this.emit("component:unregistered", { id });
|
|
220
|
+
if (this.config.verbose) {
|
|
221
|
+
console.log(`[ui-bridge-native] Unregistered component: ${id}`);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
/**
|
|
226
|
+
* Get a registered component
|
|
227
|
+
*/
|
|
228
|
+
getComponent(id) {
|
|
229
|
+
return this.components.get(id);
|
|
230
|
+
}
|
|
231
|
+
/**
|
|
232
|
+
* Get all registered components
|
|
233
|
+
*/
|
|
234
|
+
getAllComponents() {
|
|
235
|
+
return Array.from(this.components.values());
|
|
236
|
+
}
|
|
237
|
+
// ============================================================================
|
|
238
|
+
// Workflow Management
|
|
239
|
+
// ============================================================================
|
|
240
|
+
/**
|
|
241
|
+
* Register a workflow
|
|
242
|
+
*/
|
|
243
|
+
registerWorkflow(workflow) {
|
|
244
|
+
this.workflows.set(workflow.id, workflow);
|
|
245
|
+
if (this.config.verbose) {
|
|
246
|
+
console.log(`[ui-bridge-native] Registered workflow: ${workflow.id}`);
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
/**
|
|
250
|
+
* Unregister a workflow
|
|
251
|
+
*/
|
|
252
|
+
unregisterWorkflow(id) {
|
|
253
|
+
this.workflows.delete(id);
|
|
254
|
+
}
|
|
255
|
+
/**
|
|
256
|
+
* Get a workflow
|
|
257
|
+
*/
|
|
258
|
+
getWorkflow(id) {
|
|
259
|
+
return this.workflows.get(id);
|
|
260
|
+
}
|
|
261
|
+
/**
|
|
262
|
+
* Get all workflows
|
|
263
|
+
*/
|
|
264
|
+
getAllWorkflows() {
|
|
265
|
+
return Array.from(this.workflows.values());
|
|
266
|
+
}
|
|
267
|
+
// ============================================================================
|
|
268
|
+
// Event System
|
|
269
|
+
// ============================================================================
|
|
270
|
+
/**
|
|
271
|
+
* Subscribe to events
|
|
272
|
+
*/
|
|
273
|
+
on(type, listener) {
|
|
274
|
+
if (!this.eventListeners.has(type)) {
|
|
275
|
+
this.eventListeners.set(type, /* @__PURE__ */ new Set());
|
|
276
|
+
}
|
|
277
|
+
this.eventListeners.get(type).add(listener);
|
|
278
|
+
return () => this.off(type, listener);
|
|
279
|
+
}
|
|
280
|
+
/**
|
|
281
|
+
* Unsubscribe from events
|
|
282
|
+
*/
|
|
283
|
+
off(type, listener) {
|
|
284
|
+
this.eventListeners.get(type)?.delete(listener);
|
|
285
|
+
}
|
|
286
|
+
/**
|
|
287
|
+
* Emit an event
|
|
288
|
+
*/
|
|
289
|
+
emit(type, data) {
|
|
290
|
+
const event = {
|
|
291
|
+
type,
|
|
292
|
+
timestamp: Date.now(),
|
|
293
|
+
data
|
|
294
|
+
};
|
|
295
|
+
const listeners = this.eventListeners.get(type);
|
|
296
|
+
if (listeners) {
|
|
297
|
+
for (const listener of listeners) {
|
|
298
|
+
try {
|
|
299
|
+
listener(event);
|
|
300
|
+
} catch (error) {
|
|
301
|
+
console.error(`[ui-bridge-native] Event listener error:`, error);
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
if (this.config.onEvent) {
|
|
306
|
+
try {
|
|
307
|
+
this.config.onEvent(event);
|
|
308
|
+
} catch (error) {
|
|
309
|
+
console.error(`[ui-bridge-native] Global event handler error:`, error);
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
// ============================================================================
|
|
314
|
+
// Snapshots
|
|
315
|
+
// ============================================================================
|
|
316
|
+
/**
|
|
317
|
+
* Create a snapshot of the current state
|
|
318
|
+
*/
|
|
319
|
+
createSnapshot() {
|
|
320
|
+
return {
|
|
321
|
+
timestamp: Date.now(),
|
|
322
|
+
elements: this.getAllElements().map((e) => ({
|
|
323
|
+
id: e.id,
|
|
324
|
+
type: e.type,
|
|
325
|
+
label: e.label,
|
|
326
|
+
identifier: e.getIdentifier(),
|
|
327
|
+
state: e.getState(),
|
|
328
|
+
actions: e.actions,
|
|
329
|
+
customActions: e.customActions ? Object.keys(e.customActions) : void 0
|
|
330
|
+
})),
|
|
331
|
+
components: this.getAllComponents().map((c) => ({
|
|
332
|
+
id: c.id,
|
|
333
|
+
name: c.name,
|
|
334
|
+
description: c.description,
|
|
335
|
+
actions: c.actions.map((a) => a.id),
|
|
336
|
+
elementIds: c.elementIds
|
|
337
|
+
})),
|
|
338
|
+
workflows: this.getAllWorkflows().map((w) => ({
|
|
339
|
+
id: w.id,
|
|
340
|
+
name: w.name,
|
|
341
|
+
description: w.description,
|
|
342
|
+
stepCount: w.steps.length
|
|
343
|
+
}))
|
|
344
|
+
};
|
|
345
|
+
}
|
|
346
|
+
/**
|
|
347
|
+
* Get registry statistics
|
|
348
|
+
*/
|
|
349
|
+
getStats() {
|
|
350
|
+
return {
|
|
351
|
+
elements: this.elements.size,
|
|
352
|
+
components: this.components.size,
|
|
353
|
+
workflows: this.workflows.size
|
|
354
|
+
};
|
|
355
|
+
}
|
|
356
|
+
/**
|
|
357
|
+
* Clear all registrations
|
|
358
|
+
*/
|
|
359
|
+
clear() {
|
|
360
|
+
this.elements.clear();
|
|
361
|
+
this.components.clear();
|
|
362
|
+
this.workflows.clear();
|
|
363
|
+
if (this.config.verbose) {
|
|
364
|
+
console.log(`[ui-bridge-native] Registry cleared`);
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
};
|
|
368
|
+
var globalRegistry = null;
|
|
369
|
+
function setGlobalRegistry(registry) {
|
|
370
|
+
globalRegistry = registry;
|
|
371
|
+
}
|
|
372
|
+
function getGlobalRegistry() {
|
|
373
|
+
return globalRegistry;
|
|
374
|
+
}
|
|
375
|
+
function resetGlobalRegistry() {
|
|
376
|
+
globalRegistry?.clear();
|
|
377
|
+
globalRegistry = null;
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
// src/native/core/element-identifier.ts
|
|
381
|
+
function createNativeElementIdentifier(id, options = {}) {
|
|
382
|
+
return {
|
|
383
|
+
uiId: id,
|
|
384
|
+
testId: options.testId || id,
|
|
385
|
+
accessibilityLabel: options.accessibilityLabel,
|
|
386
|
+
accessibilityHint: options.accessibilityHint,
|
|
387
|
+
treePath: options.treePath || id
|
|
388
|
+
};
|
|
389
|
+
}
|
|
390
|
+
function findElementByIdentifier(identifier) {
|
|
391
|
+
const registry = getGlobalRegistry();
|
|
392
|
+
if (!registry) return null;
|
|
393
|
+
if (typeof identifier === "string") {
|
|
394
|
+
const byId = registry.getElement(identifier);
|
|
395
|
+
if (byId) return byId;
|
|
396
|
+
const byTestId = registry.findByTestId(identifier);
|
|
397
|
+
if (byTestId) return byTestId;
|
|
398
|
+
return findByPattern(registry, identifier);
|
|
399
|
+
}
|
|
400
|
+
if (identifier.uiId) {
|
|
401
|
+
const byId = registry.getElement(identifier.uiId);
|
|
402
|
+
if (byId) return byId;
|
|
403
|
+
}
|
|
404
|
+
if (identifier.testId) {
|
|
405
|
+
const byTestId = registry.findByTestId(identifier.testId);
|
|
406
|
+
if (byTestId) return byTestId;
|
|
407
|
+
}
|
|
408
|
+
return null;
|
|
409
|
+
}
|
|
410
|
+
function findByPattern(registry, pattern) {
|
|
411
|
+
if (!registry) return null;
|
|
412
|
+
const regexPattern = pattern.replace(/[.+^${}()|[\]\\]/g, "\\$&").replace(/\*/g, ".*").replace(/\?/g, ".");
|
|
413
|
+
const regex = new RegExp(`^${regexPattern}$`, "i");
|
|
414
|
+
for (const element of registry.getAllElements()) {
|
|
415
|
+
const identifier = element.getIdentifier();
|
|
416
|
+
if (identifier.testId && regex.test(identifier.testId)) {
|
|
417
|
+
return element;
|
|
418
|
+
}
|
|
419
|
+
if (identifier.uiId && regex.test(identifier.uiId)) {
|
|
420
|
+
return element;
|
|
421
|
+
}
|
|
422
|
+
if (identifier.treePath && regex.test(identifier.treePath)) {
|
|
423
|
+
return element;
|
|
424
|
+
}
|
|
425
|
+
if (identifier.accessibilityLabel && regex.test(identifier.accessibilityLabel)) {
|
|
426
|
+
return element;
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
return null;
|
|
430
|
+
}
|
|
431
|
+
function findAllByPattern(pattern) {
|
|
432
|
+
const registry = getGlobalRegistry();
|
|
433
|
+
if (!registry) return [];
|
|
434
|
+
const regexPattern = pattern.replace(/[.+^${}()|[\]\\]/g, "\\$&").replace(/\*/g, ".*").replace(/\?/g, ".");
|
|
435
|
+
const regex = new RegExp(`^${regexPattern}$`, "i");
|
|
436
|
+
const results = [];
|
|
437
|
+
for (const element of registry.getAllElements()) {
|
|
438
|
+
const identifier = element.getIdentifier();
|
|
439
|
+
if (identifier.testId && regex.test(identifier.testId) || identifier.uiId && regex.test(identifier.uiId) || identifier.treePath && regex.test(identifier.treePath) || identifier.accessibilityLabel && regex.test(identifier.accessibilityLabel)) {
|
|
440
|
+
results.push(element);
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
return results;
|
|
444
|
+
}
|
|
445
|
+
function buildTreePath(componentPath, elementIndex) {
|
|
446
|
+
let path = componentPath.join("/");
|
|
447
|
+
if (elementIndex !== void 0) {
|
|
448
|
+
path += `[${elementIndex}]`;
|
|
449
|
+
}
|
|
450
|
+
return path;
|
|
451
|
+
}
|
|
452
|
+
function parseTreePath(treePath) {
|
|
453
|
+
const indexMatch = treePath.match(/\[(\d+)\]$/);
|
|
454
|
+
const index = indexMatch ? parseInt(indexMatch[1], 10) : void 0;
|
|
455
|
+
const pathWithoutIndex = treePath.replace(/\[\d+\]$/, "");
|
|
456
|
+
const components = pathWithoutIndex.split("/").filter(Boolean);
|
|
457
|
+
return { components, index };
|
|
458
|
+
}
|
|
459
|
+
function matchesIdentifier(identifier, criteria) {
|
|
460
|
+
if (criteria.uiId && identifier.uiId !== criteria.uiId) {
|
|
461
|
+
return false;
|
|
462
|
+
}
|
|
463
|
+
if (criteria.testId && identifier.testId !== criteria.testId) {
|
|
464
|
+
return false;
|
|
465
|
+
}
|
|
466
|
+
if (criteria.accessibilityLabel && identifier.accessibilityLabel !== criteria.accessibilityLabel) {
|
|
467
|
+
return false;
|
|
468
|
+
}
|
|
469
|
+
if (criteria.treePath && identifier.treePath !== criteria.treePath) {
|
|
470
|
+
return false;
|
|
471
|
+
}
|
|
472
|
+
return true;
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
exports.NativeUIBridgeRegistry = NativeUIBridgeRegistry;
|
|
476
|
+
exports.buildTreePath = buildTreePath;
|
|
477
|
+
exports.createNativeElementIdentifier = createNativeElementIdentifier;
|
|
478
|
+
exports.findAllByPattern = findAllByPattern;
|
|
479
|
+
exports.findElementByIdentifier = findElementByIdentifier;
|
|
480
|
+
exports.getGlobalRegistry = getGlobalRegistry;
|
|
481
|
+
exports.matchesIdentifier = matchesIdentifier;
|
|
482
|
+
exports.parseTreePath = parseTreePath;
|
|
483
|
+
exports.resetGlobalRegistry = resetGlobalRegistry;
|
|
484
|
+
exports.setGlobalRegistry = setGlobalRegistry;
|
|
485
|
+
//# sourceMappingURL=index.js.map
|
|
486
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/native/core/registry.ts","../../../src/native/core/element-identifier.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Native Element and Component Registry\n *\n * Central registry for all UI elements and components registered with UI Bridge Native.\n * Adapted from ui-bridge for React Native environments.\n */\n\nimport type {\n RegisteredNativeElement,\n RegisteredNativeComponent,\n NativeElementState,\n NativeElementType,\n NativeStandardAction,\n NativeCustomAction,\n NativeBridgeSnapshot,\n NativeElementIdentifier,\n NativeElementRef,\n Workflow,\n BridgeEvent,\n BridgeEventType,\n BridgeEventListener,\n} from './types';\n\n/**\n * Options for registering an element\n */\nexport interface RegisterElementOptions {\n type?: NativeElementType;\n label?: string;\n actions?: NativeStandardAction[];\n customActions?: Record<string, NativeCustomAction>;\n props?: Record<string, unknown>;\n treePath?: string;\n testId?: string;\n accessibilityLabel?: string;\n}\n\n/**\n * Options for registering a component\n */\nexport interface RegisterComponentOptions {\n name: string;\n description?: string;\n actions?: Array<{\n id: string;\n label?: string;\n description?: string;\n handler: (params?: unknown) => unknown | Promise<unknown>;\n }>;\n elementIds?: string[];\n}\n\n/**\n * Registry configuration\n */\nexport interface NativeRegistryConfig {\n verbose?: boolean;\n onEvent?: BridgeEventListener;\n}\n\n/**\n * Infer available actions based on element type\n */\nfunction inferActions(type: NativeElementType): NativeStandardAction[] {\n const baseActions: NativeStandardAction[] = ['focus', 'blur'];\n\n switch (type) {\n case 'button':\n case 'touchable':\n case 'pressable':\n return [...baseActions, 'press', 'longPress', 'doubleTap'];\n case 'input':\n return [...baseActions, 'press', 'type', 'clear'];\n case 'text':\n return [...baseActions, 'press', 'longPress'];\n case 'view':\n return [...baseActions, 'press'];\n case 'scroll':\n return [...baseActions, 'scroll', 'swipe'];\n case 'list':\n return [...baseActions, 'scroll', 'swipe'];\n case 'listItem':\n return [...baseActions, 'press', 'longPress', 'swipe'];\n case 'switch':\n case 'checkbox':\n return [...baseActions, 'press', 'toggle'];\n case 'radio':\n return [...baseActions, 'press'];\n case 'image':\n return [...baseActions, 'press', 'longPress'];\n case 'modal':\n return ['focus', 'blur'];\n case 'custom':\n default:\n return [...baseActions, 'press'];\n }\n}\n\n/**\n * Native UI Bridge Registry\n *\n * Manages registration and lookup of native UI elements and components.\n */\nexport class NativeUIBridgeRegistry {\n private elements = new Map<string, RegisteredNativeElement>();\n private components = new Map<string, RegisteredNativeComponent>();\n private workflows = new Map<string, Workflow>();\n private eventListeners = new Map<BridgeEventType, Set<BridgeEventListener>>();\n private config: NativeRegistryConfig;\n\n constructor(config: NativeRegistryConfig = {}) {\n this.config = config;\n }\n\n // ============================================================================\n // Element Management\n // ============================================================================\n\n /**\n * Register a native element\n */\n registerElement(\n id: string,\n ref: React.RefObject<NativeElementRef>,\n options: RegisterElementOptions = {}\n ): RegisteredNativeElement {\n const {\n type = 'custom',\n label,\n actions = inferActions(type),\n customActions,\n props,\n treePath = id,\n testId,\n accessibilityLabel,\n } = options;\n\n // Create state getter\n const getState = (): NativeElementState => {\n const element = ref.current;\n if (!element) {\n return {\n mounted: false,\n visible: false,\n enabled: false,\n focused: false,\n layout: null,\n };\n }\n\n // State is populated by the element during onLayout\n // Here we return the stored state from the element's metadata\n const stored = this.elements.get(id);\n if (stored && stored.getState !== getState) {\n return stored.getState();\n }\n\n return {\n mounted: true,\n visible: true,\n enabled: true,\n focused: false,\n layout: null,\n };\n };\n\n // Create identifier getter\n const getIdentifier = (): NativeElementIdentifier => ({\n uiId: id,\n testId: testId || id,\n accessibilityLabel,\n treePath,\n });\n\n const registered: RegisteredNativeElement = {\n id,\n ref,\n type,\n label,\n actions,\n customActions,\n props,\n getState,\n getIdentifier,\n registeredAt: Date.now(),\n mounted: true,\n };\n\n this.elements.set(id, registered);\n\n this.emit('element:registered', { id, type, label });\n\n if (this.config.verbose) {\n console.log(`[ui-bridge-native] Registered element: ${id} (${type})`);\n }\n\n return registered;\n }\n\n /**\n * Unregister an element\n */\n unregisterElement(id: string): void {\n const element = this.elements.get(id);\n if (element) {\n this.elements.delete(id);\n this.emit('element:unregistered', { id });\n\n if (this.config.verbose) {\n console.log(`[ui-bridge-native] Unregistered element: ${id}`);\n }\n }\n }\n\n /**\n * Get a registered element\n */\n getElement(id: string): RegisteredNativeElement | undefined {\n return this.elements.get(id);\n }\n\n /**\n * Get all registered elements\n */\n getAllElements(): RegisteredNativeElement[] {\n return Array.from(this.elements.values());\n }\n\n /**\n * Update element state\n */\n updateElementState(id: string, state: Partial<NativeElementState>): void {\n const element = this.elements.get(id);\n if (element) {\n // Create a new getState that includes the updated state\n const currentState = element.getState();\n const newState = { ...currentState, ...state };\n\n const updated: RegisteredNativeElement = {\n ...element,\n getState: () => newState,\n };\n\n this.elements.set(id, updated);\n this.emit('element:stateChanged', { id, state: newState });\n }\n }\n\n /**\n * Update element props (for action execution)\n */\n updateElementProps(id: string, props: Record<string, unknown>): void {\n const element = this.elements.get(id);\n if (element) {\n const updated: RegisteredNativeElement = {\n ...element,\n props: { ...element.props, ...props },\n };\n this.elements.set(id, updated);\n }\n }\n\n /**\n * Find element by testID\n */\n findByTestId(testId: string): RegisteredNativeElement | undefined {\n for (const element of this.elements.values()) {\n const identifier = element.getIdentifier();\n if (identifier.testId === testId) {\n return element;\n }\n }\n return undefined;\n }\n\n /**\n * Find elements by type\n */\n findByType(type: NativeElementType): RegisteredNativeElement[] {\n return Array.from(this.elements.values()).filter((e) => e.type === type);\n }\n\n // ============================================================================\n // Component Management\n // ============================================================================\n\n /**\n * Register a component\n */\n registerComponent(id: string, options: RegisterComponentOptions): RegisteredNativeComponent {\n const { name, description, actions = [], elementIds } = options;\n\n const registered: RegisteredNativeComponent = {\n id,\n name,\n description,\n actions: actions.map((a) => ({\n id: a.id,\n label: a.label,\n description: a.description,\n handler: a.handler,\n })),\n elementIds,\n registeredAt: Date.now(),\n mounted: true,\n };\n\n this.components.set(id, registered);\n\n this.emit('component:registered', { id, name });\n\n if (this.config.verbose) {\n console.log(`[ui-bridge-native] Registered component: ${id} (${name})`);\n }\n\n return registered;\n }\n\n /**\n * Unregister a component\n */\n unregisterComponent(id: string): void {\n const component = this.components.get(id);\n if (component) {\n this.components.delete(id);\n this.emit('component:unregistered', { id });\n\n if (this.config.verbose) {\n console.log(`[ui-bridge-native] Unregistered component: ${id}`);\n }\n }\n }\n\n /**\n * Get a registered component\n */\n getComponent(id: string): RegisteredNativeComponent | undefined {\n return this.components.get(id);\n }\n\n /**\n * Get all registered components\n */\n getAllComponents(): RegisteredNativeComponent[] {\n return Array.from(this.components.values());\n }\n\n // ============================================================================\n // Workflow Management\n // ============================================================================\n\n /**\n * Register a workflow\n */\n registerWorkflow(workflow: Workflow): void {\n this.workflows.set(workflow.id, workflow);\n\n if (this.config.verbose) {\n console.log(`[ui-bridge-native] Registered workflow: ${workflow.id}`);\n }\n }\n\n /**\n * Unregister a workflow\n */\n unregisterWorkflow(id: string): void {\n this.workflows.delete(id);\n }\n\n /**\n * Get a workflow\n */\n getWorkflow(id: string): Workflow | undefined {\n return this.workflows.get(id);\n }\n\n /**\n * Get all workflows\n */\n getAllWorkflows(): Workflow[] {\n return Array.from(this.workflows.values());\n }\n\n // ============================================================================\n // Event System\n // ============================================================================\n\n /**\n * Subscribe to events\n */\n on<T = unknown>(type: BridgeEventType, listener: BridgeEventListener<T>): () => void {\n if (!this.eventListeners.has(type)) {\n this.eventListeners.set(type, new Set());\n }\n this.eventListeners.get(type)!.add(listener as BridgeEventListener);\n\n // Return unsubscribe function\n return () => this.off(type, listener);\n }\n\n /**\n * Unsubscribe from events\n */\n off<T = unknown>(type: BridgeEventType, listener: BridgeEventListener<T>): void {\n this.eventListeners.get(type)?.delete(listener as BridgeEventListener);\n }\n\n /**\n * Emit an event\n */\n private emit(type: BridgeEventType, data: unknown): void {\n const event: BridgeEvent = {\n type,\n timestamp: Date.now(),\n data,\n };\n\n // Notify listeners\n const listeners = this.eventListeners.get(type);\n if (listeners) {\n for (const listener of listeners) {\n try {\n listener(event);\n } catch (error) {\n console.error(`[ui-bridge-native] Event listener error:`, error);\n }\n }\n }\n\n // Notify global handler\n if (this.config.onEvent) {\n try {\n this.config.onEvent(event);\n } catch (error) {\n console.error(`[ui-bridge-native] Global event handler error:`, error);\n }\n }\n }\n\n // ============================================================================\n // Snapshots\n // ============================================================================\n\n /**\n * Create a snapshot of the current state\n */\n createSnapshot(): NativeBridgeSnapshot {\n return {\n timestamp: Date.now(),\n elements: this.getAllElements().map((e) => ({\n id: e.id,\n type: e.type,\n label: e.label,\n identifier: e.getIdentifier(),\n state: e.getState(),\n actions: e.actions,\n customActions: e.customActions ? Object.keys(e.customActions) : undefined,\n })),\n components: this.getAllComponents().map((c) => ({\n id: c.id,\n name: c.name,\n description: c.description,\n actions: c.actions.map((a) => a.id),\n elementIds: c.elementIds,\n })),\n workflows: this.getAllWorkflows().map((w) => ({\n id: w.id,\n name: w.name,\n description: w.description,\n stepCount: w.steps.length,\n })),\n };\n }\n\n /**\n * Get registry statistics\n */\n getStats(): { elements: number; components: number; workflows: number } {\n return {\n elements: this.elements.size,\n components: this.components.size,\n workflows: this.workflows.size,\n };\n }\n\n /**\n * Clear all registrations\n */\n clear(): void {\n this.elements.clear();\n this.components.clear();\n this.workflows.clear();\n\n if (this.config.verbose) {\n console.log(`[ui-bridge-native] Registry cleared`);\n }\n }\n}\n\n// ============================================================================\n// Global Registry\n// ============================================================================\n\nlet globalRegistry: NativeUIBridgeRegistry | null = null;\n\n/**\n * Set the global registry\n */\nexport function setGlobalRegistry(registry: NativeUIBridgeRegistry): void {\n globalRegistry = registry;\n}\n\n/**\n * Get the global registry\n */\nexport function getGlobalRegistry(): NativeUIBridgeRegistry | null {\n return globalRegistry;\n}\n\n/**\n * Reset the global registry\n */\nexport function resetGlobalRegistry(): void {\n globalRegistry?.clear();\n globalRegistry = null;\n}\n","/**\n * Native Element Identifier\n *\n * Utilities for identifying and finding native elements.\n * In React Native, we use testID, accessibilityLabel, and tree paths\n * instead of XPath/CSS selectors.\n */\n\nimport type { NativeElementIdentifier, RegisteredNativeElement } from './types';\nimport { getGlobalRegistry } from './registry';\n\n/**\n * Create an element identifier for a native element\n */\nexport function createNativeElementIdentifier(\n id: string,\n options: {\n testId?: string;\n accessibilityLabel?: string;\n accessibilityHint?: string;\n treePath?: string;\n } = {}\n): NativeElementIdentifier {\n return {\n uiId: id,\n testId: options.testId || id,\n accessibilityLabel: options.accessibilityLabel,\n accessibilityHint: options.accessibilityHint,\n treePath: options.treePath || id,\n };\n}\n\n/**\n * Find an element by its identifier in the global registry\n */\nexport function findElementByIdentifier(\n identifier: string | NativeElementIdentifier\n): RegisteredNativeElement | null {\n const registry = getGlobalRegistry();\n if (!registry) return null;\n\n // If string, try different lookup strategies\n if (typeof identifier === 'string') {\n // Try direct ID lookup\n const byId = registry.getElement(identifier);\n if (byId) return byId;\n\n // Try testID lookup\n const byTestId = registry.findByTestId(identifier);\n if (byTestId) return byTestId;\n\n // Try pattern matching\n return findByPattern(registry, identifier);\n }\n\n // If identifier object, try each strategy\n if (identifier.uiId) {\n const byId = registry.getElement(identifier.uiId);\n if (byId) return byId;\n }\n\n if (identifier.testId) {\n const byTestId = registry.findByTestId(identifier.testId);\n if (byTestId) return byTestId;\n }\n\n return null;\n}\n\n/**\n * Find element by pattern (supports wildcards)\n */\nfunction findByPattern(\n registry: ReturnType<typeof getGlobalRegistry>,\n pattern: string\n): RegisteredNativeElement | null {\n if (!registry) return null;\n\n // Convert pattern to regex\n const regexPattern = pattern\n .replace(/[.+^${}()|[\\]\\\\]/g, '\\\\$&') // Escape special chars\n .replace(/\\*/g, '.*') // Convert * to .*\n .replace(/\\?/g, '.'); // Convert ? to .\n\n const regex = new RegExp(`^${regexPattern}$`, 'i');\n\n for (const element of registry.getAllElements()) {\n const identifier = element.getIdentifier();\n\n // Match against testId\n if (identifier.testId && regex.test(identifier.testId)) {\n return element;\n }\n\n // Match against uiId\n if (identifier.uiId && regex.test(identifier.uiId)) {\n return element;\n }\n\n // Match against treePath\n if (identifier.treePath && regex.test(identifier.treePath)) {\n return element;\n }\n\n // Match against accessibilityLabel\n if (identifier.accessibilityLabel && regex.test(identifier.accessibilityLabel)) {\n return element;\n }\n }\n\n return null;\n}\n\n/**\n * Find all elements matching a pattern\n */\nexport function findAllByPattern(pattern: string): RegisteredNativeElement[] {\n const registry = getGlobalRegistry();\n if (!registry) return [];\n\n // Convert pattern to regex\n const regexPattern = pattern\n .replace(/[.+^${}()|[\\]\\\\]/g, '\\\\$&')\n .replace(/\\*/g, '.*')\n .replace(/\\?/g, '.');\n\n const regex = new RegExp(`^${regexPattern}$`, 'i');\n const results: RegisteredNativeElement[] = [];\n\n for (const element of registry.getAllElements()) {\n const identifier = element.getIdentifier();\n\n if (\n (identifier.testId && regex.test(identifier.testId)) ||\n (identifier.uiId && regex.test(identifier.uiId)) ||\n (identifier.treePath && regex.test(identifier.treePath)) ||\n (identifier.accessibilityLabel && regex.test(identifier.accessibilityLabel))\n ) {\n results.push(element);\n }\n }\n\n return results;\n}\n\n/**\n * Build a tree path for an element based on its position in the component tree\n */\nexport function buildTreePath(componentPath: string[], elementIndex?: number): string {\n let path = componentPath.join('/');\n if (elementIndex !== undefined) {\n path += `[${elementIndex}]`;\n }\n return path;\n}\n\n/**\n * Parse a tree path into its components\n */\nexport function parseTreePath(treePath: string): { components: string[]; index?: number } {\n const indexMatch = treePath.match(/\\[(\\d+)\\]$/);\n const index = indexMatch ? parseInt(indexMatch[1], 10) : undefined;\n const pathWithoutIndex = treePath.replace(/\\[\\d+\\]$/, '');\n const components = pathWithoutIndex.split('/').filter(Boolean);\n\n return { components, index };\n}\n\n/**\n * Check if an identifier matches criteria\n */\nexport function matchesIdentifier(\n identifier: NativeElementIdentifier,\n criteria: Partial<NativeElementIdentifier>\n): boolean {\n if (criteria.uiId && identifier.uiId !== criteria.uiId) {\n return false;\n }\n if (criteria.testId && identifier.testId !== criteria.testId) {\n return false;\n }\n if (criteria.accessibilityLabel && identifier.accessibilityLabel !== criteria.accessibilityLabel) {\n return false;\n }\n if (criteria.treePath && identifier.treePath !== criteria.treePath) {\n return false;\n }\n return true;\n}\n"]}
|