@qontinui/ui-bridge-native 0.1.4 → 0.1.6
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/{index.d.mts → action-executor.d.ts} +6 -10
- package/dist/control/action-executor.d.ts.map +1 -0
- package/dist/control/index.d.ts +5 -91
- package/dist/control/index.d.ts.map +1 -0
- package/dist/control/index.js +1 -1
- package/dist/control/index.js.map +1 -1
- package/dist/control/index.mjs +1 -1
- package/dist/control/index.mjs.map +1 -1
- package/dist/{types-BCYWwyVy.d.ts → control/types.d.ts} +17 -18
- package/dist/control/types.d.ts.map +1 -0
- package/dist/core/element-identifier.d.ts +41 -0
- package/dist/core/element-identifier.d.ts.map +1 -0
- package/dist/core/index.d.ts +6 -43
- package/dist/core/index.d.ts.map +1 -0
- package/dist/{registry-B8A_EoxS.d.ts → core/registry.d.ts} +10 -13
- package/dist/core/registry.d.ts.map +1 -0
- package/dist/{types-BPNuYxDx.d.ts → core/types.d.ts} +30 -30
- package/dist/core/types.d.ts.map +1 -0
- package/dist/debug/index.d.ts +4 -44
- package/dist/debug/index.d.ts.map +1 -0
- package/dist/debug/index.js.map +1 -1
- package/dist/debug/index.mjs.map +1 -1
- package/dist/debug/{index.d.mts → inspector.d.ts} +3 -6
- package/dist/debug/inspector.d.ts.map +1 -0
- package/dist/design/{index.d.mts → design-inspector-native.d.ts} +7 -11
- package/dist/design/design-inspector-native.d.ts.map +1 -0
- package/dist/{design-types-BHr6Q1FX.d.ts → design/design-types.d.ts} +10 -11
- package/dist/design/design-types.d.ts.map +1 -0
- package/dist/design/index.d.ts +5 -60
- package/dist/design/index.d.ts.map +1 -0
- package/dist/index.d.ts +28 -73
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +129 -23
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +129 -23
- package/dist/index.mjs.map +1 -1
- package/dist/react/UIBridgeNativeProvider.d.ts +147 -0
- package/dist/react/UIBridgeNativeProvider.d.ts.map +1 -0
- package/dist/react/index.d.ts +8 -69
- package/dist/react/index.d.ts.map +1 -0
- package/dist/react/index.js +138 -23
- package/dist/react/index.js.map +1 -1
- package/dist/react/index.mjs +138 -23
- package/dist/react/index.mjs.map +1 -1
- package/dist/react/{index.d.mts → useAutoRegister.d.ts} +7 -15
- package/dist/react/useAutoRegister.d.ts.map +1 -0
- package/dist/react/useUIBridge.d.ts +103 -0
- package/dist/react/useUIBridge.d.ts.map +1 -0
- package/dist/react/useUIComponent.d.ts +112 -0
- package/dist/react/useUIComponent.d.ts.map +1 -0
- package/dist/react/useUIElement.d.ts +162 -0
- package/dist/react/useUIElement.d.ts.map +1 -0
- package/dist/server/design-handlers.d.ts +47 -0
- package/dist/server/design-handlers.d.ts.map +1 -0
- package/dist/server/handlers.d.ts +20 -0
- package/dist/server/handlers.d.ts.map +1 -0
- package/dist/server/http-server.d.ts +247 -0
- package/dist/server/http-server.d.ts.map +1 -0
- package/dist/server/index.d.ts +13 -117
- package/dist/server/index.d.ts.map +1 -0
- package/dist/server/index.js +102 -1
- package/dist/server/index.js.map +1 -1
- package/dist/server/index.mjs +102 -1
- package/dist/server/index.mjs.map +1 -1
- package/dist/server/types.d.ts +200 -0
- package/dist/server/types.d.ts.map +1 -0
- package/dist/server/ws-connection.d.ts +48 -0
- package/dist/server/ws-connection.d.ts.map +1 -0
- package/dist/server/ws-event-bridge.d.ts +113 -0
- package/dist/server/ws-event-bridge.d.ts.map +1 -0
- package/dist/server/ws-protocol.d.ts +48 -0
- package/dist/server/ws-protocol.d.ts.map +1 -0
- package/dist/server/ws-types.d.ts +65 -0
- package/dist/server/ws-types.d.ts.map +1 -0
- package/dist/transport/CloudRelayClient.d.ts +51 -0
- package/dist/transport/CloudRelayClient.d.ts.map +1 -0
- package/dist/transport/DeviceAnnouncer.d.ts +75 -0
- package/dist/transport/DeviceAnnouncer.d.ts.map +1 -0
- package/dist/transport/index.d.ts +3 -0
- package/dist/transport/index.d.ts.map +1 -0
- package/package.json +1 -1
- package/dist/core/index.d.mts +0 -46
- package/dist/design-types-BHr6Q1FX.d.mts +0 -205
- package/dist/http-server-B7KudcYJ.d.ts +0 -622
- package/dist/http-server-D7uVANBU.d.mts +0 -622
- package/dist/index.d.mts +0 -76
- package/dist/registry-DhbGbl9c.d.mts +0 -215
- package/dist/server/index.d.mts +0 -119
- package/dist/types-BPNuYxDx.d.mts +0 -383
- package/dist/types-Bcj7ji97.d.mts +0 -177
- package/dist/useUIBridge-CDZbWxII.d.ts +0 -571
- package/dist/useUIBridge-DfIEq9EQ.d.mts +0 -571
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* UI Bridge Native Provider
|
|
3
|
+
*
|
|
4
|
+
* React context provider for UI Bridge Native functionality.
|
|
5
|
+
*/
|
|
6
|
+
import React from 'react';
|
|
7
|
+
import type { NativeUIBridgeFeatures, NativeUIBridgeConfig, RegisteredNativeElement, RegisteredNativeComponent, NativeBridgeSnapshot, BridgeEventType, BridgeEventListener } from '../core/types';
|
|
8
|
+
import { NativeUIBridgeRegistry } from '../core/registry';
|
|
9
|
+
import type { NativeActionExecutor } from '../control/types';
|
|
10
|
+
import { type ServerAdapter } from '../server/http-server';
|
|
11
|
+
import type { RouteProvider } from '../server/types';
|
|
12
|
+
import { type CloudRelayConfig } from '../transport/CloudRelayClient';
|
|
13
|
+
/**
|
|
14
|
+
* UI Bridge Native context value
|
|
15
|
+
*/
|
|
16
|
+
export interface UIBridgeNativeContextValue {
|
|
17
|
+
/** Feature flags */
|
|
18
|
+
features: NativeUIBridgeFeatures;
|
|
19
|
+
/** Configuration */
|
|
20
|
+
config: NativeUIBridgeConfig;
|
|
21
|
+
/** Element registry */
|
|
22
|
+
registry: NativeUIBridgeRegistry;
|
|
23
|
+
/** Action executor */
|
|
24
|
+
executor: NativeActionExecutor;
|
|
25
|
+
/** Get all registered elements */
|
|
26
|
+
getElements: () => RegisteredNativeElement[];
|
|
27
|
+
/** Get all registered components */
|
|
28
|
+
getComponents: () => RegisteredNativeComponent[];
|
|
29
|
+
/** Create a snapshot */
|
|
30
|
+
createSnapshot: () => NativeBridgeSnapshot;
|
|
31
|
+
/** Subscribe to events */
|
|
32
|
+
on: <T = unknown>(type: BridgeEventType, listener: BridgeEventListener<T>) => () => void;
|
|
33
|
+
/** Unsubscribe from events */
|
|
34
|
+
off: <T = unknown>(type: BridgeEventType, listener: BridgeEventListener<T>) => void;
|
|
35
|
+
/** Whether the provider is initialized */
|
|
36
|
+
initialized: boolean;
|
|
37
|
+
/** Server running status */
|
|
38
|
+
serverRunning: boolean;
|
|
39
|
+
/** Start the HTTP server */
|
|
40
|
+
startServer: () => Promise<void>;
|
|
41
|
+
/** Stop the HTTP server */
|
|
42
|
+
stopServer: () => void;
|
|
43
|
+
/** Get the current navigation route (if a RouteProvider is configured) */
|
|
44
|
+
getCurrentRoute: () => string | null;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* UI Bridge Native provider props
|
|
48
|
+
*/
|
|
49
|
+
export interface UIBridgeNativeProviderProps {
|
|
50
|
+
/** Child components */
|
|
51
|
+
children: React.ReactNode;
|
|
52
|
+
/** Feature flags */
|
|
53
|
+
features?: NativeUIBridgeFeatures;
|
|
54
|
+
/** Configuration */
|
|
55
|
+
config?: NativeUIBridgeConfig;
|
|
56
|
+
/** Event handler */
|
|
57
|
+
onEvent?: BridgeEventListener;
|
|
58
|
+
/**
|
|
59
|
+
* A ServerAdapter instance for the HTTP server.
|
|
60
|
+
* The app is responsible for creating this using its preferred native TCP/HTTP library.
|
|
61
|
+
* @see ServerAdapter interface in server/http-server.ts
|
|
62
|
+
*/
|
|
63
|
+
serverAdapter?: ServerAdapter;
|
|
64
|
+
/**
|
|
65
|
+
* Navigation provider for programmatic route navigation via UI Bridge.
|
|
66
|
+
* Pass Expo Router's push/back functions to enable `control/page/navigate`.
|
|
67
|
+
*/
|
|
68
|
+
navigationProvider?: {
|
|
69
|
+
navigate: (url: string) => void;
|
|
70
|
+
back?: () => void;
|
|
71
|
+
};
|
|
72
|
+
/**
|
|
73
|
+
* Screenshot provider for native screen capture via UI Bridge.
|
|
74
|
+
* Pass a function that captures the current screen as base64 PNG.
|
|
75
|
+
*/
|
|
76
|
+
screenshotProvider?: {
|
|
77
|
+
capture: () => Promise<{
|
|
78
|
+
base64: string;
|
|
79
|
+
width: number;
|
|
80
|
+
height: number;
|
|
81
|
+
}>;
|
|
82
|
+
};
|
|
83
|
+
/**
|
|
84
|
+
* Route provider for exposing the current navigation route in snapshots.
|
|
85
|
+
* Wire this to Expo Router's `usePathname()` / `useSegments()` via a module-level ref.
|
|
86
|
+
*/
|
|
87
|
+
routeProvider?: RouteProvider;
|
|
88
|
+
/**
|
|
89
|
+
* Configuration for the cloud relay tunnel (enables remote device verification
|
|
90
|
+
* when USB/LAN are not available). Omit `uiBridgeServer` — the provider wires
|
|
91
|
+
* that automatically after the server starts.
|
|
92
|
+
*/
|
|
93
|
+
cloudRelayConfig?: Omit<CloudRelayConfig, 'uiBridgeServer'>;
|
|
94
|
+
/**
|
|
95
|
+
* Enable mDNS advertisement so that runners on the same LAN can discover this
|
|
96
|
+
* device automatically (requires react-native-zeroconf).
|
|
97
|
+
*/
|
|
98
|
+
enableMdnsAnnounce?: boolean;
|
|
99
|
+
/**
|
|
100
|
+
* Stable device identifier used for mDNS TXT records and cloud relay
|
|
101
|
+
* registration. Typically sourced from expo-device or a UUID stored in
|
|
102
|
+
* AsyncStorage.
|
|
103
|
+
*/
|
|
104
|
+
deviceId?: string;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* UI Bridge Native Provider
|
|
108
|
+
*
|
|
109
|
+
* Provides UI Bridge Native context to child components.
|
|
110
|
+
*
|
|
111
|
+
* @example
|
|
112
|
+
* ```tsx
|
|
113
|
+
* // app/_layout.tsx
|
|
114
|
+
* import { UIBridgeNativeProvider } from 'ui-bridge-native';
|
|
115
|
+
*
|
|
116
|
+
* export default function RootLayout() {
|
|
117
|
+
* return (
|
|
118
|
+
* <UIBridgeNativeProvider
|
|
119
|
+
* features={{ server: __DEV__, debug: __DEV__ }}
|
|
120
|
+
* config={{ serverPort: 8087 }}
|
|
121
|
+
* >
|
|
122
|
+
* <Stack>{children}</Stack>
|
|
123
|
+
* </UIBridgeNativeProvider>
|
|
124
|
+
* );
|
|
125
|
+
* }
|
|
126
|
+
* ```
|
|
127
|
+
*/
|
|
128
|
+
export declare function UIBridgeNativeProvider({ children, features, config, onEvent, serverAdapter, navigationProvider, screenshotProvider, routeProvider, cloudRelayConfig, enableMdnsAnnounce, deviceId, }: UIBridgeNativeProviderProps): import("react/jsx-runtime").JSX.Element;
|
|
129
|
+
/**
|
|
130
|
+
* useUIBridgeNative hook
|
|
131
|
+
*
|
|
132
|
+
* Access the UI Bridge Native context. Throws if used outside provider.
|
|
133
|
+
*/
|
|
134
|
+
export declare function useUIBridgeNative(): UIBridgeNativeContextValue;
|
|
135
|
+
/**
|
|
136
|
+
* useUIBridgeNativeOptional hook
|
|
137
|
+
*
|
|
138
|
+
* Access the UI Bridge Native context, returning null if outside provider.
|
|
139
|
+
*/
|
|
140
|
+
export declare function useUIBridgeNativeOptional(): UIBridgeNativeContextValue | null;
|
|
141
|
+
/**
|
|
142
|
+
* useUIBridgeNativeRequired hook
|
|
143
|
+
*
|
|
144
|
+
* Alias for useUIBridgeNative (throws if outside provider).
|
|
145
|
+
*/
|
|
146
|
+
export declare const useUIBridgeNativeRequired: typeof useUIBridgeNative;
|
|
147
|
+
//# sourceMappingURL=UIBridgeNativeProvider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"UIBridgeNativeProvider.d.ts","sourceRoot":"","sources":["../../src/react/UIBridgeNativeProvider.tsx"],"names":[],"mappings":"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"}
|
package/dist/react/index.d.ts
CHANGED
|
@@ -1,72 +1,11 @@
|
|
|
1
|
-
export { b as ComponentActionDef, c as ComponentActionRequest, d as ComponentActionResponse, U as UIBridgeNativeContextValue, e as UIBridgeNativeProvider, f as UIBridgeNativeProviderProps, g as UIBridgeProps, h as UseUIBridgeReturn, i as UseUIComponentOptions, j as UseUIComponentReturn, k as UseUIElementOptions, l as UseUIElementReturn, m as UseUIElementWithPropsReturn, u as useUIBridge, n as useUIBridgeNative, o as useUIBridgeNativeOptional, p as useUIBridgeNativeRequired, q as useUIBridgeRequired, r as useUIComponent, s as useUIComponentAction, t as useUIElement, v as useUIElementWithProps } from '../useUIBridge-CDZbWxII.js';
|
|
2
|
-
import { i as NativeElementRef } from '../types-BPNuYxDx.js';
|
|
3
|
-
import { b as RegisterElementOptions } from '../registry-B8A_EoxS.js';
|
|
4
|
-
import 'react/jsx-runtime';
|
|
5
|
-
import 'react';
|
|
6
|
-
import '../types-BCYWwyVy.js';
|
|
7
|
-
import '../http-server-B7KudcYJ.js';
|
|
8
|
-
import '../design-types-BHr6Q1FX.js';
|
|
9
|
-
|
|
10
1
|
/**
|
|
11
|
-
*
|
|
2
|
+
* UI Bridge Native - React
|
|
12
3
|
*
|
|
13
|
-
*
|
|
14
|
-
* Unlike the web version, this doesn't use MutationObserver (no DOM).
|
|
15
|
-
* Instead, it provides a simple API for components to register themselves.
|
|
16
|
-
*
|
|
17
|
-
* For comprehensive coverage in React Native, components should:
|
|
18
|
-
* 1. Use this hook at the app root to enable the registry
|
|
19
|
-
* 2. Use useUIElement on interactive components (or wrap with Pressable/TouchableOpacity)
|
|
20
|
-
*/
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* Options for auto-registration in React Native
|
|
24
|
-
*/
|
|
25
|
-
interface NativeAutoRegisterOptions {
|
|
26
|
-
/** Enable auto-registration (default: true in dev mode) */
|
|
27
|
-
enabled?: boolean;
|
|
28
|
-
/** Callback when element is registered */
|
|
29
|
-
onRegister?: (id: string) => void;
|
|
30
|
-
/** Callback when element is unregistered */
|
|
31
|
-
onUnregister?: (id: string) => void;
|
|
32
|
-
}
|
|
33
|
-
/**
|
|
34
|
-
* Handle returned by useAutoRegister for programmatic registration
|
|
35
|
-
*/
|
|
36
|
-
interface NativeAutoRegisterHandle {
|
|
37
|
-
/** Register an element programmatically */
|
|
38
|
-
register: (id: string, ref: React.RefObject<NativeElementRef>, options?: RegisterElementOptions) => void;
|
|
39
|
-
/** Unregister an element programmatically */
|
|
40
|
-
unregister: (id: string) => void;
|
|
41
|
-
/** Check if auto-registration is enabled */
|
|
42
|
-
isEnabled: boolean;
|
|
43
|
-
}
|
|
44
|
-
/**
|
|
45
|
-
* Hook for enabling automatic element registration in React Native.
|
|
46
|
-
*
|
|
47
|
-
* Since React Native doesn't have a DOM to observe, this hook provides
|
|
48
|
-
* a handle for programmatic registration. For most use cases, you should
|
|
49
|
-
* use useUIElement directly on interactive components.
|
|
50
|
-
*
|
|
51
|
-
* @example
|
|
52
|
-
* ```tsx
|
|
53
|
-
* function App() {
|
|
54
|
-
* const autoRegister = useAutoRegister({ enabled: __DEV__ });
|
|
55
|
-
*
|
|
56
|
-
* // Programmatic registration (rare use case)
|
|
57
|
-
* useEffect(() => {
|
|
58
|
-
* autoRegister.register('custom-element', {
|
|
59
|
-
* type: 'button',
|
|
60
|
-
* label: 'Custom Button',
|
|
61
|
-
* });
|
|
62
|
-
*
|
|
63
|
-
* return () => autoRegister.unregister('custom-element');
|
|
64
|
-
* }, []);
|
|
65
|
-
*
|
|
66
|
-
* return <YourApp />;
|
|
67
|
-
* }
|
|
68
|
-
* ```
|
|
4
|
+
* React hooks and provider for React Native.
|
|
69
5
|
*/
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
export
|
|
6
|
+
export * from './UIBridgeNativeProvider';
|
|
7
|
+
export * from './useUIElement';
|
|
8
|
+
export * from './useUIComponent';
|
|
9
|
+
export * from './useUIBridge';
|
|
10
|
+
export * from './useAutoRegister';
|
|
11
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/react/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,cAAc,0BAA0B,CAAC;AACzC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,kBAAkB,CAAC;AACjC,cAAc,eAAe,CAAC;AAC9B,cAAc,mBAAmB,CAAC"}
|
package/dist/react/index.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var react = require('react');
|
|
4
|
-
var jsxRuntime = require('react/jsx-runtime');
|
|
5
4
|
var reactNative = require('react-native');
|
|
5
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
6
6
|
|
|
7
7
|
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
8
8
|
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
@@ -689,7 +689,7 @@ var DefaultNativeActionExecutor = class {
|
|
|
689
689
|
if (!params?.text) {
|
|
690
690
|
throw new Error("Type action requires text parameter");
|
|
691
691
|
}
|
|
692
|
-
if (params.clearFirst) {
|
|
692
|
+
if (params.clearFirst || params.clear) {
|
|
693
693
|
await this.performClear(element, props);
|
|
694
694
|
}
|
|
695
695
|
if (params.delay && params.delay > 0) {
|
|
@@ -1875,6 +1875,15 @@ function createServerHandlers(registry, executor, config) {
|
|
|
1875
1875
|
timestamp: Date.now(),
|
|
1876
1876
|
...stats
|
|
1877
1877
|
};
|
|
1878
|
+
if (config?.appInfo) {
|
|
1879
|
+
response.uiBridge = {
|
|
1880
|
+
version: "0.3.0",
|
|
1881
|
+
...config.appInfo,
|
|
1882
|
+
capabilities: ["elements", "components", "actions", "design"],
|
|
1883
|
+
elementCount: stats.elements,
|
|
1884
|
+
componentCount: stats.components
|
|
1885
|
+
};
|
|
1886
|
+
}
|
|
1878
1887
|
return success2(response);
|
|
1879
1888
|
}
|
|
1880
1889
|
};
|
|
@@ -1913,6 +1922,10 @@ var WS_ROUTES = [
|
|
|
1913
1922
|
{ pattern: "health", handler: "health", httpMethods: ["GET"] },
|
|
1914
1923
|
// Elements
|
|
1915
1924
|
{ pattern: "control/elements", handler: "getElements", httpMethods: ["GET"] },
|
|
1925
|
+
// Flat alias — matches the runner UI Bridge's `/ui-bridge/elements` path so
|
|
1926
|
+
// agents can use the same URL across runner + mobile without remembering
|
|
1927
|
+
// the `control/` prefix. Delegates to the same handler.
|
|
1928
|
+
{ pattern: "elements", handler: "getElements", httpMethods: ["GET"] },
|
|
1916
1929
|
{ pattern: "control/element/:id", handler: "getElement", httpMethods: ["GET"] },
|
|
1917
1930
|
{ pattern: "control/element/:id/state", handler: "getElementState", httpMethods: ["GET"] },
|
|
1918
1931
|
{ pattern: "control/element/:id/action", handler: "executeAction", httpMethods: ["POST"] },
|
|
@@ -1963,6 +1976,87 @@ var WS_ROUTES = [
|
|
|
1963
1976
|
// Meta / Introspection
|
|
1964
1977
|
{ pattern: "meta/methods", handler: "getMethods", httpMethods: ["GET"] }
|
|
1965
1978
|
];
|
|
1979
|
+
var HANDLER_DESCRIPTIONS = {
|
|
1980
|
+
health: "Liveness probe; returns app metadata + element count",
|
|
1981
|
+
getElements: "Flat list of registered UI elements",
|
|
1982
|
+
getElement: "Single element by id",
|
|
1983
|
+
getElementState: "Dynamic state (value, focused, checked) for one element",
|
|
1984
|
+
executeAction: 'Run an action on an element (see "actions" below for names)',
|
|
1985
|
+
getComponents: "Higher-level components with action schemas",
|
|
1986
|
+
getComponent: "Component detail + per-action paramSchema",
|
|
1987
|
+
executeComponentAction: "Invoke a component action directly (preferred over button clicks)",
|
|
1988
|
+
find: "AI-powered element search by natural-language query",
|
|
1989
|
+
getSnapshot: "Full snapshot: elements + route + state. Supports ?visibleOnly=true and ?currentRouteOnly=true",
|
|
1990
|
+
getWorkflows: "List registered workflows",
|
|
1991
|
+
runWorkflow: "Trigger a workflow by id",
|
|
1992
|
+
pageRefresh: "Reload the current route",
|
|
1993
|
+
pageNavigate: "Imperative router.push(url) \u2014 preferred over tapping tab buttons",
|
|
1994
|
+
pageReplace: "router.replace(url)",
|
|
1995
|
+
pageGoBack: "router.back()",
|
|
1996
|
+
pageGoForward: "router.forward()",
|
|
1997
|
+
getScreenshot: "PNG screenshot of the current screen",
|
|
1998
|
+
getElementStyles: "Computed styles for an element (design review)",
|
|
1999
|
+
getElementStateStyles: "Computed styles per interaction state (hover/focus/disabled)",
|
|
2000
|
+
getDesignSnapshot: "Visual + style snapshot for design review",
|
|
2001
|
+
getResponsiveSnapshots: "Screenshots at multiple viewport widths",
|
|
2002
|
+
runDesignAudit: "Accessibility + visual audit",
|
|
2003
|
+
loadStyleGuide: "Load a design system style guide",
|
|
2004
|
+
getStyleGuide: "Fetch the currently loaded style guide",
|
|
2005
|
+
clearStyleGuide: "Unload the style guide",
|
|
2006
|
+
evaluateQuality: "Score the current UI against a quality context",
|
|
2007
|
+
getQualityContexts: "List available quality evaluation contexts",
|
|
2008
|
+
saveBaseline: "Save a quality baseline snapshot",
|
|
2009
|
+
diffBaseline: "Diff current UI against a saved baseline",
|
|
2010
|
+
getMethods: "List every handler name (legacy introspection)"
|
|
2011
|
+
};
|
|
2012
|
+
var ACTION_REFERENCE = [
|
|
2013
|
+
{ name: "press", aliases: ["click"], params: "PressActionParams (optional position)" },
|
|
2014
|
+
{ name: "longPress", params: "PressActionParams (optional position)" },
|
|
2015
|
+
{ name: "doubleTap", params: "none" },
|
|
2016
|
+
{
|
|
2017
|
+
name: "type",
|
|
2018
|
+
params: "TypeActionParams { text, delay?, clear? | clearFirst? } \u2014 `clear:true` replaces content atomically"
|
|
2019
|
+
},
|
|
2020
|
+
{ name: "clear", params: "none \u2014 empties the input" },
|
|
2021
|
+
{ name: "focus", params: "none" },
|
|
2022
|
+
{ name: "blur", params: "none" },
|
|
2023
|
+
{ name: "scroll", params: "ScrollActionParams { offset? {x,y}, to? }" },
|
|
2024
|
+
{ name: "swipe", params: "SwipeActionParams { direction, distance }" },
|
|
2025
|
+
{ name: "toggle", params: "none \u2014 flips boolean controls" }
|
|
2026
|
+
];
|
|
2027
|
+
function buildRoutesPayload() {
|
|
2028
|
+
const entries = [];
|
|
2029
|
+
for (const r of WS_ROUTES) {
|
|
2030
|
+
if (!r.httpMethods) continue;
|
|
2031
|
+
for (const m of r.httpMethods) {
|
|
2032
|
+
entries.push({ method: m, path: `/ui-bridge/${r.pattern}` });
|
|
2033
|
+
}
|
|
2034
|
+
}
|
|
2035
|
+
entries.push({ method: "GET", path: "/ui-bridge/_help" });
|
|
2036
|
+
entries.push({ method: "GET", path: "/ui-bridge/_routes" });
|
|
2037
|
+
entries.sort((a, b) => a.path.localeCompare(b.path) || a.method.localeCompare(b.method));
|
|
2038
|
+
return { routes: entries, count: entries.length };
|
|
2039
|
+
}
|
|
2040
|
+
function buildHelpPayload() {
|
|
2041
|
+
return {
|
|
2042
|
+
version: 1,
|
|
2043
|
+
description: "UI Bridge Native HTTP surface. Prefix every path with /ui-bridge/.",
|
|
2044
|
+
routes: WS_ROUTES.map((r) => ({
|
|
2045
|
+
pattern: r.pattern,
|
|
2046
|
+
httpMethods: r.httpMethods ?? [],
|
|
2047
|
+
wsOnly: !r.httpMethods,
|
|
2048
|
+
handler: r.handler,
|
|
2049
|
+
description: HANDLER_DESCRIPTIONS[r.handler] ?? ""
|
|
2050
|
+
})),
|
|
2051
|
+
actions: ACTION_REFERENCE,
|
|
2052
|
+
tips: [
|
|
2053
|
+
"Start with `GET /ui-bridge/control/snapshot?visibleOnly=true` to see what the user actually sees.",
|
|
2054
|
+
"Prefer `control/component/:id/action/:actionId` over button presses \u2014 typed paramSchema, no button-id guessing.",
|
|
2055
|
+
"Use `pageNavigate` for tab switches instead of pressing tab buttons; gesture state often swallows clicks.",
|
|
2056
|
+
"The `type` action supports `clear:true` to replace existing text atomically in one call."
|
|
2057
|
+
]
|
|
2058
|
+
};
|
|
2059
|
+
}
|
|
1966
2060
|
var NativeUIBridgeServer = class {
|
|
1967
2061
|
constructor(registry, executor, config = {}) {
|
|
1968
2062
|
this.registry = registry;
|
|
@@ -1979,7 +2073,9 @@ var NativeUIBridgeServer = class {
|
|
|
1979
2073
|
cors: true,
|
|
1980
2074
|
...config
|
|
1981
2075
|
};
|
|
1982
|
-
this.handlers = createServerHandlers(registry, executor
|
|
2076
|
+
this.handlers = createServerHandlers(registry, executor, {
|
|
2077
|
+
appInfo: this.config.appInfo
|
|
2078
|
+
});
|
|
1983
2079
|
this.handlers.getMethods = async () => {
|
|
1984
2080
|
const methods = WS_ROUTES.map((r) => ({
|
|
1985
2081
|
method: r.pattern,
|
|
@@ -2783,6 +2879,20 @@ var NativeUIBridgeServer = class {
|
|
|
2783
2879
|
};
|
|
2784
2880
|
}
|
|
2785
2881
|
const stripped = path.slice(PREFIX.length);
|
|
2882
|
+
if (method === "GET" && stripped === "_help") {
|
|
2883
|
+
return {
|
|
2884
|
+
success: true,
|
|
2885
|
+
data: buildHelpPayload(),
|
|
2886
|
+
timestamp: Date.now()
|
|
2887
|
+
};
|
|
2888
|
+
}
|
|
2889
|
+
if (method === "GET" && stripped === "_routes") {
|
|
2890
|
+
return {
|
|
2891
|
+
success: true,
|
|
2892
|
+
data: buildRoutesPayload(),
|
|
2893
|
+
timestamp: Date.now()
|
|
2894
|
+
};
|
|
2895
|
+
}
|
|
2786
2896
|
let patternMatchedButWrongVerb = false;
|
|
2787
2897
|
for (const route of WS_ROUTES) {
|
|
2788
2898
|
const pathParams = parsePath(route.pattern, stripped);
|
|
@@ -3083,8 +3193,6 @@ var WebSocketEventBridge = class {
|
|
|
3083
3193
|
}, this.heartbeatIntervalMs);
|
|
3084
3194
|
}
|
|
3085
3195
|
};
|
|
3086
|
-
|
|
3087
|
-
// src/transport/DeviceAnnouncer.ts
|
|
3088
3196
|
var DEFAULT_PORT = 8087;
|
|
3089
3197
|
var RECONNECT_INITIAL_DELAY_MS = 2e3;
|
|
3090
3198
|
var RECONNECT_MAX_DELAY_MS = 6e4;
|
|
@@ -3105,15 +3213,27 @@ var DeviceAnnouncer = class {
|
|
|
3105
3213
|
}
|
|
3106
3214
|
// ── mDNS ──────────────────────────────────────────────────────────────────
|
|
3107
3215
|
/**
|
|
3108
|
-
* Start mDNS advertisement
|
|
3216
|
+
* Start mDNS advertisement.
|
|
3217
|
+
*
|
|
3218
|
+
* The consumer must pass the `Zeroconf` constructor (from `react-native-zeroconf`)
|
|
3219
|
+
* explicitly; otherwise this is a no-op.
|
|
3109
3220
|
*
|
|
3110
|
-
*
|
|
3221
|
+
* Rationale: Metro's `require()` throws an uncatchable module-load error if the
|
|
3222
|
+
* bundle doesn't include the named package. That error escapes async try/catch
|
|
3223
|
+
* boundaries and crashes the app. We avoid it by never calling `require()`
|
|
3224
|
+
* ourselves — the consumer imports the package when they know it's installed.
|
|
3225
|
+
*
|
|
3226
|
+
* @param ZeroconfCtor - constructor from `import Zeroconf from 'react-native-zeroconf'`
|
|
3111
3227
|
*/
|
|
3112
|
-
async startMdnsAdvertise() {
|
|
3228
|
+
async startMdnsAdvertise(ZeroconfCtor) {
|
|
3229
|
+
if (!ZeroconfCtor) {
|
|
3230
|
+
console.log(
|
|
3231
|
+
"[DeviceAnnouncer] mDNS advertisement skipped (no Zeroconf constructor provided). Pass one to enable mDNS."
|
|
3232
|
+
);
|
|
3233
|
+
return;
|
|
3234
|
+
}
|
|
3113
3235
|
try {
|
|
3114
|
-
|
|
3115
|
-
const Zeroconf = ZeroconfModule.default ?? ZeroconfModule;
|
|
3116
|
-
this.zeroconf = new Zeroconf();
|
|
3236
|
+
this.zeroconf = new ZeroconfCtor();
|
|
3117
3237
|
const port = this.config.port ?? DEFAULT_PORT;
|
|
3118
3238
|
const serviceName = `UIBridge-${this.config.deviceId.slice(0, 8)}`;
|
|
3119
3239
|
this.zeroconf.publishService("_uibridge", "_tcp.", "local.", serviceName, port, {
|
|
@@ -3124,10 +3244,8 @@ var DeviceAnnouncer = class {
|
|
|
3124
3244
|
});
|
|
3125
3245
|
this.state = { ...this.state, mdnsActive: true };
|
|
3126
3246
|
console.log(`[DeviceAnnouncer] mDNS: advertising "${serviceName}" on port ${port}`);
|
|
3127
|
-
} catch (
|
|
3128
|
-
console.warn(
|
|
3129
|
-
"[DeviceAnnouncer] react-native-zeroconf not available \u2014 mDNS advertisement skipped. Install it with: npx expo install react-native-zeroconf"
|
|
3130
|
-
);
|
|
3247
|
+
} catch (err) {
|
|
3248
|
+
console.warn("[DeviceAnnouncer] mDNS start failed:", err);
|
|
3131
3249
|
}
|
|
3132
3250
|
}
|
|
3133
3251
|
// ── Cloud relay ───────────────────────────────────────────────────────────
|
|
@@ -3232,12 +3350,7 @@ function generateHex(bytes) {
|
|
|
3232
3350
|
return Array.from(arr).map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
3233
3351
|
}
|
|
3234
3352
|
function getPlatform() {
|
|
3235
|
-
|
|
3236
|
-
const { Platform } = __require("react-native");
|
|
3237
|
-
return Platform.OS ?? "unknown";
|
|
3238
|
-
} catch {
|
|
3239
|
-
return "unknown";
|
|
3240
|
-
}
|
|
3353
|
+
return reactNative.Platform?.OS ?? "unknown";
|
|
3241
3354
|
}
|
|
3242
3355
|
|
|
3243
3356
|
// src/transport/CloudRelayClient.ts
|
|
@@ -3444,7 +3557,8 @@ function UIBridgeNativeProvider({
|
|
|
3444
3557
|
}
|
|
3445
3558
|
const server = createNativeServer(registry, executor, {
|
|
3446
3559
|
serverPort: config.serverPort || 8087,
|
|
3447
|
-
cors: true
|
|
3560
|
+
cors: true,
|
|
3561
|
+
appInfo: config.appInfo
|
|
3448
3562
|
});
|
|
3449
3563
|
server.setAdapter(serverAdapter);
|
|
3450
3564
|
if (navigationProvider) {
|
|
@@ -3531,7 +3645,8 @@ function UIBridgeNativeProvider({
|
|
|
3531
3645
|
try {
|
|
3532
3646
|
const bareServer = createNativeServer(registry, executor, {
|
|
3533
3647
|
serverPort: config.serverPort || 8087,
|
|
3534
|
-
cors: true
|
|
3648
|
+
cors: true,
|
|
3649
|
+
appInfo: config.appInfo
|
|
3535
3650
|
});
|
|
3536
3651
|
if (navigationProvider) bareServer.setNavigationProvider(navigationProvider);
|
|
3537
3652
|
if (screenshotProvider) bareServer.setScreenshotProvider(screenshotProvider);
|