@qontinui/ui-bridge-native 0.1.6 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/control/{action-executor.d.ts → index.d.mts} +14 -6
- package/dist/control/index.d.ts +95 -5
- package/dist/control/index.js +74 -11
- package/dist/control/index.js.map +1 -1
- package/dist/control/index.mjs +74 -11
- package/dist/control/index.mjs.map +1 -1
- package/dist/core/index.d.mts +46 -0
- package/dist/core/index.d.ts +43 -6
- package/dist/core/index.js +69 -1
- package/dist/core/index.js.map +1 -1
- package/dist/core/index.mjs +69 -1
- package/dist/core/index.mjs.map +1 -1
- package/dist/debug/{inspector.d.ts → index.d.mts} +6 -3
- package/dist/debug/index.d.ts +44 -4
- package/dist/debug/index.js.map +1 -1
- package/dist/debug/index.mjs.map +1 -1
- package/dist/design/{design-inspector-native.d.ts → index.d.mts} +11 -7
- package/dist/design/index.d.ts +60 -5
- package/dist/{design/design-types.d.ts → design-types-BHr6Q1FX.d.mts} +11 -10
- package/dist/design-types-BHr6Q1FX.d.ts +205 -0
- package/dist/http-server-DCdR8WlL.d.mts +622 -0
- package/dist/http-server-Dj3grQW4.d.ts +622 -0
- package/dist/index.d.mts +89 -0
- package/dist/index.d.ts +86 -28
- package/dist/index.js +391 -12
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +386 -13
- package/dist/index.mjs.map +1 -1
- package/dist/react/{useAutoRegister.d.ts → index.d.mts} +15 -7
- package/dist/react/index.d.ts +69 -8
- package/dist/react/index.js +388 -12
- package/dist/react/index.js.map +1 -1
- package/dist/react/index.mjs +386 -13
- package/dist/react/index.mjs.map +1 -1
- package/dist/registry-Cahd8Gn2.d.mts +230 -0
- package/dist/{core/registry.d.ts → registry-z-3WJsxp.d.ts} +28 -10
- package/dist/server/index.d.mts +119 -0
- package/dist/server/index.d.ts +117 -13
- package/dist/server/index.js.map +1 -1
- package/dist/server/index.mjs.map +1 -1
- package/dist/types-DAfCeWXc.d.mts +197 -0
- package/dist/{core/types.d.ts → types-Oz13YLZq.d.mts} +124 -30
- package/dist/types-Oz13YLZq.d.ts +477 -0
- package/dist/{control/types.d.ts → types-ajakyp-l.d.ts} +36 -15
- package/dist/useUIBridgeToast-D32KXyL1.d.ts +720 -0
- package/dist/useUIBridgeToast-GmT1TzUe.d.mts +720 -0
- package/package.json +1 -1
- package/dist/control/action-executor.d.ts.map +0 -1
- package/dist/control/index.d.ts.map +0 -1
- package/dist/control/types.d.ts.map +0 -1
- package/dist/core/element-identifier.d.ts +0 -41
- package/dist/core/element-identifier.d.ts.map +0 -1
- package/dist/core/index.d.ts.map +0 -1
- package/dist/core/registry.d.ts.map +0 -1
- package/dist/core/types.d.ts.map +0 -1
- package/dist/debug/index.d.ts.map +0 -1
- package/dist/debug/inspector.d.ts.map +0 -1
- package/dist/design/design-inspector-native.d.ts.map +0 -1
- package/dist/design/design-types.d.ts.map +0 -1
- package/dist/design/index.d.ts.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/react/UIBridgeNativeProvider.d.ts +0 -147
- package/dist/react/UIBridgeNativeProvider.d.ts.map +0 -1
- package/dist/react/index.d.ts.map +0 -1
- package/dist/react/useAutoRegister.d.ts.map +0 -1
- package/dist/react/useUIBridge.d.ts +0 -103
- package/dist/react/useUIBridge.d.ts.map +0 -1
- package/dist/react/useUIComponent.d.ts +0 -112
- package/dist/react/useUIComponent.d.ts.map +0 -1
- package/dist/react/useUIElement.d.ts +0 -162
- package/dist/react/useUIElement.d.ts.map +0 -1
- package/dist/server/design-handlers.d.ts +0 -47
- package/dist/server/design-handlers.d.ts.map +0 -1
- package/dist/server/handlers.d.ts +0 -20
- package/dist/server/handlers.d.ts.map +0 -1
- package/dist/server/http-server.d.ts +0 -247
- package/dist/server/http-server.d.ts.map +0 -1
- package/dist/server/index.d.ts.map +0 -1
- package/dist/server/types.d.ts +0 -200
- package/dist/server/types.d.ts.map +0 -1
- package/dist/server/ws-connection.d.ts +0 -48
- package/dist/server/ws-connection.d.ts.map +0 -1
- package/dist/server/ws-event-bridge.d.ts +0 -113
- package/dist/server/ws-event-bridge.d.ts.map +0 -1
- package/dist/server/ws-protocol.d.ts +0 -48
- package/dist/server/ws-protocol.d.ts.map +0 -1
- package/dist/server/ws-types.d.ts +0 -65
- package/dist/server/ws-types.d.ts.map +0 -1
- package/dist/transport/CloudRelayClient.d.ts +0 -51
- package/dist/transport/CloudRelayClient.d.ts.map +0 -1
- package/dist/transport/DeviceAnnouncer.d.ts +0 -75
- package/dist/transport/DeviceAnnouncer.d.ts.map +0 -1
- package/dist/transport/index.d.ts +0 -3
- package/dist/transport/index.d.ts.map +0 -1
|
@@ -0,0 +1,720 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import React$1 from 'react';
|
|
3
|
+
import { p as NativeModalInfo, s as NativeSnapshotModalContext, f as NativeCapturedToast, t as NativeSnapshotToastContext, u as NativeSnapshotUndoContext, x as NativeUIBridgeFeatures, w as NativeUIBridgeConfig, y as RegisteredNativeElement, R as RegisteredNativeComponent, e as NativeBridgeSnapshot, b as BridgeEventType, a as BridgeEventListener, l as NativeElementType, v as NativeStandardAction, h as NativeCustomAction, k as NativeElementState, j as NativeElementRef, i as NativeElementIdentifier, z as Workflow, N as NativeActionRequest, d as NativeActionResponse, m as NativeFindRequest, n as NativeFindResponse } from './types-Oz13YLZq.js';
|
|
4
|
+
import { a as NativeUIBridgeRegistry } from './registry-z-3WJsxp.js';
|
|
5
|
+
import { N as NativeActionExecutor } from './types-ajakyp-l.js';
|
|
6
|
+
import { i as NativeUIBridgeServer, m as ServerAdapter, l as RouteProvider } from './http-server-Dj3grQW4.js';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Cloud Relay Client — WebSocket tunnel from mobile device to backend
|
|
10
|
+
*
|
|
11
|
+
* Maintains a persistent WebSocket connection to the qontinui.io backend.
|
|
12
|
+
* Receives tunneled HTTP requests from runners, calls the local NativeUIBridgeServer,
|
|
13
|
+
* and sends responses back through the tunnel.
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
interface CloudRelayConfig {
|
|
17
|
+
/** WebSocket URL for the device bridge endpoint */
|
|
18
|
+
relayUrl: string;
|
|
19
|
+
/** Stable device identifier */
|
|
20
|
+
deviceId: string;
|
|
21
|
+
/** Authentication token */
|
|
22
|
+
authToken: string;
|
|
23
|
+
/** Reference to the local UI Bridge server for processing requests */
|
|
24
|
+
uiBridgeServer: NativeUIBridgeServer;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Manages a WebSocket tunnel from the mobile device to the qontinui.io backend.
|
|
28
|
+
*
|
|
29
|
+
* When a runner sends an HTTP request to a cloud device it is serialised as a
|
|
30
|
+
* `TunnelRequest` JSON frame by the backend and forwarded here. This client
|
|
31
|
+
* deserializes it, calls `NativeUIBridgeServer.handleRequest()` directly
|
|
32
|
+
* (avoiding loopback TCP overhead), and sends the `TunnelResponse` back.
|
|
33
|
+
*/
|
|
34
|
+
declare class CloudRelayClient {
|
|
35
|
+
private ws;
|
|
36
|
+
private config;
|
|
37
|
+
private reconnectDelay;
|
|
38
|
+
private maxReconnectDelay;
|
|
39
|
+
private stopped;
|
|
40
|
+
private _isConnected;
|
|
41
|
+
private reconnectTimer;
|
|
42
|
+
constructor(config: CloudRelayConfig);
|
|
43
|
+
/** Whether the relay WebSocket is currently connected */
|
|
44
|
+
get isConnected(): boolean;
|
|
45
|
+
/** Connect to the relay and start processing tunneled requests. */
|
|
46
|
+
start(): void;
|
|
47
|
+
/** Disconnect and stop reconnecting. */
|
|
48
|
+
stop(): void;
|
|
49
|
+
private connect;
|
|
50
|
+
private onMessage;
|
|
51
|
+
/**
|
|
52
|
+
* Process a tunneled HTTP request by calling the local NativeUIBridgeServer
|
|
53
|
+
* directly (no loopback TCP involved).
|
|
54
|
+
*/
|
|
55
|
+
private handleTunneledRequest;
|
|
56
|
+
private scheduleReconnect;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
interface ModalPushInput {
|
|
60
|
+
id: string;
|
|
61
|
+
title?: string;
|
|
62
|
+
type?: NativeModalInfo['type'];
|
|
63
|
+
blocking?: boolean;
|
|
64
|
+
dismissible?: boolean;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Declarative modal store. Components/hooks call pushModal/dismissModal directly
|
|
68
|
+
* — there is no DOM/tree scanner. The detector is the single source of truth for
|
|
69
|
+
* the snapshot's modalStack context.
|
|
70
|
+
*/
|
|
71
|
+
declare class ModalDetector {
|
|
72
|
+
/** Map preserves O(1) idempotent replace by id; ordering comes from detectedAt. */
|
|
73
|
+
private modals;
|
|
74
|
+
pushModal(modal: ModalPushInput): void;
|
|
75
|
+
dismissModal(id: string): void;
|
|
76
|
+
getSnapshotModalContext(): NativeSnapshotModalContext;
|
|
77
|
+
getActive(): NativeModalInfo[];
|
|
78
|
+
clear(): void;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
interface ToastRecordInput {
|
|
82
|
+
id: string;
|
|
83
|
+
message: string;
|
|
84
|
+
level?: NativeCapturedToast['level'];
|
|
85
|
+
appearedAt?: number;
|
|
86
|
+
}
|
|
87
|
+
interface ToastCaptureConfig {
|
|
88
|
+
maxRecent?: number;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Declarative toast/snackbar tracker. Components call recordToast/dismissToast
|
|
92
|
+
* directly — there is no DOM/tree scanner. The active map plus a fixed-size
|
|
93
|
+
* recent ring buffer feed the snapshot's toasts context.
|
|
94
|
+
*/
|
|
95
|
+
declare class ToastCapture {
|
|
96
|
+
private active;
|
|
97
|
+
private recent;
|
|
98
|
+
private totalCaptured;
|
|
99
|
+
private maxRecent;
|
|
100
|
+
constructor(config?: ToastCaptureConfig);
|
|
101
|
+
recordToast(toast: ToastRecordInput): void;
|
|
102
|
+
dismissToast(id: string): void;
|
|
103
|
+
getSnapshotToastContext(): NativeSnapshotToastContext;
|
|
104
|
+
clear(): void;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* A single bridge action recorded for undo correlation. Action-correlation
|
|
109
|
+
* only — RN has no DOM/execCommand probe, so we rely on developer
|
|
110
|
+
* declaration plus this rolling history of recent actions.
|
|
111
|
+
*/
|
|
112
|
+
interface ActionRecord {
|
|
113
|
+
id: string;
|
|
114
|
+
type: string;
|
|
115
|
+
targetId?: string;
|
|
116
|
+
description?: string;
|
|
117
|
+
timestamp: number;
|
|
118
|
+
/** Default true — set false for actions that aren't reversible (e.g. navigation, network calls) */
|
|
119
|
+
reversible?: boolean;
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Developer-declared undo/redo state. When set, this is authoritative and
|
|
123
|
+
* overrides any heuristic inference from action history.
|
|
124
|
+
*/
|
|
125
|
+
interface DeclaredUndoState {
|
|
126
|
+
canUndo: boolean;
|
|
127
|
+
canRedo: boolean;
|
|
128
|
+
undoDescription?: string;
|
|
129
|
+
redoDescription?: string;
|
|
130
|
+
undoDepth?: number;
|
|
131
|
+
redoDepth?: number;
|
|
132
|
+
}
|
|
133
|
+
interface UndoTrackerConfig {
|
|
134
|
+
maxHistory?: number;
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Action-correlation undo tracker for React Native.
|
|
138
|
+
*
|
|
139
|
+
* Maintains a rolling buffer of recent actions and a developer-declared
|
|
140
|
+
* undo state slot. The declared state is authoritative when set; otherwise
|
|
141
|
+
* we infer `canUndo` from whether any reversible action has been recorded.
|
|
142
|
+
* `executeUndo`/`executeRedo` are placeholders pending an IPC path through
|
|
143
|
+
* ui-bridge-native to the runner's `/control/undo`.
|
|
144
|
+
*/
|
|
145
|
+
declare class UndoTracker {
|
|
146
|
+
private readonly maxHistory;
|
|
147
|
+
private actions;
|
|
148
|
+
private declaredState;
|
|
149
|
+
constructor(config?: UndoTrackerConfig);
|
|
150
|
+
recordAction(record: ActionRecord): void;
|
|
151
|
+
setDeclaredState(state: DeclaredUndoState): void;
|
|
152
|
+
getActionHistory(): ActionRecord[];
|
|
153
|
+
getSnapshotUndoContext(): NativeSnapshotUndoContext;
|
|
154
|
+
executeUndo(): {
|
|
155
|
+
ok: boolean;
|
|
156
|
+
reason?: string;
|
|
157
|
+
};
|
|
158
|
+
executeRedo(): {
|
|
159
|
+
ok: boolean;
|
|
160
|
+
reason?: string;
|
|
161
|
+
};
|
|
162
|
+
clear(): void;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* UI Bridge Native context value
|
|
167
|
+
*/
|
|
168
|
+
interface UIBridgeNativeContextValue {
|
|
169
|
+
/** Feature flags */
|
|
170
|
+
features: NativeUIBridgeFeatures;
|
|
171
|
+
/** Configuration */
|
|
172
|
+
config: NativeUIBridgeConfig;
|
|
173
|
+
/** Element registry */
|
|
174
|
+
registry: NativeUIBridgeRegistry;
|
|
175
|
+
/** Action executor */
|
|
176
|
+
executor: NativeActionExecutor;
|
|
177
|
+
/** Modal stack tracker (declarative pushModal/dismissModal) */
|
|
178
|
+
modalDetector: ModalDetector;
|
|
179
|
+
/** Toast/snackbar tracker (declarative recordToast/dismissToast) */
|
|
180
|
+
toastCapture: ToastCapture;
|
|
181
|
+
/** Undo/redo action-correlation tracker */
|
|
182
|
+
undoTracker: UndoTracker;
|
|
183
|
+
/** Get all registered elements */
|
|
184
|
+
getElements: () => RegisteredNativeElement[];
|
|
185
|
+
/** Get all registered components */
|
|
186
|
+
getComponents: () => RegisteredNativeComponent[];
|
|
187
|
+
/** Create a snapshot */
|
|
188
|
+
createSnapshot: () => NativeBridgeSnapshot;
|
|
189
|
+
/** Subscribe to events */
|
|
190
|
+
on: <T = unknown>(type: BridgeEventType, listener: BridgeEventListener<T>) => () => void;
|
|
191
|
+
/** Unsubscribe from events */
|
|
192
|
+
off: <T = unknown>(type: BridgeEventType, listener: BridgeEventListener<T>) => void;
|
|
193
|
+
/** Whether the provider is initialized */
|
|
194
|
+
initialized: boolean;
|
|
195
|
+
/** Server running status */
|
|
196
|
+
serverRunning: boolean;
|
|
197
|
+
/** Start the HTTP server */
|
|
198
|
+
startServer: () => Promise<void>;
|
|
199
|
+
/** Stop the HTTP server */
|
|
200
|
+
stopServer: () => void;
|
|
201
|
+
/** Get the current navigation route (if a RouteProvider is configured) */
|
|
202
|
+
getCurrentRoute: () => string | null;
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* UI Bridge Native provider props
|
|
206
|
+
*/
|
|
207
|
+
interface UIBridgeNativeProviderProps {
|
|
208
|
+
/** Child components */
|
|
209
|
+
children: React$1.ReactNode;
|
|
210
|
+
/** Feature flags */
|
|
211
|
+
features?: NativeUIBridgeFeatures;
|
|
212
|
+
/** Configuration */
|
|
213
|
+
config?: NativeUIBridgeConfig;
|
|
214
|
+
/** Event handler */
|
|
215
|
+
onEvent?: BridgeEventListener;
|
|
216
|
+
/**
|
|
217
|
+
* A ServerAdapter instance for the HTTP server.
|
|
218
|
+
* The app is responsible for creating this using its preferred native TCP/HTTP library.
|
|
219
|
+
* @see ServerAdapter interface in server/http-server.ts
|
|
220
|
+
*/
|
|
221
|
+
serverAdapter?: ServerAdapter;
|
|
222
|
+
/**
|
|
223
|
+
* Navigation provider for programmatic route navigation via UI Bridge.
|
|
224
|
+
* Pass Expo Router's push/back functions to enable `control/page/navigate`.
|
|
225
|
+
*/
|
|
226
|
+
navigationProvider?: {
|
|
227
|
+
navigate: (url: string) => void;
|
|
228
|
+
back?: () => void;
|
|
229
|
+
};
|
|
230
|
+
/**
|
|
231
|
+
* Screenshot provider for native screen capture via UI Bridge.
|
|
232
|
+
* Pass a function that captures the current screen as base64 PNG.
|
|
233
|
+
*/
|
|
234
|
+
screenshotProvider?: {
|
|
235
|
+
capture: () => Promise<{
|
|
236
|
+
base64: string;
|
|
237
|
+
width: number;
|
|
238
|
+
height: number;
|
|
239
|
+
}>;
|
|
240
|
+
};
|
|
241
|
+
/**
|
|
242
|
+
* Route provider for exposing the current navigation route in snapshots.
|
|
243
|
+
* Wire this to Expo Router's `usePathname()` / `useSegments()` via a module-level ref.
|
|
244
|
+
*/
|
|
245
|
+
routeProvider?: RouteProvider;
|
|
246
|
+
/**
|
|
247
|
+
* Configuration for the cloud relay tunnel (enables remote device verification
|
|
248
|
+
* when USB/LAN are not available). Omit `uiBridgeServer` — the provider wires
|
|
249
|
+
* that automatically after the server starts.
|
|
250
|
+
*/
|
|
251
|
+
cloudRelayConfig?: Omit<CloudRelayConfig, 'uiBridgeServer'>;
|
|
252
|
+
/**
|
|
253
|
+
* Enable mDNS advertisement so that runners on the same LAN can discover this
|
|
254
|
+
* device automatically (requires react-native-zeroconf).
|
|
255
|
+
*/
|
|
256
|
+
enableMdnsAnnounce?: boolean;
|
|
257
|
+
/**
|
|
258
|
+
* Stable device identifier used for mDNS TXT records and cloud relay
|
|
259
|
+
* registration. Typically sourced from expo-device or a UUID stored in
|
|
260
|
+
* AsyncStorage.
|
|
261
|
+
*/
|
|
262
|
+
deviceId?: string;
|
|
263
|
+
}
|
|
264
|
+
/**
|
|
265
|
+
* UI Bridge Native Provider
|
|
266
|
+
*
|
|
267
|
+
* Provides UI Bridge Native context to child components.
|
|
268
|
+
*
|
|
269
|
+
* @example
|
|
270
|
+
* ```tsx
|
|
271
|
+
* // app/_layout.tsx
|
|
272
|
+
* import { UIBridgeNativeProvider } from 'ui-bridge-native';
|
|
273
|
+
*
|
|
274
|
+
* export default function RootLayout() {
|
|
275
|
+
* return (
|
|
276
|
+
* <UIBridgeNativeProvider
|
|
277
|
+
* features={{ server: __DEV__, debug: __DEV__ }}
|
|
278
|
+
* config={{ serverPort: 8087 }}
|
|
279
|
+
* >
|
|
280
|
+
* <Stack>{children}</Stack>
|
|
281
|
+
* </UIBridgeNativeProvider>
|
|
282
|
+
* );
|
|
283
|
+
* }
|
|
284
|
+
* ```
|
|
285
|
+
*/
|
|
286
|
+
declare function UIBridgeNativeProvider({ children, features, config, onEvent, serverAdapter, navigationProvider, screenshotProvider, routeProvider, cloudRelayConfig, enableMdnsAnnounce, deviceId, }: UIBridgeNativeProviderProps): react_jsx_runtime.JSX.Element;
|
|
287
|
+
/**
|
|
288
|
+
* useUIBridgeNative hook
|
|
289
|
+
*
|
|
290
|
+
* Access the UI Bridge Native context. Throws if used outside provider.
|
|
291
|
+
*/
|
|
292
|
+
declare function useUIBridgeNative(): UIBridgeNativeContextValue;
|
|
293
|
+
/**
|
|
294
|
+
* useUIBridgeNativeOptional hook
|
|
295
|
+
*
|
|
296
|
+
* Access the UI Bridge Native context, returning null if outside provider.
|
|
297
|
+
*/
|
|
298
|
+
declare function useUIBridgeNativeOptional(): UIBridgeNativeContextValue | null;
|
|
299
|
+
/**
|
|
300
|
+
* useUIBridgeNativeRequired hook
|
|
301
|
+
*
|
|
302
|
+
* Alias for useUIBridgeNative (throws if outside provider).
|
|
303
|
+
*/
|
|
304
|
+
declare const useUIBridgeNativeRequired: typeof useUIBridgeNative;
|
|
305
|
+
|
|
306
|
+
/**
|
|
307
|
+
* useUIElement Hook for React Native
|
|
308
|
+
*
|
|
309
|
+
* Register a native element with UI Bridge for control and observation.
|
|
310
|
+
*/
|
|
311
|
+
|
|
312
|
+
/**
|
|
313
|
+
* useUIElement options
|
|
314
|
+
*/
|
|
315
|
+
interface UseUIElementOptions {
|
|
316
|
+
/** Unique identifier for the element */
|
|
317
|
+
id: string;
|
|
318
|
+
/** Element type (defaults to 'custom') */
|
|
319
|
+
type?: NativeElementType;
|
|
320
|
+
/** Human-readable label */
|
|
321
|
+
label?: string;
|
|
322
|
+
/** Override available actions */
|
|
323
|
+
actions?: NativeStandardAction[];
|
|
324
|
+
/** Custom actions */
|
|
325
|
+
customActions?: Record<string, NativeCustomAction>;
|
|
326
|
+
/** Whether to automatically register on mount */
|
|
327
|
+
autoRegister?: boolean;
|
|
328
|
+
/** Callback when state changes */
|
|
329
|
+
onStateChange?: (state: NativeElementState) => void;
|
|
330
|
+
/** Parent component path for tree path generation */
|
|
331
|
+
parentPath?: string;
|
|
332
|
+
/** RN style prop — will be flattened for design review */
|
|
333
|
+
style?: unknown;
|
|
334
|
+
/** State-specific style overrides for design review (pressed, focused, disabled) */
|
|
335
|
+
stateStyles?: {
|
|
336
|
+
pressed?: unknown;
|
|
337
|
+
focused?: unknown;
|
|
338
|
+
disabled?: unknown;
|
|
339
|
+
};
|
|
340
|
+
/**
|
|
341
|
+
* Handler props to auto-register with the bridge for action execution.
|
|
342
|
+
* When provided, the bridge can invoke these handlers via press/type/toggle actions
|
|
343
|
+
* without the component needing a separate useEffect + updateElementProps call.
|
|
344
|
+
*
|
|
345
|
+
* @example
|
|
346
|
+
* ```tsx
|
|
347
|
+
* const { ref, onLayout, bridgeProps } = useUIElement({
|
|
348
|
+
* id: 'my-button',
|
|
349
|
+
* type: 'pressable',
|
|
350
|
+
* handlers: { onPress: handlePress },
|
|
351
|
+
* });
|
|
352
|
+
* ```
|
|
353
|
+
*/
|
|
354
|
+
handlers?: Record<string, ((...args: any[]) => any) | undefined>;
|
|
355
|
+
}
|
|
356
|
+
/**
|
|
357
|
+
* Bridge props to spread onto the component
|
|
358
|
+
*/
|
|
359
|
+
interface UIBridgeProps {
|
|
360
|
+
/** Test ID for automation */
|
|
361
|
+
testID: string;
|
|
362
|
+
/** Accessibility label */
|
|
363
|
+
accessibilityLabel?: string;
|
|
364
|
+
}
|
|
365
|
+
/**
|
|
366
|
+
* useUIElement return value
|
|
367
|
+
*/
|
|
368
|
+
interface UseUIElementReturn {
|
|
369
|
+
/** Ref to attach to the element */
|
|
370
|
+
ref: React.RefObject<NativeElementRef>;
|
|
371
|
+
/** onLayout handler to spread onto the element - uses generic type for RN version compatibility */
|
|
372
|
+
onLayout: (event: {
|
|
373
|
+
nativeEvent: {
|
|
374
|
+
layout: {
|
|
375
|
+
x: number;
|
|
376
|
+
y: number;
|
|
377
|
+
width: number;
|
|
378
|
+
height: number;
|
|
379
|
+
};
|
|
380
|
+
};
|
|
381
|
+
}) => void;
|
|
382
|
+
/** Props to spread onto the element for identification */
|
|
383
|
+
bridgeProps: UIBridgeProps;
|
|
384
|
+
/** Whether the element is registered */
|
|
385
|
+
registered: boolean;
|
|
386
|
+
/** Get current state */
|
|
387
|
+
getState: () => NativeElementState | null;
|
|
388
|
+
/** Get element identifier */
|
|
389
|
+
getIdentifier: () => NativeElementIdentifier | null;
|
|
390
|
+
/** Trigger an action on this element */
|
|
391
|
+
trigger: (action: NativeStandardAction | string, params?: Record<string, unknown>) => Promise<void>;
|
|
392
|
+
/** Manually register the element */
|
|
393
|
+
register: () => void;
|
|
394
|
+
/** Manually unregister the element */
|
|
395
|
+
unregister: () => void;
|
|
396
|
+
/** The registered element info */
|
|
397
|
+
registeredElement: RegisteredNativeElement | null;
|
|
398
|
+
/** Update style for design review (flattens and stores in registry) */
|
|
399
|
+
updateStyle: (style: unknown, stateStyles?: {
|
|
400
|
+
pressed?: unknown;
|
|
401
|
+
focused?: unknown;
|
|
402
|
+
disabled?: unknown;
|
|
403
|
+
}) => void;
|
|
404
|
+
}
|
|
405
|
+
/**
|
|
406
|
+
* useUIElement hook for React Native
|
|
407
|
+
*
|
|
408
|
+
* Registers a native element with UI Bridge for programmatic control.
|
|
409
|
+
*
|
|
410
|
+
* @example
|
|
411
|
+
* ```tsx
|
|
412
|
+
* function SubmitButton() {
|
|
413
|
+
* const { ref, onLayout, bridgeProps, trigger } = useUIElement({
|
|
414
|
+
* id: 'submit-btn',
|
|
415
|
+
* type: 'button',
|
|
416
|
+
* label: 'Submit Form',
|
|
417
|
+
* });
|
|
418
|
+
*
|
|
419
|
+
* return (
|
|
420
|
+
* <Pressable
|
|
421
|
+
* ref={ref}
|
|
422
|
+
* onLayout={onLayout}
|
|
423
|
+
* {...bridgeProps}
|
|
424
|
+
* onPress={() => handleSubmit()}
|
|
425
|
+
* >
|
|
426
|
+
* <Text>Submit</Text>
|
|
427
|
+
* </Pressable>
|
|
428
|
+
* );
|
|
429
|
+
* }
|
|
430
|
+
* ```
|
|
431
|
+
*/
|
|
432
|
+
declare function useUIElement(options: UseUIElementOptions): UseUIElementReturn;
|
|
433
|
+
/**
|
|
434
|
+
* useUIElementWithProps hook
|
|
435
|
+
*
|
|
436
|
+
* Extended version that also captures component props for action execution.
|
|
437
|
+
* Useful when you need the bridge to be able to call onPress, onChangeText, etc.
|
|
438
|
+
*
|
|
439
|
+
* @example
|
|
440
|
+
* ```tsx
|
|
441
|
+
* function TextInputField({ onChangeText, value }) {
|
|
442
|
+
* const { ref, onLayout, bridgeProps, captureProps } = useUIElementWithProps({
|
|
443
|
+
* id: 'email-input',
|
|
444
|
+
* type: 'input',
|
|
445
|
+
* });
|
|
446
|
+
*
|
|
447
|
+
* // Capture props so bridge can call onChangeText
|
|
448
|
+
* captureProps({ onChangeText, value });
|
|
449
|
+
*
|
|
450
|
+
* return (
|
|
451
|
+
* <TextInput
|
|
452
|
+
* ref={ref}
|
|
453
|
+
* onLayout={onLayout}
|
|
454
|
+
* {...bridgeProps}
|
|
455
|
+
* value={value}
|
|
456
|
+
* onChangeText={onChangeText}
|
|
457
|
+
* />
|
|
458
|
+
* );
|
|
459
|
+
* }
|
|
460
|
+
* ```
|
|
461
|
+
*/
|
|
462
|
+
interface UseUIElementWithPropsReturn extends UseUIElementReturn {
|
|
463
|
+
/** Capture props for action execution */
|
|
464
|
+
captureProps: (props: Record<string, unknown>) => void;
|
|
465
|
+
}
|
|
466
|
+
declare function useUIElementWithProps(options: UseUIElementOptions): UseUIElementWithPropsReturn;
|
|
467
|
+
|
|
468
|
+
/**
|
|
469
|
+
* useUIComponent Hook for React Native
|
|
470
|
+
*
|
|
471
|
+
* Register a component with UI Bridge for component-level actions.
|
|
472
|
+
*/
|
|
473
|
+
|
|
474
|
+
/**
|
|
475
|
+
* Action definition for useUIComponent
|
|
476
|
+
*/
|
|
477
|
+
interface ComponentActionDef<TParams = unknown, TResult = unknown> {
|
|
478
|
+
/** Action identifier */
|
|
479
|
+
id: string;
|
|
480
|
+
/** Human-readable label */
|
|
481
|
+
label?: string;
|
|
482
|
+
/** Description */
|
|
483
|
+
description?: string;
|
|
484
|
+
/** Handler function */
|
|
485
|
+
handler: (params?: TParams) => TResult | Promise<TResult>;
|
|
486
|
+
}
|
|
487
|
+
/**
|
|
488
|
+
* useUIComponent options
|
|
489
|
+
*/
|
|
490
|
+
interface UseUIComponentOptions {
|
|
491
|
+
/** Unique identifier for the component */
|
|
492
|
+
id: string;
|
|
493
|
+
/** Human-readable name */
|
|
494
|
+
name: string;
|
|
495
|
+
/** Description */
|
|
496
|
+
description?: string;
|
|
497
|
+
/** Actions available on this component */
|
|
498
|
+
actions?: ComponentActionDef[];
|
|
499
|
+
/** Child element IDs owned by this component */
|
|
500
|
+
elementIds?: string[];
|
|
501
|
+
/** Whether to automatically register on mount */
|
|
502
|
+
autoRegister?: boolean;
|
|
503
|
+
}
|
|
504
|
+
/**
|
|
505
|
+
* useUIComponent return value
|
|
506
|
+
*/
|
|
507
|
+
interface UseUIComponentReturn {
|
|
508
|
+
/** Whether the component is registered */
|
|
509
|
+
registered: boolean;
|
|
510
|
+
/** Execute an action on this component */
|
|
511
|
+
executeAction: <TParams = unknown, TResult = unknown>(actionId: string, params?: TParams) => Promise<TResult>;
|
|
512
|
+
/** Manually register the component */
|
|
513
|
+
register: () => void;
|
|
514
|
+
/** Manually unregister the component */
|
|
515
|
+
unregister: () => void;
|
|
516
|
+
/** Update actions dynamically */
|
|
517
|
+
updateActions: (actions: ComponentActionDef[]) => void;
|
|
518
|
+
/** Add an element ID to this component */
|
|
519
|
+
addElement: (elementId: string) => void;
|
|
520
|
+
/** Remove an element ID from this component */
|
|
521
|
+
removeElement: (elementId: string) => void;
|
|
522
|
+
/** The registered component info */
|
|
523
|
+
registeredComponent: RegisteredNativeComponent | null;
|
|
524
|
+
}
|
|
525
|
+
/**
|
|
526
|
+
* useUIComponent hook for React Native
|
|
527
|
+
*
|
|
528
|
+
* Registers a component with UI Bridge for component-level control.
|
|
529
|
+
* Components can expose high-level actions that may orchestrate multiple element interactions.
|
|
530
|
+
*
|
|
531
|
+
* @example
|
|
532
|
+
* ```tsx
|
|
533
|
+
* function LoginForm() {
|
|
534
|
+
* const [email, setEmail] = useState('');
|
|
535
|
+
* const [password, setPassword] = useState('');
|
|
536
|
+
*
|
|
537
|
+
* useUIComponent({
|
|
538
|
+
* id: 'login-form',
|
|
539
|
+
* name: 'Login Form',
|
|
540
|
+
* actions: [
|
|
541
|
+
* {
|
|
542
|
+
* id: 'login',
|
|
543
|
+
* label: 'Submit Login',
|
|
544
|
+
* handler: async ({ email, password }) => {
|
|
545
|
+
* setEmail(email);
|
|
546
|
+
* setPassword(password);
|
|
547
|
+
* await submitLogin();
|
|
548
|
+
* },
|
|
549
|
+
* },
|
|
550
|
+
* {
|
|
551
|
+
* id: 'clear',
|
|
552
|
+
* label: 'Clear Form',
|
|
553
|
+
* handler: () => {
|
|
554
|
+
* setEmail('');
|
|
555
|
+
* setPassword('');
|
|
556
|
+
* },
|
|
557
|
+
* },
|
|
558
|
+
* ],
|
|
559
|
+
* });
|
|
560
|
+
*
|
|
561
|
+
* return (
|
|
562
|
+
* <View>
|
|
563
|
+
* <TextInput value={email} onChangeText={setEmail} />
|
|
564
|
+
* <TextInput value={password} onChangeText={setPassword} secureTextEntry />
|
|
565
|
+
* <Button title="Login" onPress={handleSubmit} />
|
|
566
|
+
* </View>
|
|
567
|
+
* );
|
|
568
|
+
* }
|
|
569
|
+
* ```
|
|
570
|
+
*/
|
|
571
|
+
declare function useUIComponent(options: UseUIComponentOptions): UseUIComponentReturn;
|
|
572
|
+
/**
|
|
573
|
+
* useUIComponentAction hook
|
|
574
|
+
*
|
|
575
|
+
* Create a stable action handler that can be used with useUIComponent.
|
|
576
|
+
* Useful for memoizing action handlers.
|
|
577
|
+
*/
|
|
578
|
+
declare function useUIComponentAction<TParams = unknown, TResult = unknown>(handler: (params?: TParams) => TResult | Promise<TResult>, deps: React.DependencyList): (params?: TParams) => TResult | Promise<TResult>;
|
|
579
|
+
|
|
580
|
+
/**
|
|
581
|
+
* useUIBridge Hook for React Native
|
|
582
|
+
*
|
|
583
|
+
* Provides a simplified interface for common UI Bridge operations.
|
|
584
|
+
*/
|
|
585
|
+
|
|
586
|
+
/**
|
|
587
|
+
* Component action request
|
|
588
|
+
*/
|
|
589
|
+
interface ComponentActionRequest {
|
|
590
|
+
/** Action ID */
|
|
591
|
+
action: string;
|
|
592
|
+
/** Action parameters */
|
|
593
|
+
params?: Record<string, unknown>;
|
|
594
|
+
}
|
|
595
|
+
/**
|
|
596
|
+
* Component action response
|
|
597
|
+
*/
|
|
598
|
+
interface ComponentActionResponse {
|
|
599
|
+
/** Whether the action succeeded */
|
|
600
|
+
success: boolean;
|
|
601
|
+
/** Result of the action */
|
|
602
|
+
result?: unknown;
|
|
603
|
+
/** Error message if failed */
|
|
604
|
+
error?: string;
|
|
605
|
+
/** Duration in milliseconds */
|
|
606
|
+
durationMs: number;
|
|
607
|
+
/** Timestamp */
|
|
608
|
+
timestamp: number;
|
|
609
|
+
}
|
|
610
|
+
/**
|
|
611
|
+
* useUIBridge return type
|
|
612
|
+
*/
|
|
613
|
+
interface UseUIBridgeReturn {
|
|
614
|
+
/** Whether UI Bridge is available */
|
|
615
|
+
available: boolean;
|
|
616
|
+
/** Whether UI Bridge is initialized */
|
|
617
|
+
initialized: boolean;
|
|
618
|
+
/** All registered elements */
|
|
619
|
+
elements: RegisteredNativeElement[];
|
|
620
|
+
/** All registered components */
|
|
621
|
+
components: RegisteredNativeComponent[];
|
|
622
|
+
/** All registered workflows */
|
|
623
|
+
workflows: Workflow[];
|
|
624
|
+
/** Create a snapshot of the current state */
|
|
625
|
+
createSnapshot: () => NativeBridgeSnapshot;
|
|
626
|
+
/** Execute an action on an element */
|
|
627
|
+
executeAction: (elementId: string, request: NativeActionRequest) => Promise<NativeActionResponse>;
|
|
628
|
+
/** Execute a component action */
|
|
629
|
+
executeComponentAction: (componentId: string, request: ComponentActionRequest) => Promise<ComponentActionResponse>;
|
|
630
|
+
/** Find elements */
|
|
631
|
+
find: (request?: NativeFindRequest) => Promise<NativeFindResponse>;
|
|
632
|
+
/** Get an element by ID */
|
|
633
|
+
getElement: (id: string) => RegisteredNativeElement | undefined;
|
|
634
|
+
/** Get a component by ID */
|
|
635
|
+
getComponent: (id: string) => RegisteredNativeComponent | undefined;
|
|
636
|
+
/** Get element state by ID */
|
|
637
|
+
getElementState: (id: string) => ReturnType<RegisteredNativeElement['getState']> | null;
|
|
638
|
+
/** Register a workflow */
|
|
639
|
+
registerWorkflow: (workflow: Workflow) => void;
|
|
640
|
+
/** Unregister a workflow */
|
|
641
|
+
unregisterWorkflow: (id: string) => void;
|
|
642
|
+
}
|
|
643
|
+
/**
|
|
644
|
+
* useUIBridge hook
|
|
645
|
+
*
|
|
646
|
+
* Provides a simplified interface for accessing UI Bridge functionality.
|
|
647
|
+
*
|
|
648
|
+
* @example
|
|
649
|
+
* ```tsx
|
|
650
|
+
* function MyComponent() {
|
|
651
|
+
* const { available, elements, executeAction, find } = useUIBridge();
|
|
652
|
+
*
|
|
653
|
+
* if (!available) {
|
|
654
|
+
* return <Text>UI Bridge not available</Text>;
|
|
655
|
+
* }
|
|
656
|
+
*
|
|
657
|
+
* const handlePress = async () => {
|
|
658
|
+
* // Find all buttons
|
|
659
|
+
* const result = await find({ types: ['button'] });
|
|
660
|
+
* console.log('Found buttons:', result.elements);
|
|
661
|
+
*
|
|
662
|
+
* // Execute action on specific element
|
|
663
|
+
* await executeAction('submit-btn', { action: 'press' });
|
|
664
|
+
* };
|
|
665
|
+
*
|
|
666
|
+
* return (
|
|
667
|
+
* <View>
|
|
668
|
+
* <Text>Elements: {elements.length}</Text>
|
|
669
|
+
* <Button title="Press" onPress={handlePress} />
|
|
670
|
+
* </View>
|
|
671
|
+
* );
|
|
672
|
+
* }
|
|
673
|
+
* ```
|
|
674
|
+
*/
|
|
675
|
+
declare function useUIBridge(): UseUIBridgeReturn;
|
|
676
|
+
/**
|
|
677
|
+
* useUIBridgeRequired hook
|
|
678
|
+
*
|
|
679
|
+
* Same as useUIBridge but throws if not available.
|
|
680
|
+
*/
|
|
681
|
+
declare function useUIBridgeRequired(): UseUIBridgeReturn;
|
|
682
|
+
|
|
683
|
+
interface UseUIBridgeModalOptions {
|
|
684
|
+
id: string;
|
|
685
|
+
title?: string;
|
|
686
|
+
type?: NativeModalInfo['type'];
|
|
687
|
+
blocking?: boolean;
|
|
688
|
+
dismissible?: boolean;
|
|
689
|
+
}
|
|
690
|
+
/**
|
|
691
|
+
* Declarative hook: while mounted, registers a modal entry on the active
|
|
692
|
+
* stack so UI Bridge snapshots reflect that a modal is open.
|
|
693
|
+
*/
|
|
694
|
+
declare function useUIBridgeModal(opts: UseUIBridgeModalOptions): void;
|
|
695
|
+
|
|
696
|
+
interface UseUIBridgeToastOptions {
|
|
697
|
+
id: string;
|
|
698
|
+
message: string;
|
|
699
|
+
level?: NativeCapturedToast['level'];
|
|
700
|
+
}
|
|
701
|
+
/**
|
|
702
|
+
* Declarative hook: while mounted, surfaces a toast via the snapshot enricher.
|
|
703
|
+
* Best for explicit-lifecycle toast components.
|
|
704
|
+
*/
|
|
705
|
+
declare function useUIBridgeToast(opts: UseUIBridgeToastOptions): void;
|
|
706
|
+
interface ToastRecorderInput {
|
|
707
|
+
id: string;
|
|
708
|
+
message: string;
|
|
709
|
+
level?: NativeCapturedToast['level'];
|
|
710
|
+
}
|
|
711
|
+
/**
|
|
712
|
+
* Imperative hook: returns a `recordToast` callback for code that fires
|
|
713
|
+
* toasts outside React (catch blocks, library callbacks, etc.).
|
|
714
|
+
*/
|
|
715
|
+
declare function useToastRecorder(): {
|
|
716
|
+
recordToast: (toast: ToastRecorderInput) => void;
|
|
717
|
+
dismissToast: (id: string) => void;
|
|
718
|
+
};
|
|
719
|
+
|
|
720
|
+
export { type ActionRecord as A, useUIBridgeNativeRequired as B, CloudRelayClient as C, type DeclaredUndoState as D, useUIBridgeRequired as E, useUIBridgeToast as F, useUIComponent as G, useUIComponentAction as H, useUIElement as I, useUIElementWithProps as J, ModalDetector as M, ToastCapture as T, type UIBridgeNativeContextValue as U, type CloudRelayConfig as a, type ComponentActionDef as b, type ComponentActionRequest as c, type ComponentActionResponse as d, type ModalPushInput as e, type ToastCaptureConfig as f, type ToastRecordInput as g, type ToastRecorderInput as h, UIBridgeNativeProvider as i, type UIBridgeNativeProviderProps as j, type UIBridgeProps as k, UndoTracker as l, type UndoTrackerConfig as m, type UseUIBridgeModalOptions as n, type UseUIBridgeReturn as o, type UseUIBridgeToastOptions as p, type UseUIComponentOptions as q, type UseUIComponentReturn as r, type UseUIElementOptions as s, type UseUIElementReturn as t, type UseUIElementWithPropsReturn as u, useToastRecorder as v, useUIBridge as w, useUIBridgeModal as x, useUIBridgeNative as y, useUIBridgeNativeOptional as z };
|