@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/react/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { createContext, useRef, useState, useCallback, useEffect, useMemo, use } from 'react';
|
|
2
|
-
import { StyleSheet, Platform } from 'react-native';
|
|
2
|
+
import { Dimensions, StyleSheet, Platform } from 'react-native';
|
|
3
3
|
import { jsx, Fragment } from 'react/jsx-runtime';
|
|
4
4
|
|
|
5
5
|
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
@@ -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(),
|
|
@@ -1554,15 +1589,9 @@ function success(data) {
|
|
|
1554
1589
|
function error(message, code) {
|
|
1555
1590
|
return { success: false, error: message, code, timestamp: Date.now() };
|
|
1556
1591
|
}
|
|
1557
|
-
function createDesignHandlers(registry) {
|
|
1592
|
+
function createDesignHandlers(registry, viewportProvider) {
|
|
1558
1593
|
function getScreenDimensions() {
|
|
1559
|
-
|
|
1560
|
-
const { Dimensions } = __require("react-native");
|
|
1561
|
-
const screen = Dimensions.get("screen");
|
|
1562
|
-
return { width: screen.width, height: screen.height };
|
|
1563
|
-
} catch {
|
|
1564
|
-
return { width: 0, height: 0 };
|
|
1565
|
-
}
|
|
1594
|
+
return viewportProvider?.() ?? { width: 0, height: 0 };
|
|
1566
1595
|
}
|
|
1567
1596
|
return {
|
|
1568
1597
|
// 1. GET /design/element/:id/styles
|
|
@@ -2192,15 +2221,6 @@ async function executeWorkflowStep(step, registry, executor) {
|
|
|
2192
2221
|
};
|
|
2193
2222
|
}
|
|
2194
2223
|
}
|
|
2195
|
-
function getWindowDimensions() {
|
|
2196
|
-
try {
|
|
2197
|
-
const { Dimensions } = __require("react-native");
|
|
2198
|
-
const win = Dimensions.get("window");
|
|
2199
|
-
return { width: win.width, height: win.height };
|
|
2200
|
-
} catch {
|
|
2201
|
-
return { width: 0, height: 0 };
|
|
2202
|
-
}
|
|
2203
|
-
}
|
|
2204
2224
|
function success2(data) {
|
|
2205
2225
|
return {
|
|
2206
2226
|
success: true,
|
|
@@ -2217,7 +2237,7 @@ function error2(message, code) {
|
|
|
2217
2237
|
};
|
|
2218
2238
|
}
|
|
2219
2239
|
function createServerHandlers(registry, executor, config) {
|
|
2220
|
-
const designHandlers = createDesignHandlers(registry);
|
|
2240
|
+
const designHandlers = createDesignHandlers(registry, config?.viewportProvider);
|
|
2221
2241
|
return {
|
|
2222
2242
|
// Elements
|
|
2223
2243
|
getElements: async (ctx) => {
|
|
@@ -2225,7 +2245,7 @@ function createServerHandlers(registry, executor, config) {
|
|
|
2225
2245
|
const forRoute = ctx.query?.route || ctx.body?.route;
|
|
2226
2246
|
let allElements = visibleOnly ? registry.getMountedVisibleElements() : registry.getAllElements();
|
|
2227
2247
|
if (forRoute) {
|
|
2228
|
-
allElements = allElements.filter((e) => e.registrationRoute
|
|
2248
|
+
allElements = allElements.filter((e) => matchesCurrentRoute(e.registrationRoute, forRoute));
|
|
2229
2249
|
}
|
|
2230
2250
|
const elements = allElements.map((e) => {
|
|
2231
2251
|
const handlers = extractHandlerNames(e.props);
|
|
@@ -2408,7 +2428,7 @@ function createServerHandlers(registry, executor, config) {
|
|
|
2408
2428
|
},
|
|
2409
2429
|
getPageHealth: async (ctx) => {
|
|
2410
2430
|
const bodyViewport = ctx.body?.viewport;
|
|
2411
|
-
const viewport = bodyViewport ??
|
|
2431
|
+
const viewport = bodyViewport ?? config?.viewportProvider?.() ?? { width: 0, height: 0 };
|
|
2412
2432
|
const elements = registry.getAllElements().map((e) => ({
|
|
2413
2433
|
type: e.type,
|
|
2414
2434
|
state: e.getState()
|
|
@@ -3379,7 +3399,8 @@ var NativeUIBridgeServer = class {
|
|
|
3379
3399
|
this.handlers = createServerHandlers(registry, executor, {
|
|
3380
3400
|
appInfo: this.config.appInfo,
|
|
3381
3401
|
consoleErrorBuffer: this.consoleErrorBuffer,
|
|
3382
|
-
networkRequestBuffer: this.networkRequestBuffer
|
|
3402
|
+
networkRequestBuffer: this.networkRequestBuffer,
|
|
3403
|
+
viewportProvider: this.config.viewportProvider
|
|
3383
3404
|
});
|
|
3384
3405
|
this.handlers.getMethods = async () => {
|
|
3385
3406
|
const testHooks = this.config.testHooks === true;
|
|
@@ -5145,7 +5166,17 @@ function UIBridgeNativeProvider({
|
|
|
5145
5166
|
serverPort: config.serverPort || 8087,
|
|
5146
5167
|
cors: true,
|
|
5147
5168
|
appInfo: config.appInfo,
|
|
5148
|
-
testHooks: features.testHooks === true
|
|
5169
|
+
testHooks: features.testHooks === true,
|
|
5170
|
+
// Injected device-viewport getter for POST /control/page-health. The
|
|
5171
|
+
// server doesn't import `react-native` itself — the require/import
|
|
5172
|
+
// pattern there crashed the host RN app in 0.6.3/0.6.4 (Metro/Hermes
|
|
5173
|
+
// raised `unknownModuleError` past every try/catch). This provider
|
|
5174
|
+
// already has a live react-native import, so it's the safe injection
|
|
5175
|
+
// point. See feedback_metro_require_gotcha for the full incident.
|
|
5176
|
+
viewportProvider: () => {
|
|
5177
|
+
const win = Dimensions.get("window");
|
|
5178
|
+
return { width: win.width, height: win.height };
|
|
5179
|
+
}
|
|
5149
5180
|
});
|
|
5150
5181
|
server.setAdapter(serverAdapter);
|
|
5151
5182
|
if (navigationProvider) {
|
|
@@ -5240,7 +5271,11 @@ function UIBridgeNativeProvider({
|
|
|
5240
5271
|
serverPort: config.serverPort || 8087,
|
|
5241
5272
|
cors: true,
|
|
5242
5273
|
appInfo: config.appInfo,
|
|
5243
|
-
testHooks: features.testHooks === true
|
|
5274
|
+
testHooks: features.testHooks === true,
|
|
5275
|
+
viewportProvider: () => {
|
|
5276
|
+
const win = Dimensions.get("window");
|
|
5277
|
+
return { width: win.width, height: win.height };
|
|
5278
|
+
}
|
|
5244
5279
|
});
|
|
5245
5280
|
if (navigationProvider) bareServer.setNavigationProvider(navigationProvider);
|
|
5246
5281
|
if (screenshotProvider) bareServer.setScreenshotProvider(screenshotProvider);
|