@qontinui/ui-bridge-native 0.6.13 → 0.6.14
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/debug/index.js.map +1 -1
- package/dist/debug/index.mjs.map +1 -1
- package/dist/index.js +67 -19
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +67 -19
- package/dist/index.mjs.map +1 -1
- package/dist/react/UIBridgeNativeProvider.d.ts +18 -2
- package/dist/react/UIBridgeNativeProvider.d.ts.map +1 -1
- package/dist/react/index.js +67 -19
- package/dist/react/index.js.map +1 -1
- package/dist/react/index.mjs +67 -19
- package/dist/react/index.mjs.map +1 -1
- package/dist/server/index.js +1 -1
- package/dist/server/index.mjs +1 -1
- package/dist/transport/DeviceAnnouncer.d.ts +35 -7
- package/dist/transport/DeviceAnnouncer.d.ts.map +1 -1
- package/dist/transport/index.d.ts +1 -1
- package/dist/transport/index.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -9,6 +9,7 @@ import { NativeUIBridgeRegistry } from '../core/registry';
|
|
|
9
9
|
import type { NativeActionExecutor } from '../control/types';
|
|
10
10
|
import { type ServerAdapter } from '../server/http-server';
|
|
11
11
|
import type { RouteProvider, KeepAwakeProvider } from '../server/types';
|
|
12
|
+
import { type ZeroconfConstructor } from '../transport/DeviceAnnouncer';
|
|
12
13
|
import { type CloudRelayConfig } from '../transport/CloudRelayClient';
|
|
13
14
|
import { ModalDetector } from '../modal/modal-detector';
|
|
14
15
|
import { ToastCapture } from '../toast/toast-capture';
|
|
@@ -109,9 +110,24 @@ export interface UIBridgeNativeProviderProps {
|
|
|
109
110
|
cloudRelayConfig?: Omit<CloudRelayConfig, 'uiBridgeServer'>;
|
|
110
111
|
/**
|
|
111
112
|
* Enable mDNS advertisement so that runners on the same LAN can discover this
|
|
112
|
-
* device automatically
|
|
113
|
+
* device automatically. Advertises `_uibridge._tcp` only when `zeroconf` is
|
|
114
|
+
* also passed; without it the announcer logs that advertisement was skipped.
|
|
113
115
|
*/
|
|
114
116
|
enableMdnsAnnounce?: boolean;
|
|
117
|
+
/**
|
|
118
|
+
* The `Zeroconf` constructor from `react-native-zeroconf`
|
|
119
|
+
* (`import Zeroconf from 'react-native-zeroconf'` → `zeroconf={Zeroconf}`),
|
|
120
|
+
* forwarded to `DeviceAnnouncer.startMdnsAdvertise`. The SDK never
|
|
121
|
+
* `require()`s that package itself — Metro raises an uncatchable module-load
|
|
122
|
+
* error when it is absent — so the host app, which knows it is installed,
|
|
123
|
+
* hands the constructor in. Omitted, mDNS advertisement is skipped.
|
|
124
|
+
*
|
|
125
|
+
* Must be a STABLE reference — the module-level import, never an inline
|
|
126
|
+
* wrapper — because it is a dependency of the transport effect: a new
|
|
127
|
+
* identity per render tears down and re-publishes the advertisement (and the
|
|
128
|
+
* cloud relay) on every render.
|
|
129
|
+
*/
|
|
130
|
+
zeroconf?: ZeroconfConstructor;
|
|
115
131
|
/**
|
|
116
132
|
* Stable device identifier used for mDNS TXT records and cloud relay
|
|
117
133
|
* registration. Typically sourced from expo-device or a UUID stored in
|
|
@@ -119,7 +135,7 @@ export interface UIBridgeNativeProviderProps {
|
|
|
119
135
|
*/
|
|
120
136
|
deviceId?: string;
|
|
121
137
|
}
|
|
122
|
-
export declare function UIBridgeNativeProvider({ children, features: featuresProp, config: configProp, onEvent, serverAdapter, navigationProvider, screenshotProvider, keepAwakeProvider, routeProvider, cloudRelayConfig, enableMdnsAnnounce, deviceId, }: UIBridgeNativeProviderProps): import("react/jsx-runtime").JSX.Element;
|
|
138
|
+
export declare function UIBridgeNativeProvider({ children, features: featuresProp, config: configProp, onEvent, serverAdapter, navigationProvider, screenshotProvider, keepAwakeProvider, routeProvider, cloudRelayConfig, enableMdnsAnnounce, zeroconf, deviceId, }: UIBridgeNativeProviderProps): import("react/jsx-runtime").JSX.Element;
|
|
123
139
|
/**
|
|
124
140
|
* useUIBridgeNative hook
|
|
125
141
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"UIBridgeNativeProvider.d.ts","sourceRoot":"","sources":["../../src/react/UIBridgeNativeProvider.tsx"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAQN,MAAM,OAAO,CAAC;AAEf,OAAO,KAAK,EACV,sBAAsB,EACtB,oBAAoB,EACpB,uBAAuB,EACvB,yBAAyB,EACzB,oBAAoB,EACpB,eAAe,EACf,mBAAmB,EACpB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,sBAAsB,EAA0C,MAAM,kBAAkB,CAAC;AAElG,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAC7D,OAAO,EAGL,KAAK,aAAa,EAEnB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,KAAK,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"UIBridgeNativeProvider.d.ts","sourceRoot":"","sources":["../../src/react/UIBridgeNativeProvider.tsx"],"names":[],"mappings":"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"}
|
package/dist/react/index.js
CHANGED
|
@@ -4313,7 +4313,7 @@ function createServerHandlers(registry, executor, config) {
|
|
|
4313
4313
|
};
|
|
4314
4314
|
if (config?.appInfo) {
|
|
4315
4315
|
response.uiBridge = {
|
|
4316
|
-
version: "0.6.
|
|
4316
|
+
version: "0.6.14",
|
|
4317
4317
|
...config.appInfo,
|
|
4318
4318
|
capabilities: ["elements", "components", "actions", "design"],
|
|
4319
4319
|
elementCount: stats.elements,
|
|
@@ -6236,7 +6236,26 @@ function describeErrorEvent(event) {
|
|
|
6236
6236
|
}
|
|
6237
6237
|
|
|
6238
6238
|
// src/transport/DeviceAnnouncer.ts
|
|
6239
|
+
function registeredServiceName(result, requested) {
|
|
6240
|
+
if (result !== null && typeof result === "object") {
|
|
6241
|
+
const name = result.name;
|
|
6242
|
+
if (typeof name === "string" && name.length > 0) return name;
|
|
6243
|
+
}
|
|
6244
|
+
return requested;
|
|
6245
|
+
}
|
|
6239
6246
|
var DEFAULT_PORT = 8087;
|
|
6247
|
+
async function releaseZeroconf(zeroconf, name) {
|
|
6248
|
+
if (name !== null) {
|
|
6249
|
+
try {
|
|
6250
|
+
await zeroconf.unpublishService(name);
|
|
6251
|
+
} catch {
|
|
6252
|
+
}
|
|
6253
|
+
}
|
|
6254
|
+
try {
|
|
6255
|
+
zeroconf.removeDeviceListeners?.();
|
|
6256
|
+
} catch {
|
|
6257
|
+
}
|
|
6258
|
+
}
|
|
6240
6259
|
var RECONNECT_INITIAL_DELAY_MS = 2e3;
|
|
6241
6260
|
var RECONNECT_MAX_DELAY_MS = 6e4;
|
|
6242
6261
|
var DeviceAnnouncer = class {
|
|
@@ -6249,8 +6268,16 @@ var DeviceAnnouncer = class {
|
|
|
6249
6268
|
this.reconnectTimer = null;
|
|
6250
6269
|
this.reconnectDelay = RECONNECT_INITIAL_DELAY_MS;
|
|
6251
6270
|
this.stopped = false;
|
|
6252
|
-
/** Zeroconf instance, set when mDNS is
|
|
6271
|
+
/** Zeroconf instance, set when mDNS is started (cleared by `stop()`) */
|
|
6253
6272
|
this.zeroconf = null;
|
|
6273
|
+
/** The name the library registered — the only name this announcer may unpublish */
|
|
6274
|
+
this.publishedName = null;
|
|
6275
|
+
/**
|
|
6276
|
+
* True while a publish is awaiting the library. A `stop()` that lands in that
|
|
6277
|
+
* window leaves the cleanup to the publish path, which is the only side that
|
|
6278
|
+
* will learn the registered name.
|
|
6279
|
+
*/
|
|
6280
|
+
this.publishInFlight = false;
|
|
6254
6281
|
this.config = config;
|
|
6255
6282
|
this.pairingToken = generateHex(16);
|
|
6256
6283
|
}
|
|
@@ -6275,19 +6302,38 @@ var DeviceAnnouncer = class {
|
|
|
6275
6302
|
);
|
|
6276
6303
|
return;
|
|
6277
6304
|
}
|
|
6305
|
+
if (this.stopped) return;
|
|
6306
|
+
let zeroconf = null;
|
|
6278
6307
|
try {
|
|
6279
|
-
|
|
6308
|
+
zeroconf = new ZeroconfCtor();
|
|
6309
|
+
this.zeroconf = zeroconf;
|
|
6280
6310
|
const port = this.config.port ?? DEFAULT_PORT;
|
|
6281
6311
|
const serviceName = `UIBridge-${this.config.deviceId.slice(0, 8)}`;
|
|
6282
|
-
this.
|
|
6283
|
-
|
|
6284
|
-
|
|
6285
|
-
|
|
6286
|
-
|
|
6287
|
-
|
|
6312
|
+
this.publishInFlight = true;
|
|
6313
|
+
let result;
|
|
6314
|
+
try {
|
|
6315
|
+
result = await zeroconf.publishService("_uibridge", "_tcp.", "local.", serviceName, port, {
|
|
6316
|
+
device_id: this.config.deviceId,
|
|
6317
|
+
app_id: this.config.appId,
|
|
6318
|
+
version: this.config.version ?? "unknown",
|
|
6319
|
+
pairing_token: this.pairingToken
|
|
6320
|
+
});
|
|
6321
|
+
} finally {
|
|
6322
|
+
this.publishInFlight = false;
|
|
6323
|
+
}
|
|
6324
|
+
const registered = registeredServiceName(result, serviceName);
|
|
6325
|
+
if (this.stopped) {
|
|
6326
|
+
await releaseZeroconf(zeroconf, registered);
|
|
6327
|
+
return;
|
|
6328
|
+
}
|
|
6329
|
+
this.publishedName = registered;
|
|
6288
6330
|
this.state = { ...this.state, mdnsActive: true };
|
|
6289
|
-
transportLogger.log(`[DeviceAnnouncer] mDNS: advertising "${
|
|
6331
|
+
transportLogger.log(`[DeviceAnnouncer] mDNS: advertising "${registered}" on port ${port}`);
|
|
6290
6332
|
} catch (err) {
|
|
6333
|
+
if (this.stopped) {
|
|
6334
|
+
if (zeroconf) await releaseZeroconf(zeroconf, null);
|
|
6335
|
+
return;
|
|
6336
|
+
}
|
|
6291
6337
|
transportLogger.warn("[DeviceAnnouncer] mDNS start failed:", err);
|
|
6292
6338
|
}
|
|
6293
6339
|
}
|
|
@@ -6360,15 +6406,15 @@ var DeviceAnnouncer = class {
|
|
|
6360
6406
|
clearTimeout(this.reconnectTimer);
|
|
6361
6407
|
this.reconnectTimer = null;
|
|
6362
6408
|
}
|
|
6363
|
-
|
|
6364
|
-
|
|
6365
|
-
|
|
6366
|
-
|
|
6367
|
-
|
|
6368
|
-
}
|
|
6369
|
-
this.zeroconf = null;
|
|
6370
|
-
}
|
|
6409
|
+
const zeroconf = this.zeroconf;
|
|
6410
|
+
const publishedName = this.publishedName;
|
|
6411
|
+
const inFlight = this.publishInFlight;
|
|
6412
|
+
this.zeroconf = null;
|
|
6413
|
+
this.publishedName = null;
|
|
6371
6414
|
this.state = { ...this.state, mdnsActive: false };
|
|
6415
|
+
if (zeroconf && !inFlight) {
|
|
6416
|
+
await releaseZeroconf(zeroconf, publishedName);
|
|
6417
|
+
}
|
|
6372
6418
|
if (this.cloudWs) {
|
|
6373
6419
|
this.cloudWs.onclose = null;
|
|
6374
6420
|
this.cloudWs.close();
|
|
@@ -6784,6 +6830,7 @@ function UIBridgeNativeProvider({
|
|
|
6784
6830
|
routeProvider,
|
|
6785
6831
|
cloudRelayConfig,
|
|
6786
6832
|
enableMdnsAnnounce,
|
|
6833
|
+
zeroconf,
|
|
6787
6834
|
deviceId
|
|
6788
6835
|
}) {
|
|
6789
6836
|
const features = useValueStable(featuresProp);
|
|
@@ -6957,7 +7004,7 @@ function UIBridgeNativeProvider({
|
|
|
6957
7004
|
cloudToken: cloudRelayConfig?.authToken
|
|
6958
7005
|
});
|
|
6959
7006
|
announcerRef.current = announcer;
|
|
6960
|
-
void announcer.startMdnsAdvertise().catch((err) => {
|
|
7007
|
+
void announcer.startMdnsAdvertise(zeroconf).catch((err) => {
|
|
6961
7008
|
console.warn("[ui-bridge-native] mDNS advertise failed:", err);
|
|
6962
7009
|
});
|
|
6963
7010
|
} catch (err) {
|
|
@@ -6998,6 +7045,7 @@ function UIBridgeNativeProvider({
|
|
|
6998
7045
|
cloudRelayConfig?.relayUrl,
|
|
6999
7046
|
cloudRelayConfig?.authToken,
|
|
7000
7047
|
enableMdnsAnnounce,
|
|
7048
|
+
zeroconf,
|
|
7001
7049
|
deviceId
|
|
7002
7050
|
]);
|
|
7003
7051
|
react.useEffect(() => {
|