@qontinui/ui-bridge-native 0.6.4 → 0.6.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/core/index.js +40 -4
- package/dist/core/index.js.map +1 -1
- package/dist/core/index.mjs +40 -5
- package/dist/core/index.mjs.map +1 -1
- package/dist/core/registry.d.ts +40 -1
- package/dist/core/registry.d.ts.map +1 -1
- package/dist/debug/index.js.map +1 -1
- package/dist/debug/index.mjs.map +1 -1
- package/dist/index.js +62 -27
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +62 -27
- package/dist/index.mjs.map +1 -1
- package/dist/react/UIBridgeNativeProvider.d.ts.map +1 -1
- package/dist/react/index.js +62 -27
- package/dist/react/index.js.map +1 -1
- package/dist/react/index.mjs +63 -28
- package/dist/react/index.mjs.map +1 -1
- package/dist/server/design-handlers.d.ts +21 -1
- package/dist/server/design-handlers.d.ts.map +1 -1
- package/dist/server/handlers.d.ts +14 -0
- package/dist/server/handlers.d.ts.map +1 -1
- package/dist/server/http-server.d.ts.map +1 -1
- package/dist/server/index.js +11 -21
- package/dist/server/index.js.map +1 -1
- package/dist/server/index.mjs +11 -21
- package/dist/server/index.mjs.map +1 -1
- package/dist/server/types.d.ts +18 -0
- package/dist/server/types.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -14,6 +14,10 @@ function extractHandlerNames(props) {
|
|
|
14
14
|
if (!props) return [];
|
|
15
15
|
return Object.keys(props).filter((k) => typeof props[k] === "function");
|
|
16
16
|
}
|
|
17
|
+
function matchesCurrentRoute(registrationRoute, currentRoute) {
|
|
18
|
+
if (registrationRoute == null || registrationRoute === "") return true;
|
|
19
|
+
return registrationRoute === currentRoute;
|
|
20
|
+
}
|
|
17
21
|
function inferActions(type) {
|
|
18
22
|
const baseActions = ["focus", "blur"];
|
|
19
23
|
switch (type) {
|
|
@@ -219,13 +223,20 @@ var NativeUIBridgeRegistry = class {
|
|
|
219
223
|
if (this.config.verbose) {
|
|
220
224
|
console.log(`[ui-bridge-native] Registered element: ${id} (${type})`);
|
|
221
225
|
}
|
|
222
|
-
|
|
226
|
+
const seededState = {
|
|
223
227
|
mounted: true,
|
|
224
228
|
visible: true,
|
|
225
229
|
enabled: true,
|
|
226
230
|
focused: false,
|
|
227
231
|
layout: null
|
|
228
|
-
}
|
|
232
|
+
};
|
|
233
|
+
if (type === "input" && typeof props?.value === "string") {
|
|
234
|
+
seededState.value = props.value;
|
|
235
|
+
}
|
|
236
|
+
if (type === "text" && typeof label === "string") {
|
|
237
|
+
seededState.value = label;
|
|
238
|
+
}
|
|
239
|
+
this.updateElementState(id, seededState);
|
|
229
240
|
return registered;
|
|
230
241
|
}
|
|
231
242
|
/**
|
|
@@ -387,6 +398,9 @@ var NativeUIBridgeRegistry = class {
|
|
|
387
398
|
})
|
|
388
399
|
};
|
|
389
400
|
this.elements.set(id, updated);
|
|
401
|
+
if (element.type === "text" && labelChanged && typeof nextLabel === "string") {
|
|
402
|
+
this.updateElementState(id, { value: nextLabel });
|
|
403
|
+
}
|
|
390
404
|
this.emit("element:registered", {
|
|
391
405
|
id,
|
|
392
406
|
type: element.type,
|
|
@@ -395,7 +409,22 @@ var NativeUIBridgeRegistry = class {
|
|
|
395
409
|
return true;
|
|
396
410
|
}
|
|
397
411
|
/**
|
|
398
|
-
* Update element props (for action execution)
|
|
412
|
+
* Update element props (for action execution).
|
|
413
|
+
*
|
|
414
|
+
* Side effect for `type: 'input'` elements: when `props.value` is a string,
|
|
415
|
+
* mirror it into `state.value` so AI drivers reading the registry don't see
|
|
416
|
+
* `state.value === undefined` until the user types. Before this mirror,
|
|
417
|
+
* controlled-input consumers (`<TextInput value={x} onChangeText={setX} />`
|
|
418
|
+
* with `captureProps({ value: x, onChangeText: setX })`) registered an
|
|
419
|
+
* input whose `state.value` only became defined after the FIRST
|
|
420
|
+
* `onChangeText` call — bridge consumers couldn't read the default value
|
|
421
|
+
* (e.g. a pre-populated API-URL input) until someone typed into it.
|
|
422
|
+
*
|
|
423
|
+
* Re-runs on every `updateElementProps` so a parent passing a fresh
|
|
424
|
+
* `value` prop (controlled re-render) keeps the registry in sync. The
|
|
425
|
+
* mirror is gated on `type === 'input'` to avoid touching non-input
|
|
426
|
+
* elements that may carry an unrelated `value` prop (e.g. a Switch's
|
|
427
|
+
* boolean value, which lives on `state.checked`).
|
|
399
428
|
*/
|
|
400
429
|
updateElementProps(id, props) {
|
|
401
430
|
const element = this.elements.get(id);
|
|
@@ -405,6 +434,12 @@ var NativeUIBridgeRegistry = class {
|
|
|
405
434
|
props: { ...element.props, ...props }
|
|
406
435
|
};
|
|
407
436
|
this.elements.set(id, updated);
|
|
437
|
+
if (element.type === "input" && Object.prototype.hasOwnProperty.call(props, "value") && typeof props.value === "string") {
|
|
438
|
+
const currentState = updated.getState();
|
|
439
|
+
if (currentState.value !== props.value) {
|
|
440
|
+
this.updateElementState(id, { value: props.value });
|
|
441
|
+
}
|
|
442
|
+
}
|
|
408
443
|
}
|
|
409
444
|
}
|
|
410
445
|
/**
|
|
@@ -615,7 +650,7 @@ var NativeUIBridgeRegistry = class {
|
|
|
615
650
|
let elements = options?.visibleOnly ? this.getMountedVisibleElements() : this.getAllElements();
|
|
616
651
|
if (options?.currentRouteOnly && resolvedRoute.currentRoute) {
|
|
617
652
|
const currentRoute = resolvedRoute.currentRoute;
|
|
618
|
-
elements = elements.filter((e) => e.registrationRoute
|
|
653
|
+
elements = elements.filter((e) => matchesCurrentRoute(e.registrationRoute, currentRoute));
|
|
619
654
|
}
|
|
620
655
|
const snapshot = {
|
|
621
656
|
timestamp: Date.now(),
|
|
@@ -1606,15 +1641,9 @@ function success(data) {
|
|
|
1606
1641
|
function error(message, code) {
|
|
1607
1642
|
return { success: false, error: message, code, timestamp: Date.now() };
|
|
1608
1643
|
}
|
|
1609
|
-
function createDesignHandlers(registry) {
|
|
1644
|
+
function createDesignHandlers(registry, viewportProvider) {
|
|
1610
1645
|
function getScreenDimensions() {
|
|
1611
|
-
|
|
1612
|
-
const { Dimensions: Dimensions2 } = __require("react-native");
|
|
1613
|
-
const screen = Dimensions2.get("screen");
|
|
1614
|
-
return { width: screen.width, height: screen.height };
|
|
1615
|
-
} catch {
|
|
1616
|
-
return { width: 0, height: 0 };
|
|
1617
|
-
}
|
|
1646
|
+
return viewportProvider?.() ?? { width: 0, height: 0 };
|
|
1618
1647
|
}
|
|
1619
1648
|
return {
|
|
1620
1649
|
// 1. GET /design/element/:id/styles
|
|
@@ -2244,15 +2273,6 @@ async function executeWorkflowStep(step, registry, executor) {
|
|
|
2244
2273
|
};
|
|
2245
2274
|
}
|
|
2246
2275
|
}
|
|
2247
|
-
function getWindowDimensions() {
|
|
2248
|
-
try {
|
|
2249
|
-
const { Dimensions: Dimensions2 } = __require("react-native");
|
|
2250
|
-
const win = Dimensions2.get("window");
|
|
2251
|
-
return { width: win.width, height: win.height };
|
|
2252
|
-
} catch {
|
|
2253
|
-
return { width: 0, height: 0 };
|
|
2254
|
-
}
|
|
2255
|
-
}
|
|
2256
2276
|
function success2(data) {
|
|
2257
2277
|
return {
|
|
2258
2278
|
success: true,
|
|
@@ -2269,7 +2289,7 @@ function error2(message, code) {
|
|
|
2269
2289
|
};
|
|
2270
2290
|
}
|
|
2271
2291
|
function createServerHandlers(registry, executor, config) {
|
|
2272
|
-
const designHandlers = createDesignHandlers(registry);
|
|
2292
|
+
const designHandlers = createDesignHandlers(registry, config?.viewportProvider);
|
|
2273
2293
|
return {
|
|
2274
2294
|
// Elements
|
|
2275
2295
|
getElements: async (ctx) => {
|
|
@@ -2277,7 +2297,7 @@ function createServerHandlers(registry, executor, config) {
|
|
|
2277
2297
|
const forRoute = ctx.query?.route || ctx.body?.route;
|
|
2278
2298
|
let allElements = visibleOnly ? registry.getMountedVisibleElements() : registry.getAllElements();
|
|
2279
2299
|
if (forRoute) {
|
|
2280
|
-
allElements = allElements.filter((e) => e.registrationRoute
|
|
2300
|
+
allElements = allElements.filter((e) => matchesCurrentRoute(e.registrationRoute, forRoute));
|
|
2281
2301
|
}
|
|
2282
2302
|
const elements = allElements.map((e) => {
|
|
2283
2303
|
const handlers = extractHandlerNames(e.props);
|
|
@@ -2460,7 +2480,7 @@ function createServerHandlers(registry, executor, config) {
|
|
|
2460
2480
|
},
|
|
2461
2481
|
getPageHealth: async (ctx) => {
|
|
2462
2482
|
const bodyViewport = ctx.body?.viewport;
|
|
2463
|
-
const viewport = bodyViewport ??
|
|
2483
|
+
const viewport = bodyViewport ?? config?.viewportProvider?.() ?? { width: 0, height: 0 };
|
|
2464
2484
|
const elements = registry.getAllElements().map((e) => ({
|
|
2465
2485
|
type: e.type,
|
|
2466
2486
|
state: e.getState()
|
|
@@ -3431,7 +3451,8 @@ var NativeUIBridgeServer = class {
|
|
|
3431
3451
|
this.handlers = createServerHandlers(registry, executor, {
|
|
3432
3452
|
appInfo: this.config.appInfo,
|
|
3433
3453
|
consoleErrorBuffer: this.consoleErrorBuffer,
|
|
3434
|
-
networkRequestBuffer: this.networkRequestBuffer
|
|
3454
|
+
networkRequestBuffer: this.networkRequestBuffer,
|
|
3455
|
+
viewportProvider: this.config.viewportProvider
|
|
3435
3456
|
});
|
|
3436
3457
|
this.handlers.getMethods = async () => {
|
|
3437
3458
|
const testHooks = this.config.testHooks === true;
|
|
@@ -5197,7 +5218,17 @@ function UIBridgeNativeProvider({
|
|
|
5197
5218
|
serverPort: config.serverPort || 8087,
|
|
5198
5219
|
cors: true,
|
|
5199
5220
|
appInfo: config.appInfo,
|
|
5200
|
-
testHooks: features.testHooks === true
|
|
5221
|
+
testHooks: features.testHooks === true,
|
|
5222
|
+
// Injected device-viewport getter for POST /control/page-health. The
|
|
5223
|
+
// server doesn't import `react-native` itself — the require/import
|
|
5224
|
+
// pattern there crashed the host RN app in 0.6.3/0.6.4 (Metro/Hermes
|
|
5225
|
+
// raised `unknownModuleError` past every try/catch). This provider
|
|
5226
|
+
// already has a live react-native import, so it's the safe injection
|
|
5227
|
+
// point. See feedback_metro_require_gotcha for the full incident.
|
|
5228
|
+
viewportProvider: () => {
|
|
5229
|
+
const win = Dimensions.get("window");
|
|
5230
|
+
return { width: win.width, height: win.height };
|
|
5231
|
+
}
|
|
5201
5232
|
});
|
|
5202
5233
|
server.setAdapter(serverAdapter);
|
|
5203
5234
|
if (navigationProvider) {
|
|
@@ -5292,7 +5323,11 @@ function UIBridgeNativeProvider({
|
|
|
5292
5323
|
serverPort: config.serverPort || 8087,
|
|
5293
5324
|
cors: true,
|
|
5294
5325
|
appInfo: config.appInfo,
|
|
5295
|
-
testHooks: features.testHooks === true
|
|
5326
|
+
testHooks: features.testHooks === true,
|
|
5327
|
+
viewportProvider: () => {
|
|
5328
|
+
const win = Dimensions.get("window");
|
|
5329
|
+
return { width: win.width, height: win.height };
|
|
5330
|
+
}
|
|
5296
5331
|
});
|
|
5297
5332
|
if (navigationProvider) bareServer.setNavigationProvider(navigationProvider);
|
|
5298
5333
|
if (screenshotProvider) bareServer.setScreenshotProvider(screenshotProvider);
|