@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.
@@ -9,6 +9,164 @@ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require
9
9
  throw Error('Dynamic require of "' + x + '" is not supported');
10
10
  });
11
11
 
12
+ // src/core/sha256.ts
13
+ var K = new Uint32Array([
14
+ 1116352408,
15
+ 1899447441,
16
+ 3049323471,
17
+ 3921009573,
18
+ 961987163,
19
+ 1508970993,
20
+ 2453635748,
21
+ 2870763221,
22
+ 3624381080,
23
+ 310598401,
24
+ 607225278,
25
+ 1426881987,
26
+ 1925078388,
27
+ 2162078206,
28
+ 2614888103,
29
+ 3248222580,
30
+ 3835390401,
31
+ 4022224774,
32
+ 264347078,
33
+ 604807628,
34
+ 770255983,
35
+ 1249150122,
36
+ 1555081692,
37
+ 1996064986,
38
+ 2554220882,
39
+ 2821834349,
40
+ 2952996808,
41
+ 3210313671,
42
+ 3336571891,
43
+ 3584528711,
44
+ 113926993,
45
+ 338241895,
46
+ 666307205,
47
+ 773529912,
48
+ 1294757372,
49
+ 1396182291,
50
+ 1695183700,
51
+ 1986661051,
52
+ 2177026350,
53
+ 2456956037,
54
+ 2730485921,
55
+ 2820302411,
56
+ 3259730800,
57
+ 3345764771,
58
+ 3516065817,
59
+ 3600352804,
60
+ 4094571909,
61
+ 275423344,
62
+ 430227734,
63
+ 506948616,
64
+ 659060556,
65
+ 883997877,
66
+ 958139571,
67
+ 1322822218,
68
+ 1537002063,
69
+ 1747873779,
70
+ 1955562222,
71
+ 2024104815,
72
+ 2227730452,
73
+ 2361852424,
74
+ 2428436474,
75
+ 2756734187,
76
+ 3204031479,
77
+ 3329325298
78
+ ]);
79
+ var H0 = [
80
+ 1779033703,
81
+ 3144134277,
82
+ 1013904242,
83
+ 2773480762,
84
+ 1359893119,
85
+ 2600822924,
86
+ 528734635,
87
+ 1541459225
88
+ ];
89
+ function utf8Bytes(input) {
90
+ const out = [];
91
+ for (let i = 0; i < input.length; i++) {
92
+ let cp = input.charCodeAt(i);
93
+ if (cp >= 55296 && cp <= 56319) {
94
+ const next = i + 1 < input.length ? input.charCodeAt(i + 1) : 0;
95
+ if (next >= 56320 && next <= 57343) {
96
+ cp = 65536 + (cp - 55296 << 10) + (next - 56320);
97
+ i++;
98
+ } else {
99
+ cp = 65533;
100
+ }
101
+ } else if (cp >= 56320 && cp <= 57343) {
102
+ cp = 65533;
103
+ }
104
+ if (cp < 128) {
105
+ out.push(cp);
106
+ } else if (cp < 2048) {
107
+ out.push(192 | cp >> 6, 128 | cp & 63);
108
+ } else if (cp < 65536) {
109
+ out.push(224 | cp >> 12, 128 | cp >> 6 & 63, 128 | cp & 63);
110
+ } else {
111
+ out.push(
112
+ 240 | cp >> 18,
113
+ 128 | cp >> 12 & 63,
114
+ 128 | cp >> 6 & 63,
115
+ 128 | cp & 63
116
+ );
117
+ }
118
+ }
119
+ return Uint8Array.from(out);
120
+ }
121
+ var rotr = (x, n) => x >>> n | x << 32 - n;
122
+ function sha256Hex(input) {
123
+ const bytes = utf8Bytes(input);
124
+ const blockBytes = Math.ceil((bytes.length + 9) / 64) * 64;
125
+ const buffer = new Uint8Array(blockBytes);
126
+ buffer.set(bytes);
127
+ buffer[bytes.length] = 128;
128
+ const view = new DataView(buffer.buffer);
129
+ const bitLength = bytes.length * 8;
130
+ view.setUint32(blockBytes - 8, Math.floor(bitLength / 4294967296));
131
+ view.setUint32(blockBytes - 4, bitLength >>> 0);
132
+ const h = H0.slice();
133
+ const w = new Uint32Array(64);
134
+ for (let block = 0; block < blockBytes; block += 64) {
135
+ for (let t = 0; t < 16; t++) w[t] = view.getUint32(block + t * 4);
136
+ for (let t = 16; t < 64; t++) {
137
+ const s0 = rotr(w[t - 15], 7) ^ rotr(w[t - 15], 18) ^ w[t - 15] >>> 3;
138
+ const s1 = rotr(w[t - 2], 17) ^ rotr(w[t - 2], 19) ^ w[t - 2] >>> 10;
139
+ w[t] = w[t - 16] + s0 + w[t - 7] + s1;
140
+ }
141
+ let [a, b, c, d, e, f, g, hh] = h;
142
+ for (let t = 0; t < 64; t++) {
143
+ const S1 = rotr(e, 6) ^ rotr(e, 11) ^ rotr(e, 25);
144
+ const ch = e & f ^ ~e & g;
145
+ const t1 = hh + S1 + ch + K[t] + w[t] | 0;
146
+ const S0 = rotr(a, 2) ^ rotr(a, 13) ^ rotr(a, 22);
147
+ const maj = a & b ^ a & c ^ b & c;
148
+ const t2 = S0 + maj | 0;
149
+ hh = g;
150
+ g = f;
151
+ f = e;
152
+ e = d + t1 | 0;
153
+ d = c;
154
+ c = b;
155
+ b = a;
156
+ a = t1 + t2 | 0;
157
+ }
158
+ h[0] = h[0] + a | 0;
159
+ h[1] = h[1] + b | 0;
160
+ h[2] = h[2] + c | 0;
161
+ h[3] = h[3] + d | 0;
162
+ h[4] = h[4] + e | 0;
163
+ h[5] = h[5] + f | 0;
164
+ h[6] = h[6] + g | 0;
165
+ h[7] = h[7] + hh | 0;
166
+ }
167
+ return h.map((word) => (word >>> 0).toString(16).padStart(8, "0")).join("");
168
+ }
169
+
12
170
  // src/core/vision-fields.ts
13
171
  var INTERACTIVE_HANDLER_NAMES = /* @__PURE__ */ new Set([
14
172
  "onPress",
@@ -92,13 +250,18 @@ var NAMED_COLORS = {
92
250
  gray: { r: 128, g: 128, b: 128 },
93
251
  grey: { r: 128, g: 128, b: 128 },
94
252
  silver: { r: 192, g: 192, b: 192 },
95
- transparent: { r: 0, g: 0, b: 0 },
96
253
  orange: { r: 255, g: 165, b: 0 },
97
254
  yellow: { r: 255, g: 255, b: 0 },
98
255
  purple: { r: 128, g: 0, b: 128 },
99
256
  navy: { r: 0, g: 0, b: 128 }
100
257
  };
101
258
  var clamp255 = (n) => Math.max(0, Math.min(255, Math.round(n)));
259
+ function parseAlpha(p) {
260
+ const pct = p.endsWith("%");
261
+ const n = parseFloat(pct ? p.slice(0, -1) : p);
262
+ if (!Number.isFinite(n)) return void 0;
263
+ return Math.min(1, pct ? n / 100 : n);
264
+ }
102
265
  function parseColorToRgb(input) {
103
266
  if (typeof input !== "string") return void 0;
104
267
  const raw = input.trim().toLowerCase();
@@ -109,6 +272,7 @@ function parseColorToRgb(input) {
109
272
  if (raw.startsWith("#")) {
110
273
  const hex = raw.slice(1);
111
274
  if (hex.length === 3 || hex.length === 4) {
275
+ if (hex.length === 4 && hex[3] !== "f") return void 0;
112
276
  const r = parseInt(hex[0] + hex[0], 16);
113
277
  const g = parseInt(hex[1] + hex[1], 16);
114
278
  const b = parseInt(hex[2] + hex[2], 16);
@@ -116,6 +280,7 @@ function parseColorToRgb(input) {
116
280
  return void 0;
117
281
  }
118
282
  if (hex.length === 6 || hex.length === 8) {
283
+ if (hex.length === 8 && hex.slice(6, 8) !== "ff") return void 0;
119
284
  const r = parseInt(hex.slice(0, 2), 16);
120
285
  const g = parseInt(hex.slice(2, 4), 16);
121
286
  const b = parseInt(hex.slice(4, 6), 16);
@@ -127,7 +292,11 @@ function parseColorToRgb(input) {
127
292
  const rgbMatch = raw.match(/^rgba?\(([^)]+)\)$/);
128
293
  if (rgbMatch) {
129
294
  const parts = rgbMatch[1].split(",").map((p) => p.trim());
130
- if (parts.length < 3) return void 0;
295
+ if (parts.length < 3 || parts.length > 4) return void 0;
296
+ if (parts.length === 4) {
297
+ const alpha = parseAlpha(parts[3]);
298
+ if (alpha === void 0 || alpha < 1) return void 0;
299
+ }
131
300
  const channel = (p) => {
132
301
  if (p.endsWith("%")) {
133
302
  const pct = parseFloat(p.slice(0, -1));
@@ -159,13 +328,87 @@ function parseFontSizePx(input) {
159
328
  }
160
329
  return void 0;
161
330
  }
331
+ var ASCII_WHITESPACE_EDGES = /^[\t\n\f\r ]+|[\t\n\f\r ]+$/g;
332
+ function nonEmptyString(v) {
333
+ return typeof v === "string" && v.length > 0 ? v : void 0;
334
+ }
335
+ var OBJECT_FIT_TO_RESIZE_MODE = /* @__PURE__ */ new Map([
336
+ ["contain", "contain"],
337
+ ["cover", "cover"],
338
+ ["fill", "stretch"],
339
+ ["scale-down", "contain"],
340
+ ["none", "none"]
341
+ ]);
342
+ var RESIZE_MODE_TO_OBJECT_FIT = /* @__PURE__ */ new Map([
343
+ ["cover", "cover"],
344
+ ["contain", "contain"],
345
+ ["stretch", "fill"],
346
+ ["center", "scale-down"],
347
+ ["none", "none"]
348
+ ]);
349
+ function resolveObjectFit(props, flatStyle) {
350
+ const styleFit = nonEmptyString(flatStyle?.objectFit);
351
+ const mode = (styleFit !== void 0 ? OBJECT_FIT_TO_RESIZE_MODE.get(styleFit) : void 0) ?? nonEmptyString(props?.resizeMode) ?? nonEmptyString(flatStyle?.resizeMode);
352
+ return mode !== void 0 ? RESIZE_MODE_TO_OBJECT_FIT.get(mode) : void 0;
353
+ }
354
+ function resolveImageSource(props) {
355
+ if (!props) return void 0;
356
+ if (props.srcSet !== void 0 && props.srcSet !== null) return void 0;
357
+ const src = nonEmptyString(props.src);
358
+ if (src !== void 0) return src;
359
+ const source = props.source;
360
+ const one = Array.isArray(source) ? source.length === 1 ? source[0] : void 0 : source;
361
+ if (one && typeof one === "object") {
362
+ return nonEmptyString(one.uri);
363
+ }
364
+ return void 0;
365
+ }
366
+ function isHiddenFromAccessibility(props) {
367
+ if (!props) return false;
368
+ return props.accessible === false && props.alt === void 0 || props.importantForAccessibility === "no" || props.importantForAccessibility === "no-hide-descendants" || props.accessibilityElementsHidden === true;
369
+ }
370
+ function resolveImageLabel(props, registryLabel) {
371
+ if (props === void 0) return registryLabel;
372
+ const own = props["aria-label"] ?? props.accessibilityLabel ?? props.alt;
373
+ return typeof own === "string" ? own : void 0;
374
+ }
375
+ function projectMedia(args) {
376
+ const { layout, props, flatStyle, accessibilityLabel, inViewport } = args;
377
+ const media = { kind: "img" };
378
+ if (layout && Number.isFinite(layout.width) && Number.isFinite(layout.height) && layout.width >= 0 && layout.height >= 0) {
379
+ media.rendered_px = { w: layout.width, h: layout.height };
380
+ }
381
+ const objectFit = resolveObjectFit(props, flatStyle);
382
+ if (objectFit !== void 0) media.object_fit = objectFit;
383
+ if (isHiddenFromAccessibility(props)) {
384
+ media.alt = { decorative: true };
385
+ } else {
386
+ const label = resolveImageLabel(props, accessibilityLabel);
387
+ const text = label?.replace(ASCII_WHITESPACE_EDGES, "");
388
+ if (text) media.alt = { decorative: false, text };
389
+ }
390
+ const src = resolveImageSource(props);
391
+ if (src !== void 0) media.src_digest = sha256Hex(src);
392
+ if (inViewport !== void 0) media.in_viewport = inViewport;
393
+ return media;
394
+ }
162
395
  function projectVisionFields(args) {
163
396
  const { type, label, handlerNames, state, flatStyle } = args;
164
397
  const fields = {
165
398
  interactable: deriveInteractable(type, handlerNames)
166
399
  };
167
- const text = deriveText(state, label);
168
- if (text !== void 0) fields.text = text;
400
+ if (type === "image") {
401
+ fields.media = projectMedia({
402
+ layout: state.layout,
403
+ props: args.props,
404
+ flatStyle,
405
+ accessibilityLabel: args.accessibilityLabel,
406
+ inViewport: args.inViewport
407
+ });
408
+ } else {
409
+ const text = deriveText(state, label);
410
+ if (text !== void 0) fields.text = text;
411
+ }
169
412
  const role = roleForType(type);
170
413
  if (role !== void 0) fields.role = role;
171
414
  if (flatStyle) {
@@ -305,11 +548,17 @@ function computeVisibility(state, clip) {
305
548
  if (!rect) {
306
549
  return { visibility: "visible" };
307
550
  }
308
- if (isEmptyRect(clip)) {
309
- return { visibility: "hidden", visibilityReason: "off-screen" };
310
- }
311
- const onScreen = spansOverlap(rect.left, rect.right, clip.left, clip.right) && spansOverlap(rect.top, rect.bottom, clip.top, clip.bottom);
312
- return onScreen ? { visibility: "visible" } : { visibility: "hidden", visibilityReason: "off-screen" };
551
+ return rectReachesClip(rect, clip) ? { visibility: "visible" } : { visibility: "hidden", visibilityReason: "off-screen" };
552
+ }
553
+ function rectReachesClip(rect, clip) {
554
+ if (isEmptyRect(clip)) return false;
555
+ return spansOverlap(rect.left, rect.right, clip.left, clip.right) && spansOverlap(rect.top, rect.bottom, clip.top, clip.bottom);
556
+ }
557
+ function computeInViewport(state, clip) {
558
+ if (!state.visible || !clip) return void 0;
559
+ const rect = pageRectOf(state);
560
+ if (!rect) return void 0;
561
+ return rectReachesClip(rect, clip);
313
562
  }
314
563
  function copyRouteInfo(info) {
315
564
  const copy = { ...info };
@@ -1252,10 +1501,9 @@ var NativeUIBridgeRegistry = class {
1252
1501
  elements: elements.map((e) => {
1253
1502
  const handlers = extractHandlerNames(e.props);
1254
1503
  const state = e.getState();
1255
- const { visibility, visibilityReason } = computeVisibility(
1256
- state,
1257
- this.getClipRectFor(e, viewport)
1258
- );
1504
+ const identifier = e.getIdentifier();
1505
+ const clip = this.getClipRectFor(e, viewport);
1506
+ const { visibility, visibilityReason } = computeVisibility(state, clip);
1259
1507
  const bbox = projectBbox(state, visibility, this.pixelRatio);
1260
1508
  const vision = projectVisionFields({
1261
1509
  type: e.type,
@@ -1266,13 +1514,16 @@ var NativeUIBridgeRegistry = class {
1266
1514
  // using it would mark plain text/view nodes interactable.
1267
1515
  handlerNames: handlers,
1268
1516
  state,
1269
- flatStyle: e.flatStyle
1517
+ flatStyle: e.flatStyle,
1518
+ props: e.props,
1519
+ accessibilityLabel: identifier.accessibilityLabel,
1520
+ inViewport: computeInViewport(state, clip)
1270
1521
  });
1271
1522
  return {
1272
1523
  id: e.id,
1273
1524
  type: e.type,
1274
1525
  label: e.label,
1275
- identifier: e.getIdentifier(),
1526
+ identifier,
1276
1527
  state,
1277
1528
  actions: e.actions,
1278
1529
  customActions: serializeElementCustomActions(e.customActions),
@@ -3359,7 +3610,7 @@ var NATIVE_PAGE_HEALTH_PRODUCER_ID = "sdk-native/page-health";
3359
3610
  function defaultProducer() {
3360
3611
  return {
3361
3612
  id: NATIVE_PAGE_HEALTH_PRODUCER_ID,
3362
- version: "0.7.0"
3613
+ version: "0.8.0"
3363
3614
  };
3364
3615
  }
3365
3616
  function pageHealthUnknown(code, detail, options = {}) {
@@ -3401,14 +3652,7 @@ var LOADING_PHRASES = [
3401
3652
  "initializing",
3402
3653
  "fetching"
3403
3654
  ];
3404
- var EMPTY_PHRASES = [
3405
- "no data",
3406
- "no results",
3407
- "nothing here",
3408
- "empty",
3409
- "no items",
3410
- "get started"
3411
- ];
3655
+ var EMPTY_PHRASES = ["no data", "no results", "nothing here", "empty", "no items", "get started"];
3412
3656
  function severityRank(s) {
3413
3657
  if (s === "CRITICAL") return 3;
3414
3658
  if (s === "WARNING") return 2;
@@ -3483,20 +3727,44 @@ function observe(input, producer, evaluatedAt) {
3483
3727
  }
3484
3728
  return analyze(elements, viewport, base);
3485
3729
  }
3730
+ function nothingOnScreenDetail(elements, visibleCount, visibilityUnstated) {
3731
+ if (visibilityUnstated === 0 && visibleCount > 0) {
3732
+ return `all ${visibleCount} visible element(s) have no measured layout yet, so spatial coverage, layout regions and visual anomalies cannot be measured`;
3733
+ }
3734
+ if (visibilityUnstated > 0) {
3735
+ const geometry = visibleCount > 0 ? ` and none of the ${visibleCount} visible one(s) has a measured layout` : "";
3736
+ 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`;
3737
+ }
3738
+ const unmounted = elements.filter((el) => el.state?.mounted === false).length;
3739
+ 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`;
3740
+ }
3486
3741
  function analyze(elements, viewport, base) {
3487
3742
  const findings = [];
3488
- const considered = elements.filter((el) => el.state.visible);
3489
- const visible = considered.flatMap((el) => {
3743
+ const onScreen = elements.filter((el) => el.state?.visible === true);
3744
+ const visibilityUnstated = elements.filter(
3745
+ (el) => typeof el.state?.visible !== "boolean"
3746
+ ).length;
3747
+ const visible = onScreen.flatMap((el) => {
3490
3748
  const rect = normalizeRect(el.state, viewport);
3491
3749
  return rect ? [{ el, rect }] : [];
3492
3750
  });
3493
- const withoutGeometry = considered.length - visible.length;
3494
- const unmeasured = withoutGeometry > 0 ? [{ dimension: "geometry", count: withoutGeometry, code: "input_missing" }] : [];
3495
- const coverage = { considered: considered.length, measured: visible.length, unmeasured };
3496
- if (considered.length > 0 && visible.length === 0) {
3751
+ const withoutGeometry = onScreen.length - visible.length;
3752
+ const unmeasured = [];
3753
+ if (withoutGeometry > 0) {
3754
+ unmeasured.push({ dimension: "geometry", count: withoutGeometry, code: "input_missing" });
3755
+ }
3756
+ if (visibilityUnstated > 0) {
3757
+ unmeasured.push({ dimension: "visibility", count: visibilityUnstated, code: "input_missing" });
3758
+ }
3759
+ const coverage = {
3760
+ considered: onScreen.length + visibilityUnstated,
3761
+ measured: visible.length,
3762
+ unmeasured
3763
+ };
3764
+ if (elements.length > 0 && visible.length === 0) {
3497
3765
  return Observation.unknown(
3498
3766
  "input_missing",
3499
- `all ${considered.length} visible element(s) have no measured layout yet, so spatial coverage, layout regions and visual anomalies cannot be measured`,
3767
+ nothingOnScreenDetail(elements, onScreen.length, visibilityUnstated),
3500
3768
  Observation.provenance({ ...base, coverage })
3501
3769
  );
3502
3770
  }
@@ -3586,7 +3854,7 @@ function analyze(elements, viewport, base) {
3586
3854
  for (const el of elements) {
3587
3855
  const elType = el.type ?? "";
3588
3856
  if (SKIP_TEXT_TYPES.has(elType)) continue;
3589
- const text = (el.state.textContent ?? "").toString();
3857
+ const text = (el.state?.textContent ?? "").toString();
3590
3858
  if (!text) continue;
3591
3859
  const textLower = text.toLowerCase();
3592
3860
  for (const p of ERROR_PHRASES) {
@@ -3627,7 +3895,7 @@ function analyze(elements, viewport, base) {
3627
3895
  for (const el of elements) {
3628
3896
  if (!INTERACTIVE_TYPES2.has(el.type)) continue;
3629
3897
  interactiveTotal++;
3630
- if (el.state.enabled === false) interactiveDisabled++;
3898
+ if (el.state?.enabled === false) interactiveDisabled++;
3631
3899
  }
3632
3900
  const interactiveSeverity = interactiveTotal > 0 && interactiveDisabled / interactiveTotal > 0.5 ? "WARNING" : "OK";
3633
3901
  findings.push({
@@ -3651,9 +3919,7 @@ function analyze(elements, viewport, base) {
3651
3919
  detail: `zero_size=${zeroSize}, outside_viewport=${outsideViewport} (horizontal-overflow only; below/above-fold scrollable content is not an anomaly)`,
3652
3920
  data: { zero_size: zeroSize, outside_viewport: outsideViewport }
3653
3921
  });
3654
- const heatmap = grid.map(
3655
- (row) => row.map((cell) => cell ? "#" : ".").join("")
3656
- );
3922
+ const heatmap = grid.map((row) => row.map((cell) => cell ? "#" : ".").join(""));
3657
3923
  return Observation.measured(
3658
3924
  {
3659
3925
  summary: worstSeverity(findings),
@@ -3913,10 +4179,9 @@ function createServerHandlers(registry, executor, config) {
3913
4179
  const elements = allElements.map((e) => {
3914
4180
  const handlers = extractHandlerNames(e.props);
3915
4181
  const state = e.getState();
3916
- const { visibility, visibilityReason } = computeVisibility(
3917
- state,
3918
- registry.getClipRectFor(e, viewport)
3919
- );
4182
+ const identifier = e.getIdentifier();
4183
+ const clip = registry.getClipRectFor(e, viewport);
4184
+ const { visibility, visibilityReason } = computeVisibility(state, clip);
3920
4185
  const bbox = projectBbox(state, visibility, registry.getPixelRatio());
3921
4186
  const vision = projectVisionFields({
3922
4187
  type: e.type,
@@ -3925,13 +4190,16 @@ function createServerHandlers(registry, executor, config) {
3925
4190
  // synthesize press/click onto every element. See projectVisionFields.
3926
4191
  handlerNames: handlers,
3927
4192
  state,
3928
- flatStyle: e.flatStyle
4193
+ flatStyle: e.flatStyle,
4194
+ props: e.props,
4195
+ accessibilityLabel: identifier.accessibilityLabel,
4196
+ inViewport: computeInViewport(state, clip)
3929
4197
  });
3930
4198
  return {
3931
4199
  id: e.id,
3932
4200
  type: e.type,
3933
4201
  label: e.label,
3934
- identifier: e.getIdentifier(),
4202
+ identifier,
3935
4203
  state,
3936
4204
  actions: e.actions,
3937
4205
  customActions: serializeElementCustomActions(e.customActions),
@@ -4639,7 +4907,7 @@ function createServerHandlers(registry, executor, config) {
4639
4907
  };
4640
4908
  if (config?.appInfo) {
4641
4909
  response.uiBridge = {
4642
- version: "0.7.0",
4910
+ version: "0.8.0",
4643
4911
  ...config.appInfo,
4644
4912
  capabilities: ["elements", "components", "actions", "design"],
4645
4913
  elementCount: stats.elements,
@@ -8202,7 +8470,9 @@ function TransitionTo(props) {
8202
8470
  return /* @__PURE__ */ jsx(Fragment, { children: props.children });
8203
8471
  }
8204
8472
  function effectiveInfo(info, unmatched) {
8205
- return unmatched ? { ...info, pattern: null, params: void 0 } : info;
8473
+ if (!unmatched) return info;
8474
+ const { params: _dropped, ...rest } = info;
8475
+ return { ...rest, pattern: null };
8206
8476
  }
8207
8477
  function useRouteAwareness(info, options = {}) {
8208
8478
  const bridge = useUIBridgeNativeOptional();