@qontinui/ui-bridge-native 0.7.0 → 0.8.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/index.js CHANGED
@@ -11,6 +11,164 @@ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require
11
11
  throw Error('Dynamic require of "' + x + '" is not supported');
12
12
  });
13
13
 
14
+ // src/core/sha256.ts
15
+ var K = new Uint32Array([
16
+ 1116352408,
17
+ 1899447441,
18
+ 3049323471,
19
+ 3921009573,
20
+ 961987163,
21
+ 1508970993,
22
+ 2453635748,
23
+ 2870763221,
24
+ 3624381080,
25
+ 310598401,
26
+ 607225278,
27
+ 1426881987,
28
+ 1925078388,
29
+ 2162078206,
30
+ 2614888103,
31
+ 3248222580,
32
+ 3835390401,
33
+ 4022224774,
34
+ 264347078,
35
+ 604807628,
36
+ 770255983,
37
+ 1249150122,
38
+ 1555081692,
39
+ 1996064986,
40
+ 2554220882,
41
+ 2821834349,
42
+ 2952996808,
43
+ 3210313671,
44
+ 3336571891,
45
+ 3584528711,
46
+ 113926993,
47
+ 338241895,
48
+ 666307205,
49
+ 773529912,
50
+ 1294757372,
51
+ 1396182291,
52
+ 1695183700,
53
+ 1986661051,
54
+ 2177026350,
55
+ 2456956037,
56
+ 2730485921,
57
+ 2820302411,
58
+ 3259730800,
59
+ 3345764771,
60
+ 3516065817,
61
+ 3600352804,
62
+ 4094571909,
63
+ 275423344,
64
+ 430227734,
65
+ 506948616,
66
+ 659060556,
67
+ 883997877,
68
+ 958139571,
69
+ 1322822218,
70
+ 1537002063,
71
+ 1747873779,
72
+ 1955562222,
73
+ 2024104815,
74
+ 2227730452,
75
+ 2361852424,
76
+ 2428436474,
77
+ 2756734187,
78
+ 3204031479,
79
+ 3329325298
80
+ ]);
81
+ var H0 = [
82
+ 1779033703,
83
+ 3144134277,
84
+ 1013904242,
85
+ 2773480762,
86
+ 1359893119,
87
+ 2600822924,
88
+ 528734635,
89
+ 1541459225
90
+ ];
91
+ function utf8Bytes(input) {
92
+ const out = [];
93
+ for (let i = 0; i < input.length; i++) {
94
+ let cp = input.charCodeAt(i);
95
+ if (cp >= 55296 && cp <= 56319) {
96
+ const next = i + 1 < input.length ? input.charCodeAt(i + 1) : 0;
97
+ if (next >= 56320 && next <= 57343) {
98
+ cp = 65536 + (cp - 55296 << 10) + (next - 56320);
99
+ i++;
100
+ } else {
101
+ cp = 65533;
102
+ }
103
+ } else if (cp >= 56320 && cp <= 57343) {
104
+ cp = 65533;
105
+ }
106
+ if (cp < 128) {
107
+ out.push(cp);
108
+ } else if (cp < 2048) {
109
+ out.push(192 | cp >> 6, 128 | cp & 63);
110
+ } else if (cp < 65536) {
111
+ out.push(224 | cp >> 12, 128 | cp >> 6 & 63, 128 | cp & 63);
112
+ } else {
113
+ out.push(
114
+ 240 | cp >> 18,
115
+ 128 | cp >> 12 & 63,
116
+ 128 | cp >> 6 & 63,
117
+ 128 | cp & 63
118
+ );
119
+ }
120
+ }
121
+ return Uint8Array.from(out);
122
+ }
123
+ var rotr = (x, n) => x >>> n | x << 32 - n;
124
+ function sha256Hex(input) {
125
+ const bytes = utf8Bytes(input);
126
+ const blockBytes = Math.ceil((bytes.length + 9) / 64) * 64;
127
+ const buffer = new Uint8Array(blockBytes);
128
+ buffer.set(bytes);
129
+ buffer[bytes.length] = 128;
130
+ const view = new DataView(buffer.buffer);
131
+ const bitLength = bytes.length * 8;
132
+ view.setUint32(blockBytes - 8, Math.floor(bitLength / 4294967296));
133
+ view.setUint32(blockBytes - 4, bitLength >>> 0);
134
+ const h = H0.slice();
135
+ const w = new Uint32Array(64);
136
+ for (let block = 0; block < blockBytes; block += 64) {
137
+ for (let t = 0; t < 16; t++) w[t] = view.getUint32(block + t * 4);
138
+ for (let t = 16; t < 64; t++) {
139
+ const s0 = rotr(w[t - 15], 7) ^ rotr(w[t - 15], 18) ^ w[t - 15] >>> 3;
140
+ const s1 = rotr(w[t - 2], 17) ^ rotr(w[t - 2], 19) ^ w[t - 2] >>> 10;
141
+ w[t] = w[t - 16] + s0 + w[t - 7] + s1;
142
+ }
143
+ let [a, b, c, d, e, f, g, hh] = h;
144
+ for (let t = 0; t < 64; t++) {
145
+ const S1 = rotr(e, 6) ^ rotr(e, 11) ^ rotr(e, 25);
146
+ const ch = e & f ^ ~e & g;
147
+ const t1 = hh + S1 + ch + K[t] + w[t] | 0;
148
+ const S0 = rotr(a, 2) ^ rotr(a, 13) ^ rotr(a, 22);
149
+ const maj = a & b ^ a & c ^ b & c;
150
+ const t2 = S0 + maj | 0;
151
+ hh = g;
152
+ g = f;
153
+ f = e;
154
+ e = d + t1 | 0;
155
+ d = c;
156
+ c = b;
157
+ b = a;
158
+ a = t1 + t2 | 0;
159
+ }
160
+ h[0] = h[0] + a | 0;
161
+ h[1] = h[1] + b | 0;
162
+ h[2] = h[2] + c | 0;
163
+ h[3] = h[3] + d | 0;
164
+ h[4] = h[4] + e | 0;
165
+ h[5] = h[5] + f | 0;
166
+ h[6] = h[6] + g | 0;
167
+ h[7] = h[7] + hh | 0;
168
+ }
169
+ return h.map((word) => (word >>> 0).toString(16).padStart(8, "0")).join("");
170
+ }
171
+
14
172
  // src/core/vision-fields.ts
15
173
  var INTERACTIVE_HANDLER_NAMES = /* @__PURE__ */ new Set([
16
174
  "onPress",
@@ -94,13 +252,18 @@ var NAMED_COLORS = {
94
252
  gray: { r: 128, g: 128, b: 128 },
95
253
  grey: { r: 128, g: 128, b: 128 },
96
254
  silver: { r: 192, g: 192, b: 192 },
97
- transparent: { r: 0, g: 0, b: 0 },
98
255
  orange: { r: 255, g: 165, b: 0 },
99
256
  yellow: { r: 255, g: 255, b: 0 },
100
257
  purple: { r: 128, g: 0, b: 128 },
101
258
  navy: { r: 0, g: 0, b: 128 }
102
259
  };
103
260
  var clamp255 = (n) => Math.max(0, Math.min(255, Math.round(n)));
261
+ function parseAlpha(p) {
262
+ const pct = p.endsWith("%");
263
+ const n = parseFloat(pct ? p.slice(0, -1) : p);
264
+ if (!Number.isFinite(n)) return void 0;
265
+ return Math.min(1, pct ? n / 100 : n);
266
+ }
104
267
  function parseColorToRgb(input) {
105
268
  if (typeof input !== "string") return void 0;
106
269
  const raw = input.trim().toLowerCase();
@@ -111,6 +274,7 @@ function parseColorToRgb(input) {
111
274
  if (raw.startsWith("#")) {
112
275
  const hex = raw.slice(1);
113
276
  if (hex.length === 3 || hex.length === 4) {
277
+ if (hex.length === 4 && hex[3] !== "f") return void 0;
114
278
  const r = parseInt(hex[0] + hex[0], 16);
115
279
  const g = parseInt(hex[1] + hex[1], 16);
116
280
  const b = parseInt(hex[2] + hex[2], 16);
@@ -118,6 +282,7 @@ function parseColorToRgb(input) {
118
282
  return void 0;
119
283
  }
120
284
  if (hex.length === 6 || hex.length === 8) {
285
+ if (hex.length === 8 && hex.slice(6, 8) !== "ff") return void 0;
121
286
  const r = parseInt(hex.slice(0, 2), 16);
122
287
  const g = parseInt(hex.slice(2, 4), 16);
123
288
  const b = parseInt(hex.slice(4, 6), 16);
@@ -129,7 +294,11 @@ function parseColorToRgb(input) {
129
294
  const rgbMatch = raw.match(/^rgba?\(([^)]+)\)$/);
130
295
  if (rgbMatch) {
131
296
  const parts = rgbMatch[1].split(",").map((p) => p.trim());
132
- if (parts.length < 3) return void 0;
297
+ if (parts.length < 3 || parts.length > 4) return void 0;
298
+ if (parts.length === 4) {
299
+ const alpha = parseAlpha(parts[3]);
300
+ if (alpha === void 0 || alpha < 1) return void 0;
301
+ }
133
302
  const channel = (p) => {
134
303
  if (p.endsWith("%")) {
135
304
  const pct = parseFloat(p.slice(0, -1));
@@ -161,13 +330,87 @@ function parseFontSizePx(input) {
161
330
  }
162
331
  return void 0;
163
332
  }
333
+ var ASCII_WHITESPACE_EDGES = /^[\t\n\f\r ]+|[\t\n\f\r ]+$/g;
334
+ function nonEmptyString(v) {
335
+ return typeof v === "string" && v.length > 0 ? v : void 0;
336
+ }
337
+ var OBJECT_FIT_TO_RESIZE_MODE = /* @__PURE__ */ new Map([
338
+ ["contain", "contain"],
339
+ ["cover", "cover"],
340
+ ["fill", "stretch"],
341
+ ["scale-down", "contain"],
342
+ ["none", "none"]
343
+ ]);
344
+ var RESIZE_MODE_TO_OBJECT_FIT = /* @__PURE__ */ new Map([
345
+ ["cover", "cover"],
346
+ ["contain", "contain"],
347
+ ["stretch", "fill"],
348
+ ["center", "scale-down"],
349
+ ["none", "none"]
350
+ ]);
351
+ function resolveObjectFit(props, flatStyle) {
352
+ const styleFit = nonEmptyString(flatStyle?.objectFit);
353
+ const mode = (styleFit !== void 0 ? OBJECT_FIT_TO_RESIZE_MODE.get(styleFit) : void 0) ?? nonEmptyString(props?.resizeMode) ?? nonEmptyString(flatStyle?.resizeMode);
354
+ return mode !== void 0 ? RESIZE_MODE_TO_OBJECT_FIT.get(mode) : void 0;
355
+ }
356
+ function resolveImageSource(props) {
357
+ if (!props) return void 0;
358
+ if (props.srcSet !== void 0 && props.srcSet !== null) return void 0;
359
+ const src = nonEmptyString(props.src);
360
+ if (src !== void 0) return src;
361
+ const source = props.source;
362
+ const one = Array.isArray(source) ? source.length === 1 ? source[0] : void 0 : source;
363
+ if (one && typeof one === "object") {
364
+ return nonEmptyString(one.uri);
365
+ }
366
+ return void 0;
367
+ }
368
+ function isHiddenFromAccessibility(props) {
369
+ if (!props) return false;
370
+ return props.accessible === false && props.alt === void 0 || props.importantForAccessibility === "no" || props.importantForAccessibility === "no-hide-descendants" || props.accessibilityElementsHidden === true;
371
+ }
372
+ function resolveImageLabel(props, registryLabel) {
373
+ if (props === void 0) return registryLabel;
374
+ const own = props["aria-label"] ?? props.accessibilityLabel ?? props.alt;
375
+ return typeof own === "string" ? own : void 0;
376
+ }
377
+ function projectMedia(args) {
378
+ const { layout, props, flatStyle, accessibilityLabel, inViewport } = args;
379
+ const media = { kind: "img" };
380
+ if (layout && Number.isFinite(layout.width) && Number.isFinite(layout.height) && layout.width >= 0 && layout.height >= 0) {
381
+ media.rendered_px = { w: layout.width, h: layout.height };
382
+ }
383
+ const objectFit = resolveObjectFit(props, flatStyle);
384
+ if (objectFit !== void 0) media.object_fit = objectFit;
385
+ if (isHiddenFromAccessibility(props)) {
386
+ media.alt = { decorative: true };
387
+ } else {
388
+ const label = resolveImageLabel(props, accessibilityLabel);
389
+ const text = label?.replace(ASCII_WHITESPACE_EDGES, "");
390
+ if (text) media.alt = { decorative: false, text };
391
+ }
392
+ const src = resolveImageSource(props);
393
+ if (src !== void 0) media.src_digest = sha256Hex(src);
394
+ if (inViewport !== void 0) media.in_viewport = inViewport;
395
+ return media;
396
+ }
164
397
  function projectVisionFields(args) {
165
398
  const { type, label, handlerNames, state, flatStyle } = args;
166
399
  const fields = {
167
400
  interactable: deriveInteractable(type, handlerNames)
168
401
  };
169
- const text = deriveText(state, label);
170
- if (text !== void 0) fields.text = text;
402
+ if (type === "image") {
403
+ fields.media = projectMedia({
404
+ layout: state.layout,
405
+ props: args.props,
406
+ flatStyle,
407
+ accessibilityLabel: args.accessibilityLabel,
408
+ inViewport: args.inViewport
409
+ });
410
+ } else {
411
+ const text = deriveText(state, label);
412
+ if (text !== void 0) fields.text = text;
413
+ }
171
414
  const role = roleForType(type);
172
415
  if (role !== void 0) fields.role = role;
173
416
  if (flatStyle) {
@@ -307,11 +550,17 @@ function computeVisibility(state, clip) {
307
550
  if (!rect) {
308
551
  return { visibility: "visible" };
309
552
  }
310
- if (isEmptyRect(clip)) {
311
- return { visibility: "hidden", visibilityReason: "off-screen" };
312
- }
313
- const onScreen = spansOverlap(rect.left, rect.right, clip.left, clip.right) && spansOverlap(rect.top, rect.bottom, clip.top, clip.bottom);
314
- return onScreen ? { visibility: "visible" } : { visibility: "hidden", visibilityReason: "off-screen" };
553
+ return rectReachesClip(rect, clip) ? { visibility: "visible" } : { visibility: "hidden", visibilityReason: "off-screen" };
554
+ }
555
+ function rectReachesClip(rect, clip) {
556
+ if (isEmptyRect(clip)) return false;
557
+ return spansOverlap(rect.left, rect.right, clip.left, clip.right) && spansOverlap(rect.top, rect.bottom, clip.top, clip.bottom);
558
+ }
559
+ function computeInViewport(state, clip) {
560
+ if (!state.visible || !clip) return void 0;
561
+ const rect = pageRectOf(state);
562
+ if (!rect) return void 0;
563
+ return rectReachesClip(rect, clip);
315
564
  }
316
565
  function copyRouteInfo(info) {
317
566
  const copy = { ...info };
@@ -1254,10 +1503,9 @@ var NativeUIBridgeRegistry = class {
1254
1503
  elements: elements.map((e) => {
1255
1504
  const handlers = extractHandlerNames(e.props);
1256
1505
  const state = e.getState();
1257
- const { visibility, visibilityReason } = computeVisibility(
1258
- state,
1259
- this.getClipRectFor(e, viewport)
1260
- );
1506
+ const identifier = e.getIdentifier();
1507
+ const clip = this.getClipRectFor(e, viewport);
1508
+ const { visibility, visibilityReason } = computeVisibility(state, clip);
1261
1509
  const bbox = projectBbox(state, visibility, this.pixelRatio);
1262
1510
  const vision = projectVisionFields({
1263
1511
  type: e.type,
@@ -1268,13 +1516,16 @@ var NativeUIBridgeRegistry = class {
1268
1516
  // using it would mark plain text/view nodes interactable.
1269
1517
  handlerNames: handlers,
1270
1518
  state,
1271
- flatStyle: e.flatStyle
1519
+ flatStyle: e.flatStyle,
1520
+ props: e.props,
1521
+ accessibilityLabel: identifier.accessibilityLabel,
1522
+ inViewport: computeInViewport(state, clip)
1272
1523
  });
1273
1524
  return {
1274
1525
  id: e.id,
1275
1526
  type: e.type,
1276
1527
  label: e.label,
1277
- identifier: e.getIdentifier(),
1528
+ identifier,
1278
1529
  state,
1279
1530
  actions: e.actions,
1280
1531
  customActions: serializeElementCustomActions(e.customActions),
@@ -3444,7 +3695,7 @@ var NATIVE_PAGE_HEALTH_PRODUCER_ID = "sdk-native/page-health";
3444
3695
  function defaultProducer() {
3445
3696
  return {
3446
3697
  id: NATIVE_PAGE_HEALTH_PRODUCER_ID,
3447
- version: "0.7.0"
3698
+ version: "0.8.0"
3448
3699
  };
3449
3700
  }
3450
3701
  function pageHealthUnknown(code, detail, options = {}) {
@@ -3486,14 +3737,7 @@ var LOADING_PHRASES = [
3486
3737
  "initializing",
3487
3738
  "fetching"
3488
3739
  ];
3489
- var EMPTY_PHRASES = [
3490
- "no data",
3491
- "no results",
3492
- "nothing here",
3493
- "empty",
3494
- "no items",
3495
- "get started"
3496
- ];
3740
+ var EMPTY_PHRASES = ["no data", "no results", "nothing here", "empty", "no items", "get started"];
3497
3741
  function severityRank(s) {
3498
3742
  if (s === "CRITICAL") return 3;
3499
3743
  if (s === "WARNING") return 2;
@@ -3568,20 +3812,44 @@ function observe(input, producer, evaluatedAt) {
3568
3812
  }
3569
3813
  return analyze(elements, viewport, base);
3570
3814
  }
3815
+ function nothingOnScreenDetail(elements, visibleCount, visibilityUnstated) {
3816
+ if (visibilityUnstated === 0 && visibleCount > 0) {
3817
+ return `all ${visibleCount} visible element(s) have no measured layout yet, so spatial coverage, layout regions and visual anomalies cannot be measured`;
3818
+ }
3819
+ if (visibilityUnstated > 0) {
3820
+ const geometry = visibleCount > 0 ? ` and none of the ${visibleCount} visible one(s) has a measured layout` : "";
3821
+ return `${visibilityUnstated} of ${elements.length} element(s) carry no boolean \`state.visible\`${geometry}, so no element can be placed on screen; spatial coverage, layout regions and visual anomalies cannot be measured`;
3822
+ }
3823
+ const unmounted = elements.filter((el) => el.state?.mounted === false).length;
3824
+ return `all ${elements.length} registered element(s) report visible: false (unmounted=${unmounted}, off-screen route or otherwise=${elements.length - unmounted}), so whatever is on screen is not a registered element and there is nothing on screen to measure; this says nothing about whether the screen is blank`;
3825
+ }
3571
3826
  function analyze(elements, viewport, base) {
3572
3827
  const findings = [];
3573
- const considered = elements.filter((el) => el.state.visible);
3574
- const visible = considered.flatMap((el) => {
3828
+ const onScreen = elements.filter((el) => el.state?.visible === true);
3829
+ const visibilityUnstated = elements.filter(
3830
+ (el) => typeof el.state?.visible !== "boolean"
3831
+ ).length;
3832
+ const visible = onScreen.flatMap((el) => {
3575
3833
  const rect = normalizeRect(el.state, viewport);
3576
3834
  return rect ? [{ el, rect }] : [];
3577
3835
  });
3578
- const withoutGeometry = considered.length - visible.length;
3579
- const unmeasured = withoutGeometry > 0 ? [{ dimension: "geometry", count: withoutGeometry, code: "input_missing" }] : [];
3580
- const coverage = { considered: considered.length, measured: visible.length, unmeasured };
3581
- if (considered.length > 0 && visible.length === 0) {
3836
+ const withoutGeometry = onScreen.length - visible.length;
3837
+ const unmeasured = [];
3838
+ if (withoutGeometry > 0) {
3839
+ unmeasured.push({ dimension: "geometry", count: withoutGeometry, code: "input_missing" });
3840
+ }
3841
+ if (visibilityUnstated > 0) {
3842
+ unmeasured.push({ dimension: "visibility", count: visibilityUnstated, code: "input_missing" });
3843
+ }
3844
+ const coverage = {
3845
+ considered: onScreen.length + visibilityUnstated,
3846
+ measured: visible.length,
3847
+ unmeasured
3848
+ };
3849
+ if (elements.length > 0 && visible.length === 0) {
3582
3850
  return Observation.unknown(
3583
3851
  "input_missing",
3584
- `all ${considered.length} visible element(s) have no measured layout yet, so spatial coverage, layout regions and visual anomalies cannot be measured`,
3852
+ nothingOnScreenDetail(elements, onScreen.length, visibilityUnstated),
3585
3853
  Observation.provenance({ ...base, coverage })
3586
3854
  );
3587
3855
  }
@@ -3671,7 +3939,7 @@ function analyze(elements, viewport, base) {
3671
3939
  for (const el of elements) {
3672
3940
  const elType = el.type ?? "";
3673
3941
  if (SKIP_TEXT_TYPES.has(elType)) continue;
3674
- const text = (el.state.textContent ?? "").toString();
3942
+ const text = (el.state?.textContent ?? "").toString();
3675
3943
  if (!text) continue;
3676
3944
  const textLower = text.toLowerCase();
3677
3945
  for (const p of ERROR_PHRASES) {
@@ -3712,7 +3980,7 @@ function analyze(elements, viewport, base) {
3712
3980
  for (const el of elements) {
3713
3981
  if (!INTERACTIVE_TYPES2.has(el.type)) continue;
3714
3982
  interactiveTotal++;
3715
- if (el.state.enabled === false) interactiveDisabled++;
3983
+ if (el.state?.enabled === false) interactiveDisabled++;
3716
3984
  }
3717
3985
  const interactiveSeverity = interactiveTotal > 0 && interactiveDisabled / interactiveTotal > 0.5 ? "WARNING" : "OK";
3718
3986
  findings.push({
@@ -3736,9 +4004,7 @@ function analyze(elements, viewport, base) {
3736
4004
  detail: `zero_size=${zeroSize}, outside_viewport=${outsideViewport} (horizontal-overflow only; below/above-fold scrollable content is not an anomaly)`,
3737
4005
  data: { zero_size: zeroSize, outside_viewport: outsideViewport }
3738
4006
  });
3739
- const heatmap = grid.map(
3740
- (row) => row.map((cell) => cell ? "#" : ".").join("")
3741
- );
4007
+ const heatmap = grid.map((row) => row.map((cell) => cell ? "#" : ".").join(""));
3742
4008
  return Observation.measured(
3743
4009
  {
3744
4010
  summary: worstSeverity(findings),
@@ -3998,10 +4264,9 @@ function createServerHandlers(registry, executor, config) {
3998
4264
  const elements = allElements.map((e) => {
3999
4265
  const handlers = extractHandlerNames(e.props);
4000
4266
  const state = e.getState();
4001
- const { visibility, visibilityReason } = computeVisibility(
4002
- state,
4003
- registry.getClipRectFor(e, viewport)
4004
- );
4267
+ const identifier = e.getIdentifier();
4268
+ const clip = registry.getClipRectFor(e, viewport);
4269
+ const { visibility, visibilityReason } = computeVisibility(state, clip);
4005
4270
  const bbox = projectBbox(state, visibility, registry.getPixelRatio());
4006
4271
  const vision = projectVisionFields({
4007
4272
  type: e.type,
@@ -4010,13 +4275,16 @@ function createServerHandlers(registry, executor, config) {
4010
4275
  // synthesize press/click onto every element. See projectVisionFields.
4011
4276
  handlerNames: handlers,
4012
4277
  state,
4013
- flatStyle: e.flatStyle
4278
+ flatStyle: e.flatStyle,
4279
+ props: e.props,
4280
+ accessibilityLabel: identifier.accessibilityLabel,
4281
+ inViewport: computeInViewport(state, clip)
4014
4282
  });
4015
4283
  return {
4016
4284
  id: e.id,
4017
4285
  type: e.type,
4018
4286
  label: e.label,
4019
- identifier: e.getIdentifier(),
4287
+ identifier,
4020
4288
  state,
4021
4289
  actions: e.actions,
4022
4290
  customActions: serializeElementCustomActions(e.customActions),
@@ -4724,7 +4992,7 @@ function createServerHandlers(registry, executor, config) {
4724
4992
  };
4725
4993
  if (config?.appInfo) {
4726
4994
  response.uiBridge = {
4727
- version: "0.7.0",
4995
+ version: "0.8.0",
4728
4996
  ...config.appInfo,
4729
4997
  capabilities: ["elements", "components", "actions", "design"],
4730
4998
  elementCount: stats.elements,
@@ -8222,7 +8490,9 @@ function useUIBridgeModal(opts) {
8222
8490
  }, [modalDetector, id, title, type, blocking, dismissible]);
8223
8491
  }
8224
8492
  function effectiveInfo(info, unmatched) {
8225
- return unmatched ? { ...info, pattern: null, params: void 0 } : info;
8493
+ if (!unmatched) return info;
8494
+ const { params: _dropped, ...rest } = info;
8495
+ return { ...rest, pattern: null };
8226
8496
  }
8227
8497
  function useRouteAwareness(info, options = {}) {
8228
8498
  const bridge = useUIBridgeNativeOptional();
@@ -9476,6 +9746,7 @@ exports.buildUpgradeResponse = buildUpgradeResponse;
9476
9746
  exports.captureNativeResponsiveSnapshot = captureNativeResponsiveSnapshot;
9477
9747
  exports.captureNativeStateVariations = captureNativeStateVariations;
9478
9748
  exports.computeAcceptKey = computeAcceptKey;
9749
+ exports.computeInViewport = computeInViewport;
9479
9750
  exports.computeVisibility = computeVisibility;
9480
9751
  exports.createDesignHandlers = createDesignHandlers;
9481
9752
  exports.createNativeActionExecutor = createNativeActionExecutor;
@@ -9499,6 +9770,7 @@ exports.intersectRects = intersectRects;
9499
9770
  exports.isAddrInUseError = isAddrInUseError;
9500
9771
  exports.isEmptyRect = isEmptyRect;
9501
9772
  exports.isExpoRouterUnmatched = isExpoRouterUnmatched;
9773
+ exports.isHiddenFromAccessibility = isHiddenFromAccessibility;
9502
9774
  exports.mapNativeStyleToExtended = mapNativeStyleToExtended;
9503
9775
  exports.matchesIdentifier = matchesIdentifier;
9504
9776
  exports.nativeStandardActionEffect = nativeStandardActionEffect;
@@ -9507,11 +9779,15 @@ exports.pageRectOf = pageRectOf;
9507
9779
  exports.parseColorToRgb = parseColorToRgb;
9508
9780
  exports.parseFontSizePx = parseFontSizePx;
9509
9781
  exports.parseTreePath = parseTreePath;
9782
+ exports.projectMedia = projectMedia;
9510
9783
  exports.projectVisionFields = projectVisionFields;
9511
9784
  exports.reactNavigationPattern = reactNavigationPattern;
9512
9785
  exports.resetDefaultParamValidationMode = resetDefaultParamValidationMode;
9513
9786
  exports.resetGlobalRegistry = resetGlobalRegistry;
9514
9787
  exports.resolveActionEffect = resolveActionEffect;
9788
+ exports.resolveImageLabel = resolveImageLabel;
9789
+ exports.resolveImageSource = resolveImageSource;
9790
+ exports.resolveObjectFit = resolveObjectFit;
9515
9791
  exports.roleForType = roleForType;
9516
9792
  exports.runAbortable = runAbortable;
9517
9793
  exports.setDefaultParamValidationMode = setDefaultParamValidationMode;