@qontinui/ui-bridge-native 0.6.16 → 0.7.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.
@@ -1 +1 @@
1
- {"version":3,"file":"handlers.d.ts","sourceRoot":"","sources":["../../src/server/handlers.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAaH,OAAO,EACL,KAAK,sBAAsB,EAK5B,MAAM,kBAAkB,CAAC;AAG1B,OAAO,KAAK,EAAwB,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AACnF,OAAO,KAAK,EAQV,oBAAoB,EAKrB,MAAM,SAAS,CAAC;AAEjB,OAAO,KAAK,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AA4VhF;;GAEG;AACH,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,sBAAsB,EAChC,QAAQ,EAAE,oBAAoB,EAC9B,MAAM,CAAC,EAAE;IACP,OAAO,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAClF,iFAAiF;IACjF,kBAAkB,CAAC,EAAE,kBAAkB,CAAC;IACxC,iFAAiF;IACjF,oBAAoB,CAAC,EAAE,oBAAoB,CAAC;IAC5C;;;;;;;;;OASG;IACH,gBAAgB,CAAC,EAAE,MAAM;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;CAC5D,GACA,oBAAoB,CA4/BtB"}
1
+ {"version":3,"file":"handlers.d.ts","sourceRoot":"","sources":["../../src/server/handlers.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAaH,OAAO,EACL,KAAK,sBAAsB,EAK5B,MAAM,kBAAkB,CAAC;AAG1B,OAAO,KAAK,EAAwB,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AACnF,OAAO,KAAK,EAQV,oBAAoB,EAKrB,MAAM,SAAS,CAAC;AAEjB,OAAO,KAAK,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AA4VhF;;GAEG;AACH,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,sBAAsB,EAChC,QAAQ,EAAE,oBAAoB,EAC9B,MAAM,CAAC,EAAE;IACP,OAAO,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAClF,iFAAiF;IACjF,kBAAkB,CAAC,EAAE,kBAAkB,CAAC;IACxC,iFAAiF;IACjF,oBAAoB,CAAC,EAAE,oBAAoB,CAAC;IAC5C;;;;;;;;;OASG;IACH,gBAAgB,CAAC,EAAE,MAAM;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;CAC5D,GACA,oBAAoB,CAmhCtB"}
@@ -15,4 +15,6 @@ export { WebSocketEventBridge } from './ws-event-bridge';
15
15
  export { ConsoleErrorBuffer, NetworkRequestBuffer } from './observability';
16
16
  export { bindWithRetry, isAddrInUseError } from './bind-retry';
17
17
  export type { BindWithRetryOptions } from './bind-retry';
18
+ export { diagnosePageHealth, pageHealthUnknown, NATIVE_PAGE_HEALTH_PRODUCER_ID, type PageHealthValue, type PageHealthObservation, type PageHealthInput, type PageHealthOptions, type PageHealthElement, type PageHealthFinding, type PageHealthSeverity, } from './page-health';
19
+ export { Observation, ObservationError, UNKNOWN_CODES, isUnknownCode, type UnknownCode, type ObservationStatus, type ObservationProducer, type ObservationCoverage, type UnmeasuredDimension, type ObservationCache, type ObservationProvenance, type ObservationUnknown, type MeasuredObservation, type AbsentObservation, type UnknownObservation, } from '../observation';
18
20
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,cAAc,SAAS,CAAC;AACxB,cAAc,YAAY,CAAC;AAC3B,cAAc,mBAAmB,CAAC;AAClC,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC;AAC9B,cAAc,YAAY,CAAC;AAC3B,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AACtD,YAAY,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAC;AAC/D,OAAO,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AACzD,OAAO,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAC3E,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAC/D,YAAY,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,cAAc,SAAS,CAAC;AACxB,cAAc,YAAY,CAAC;AAC3B,cAAc,mBAAmB,CAAC;AAClC,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC;AAC9B,cAAc,YAAY,CAAC;AAC3B,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AACtD,YAAY,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAC;AAC/D,OAAO,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AACzD,OAAO,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAC3E,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAC/D,YAAY,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AAIzD,OAAO,EACL,kBAAkB,EAClB,iBAAiB,EACjB,8BAA8B,EAC9B,KAAK,eAAe,EACpB,KAAK,qBAAqB,EAC1B,KAAK,eAAe,EACpB,KAAK,iBAAiB,EACtB,KAAK,iBAAiB,EACtB,KAAK,iBAAiB,EACtB,KAAK,kBAAkB,GACxB,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,WAAW,EACX,gBAAgB,EAChB,aAAa,EACb,aAAa,EACb,KAAK,WAAW,EAChB,KAAK,iBAAiB,EACtB,KAAK,mBAAmB,EACxB,KAAK,mBAAmB,EACxB,KAAK,mBAAmB,EACxB,KAAK,gBAAgB,EACrB,KAAK,qBAAqB,EAC1B,KAAK,kBAAkB,EACvB,KAAK,mBAAmB,EACxB,KAAK,iBAAiB,EACtB,KAAK,kBAAkB,GACxB,MAAM,gBAAgB,CAAC"}
@@ -1066,7 +1066,219 @@ function createDesignHandlers(registry, viewportProvider) {
1066
1066
  };
1067
1067
  }
1068
1068
 
1069
+ // src/observation/observation.ts
1070
+ var UNKNOWN_CODES = [
1071
+ "app_unreachable",
1072
+ "capability_unavailable_in_build",
1073
+ "producer_failed",
1074
+ "producer_not_run",
1075
+ "input_missing",
1076
+ "below_confidence_floor",
1077
+ "model_reply_unparseable",
1078
+ "needs_multi_frame_input",
1079
+ "stale_input"
1080
+ ];
1081
+ function isUnknownCode(value) {
1082
+ return typeof value === "string" && UNKNOWN_CODES.includes(value);
1083
+ }
1084
+ var ObservationError = class extends Error {
1085
+ constructor(message) {
1086
+ super(message);
1087
+ this.name = "ObservationError";
1088
+ }
1089
+ };
1090
+ function toRfc3339(t) {
1091
+ const d = t instanceof Date ? t : new Date(t);
1092
+ if (Number.isNaN(d.getTime())) {
1093
+ throw new ObservationError(`not a valid timestamp: ${String(t)}`);
1094
+ }
1095
+ return d.toISOString();
1096
+ }
1097
+ function normalizeConfidence(c) {
1098
+ if (c === null || c === void 0 || !Number.isFinite(c)) return null;
1099
+ return Math.min(1, Math.max(0, c));
1100
+ }
1101
+ function fullCoverage(n) {
1102
+ return { considered: n, measured: n, unmeasured: [] };
1103
+ }
1104
+ function assertCount(value, what) {
1105
+ if (typeof value !== "number" || !Number.isSafeInteger(value) || value < 0) {
1106
+ throw new ObservationError(`${what} must be a non-negative integer, got ${String(value)}`);
1107
+ }
1108
+ }
1109
+ function assertCoverage(coverage) {
1110
+ if (!coverage || typeof coverage !== "object") {
1111
+ throw new ObservationError("coverage must be an object");
1112
+ }
1113
+ assertCount(coverage.considered, "coverage.considered");
1114
+ assertCount(coverage.measured, "coverage.measured");
1115
+ if (!Array.isArray(coverage.unmeasured)) {
1116
+ throw new ObservationError("coverage.unmeasured must be an array");
1117
+ }
1118
+ coverage.unmeasured.forEach((u, i) => {
1119
+ if (!u || typeof u.dimension !== "string") {
1120
+ throw new ObservationError(`coverage.unmeasured[${i}].dimension must be a string`);
1121
+ }
1122
+ assertCount(u.count, `coverage.unmeasured[${i}].count`);
1123
+ if (!isUnknownCode(u.code)) {
1124
+ throw new ObservationError(
1125
+ `coverage.unmeasured[${i}].code is not an UnknownCode: ${String(u.code)}`
1126
+ );
1127
+ }
1128
+ });
1129
+ }
1130
+ function assertSource(source) {
1131
+ if (source === null) return;
1132
+ if (typeof source !== "object" || Array.isArray(source)) {
1133
+ throw new ObservationError("source must be a JSON object or null");
1134
+ }
1135
+ }
1136
+ var RFC3339 = /^(\d{4})-(\d{2})-(\d{2})[Tt ](\d{2}):(\d{2}):(\d{2})(\.\d+)?([Zz]|[+-](\d{2}):(\d{2}))$/;
1137
+ function isRfc3339(value) {
1138
+ if (typeof value !== "string") return false;
1139
+ const m = RFC3339.exec(value);
1140
+ if (!m) return false;
1141
+ const [y, mo, d, h, mi, s] = [m[1], m[2], m[3], m[4], m[5], m[6]].map(Number);
1142
+ if (mo < 1 || mo > 12 || d < 1 || h > 23 || mi > 59 || s > 60) return false;
1143
+ const leap = y % 4 === 0 && y % 100 !== 0 || y % 400 === 0;
1144
+ const daysInMonth = [31, leap ? 29 : 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][mo - 1];
1145
+ if (d > daysInMonth) return false;
1146
+ if (m[9] !== void 0 && (Number(m[9]) > 23 || Number(m[10]) > 59)) return false;
1147
+ return true;
1148
+ }
1149
+ function assertProvenance(prov) {
1150
+ if (!prov || typeof prov !== "object") throw new ObservationError("provenance is required");
1151
+ if (!prov.producer || typeof prov.producer.id !== "string" || typeof prov.producer.version !== "string") {
1152
+ throw new ObservationError("producer must carry a string id and version");
1153
+ }
1154
+ if (!isRfc3339(prov.evaluatedAt)) {
1155
+ throw new ObservationError(
1156
+ `evaluatedAt must be an RFC3339 date-time, got ${String(prov.evaluatedAt)}`
1157
+ );
1158
+ }
1159
+ if (prov.observedAt !== null && !isRfc3339(prov.observedAt)) {
1160
+ throw new ObservationError(
1161
+ `observedAt must be an RFC3339 date-time or null, got ${String(prov.observedAt)}`
1162
+ );
1163
+ }
1164
+ assertCoverage(prov.coverage);
1165
+ if (prov.confidence !== null && (typeof prov.confidence !== "number" || !Number.isFinite(prov.confidence) || prov.confidence < 0 || prov.confidence > 1)) {
1166
+ throw new ObservationError(
1167
+ `confidence must be in [0, 1] or null, got ${String(prov.confidence)}`
1168
+ );
1169
+ }
1170
+ if (prov.cache !== null) {
1171
+ if (typeof prov.cache !== "object" || typeof prov.cache.hit !== "boolean" || !Array.isArray(prov.cache.keyInputs) || !prov.cache.keyInputs.every((k) => typeof k === "string")) {
1172
+ throw new ObservationError(
1173
+ "cache must be { hit: boolean, storedAt, keyInputs: string[] } or null"
1174
+ );
1175
+ }
1176
+ if (prov.cache.storedAt !== null && !isRfc3339(prov.cache.storedAt)) {
1177
+ throw new ObservationError(
1178
+ `cache.storedAt must be an RFC3339 date-time or null, got ${String(prov.cache.storedAt)}`
1179
+ );
1180
+ }
1181
+ }
1182
+ assertSource(prov.source);
1183
+ }
1184
+ function provenance(init) {
1185
+ if (!init.producer || typeof init.producer.id !== "string" || typeof init.producer.version !== "string") {
1186
+ throw new ObservationError("producer must carry a string id and version");
1187
+ }
1188
+ const coverage = init.coverage ?? fullCoverage(0);
1189
+ assertCoverage(coverage);
1190
+ const source = init.source ?? null;
1191
+ assertSource(source);
1192
+ const built = {
1193
+ producer: { id: init.producer.id, version: init.producer.version },
1194
+ observedAt: init.observedAt === void 0 || init.observedAt === null ? null : toRfc3339(init.observedAt),
1195
+ evaluatedAt: toRfc3339(init.evaluatedAt ?? /* @__PURE__ */ new Date()),
1196
+ coverage: {
1197
+ considered: coverage.considered,
1198
+ measured: coverage.measured,
1199
+ unmeasured: coverage.unmeasured.map((u) => ({
1200
+ dimension: u.dimension,
1201
+ count: u.count,
1202
+ code: u.code
1203
+ }))
1204
+ },
1205
+ confidence: normalizeConfidence(init.confidence),
1206
+ cache: init.cache ? {
1207
+ hit: init.cache.hit,
1208
+ storedAt: init.cache.storedAt === null ? null : toRfc3339(init.cache.storedAt),
1209
+ keyInputs: [...init.cache.keyInputs]
1210
+ } : null,
1211
+ source
1212
+ };
1213
+ assertProvenance(built);
1214
+ return built;
1215
+ }
1216
+ function measured(value, prov) {
1217
+ if (value === void 0) {
1218
+ throw new ObservationError(
1219
+ 'measured requires a value; report "nothing there" as absent and "could not look" as unknown'
1220
+ );
1221
+ }
1222
+ assertProvenance(prov);
1223
+ return { status: "measured", value, provenance: prov };
1224
+ }
1225
+ function absent(prov) {
1226
+ assertProvenance(prov);
1227
+ const { considered, measured: measured2, unmeasured } = prov.coverage;
1228
+ if (unmeasured.length > 0) {
1229
+ const dims = unmeasured.map((u) => `${u.dimension} x${u.count} (${u.code})`).join(", ");
1230
+ throw new ObservationError(
1231
+ `cannot assert absent over unmeasured coverage: ${dims}. Report the observation as measured (degraded) or unknown instead.`
1232
+ );
1233
+ }
1234
+ if (considered === 0) {
1235
+ throw new ObservationError(
1236
+ "cannot assert absent over zero considered items: the producer looked at nothing. Report the observation as unknown instead."
1237
+ );
1238
+ }
1239
+ if (measured2 !== considered) {
1240
+ throw new ObservationError(
1241
+ `an \`absent\` observation must have measured every considered item (measured ${measured2} of ${considered}); a partial look is \`measured\` with its gaps in \`coverage.unmeasured\`, never \`absent\``
1242
+ );
1243
+ }
1244
+ return { status: "absent", provenance: prov };
1245
+ }
1246
+ function unknown(code, detail, prov) {
1247
+ if (!isUnknownCode(code)) {
1248
+ throw new ObservationError(`not an UnknownCode: ${String(code)}`);
1249
+ }
1250
+ if (typeof detail !== "string") {
1251
+ throw new ObservationError("unknown requires a string detail");
1252
+ }
1253
+ assertProvenance(prov);
1254
+ return { status: "unknown", unknown: { code, detail }, provenance: prov };
1255
+ }
1256
+ var Observation = {
1257
+ provenance,
1258
+ fullCoverage,
1259
+ measured,
1260
+ absent,
1261
+ unknown
1262
+ };
1263
+
1069
1264
  // src/server/page-health.ts
1265
+ var NATIVE_PAGE_HEALTH_PRODUCER_ID = "sdk-native/page-health";
1266
+ function defaultProducer() {
1267
+ return {
1268
+ id: NATIVE_PAGE_HEALTH_PRODUCER_ID,
1269
+ version: "0.7.0"
1270
+ };
1271
+ }
1272
+ function pageHealthUnknown(code, detail, options = {}) {
1273
+ return Observation.unknown(
1274
+ code,
1275
+ detail,
1276
+ Observation.provenance({
1277
+ producer: options.producer ?? defaultProducer(),
1278
+ evaluatedAt: options.evaluatedAt
1279
+ })
1280
+ );
1281
+ }
1070
1282
  var GRID_SIZE = 20;
1071
1283
  var NAV_TYPES = /* @__PURE__ */ new Set(["button", "heading", "badge", "status-message"]);
1072
1284
  var SKIP_TEXT_TYPES = /* @__PURE__ */ new Set(["button", "link", "tab", "menuitem"]);
@@ -1135,13 +1347,66 @@ function normalizeRect(state, viewport) {
1135
1347
  height: layout.height / viewport.height
1136
1348
  };
1137
1349
  }
1138
- function diagnosePageHealth(elements, viewport) {
1350
+ function diagnosePageHealth(input, options = {}) {
1351
+ const producer = options.producer ?? defaultProducer();
1352
+ try {
1353
+ return observe(input, producer, options.evaluatedAt);
1354
+ } catch (err) {
1355
+ return Observation.unknown(
1356
+ "producer_failed",
1357
+ `page-health producer threw: ${err instanceof Error ? err.message : String(err)}`,
1358
+ Observation.provenance({ producer })
1359
+ );
1360
+ }
1361
+ }
1362
+ function observe(input, producer, evaluatedAt) {
1363
+ const base = {
1364
+ producer,
1365
+ observedAt: input.observedAt,
1366
+ evaluatedAt
1367
+ };
1368
+ if (!Array.isArray(input.elements)) {
1369
+ return Observation.unknown(
1370
+ "input_missing",
1371
+ "the registry handed over no `elements` array, so there was nothing to analyze; this says nothing about the screen itself",
1372
+ Observation.provenance({ ...base, observedAt: null })
1373
+ );
1374
+ }
1375
+ const elements = input.elements;
1376
+ const viewport = input.viewport;
1377
+ if (!viewport || !(viewport.width > 0) || !(viewport.height > 0)) {
1378
+ return Observation.unknown(
1379
+ "input_missing",
1380
+ viewport ? `the device viewport is degenerate (${viewport.width}x${viewport.height}), so no element can be placed on screen \u2014 pass \`body.viewport\` or wire \`viewportProvider\`` : "the device viewport is unknown, so no element can be placed on screen \u2014 pass `body.viewport` or wire `viewportProvider`",
1381
+ Observation.provenance(base)
1382
+ );
1383
+ }
1384
+ if (elements.length === 0 && (input.registeredComponents ?? 0) === 0) {
1385
+ return Observation.unknown(
1386
+ "producer_not_run",
1387
+ "the registry reports zero elements and zero components \u2014 nothing has registered yet, so there was nothing to look at",
1388
+ Observation.provenance(base)
1389
+ );
1390
+ }
1391
+ return analyze(elements, viewport, base);
1392
+ }
1393
+ function analyze(elements, viewport, base) {
1139
1394
  const findings = [];
1140
- const projected = elements.map((el) => ({
1141
- el,
1142
- rect: el.state.visible ? normalizeRect(el.state, viewport) : null
1143
- }));
1144
- const visible = projected.filter((p) => p.rect !== null);
1395
+ const considered = elements.filter((el) => el.state.visible);
1396
+ const visible = considered.flatMap((el) => {
1397
+ const rect = normalizeRect(el.state, viewport);
1398
+ return rect ? [{ el, rect }] : [];
1399
+ });
1400
+ const withoutGeometry = considered.length - visible.length;
1401
+ const unmeasured = withoutGeometry > 0 ? [{ dimension: "geometry", count: withoutGeometry, code: "input_missing" }] : [];
1402
+ const coverage = { considered: considered.length, measured: visible.length, unmeasured };
1403
+ if (considered.length > 0 && visible.length === 0) {
1404
+ return Observation.unknown(
1405
+ "input_missing",
1406
+ `all ${considered.length} visible element(s) have no measured layout yet, so spatial coverage, layout regions and visual anomalies cannot be measured`,
1407
+ Observation.provenance({ ...base, coverage })
1408
+ );
1409
+ }
1145
1410
  const grid = Array.from(
1146
1411
  { length: GRID_SIZE },
1147
1412
  () => Array.from({ length: GRID_SIZE }, () => false)
@@ -1296,13 +1561,17 @@ function diagnosePageHealth(elements, viewport) {
1296
1561
  const heatmap = grid.map(
1297
1562
  (row) => row.map((cell) => cell ? "#" : ".").join("")
1298
1563
  );
1299
- return {
1300
- summary: worstSeverity(findings),
1301
- findings,
1302
- heatmap,
1303
- element_count: elements.length,
1304
- visible_count: visible.length
1305
- };
1564
+ return Observation.measured(
1565
+ {
1566
+ summary: worstSeverity(findings),
1567
+ findings,
1568
+ heatmap,
1569
+ element_count: elements.length,
1570
+ visible_count: visible.length
1571
+ },
1572
+ // A deduction over the registry, not an estimate.
1573
+ Observation.provenance({ ...base, coverage })
1574
+ );
1306
1575
  }
1307
1576
 
1308
1577
  // src/server/handlers.ts
@@ -1750,13 +2019,30 @@ function createServerHandlers(registry, executor, config) {
1750
2019
  },
1751
2020
  getPageHealth: async (ctx) => {
1752
2021
  const bodyViewport = ctx.body?.viewport;
1753
- const viewport = bodyViewport ?? config?.viewportProvider?.() ?? { width: 0, height: 0 };
1754
- const elements = registry.getAllElements().map((e) => ({
1755
- type: e.type,
1756
- state: e.getState()
1757
- }));
1758
- const report = diagnosePageHealth(elements, viewport);
1759
- return success2(report);
2022
+ let viewport;
2023
+ try {
2024
+ viewport = bodyViewport ?? config?.viewportProvider?.() ?? null;
2025
+ } catch {
2026
+ viewport = null;
2027
+ }
2028
+ const observedAt = Date.now();
2029
+ let elements;
2030
+ let registeredComponents;
2031
+ try {
2032
+ elements = registry.getAllElements().map((e) => ({
2033
+ type: e.type,
2034
+ state: e.getState()
2035
+ }));
2036
+ registeredComponents = registry.getAllComponents().length;
2037
+ } catch (err) {
2038
+ return success2(
2039
+ pageHealthUnknown(
2040
+ "producer_failed",
2041
+ `could not read the registry: ${err instanceof Error ? err.message : String(err)}`
2042
+ )
2043
+ );
2044
+ }
2045
+ return success2(diagnosePageHealth({ elements, registeredComponents, viewport, observedAt }));
1760
2046
  },
1761
2047
  // Workflows
1762
2048
  getWorkflows: async () => {
@@ -2260,7 +2546,7 @@ function createServerHandlers(registry, executor, config) {
2260
2546
  };
2261
2547
  if (config?.appInfo) {
2262
2548
  response.uiBridge = {
2263
- version: "0.6.16",
2549
+ version: "0.7.0",
2264
2550
  ...config.appInfo,
2265
2551
  capabilities: ["elements", "components", "actions", "design"],
2266
2552
  elementCount: stats.elements,
@@ -4551,6 +4837,7 @@ async function bindWithRetry(attempt, options = {}) {
4551
4837
  }
4552
4838
 
4553
4839
  exports.ConsoleErrorBuffer = ConsoleErrorBuffer;
4840
+ exports.NATIVE_PAGE_HEALTH_PRODUCER_ID = NATIVE_PAGE_HEALTH_PRODUCER_ID;
4554
4841
  exports.NativeUIBridgeServer = NativeUIBridgeServer;
4555
4842
  exports.NetworkRequestBuffer = NetworkRequestBuffer;
4556
4843
  exports.OPCODE_BINARY = OPCODE_BINARY;
@@ -4559,7 +4846,10 @@ exports.OPCODE_CONTINUATION = OPCODE_CONTINUATION;
4559
4846
  exports.OPCODE_PING = OPCODE_PING;
4560
4847
  exports.OPCODE_PONG = OPCODE_PONG;
4561
4848
  exports.OPCODE_TEXT = OPCODE_TEXT;
4849
+ exports.Observation = Observation;
4850
+ exports.ObservationError = ObservationError;
4562
4851
  exports.UI_BRIDGE_NATIVE_ROUTES = UI_BRIDGE_NATIVE_ROUTES;
4852
+ exports.UNKNOWN_CODES = UNKNOWN_CODES;
4563
4853
  exports.WebSocketConnection = WebSocketConnection;
4564
4854
  exports.WebSocketEventBridge = WebSocketEventBridge;
4565
4855
  exports.bindWithRetry = bindWithRetry;
@@ -4570,6 +4860,7 @@ exports.createNativeServer = createNativeServer;
4570
4860
  exports.createServerHandlers = createServerHandlers;
4571
4861
  exports.decodeFrames = decodeFrames;
4572
4862
  exports.decodeTextPayload = decodeTextPayload;
4863
+ exports.diagnosePageHealth = diagnosePageHealth;
4573
4864
  exports.encodeCloseFrame = encodeCloseFrame;
4574
4865
  exports.encodePingFrame = encodePingFrame;
4575
4866
  exports.encodePongFrame = encodePongFrame;
@@ -4578,6 +4869,8 @@ exports.httpStatusForResponse = httpStatusForResponse;
4578
4869
  exports.isAddrInUseError = isAddrInUseError;
4579
4870
  exports.isBatchRequest = isBatchRequest;
4580
4871
  exports.isSubscribe = isSubscribe;
4872
+ exports.isUnknownCode = isUnknownCode;
4581
4873
  exports.isUnsubscribe = isUnsubscribe;
4874
+ exports.pageHealthUnknown = pageHealthUnknown;
4582
4875
  //# sourceMappingURL=index.js.map
4583
4876
  //# sourceMappingURL=index.js.map