@appilots/sdk 0.11.0 → 0.11.1
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/.build-meta.json +3 -3
- package/dist/{chunk-IZEWWAA7.js → chunk-DRXUBLGY.js} +8 -8
- package/dist/{chunk-NA5H4IHH.mjs → chunk-GSHE45YX.mjs} +263 -81
- package/dist/{chunk-55Y2AQE7.js → chunk-KZ2BLMS4.js} +3 -1
- package/dist/{chunk-3K7ORC4X.mjs → chunk-LLH7QCSX.mjs} +1 -1
- package/dist/{chunk-G6KI7KVH.mjs → chunk-PQZ64CCE.mjs} +3 -1
- package/dist/{chunk-2YPEQTL2.js → chunk-X4MPSZL3.js} +537 -355
- package/dist/hooks/index.d.mts +1 -1
- package/dist/hooks/index.d.ts +1 -1
- package/dist/hooks/index.js +11 -11
- package/dist/hooks/index.mjs +2 -2
- package/dist/{index-BPZ0j71S.d.mts → index-C01Spw6F.d.mts} +1 -1
- package/dist/{index-BPZ0j71S.d.ts → index-C01Spw6F.d.ts} +1 -1
- package/dist/index.d.mts +3 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.js +72 -72
- package/dist/index.mjs +5 -5
- package/dist/navigation/index.js +13 -13
- package/dist/navigation/index.mjs +2 -2
- package/package.json +1 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var chunkKZ2BLMS4_js = require('./chunk-KZ2BLMS4.js');
|
|
4
4
|
var React = require('react');
|
|
5
5
|
var reactNative = require('react-native');
|
|
6
6
|
|
|
@@ -23,9 +23,9 @@ function fiberSliderMatches(fiber, registryId, registryLabel) {
|
|
|
23
23
|
function reconcileSliders(snapshot) {
|
|
24
24
|
const fiberSliders = snapshot.sliders;
|
|
25
25
|
const out = [];
|
|
26
|
-
for (const { id, kind } of
|
|
26
|
+
for (const { id, kind } of chunkKZ2BLMS4_js.componentRegistry.snapshot()) {
|
|
27
27
|
if (kind !== "slider") continue;
|
|
28
|
-
const entry =
|
|
28
|
+
const entry = chunkKZ2BLMS4_js.componentRegistry.getSlider(id);
|
|
29
29
|
if (!entry) continue;
|
|
30
30
|
const fiber = fiberSliders.find((s) => fiberSliderMatches(s, id, entry.label));
|
|
31
31
|
const visible = !!fiber || typeof entry.screen === "string" && entry.screen === snapshot.route;
|
|
@@ -53,7 +53,7 @@ function normalizeFieldKey(value) {
|
|
|
53
53
|
}
|
|
54
54
|
function canonicalizeRegisteredFields(snapshot) {
|
|
55
55
|
const claimed = /* @__PURE__ */ new Set();
|
|
56
|
-
for (const { id, kind, label } of
|
|
56
|
+
for (const { id, kind, label } of chunkKZ2BLMS4_js.componentRegistry.snapshot()) {
|
|
57
57
|
if (kind !== "field") continue;
|
|
58
58
|
if (snapshot.inputs.some((input) => input.id === id)) continue;
|
|
59
59
|
const registryLabel = (label ?? "").toLowerCase();
|
|
@@ -72,7 +72,7 @@ function canonicalizeRegisteredFields(snapshot) {
|
|
|
72
72
|
}
|
|
73
73
|
}
|
|
74
74
|
function mergeRegisteredLists(snapshot) {
|
|
75
|
-
const registered =
|
|
75
|
+
const registered = chunkKZ2BLMS4_js.listRegistry.snapshot();
|
|
76
76
|
if (registered.length === 0) return;
|
|
77
77
|
const byId = /* @__PURE__ */ new Map();
|
|
78
78
|
for (const list of snapshot.lists) {
|
|
@@ -121,7 +121,7 @@ function mergeRegisteredLists(snapshot) {
|
|
|
121
121
|
}
|
|
122
122
|
}
|
|
123
123
|
function mergeRegisteredScrollables(snapshot) {
|
|
124
|
-
const registered =
|
|
124
|
+
const registered = chunkKZ2BLMS4_js.listRegistry.snapshot().filter((e) => e.kind === "scroll");
|
|
125
125
|
if (registered.length === 0) return;
|
|
126
126
|
const listsById = /* @__PURE__ */ new Map();
|
|
127
127
|
for (const list of snapshot.lists) {
|
|
@@ -154,7 +154,7 @@ function mergeRegisteredScrollables(snapshot) {
|
|
|
154
154
|
if (out.length > 0) snapshot.scrollables = out;
|
|
155
155
|
}
|
|
156
156
|
function mergeNativeDialog(snapshot) {
|
|
157
|
-
const dialog =
|
|
157
|
+
const dialog = chunkKZ2BLMS4_js.getOpenNativeDialog();
|
|
158
158
|
if (!dialog) return;
|
|
159
159
|
snapshot.nativeDialog = {
|
|
160
160
|
id: dialog.id,
|
|
@@ -169,21 +169,21 @@ function mergeNativeDialog(snapshot) {
|
|
|
169
169
|
}
|
|
170
170
|
var MIN_FIBERS_FOR_BLINDNESS = 200;
|
|
171
171
|
function recordBlindWalk() {
|
|
172
|
-
const walk =
|
|
172
|
+
const walk = chunkKZ2BLMS4_js.getLastWalkDiagnostics();
|
|
173
173
|
if (!walk) return;
|
|
174
174
|
if (walk.visitedFibers < MIN_FIBERS_FOR_BLINDNESS) return;
|
|
175
|
-
if (
|
|
176
|
-
|
|
175
|
+
if (chunkKZ2BLMS4_js.totalDetectorHits(walk.detectors) > 0) return;
|
|
176
|
+
chunkKZ2BLMS4_js.recordIntrospectionFailure("walk-recognized-nothing", null);
|
|
177
177
|
}
|
|
178
178
|
function captureSnapshot() {
|
|
179
|
-
const root =
|
|
179
|
+
const root = chunkKZ2BLMS4_js.getFiberRoot();
|
|
180
180
|
if (!root) {
|
|
181
|
-
|
|
181
|
+
chunkKZ2BLMS4_js.appilotsDebugWarn(
|
|
182
182
|
"captureSnapshot: fiber root not captured yet. Ensure <AppilotsProvider> has rendered before calling this."
|
|
183
183
|
);
|
|
184
|
-
|
|
184
|
+
chunkKZ2BLMS4_js.recordIntrospectionFailure("never-mounted", null);
|
|
185
185
|
return {
|
|
186
|
-
route:
|
|
186
|
+
route: chunkKZ2BLMS4_js.getCurrentScreen(),
|
|
187
187
|
texts: [],
|
|
188
188
|
inputs: [],
|
|
189
189
|
buttons: [],
|
|
@@ -197,9 +197,9 @@ function captureSnapshot() {
|
|
|
197
197
|
};
|
|
198
198
|
}
|
|
199
199
|
const start = Date.now();
|
|
200
|
-
const snapshot =
|
|
200
|
+
const snapshot = chunkKZ2BLMS4_js.walkFiber(root);
|
|
201
201
|
recordBlindWalk();
|
|
202
|
-
const activePath =
|
|
202
|
+
const activePath = chunkKZ2BLMS4_js.getActiveRouteNames();
|
|
203
203
|
const deepestRoute = activePath[activePath.length - 1];
|
|
204
204
|
if (deepestRoute) snapshot.route = deepestRoute;
|
|
205
205
|
mergeRegisteredLists(snapshot);
|
|
@@ -207,15 +207,15 @@ function captureSnapshot() {
|
|
|
207
207
|
mergeNativeDialog(snapshot);
|
|
208
208
|
reconcileSliders(snapshot);
|
|
209
209
|
canonicalizeRegisteredFields(snapshot);
|
|
210
|
-
|
|
211
|
-
const entries =
|
|
210
|
+
chunkKZ2BLMS4_js.clampSnapshotToWireLimits(snapshot);
|
|
211
|
+
const entries = chunkKZ2BLMS4_js.deriveInteractionElements(snapshot, { rectOf: chunkKZ2BLMS4_js.rectForNode });
|
|
212
212
|
const rectById = new Map(
|
|
213
213
|
entries.flatMap((entry) => entry.rect ? [[entry.id, entry.rect]] : [])
|
|
214
214
|
);
|
|
215
|
-
snapshot.elements = entries.map(
|
|
216
|
-
snapshot.choiceGroups =
|
|
217
|
-
|
|
218
|
-
|
|
215
|
+
snapshot.elements = entries.map(chunkKZ2BLMS4_js.toWireElement);
|
|
216
|
+
snapshot.choiceGroups = chunkKZ2BLMS4_js.attachElementIdsToChoiceGroups(snapshot.choiceGroups, snapshot.elements);
|
|
217
|
+
chunkKZ2BLMS4_js.clampSnapshotToWireLimits(snapshot);
|
|
218
|
+
chunkKZ2BLMS4_js.elementRegistry.replaceAll(
|
|
219
219
|
snapshot.elements.map((element) => {
|
|
220
220
|
const rect = rectById.get(element.id);
|
|
221
221
|
return rect ? { ...element, rect } : element;
|
|
@@ -227,10 +227,10 @@ function captureSnapshot() {
|
|
|
227
227
|
(acc, l) => acc + (typeof l.itemCount === "number" ? l.itemCount : 0),
|
|
228
228
|
0
|
|
229
229
|
);
|
|
230
|
-
|
|
230
|
+
chunkKZ2BLMS4_js.appilotsDebugLog(
|
|
231
231
|
`captureSnapshot: route="${snapshot.route}" texts=${snapshot.texts.length} inputs=${snapshot.inputs.length} buttons=${snapshot.buttons.length} toggles=${snapshot.toggles.length} sliders=${snapshot.sliders.length} loading=${snapshot.loading} modal=${snapshot.modalOpen} lists=${snapshot.lists.length}(visibleItems=${totalListItems}, dataItems=${totalListDataItems}) choices=${snapshot.choiceGroups.length} elements=${snapshot.elements.length} ` + (snapshot.truncated ? "truncated=true " : "") + `(walked ${snapshot.stats?.visitedFibers ?? 0} fibers, skipped ${snapshot.stats?.skippedHidden ?? 0} hidden, ${elapsed}ms)`
|
|
232
232
|
);
|
|
233
|
-
|
|
233
|
+
chunkKZ2BLMS4_js.appilotsDebugLog(
|
|
234
234
|
`captureSnapshot detail: lists=[${snapshot.lists.map((l) => `${l.containerType}:${l.id ?? l.label ?? "?"}(rows=${l.items.length})`).join(", ")}] inputs=[${snapshot.inputs.map((i) => i.id ?? i.label ?? "?").slice(0, 12).join(", ")}] buttons=[${snapshot.buttons.map((b) => b.id ?? b.label ?? "?").slice(0, 15).join(", ")}]`
|
|
235
235
|
);
|
|
236
236
|
return snapshot;
|
|
@@ -241,10 +241,10 @@ function registryCounts() {
|
|
|
241
241
|
toggles: 0,
|
|
242
242
|
sliders: 0,
|
|
243
243
|
targets: 0,
|
|
244
|
-
lists:
|
|
245
|
-
elements:
|
|
244
|
+
lists: chunkKZ2BLMS4_js.listRegistry.snapshot().length,
|
|
245
|
+
elements: chunkKZ2BLMS4_js.elementRegistry.size
|
|
246
246
|
};
|
|
247
|
-
for (const { kind } of
|
|
247
|
+
for (const { kind } of chunkKZ2BLMS4_js.componentRegistry.snapshot()) {
|
|
248
248
|
if (kind === "field") counts.fields++;
|
|
249
249
|
else if (kind === "toggle") counts.toggles++;
|
|
250
250
|
else if (kind === "slider") counts.sliders++;
|
|
@@ -253,29 +253,62 @@ function registryCounts() {
|
|
|
253
253
|
return counts;
|
|
254
254
|
}
|
|
255
255
|
function appilotsSelfCheck() {
|
|
256
|
-
const root =
|
|
256
|
+
const root = chunkKZ2BLMS4_js.getFiberRoot();
|
|
257
257
|
const start = Date.now();
|
|
258
|
-
if (root)
|
|
258
|
+
if (root) chunkKZ2BLMS4_js.walkFiber(root);
|
|
259
259
|
const elapsedMs = Date.now() - start;
|
|
260
|
-
const walk =
|
|
260
|
+
const walk = chunkKZ2BLMS4_js.getLastWalkDiagnostics();
|
|
261
261
|
return {
|
|
262
|
-
sdkVersion:
|
|
262
|
+
sdkVersion: chunkKZ2BLMS4_js.SDK_VERSION,
|
|
263
263
|
reactVersion: React__default.default.version ?? null,
|
|
264
|
-
route:
|
|
265
|
-
introspection:
|
|
266
|
-
autoTracking:
|
|
264
|
+
route: chunkKZ2BLMS4_js.getCurrentScreen() || null,
|
|
265
|
+
introspection: chunkKZ2BLMS4_js.getIntrospectionDiagnostics(),
|
|
266
|
+
autoTracking: chunkKZ2BLMS4_js.getAutoTrackingState(),
|
|
267
267
|
walk: {
|
|
268
268
|
visitedFibers: root ? walk?.visitedFibers ?? 0 : 0,
|
|
269
269
|
skippedHidden: root ? walk?.skippedHidden ?? 0 : 0,
|
|
270
270
|
elapsedMs
|
|
271
271
|
},
|
|
272
|
-
detectors: root ? walk?.detectors ??
|
|
272
|
+
detectors: root ? walk?.detectors ?? chunkKZ2BLMS4_js.emptyDetectorCounts() : chunkKZ2BLMS4_js.emptyDetectorCounts(),
|
|
273
273
|
registry: registryCounts(),
|
|
274
|
-
nameMangling:
|
|
275
|
-
geometry: { availability:
|
|
274
|
+
nameMangling: chunkKZ2BLMS4_js.getNameManglingProbe(),
|
|
275
|
+
geometry: { availability: chunkKZ2BLMS4_js.geometryAvailability(), ...chunkKZ2BLMS4_js.geometryStats() }
|
|
276
276
|
};
|
|
277
277
|
}
|
|
278
278
|
|
|
279
|
+
// src/introspection/switchFlip.ts
|
|
280
|
+
function declaredState(props) {
|
|
281
|
+
if (typeof props?.value === "boolean") return props.value;
|
|
282
|
+
const aria = props?.["aria-checked"];
|
|
283
|
+
if (typeof aria === "boolean") return aria;
|
|
284
|
+
const checked = props?.accessibilityState?.checked;
|
|
285
|
+
return typeof checked === "boolean" ? checked : void 0;
|
|
286
|
+
}
|
|
287
|
+
function isReactNativeSwitch(fiber) {
|
|
288
|
+
return chunkKZ2BLMS4_js.getTypeName(fiber?.type) === "Switch" || chunkKZ2BLMS4_js.getTypeName(fiber?.elementType) === "Switch";
|
|
289
|
+
}
|
|
290
|
+
var SWITCH_FLIP_HANDLERS = ["onValueChange", "onChange", "onPress"];
|
|
291
|
+
function flipSwitchFiber(fiber, next) {
|
|
292
|
+
const props = fiber?.memoizedProps ?? {};
|
|
293
|
+
const onValueChange = props.onValueChange;
|
|
294
|
+
const onChange = props.onChange;
|
|
295
|
+
const onPress = props.onPress;
|
|
296
|
+
const handler = typeof onValueChange === "function" ? { fn: onValueChange, via: "onValueChange" } : typeof onChange === "function" ? { fn: onChange, via: "onChange" } : typeof onPress === "function" ? { fn: onPress, via: "onPress" } : null;
|
|
297
|
+
if (!handler) return { ok: false, reason: "no-handler" };
|
|
298
|
+
try {
|
|
299
|
+
if (handler.via === "onPress") {
|
|
300
|
+
if (declaredState(props) === next) return { ok: true, via: "onPress", noop: true };
|
|
301
|
+
handler.fn();
|
|
302
|
+
} else if (handler.via === "onChange") {
|
|
303
|
+
if (isReactNativeSwitch(fiber)) handler.fn({ nativeEvent: { value: next }, value: next });
|
|
304
|
+
else handler.fn(next);
|
|
305
|
+
} else handler.fn(next);
|
|
306
|
+
} catch (err) {
|
|
307
|
+
return { ok: false, reason: "threw", error: err?.message ?? "switch handler threw" };
|
|
308
|
+
}
|
|
309
|
+
return { ok: true, via: handler.via };
|
|
310
|
+
}
|
|
311
|
+
|
|
279
312
|
// src/introspection/findInteractive.ts
|
|
280
313
|
function getTypeName2(type) {
|
|
281
314
|
if (!type) return null;
|
|
@@ -350,7 +383,7 @@ function shouldSkipSubtree2(fiber) {
|
|
|
350
383
|
const typeName = getTypeName2(fiber.type) ?? getTypeName2(fiber.elementType);
|
|
351
384
|
if (typeName && SELF_REFERENTIAL_COMPONENTS.has(typeName)) return true;
|
|
352
385
|
if (isAppilotsSkipMarked(props)) return true;
|
|
353
|
-
if (
|
|
386
|
+
if (chunkKZ2BLMS4_js.isModalFiber(fiber) && props.visible === false) return true;
|
|
354
387
|
if (matchesName(fiber, "Screen") && props.activityState === 0) return true;
|
|
355
388
|
const style = props.style;
|
|
356
389
|
if (style) {
|
|
@@ -360,8 +393,8 @@ function shouldSkipSubtree2(fiber) {
|
|
|
360
393
|
}
|
|
361
394
|
return false;
|
|
362
395
|
}
|
|
363
|
-
var normalize =
|
|
364
|
-
function
|
|
396
|
+
var normalize = chunkKZ2BLMS4_js.foldForCompare;
|
|
397
|
+
function scoreMatchDetail(fiber, queryNorm, queryRaw) {
|
|
365
398
|
const props = fiber.memoizedProps ?? {};
|
|
366
399
|
const candidates = [];
|
|
367
400
|
if (typeof props.testID === "string") candidates.push({ val: props.testID, weight: 100 });
|
|
@@ -384,13 +417,16 @@ function scoreMatch(fiber, queryNorm, queryRaw) {
|
|
|
384
417
|
else if (queryNorm && (vNorm.includes(queryNorm) || queryNorm.includes(vNorm)))
|
|
385
418
|
best = Math.max(best, weight - 20);
|
|
386
419
|
}
|
|
387
|
-
|
|
420
|
+
const named = best >= IDENTITY_MATCH_SCORE;
|
|
421
|
+
const disabledProp = props.disabled === true;
|
|
422
|
+
const disabledA11y = typeof props.accessibilityState === "object" && props.accessibilityState !== null && props.accessibilityState.disabled === true;
|
|
423
|
+
if (best > 0 && disabledProp) {
|
|
388
424
|
best = Math.max(1, best - 60);
|
|
389
425
|
}
|
|
390
|
-
if (best > 0 &&
|
|
426
|
+
if (best > 0 && disabledA11y) {
|
|
391
427
|
best = Math.max(1, best - 60);
|
|
392
428
|
}
|
|
393
|
-
return best;
|
|
429
|
+
return { score: best, named, disabled: disabledProp || disabledA11y };
|
|
394
430
|
}
|
|
395
431
|
function wrapTextInput(fiber) {
|
|
396
432
|
const getProps = () => fiber.memoizedProps ?? {};
|
|
@@ -427,13 +463,31 @@ function wrapSwitch(fiber) {
|
|
|
427
463
|
return {
|
|
428
464
|
kind: "toggle",
|
|
429
465
|
label: getProps().accessibilityLabel ?? getProps().testID,
|
|
430
|
-
|
|
466
|
+
// `switchValue` reads `accessibilityState.checked` when there is no
|
|
467
|
+
// `value` prop. A CUSTOM switch (a Pressable with
|
|
468
|
+
// `accessibilityRole="switch"`) has only the former, and reporting
|
|
469
|
+
// `false` for a control that is on is worse than reporting nothing:
|
|
470
|
+
// the caller inverts this to decide where to move.
|
|
471
|
+
getValue: () => chunkKZ2BLMS4_js.switchValue(getProps()),
|
|
431
472
|
setValue: (value) => {
|
|
432
|
-
const { onValueChange, onChange } = getProps();
|
|
433
473
|
const boolVal = typeof value === "boolean" ? value : value === "true" || value === true;
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
474
|
+
const flipped = flipSwitchFiber(fiber, boolVal);
|
|
475
|
+
if (flipped.ok) return;
|
|
476
|
+
if (flipped.reason === "no-handler") {
|
|
477
|
+
throw new Error(`Switch exposes none of: ${SWITCH_FLIP_HANDLERS.join(", ")}`);
|
|
478
|
+
}
|
|
479
|
+
throw new Error(flipped.error);
|
|
480
|
+
},
|
|
481
|
+
// A custom switch is a `Pressable` underneath, so it may well declare
|
|
482
|
+
// its own long press (hold to configure, hold for a shortcut menu).
|
|
483
|
+
// Classifying it as a toggle took it out of the `kind: 'target'`
|
|
484
|
+
// lookup, and without this the long press would fall through to the
|
|
485
|
+
// best remaining candidate — the card that WRAPS it.
|
|
486
|
+
longPress: () => {
|
|
487
|
+
const { onLongPress } = getProps();
|
|
488
|
+
if (typeof onLongPress !== "function") return false;
|
|
489
|
+
onLongPress();
|
|
490
|
+
return true;
|
|
437
491
|
}
|
|
438
492
|
};
|
|
439
493
|
}
|
|
@@ -455,10 +509,23 @@ function wrapTouchable(fiber, label) {
|
|
|
455
509
|
}
|
|
456
510
|
};
|
|
457
511
|
}
|
|
512
|
+
var IDENTITY_MATCH_SCORE = 100;
|
|
513
|
+
function describeCandidate(fiber, kind) {
|
|
514
|
+
const props = fiber?.memoizedProps ?? {};
|
|
515
|
+
return props.testID ?? props.accessibilityLabel ?? props.placeholder ?? (kind === "target" ? findChildText(fiber) : void 0);
|
|
516
|
+
}
|
|
517
|
+
function isDescendantOf(fiber, ancestor) {
|
|
518
|
+
if (!fiber || !ancestor) return false;
|
|
519
|
+
let node = fiber.return;
|
|
520
|
+
for (let depth = 0; node && depth < 200; depth++, node = node.return) {
|
|
521
|
+
if (node === ancestor) return true;
|
|
522
|
+
}
|
|
523
|
+
return false;
|
|
524
|
+
}
|
|
458
525
|
function findInteractiveByIdentifier(query, options = {}) {
|
|
459
|
-
const root =
|
|
526
|
+
const root = chunkKZ2BLMS4_js.getFiberRoot();
|
|
460
527
|
if (!root) {
|
|
461
|
-
|
|
528
|
+
chunkKZ2BLMS4_js.appilotsDebugWarn("findInteractiveByIdentifier: fiber root not captured yet");
|
|
462
529
|
return null;
|
|
463
530
|
}
|
|
464
531
|
const queryNorm = normalize(query);
|
|
@@ -466,6 +533,10 @@ function findInteractiveByIdentifier(query, options = {}) {
|
|
|
466
533
|
let bestScore = 0;
|
|
467
534
|
let bestHandle = null;
|
|
468
535
|
let bestId;
|
|
536
|
+
let bestFiber = null;
|
|
537
|
+
let bestNamed = false;
|
|
538
|
+
let bestDisabled = false;
|
|
539
|
+
let tied = [];
|
|
469
540
|
const visited = /* @__PURE__ */ new WeakSet();
|
|
470
541
|
const stack = [];
|
|
471
542
|
if (root.child) stack.push(root.child);
|
|
@@ -475,29 +546,55 @@ function findInteractiveByIdentifier(query, options = {}) {
|
|
|
475
546
|
visited.add(fiber);
|
|
476
547
|
if (fiber.sibling) stack.push(fiber.sibling);
|
|
477
548
|
if (shouldSkipSubtree2(fiber)) continue;
|
|
549
|
+
const props = fiber.memoizedProps ?? {};
|
|
478
550
|
let kind = null;
|
|
479
551
|
if (matchesName(fiber, "TextInput")) kind = "field";
|
|
480
|
-
else if (
|
|
552
|
+
else if (chunkKZ2BLMS4_js.isSwitchLike(fiber, props)) kind = "toggle";
|
|
481
553
|
else if (isPressableTarget(fiber)) kind = "target";
|
|
482
554
|
if (kind && (!options.kind || options.kind === kind)) {
|
|
483
|
-
const
|
|
484
|
-
|
|
555
|
+
const detail = scoreMatchDetail(fiber, queryNorm, queryRaw);
|
|
556
|
+
const score = detail.score;
|
|
557
|
+
if (score > 0) {
|
|
558
|
+
if (score > bestScore) tied = [{ fiber, kind }];
|
|
559
|
+
else if (score === bestScore) tied.push({ fiber, kind });
|
|
560
|
+
}
|
|
561
|
+
const beatsBest = score > bestScore || score > 0 && score === bestScore && isDescendantOf(fiber, bestFiber);
|
|
562
|
+
if (beatsBest) {
|
|
485
563
|
bestScore = score;
|
|
486
|
-
|
|
487
|
-
|
|
564
|
+
bestFiber = fiber;
|
|
565
|
+
bestNamed = detail.named;
|
|
566
|
+
bestDisabled = detail.disabled;
|
|
567
|
+
bestId = describeCandidate(fiber, kind);
|
|
488
568
|
if (kind === "field") bestHandle = wrapTextInput(fiber);
|
|
489
569
|
else if (kind === "toggle") bestHandle = wrapSwitch(fiber);
|
|
490
570
|
else bestHandle = wrapTouchable(fiber, findChildText(fiber));
|
|
491
571
|
}
|
|
492
572
|
}
|
|
573
|
+
if (kind === "toggle") continue;
|
|
493
574
|
if (fiber.child) stack.push(fiber.child);
|
|
494
575
|
}
|
|
576
|
+
if (bestHandle && bestScore < (options.minScore ?? 0)) {
|
|
577
|
+
chunkKZ2BLMS4_js.appilotsDebugLog(
|
|
578
|
+
`findInteractiveByIdentifier: query="${query}" \u2192 best match scored ${bestScore}, below the requested floor of ${options.minScore} \u2014 refusing it`
|
|
579
|
+
);
|
|
580
|
+
return null;
|
|
581
|
+
}
|
|
495
582
|
if (bestHandle) {
|
|
496
|
-
|
|
497
|
-
|
|
583
|
+
const independent = tied.filter(
|
|
584
|
+
(candidate) => !tied.some(
|
|
585
|
+
(other) => other.fiber !== candidate.fiber && isDescendantOf(other.fiber, candidate.fiber)
|
|
586
|
+
)
|
|
587
|
+
);
|
|
588
|
+
bestHandle.matchCount = independent.length;
|
|
589
|
+
bestHandle.named = bestNamed;
|
|
590
|
+
bestHandle.disabled = bestDisabled;
|
|
591
|
+
const candidates = independent.map(({ fiber, kind }) => describeCandidate(fiber, kind)).filter((id) => typeof id === "string" && id.length > 0).slice(0, 8);
|
|
592
|
+
if (candidates.length > 0) bestHandle.matchCandidates = candidates;
|
|
593
|
+
chunkKZ2BLMS4_js.appilotsDebugLog(
|
|
594
|
+
`findInteractiveByIdentifier: query="${query}" \u2192 kind=${bestHandle.kind} label="${bestHandle.label ?? bestId}" score=${bestScore} named=${bestNamed} disabled=${bestDisabled} tied=${independent.length}`
|
|
498
595
|
);
|
|
499
596
|
} else {
|
|
500
|
-
|
|
597
|
+
chunkKZ2BLMS4_js.appilotsDebugLog(`findInteractiveByIdentifier: query="${query}" \u2192 no match`);
|
|
501
598
|
}
|
|
502
599
|
return bestHandle;
|
|
503
600
|
}
|
|
@@ -546,7 +643,7 @@ function screenExistsAnywhere(state, screenName) {
|
|
|
546
643
|
function safeNavigate(nav, screenName, params, path) {
|
|
547
644
|
if (path && path.length > 0) {
|
|
548
645
|
const { root, nestedParams } = buildNestedParams(path, screenName, params);
|
|
549
|
-
|
|
646
|
+
chunkKZ2BLMS4_js.appilotsDebugLog(
|
|
550
647
|
`safeNavigate: using path-based navigation \u2014 root="${root}", nested=${JSON.stringify(nestedParams)}`
|
|
551
648
|
);
|
|
552
649
|
nav.navigate(root, nestedParams);
|
|
@@ -563,16 +660,16 @@ function safeNavigate(nav, screenName, params, path) {
|
|
|
563
660
|
`Screen "${screenName}" is not registered in any navigator. The screen may have been removed, may live inside a flow that is not currently mounted (e.g. Auth stack after login), or the MCP doc is stale.`
|
|
564
661
|
);
|
|
565
662
|
}
|
|
566
|
-
|
|
663
|
+
chunkKZ2BLMS4_js.appilotsDebugLog(
|
|
567
664
|
`safeNavigate: screen exists in nested navigator, attempting direct navigation to "${screenName}"`
|
|
568
665
|
);
|
|
569
666
|
nav.navigate(screenName, params);
|
|
570
667
|
}
|
|
571
668
|
function navigateHandler(payload, context) {
|
|
572
|
-
|
|
669
|
+
chunkKZ2BLMS4_js.appilotsDebugLog(
|
|
573
670
|
// Params carry record ids and, on some screens, the user's own
|
|
574
671
|
// data — the count answers "were params passed?" and nothing else.
|
|
575
|
-
`navigateHandler called: screenName="${payload.screenName}" action="${payload.navigationAction}" params=${
|
|
672
|
+
`navigateHandler called: screenName="${payload.screenName}" action="${payload.navigationAction}" params=${chunkKZ2BLMS4_js.describeValue(payload.params)}`
|
|
576
673
|
);
|
|
577
674
|
const { navigationRef, permissions } = context;
|
|
578
675
|
const nav = navigationRef.current;
|
|
@@ -665,12 +762,12 @@ function navigateHandler(payload, context) {
|
|
|
665
762
|
diagnose: { category: "unknown", screen: payload.screenName }
|
|
666
763
|
};
|
|
667
764
|
}
|
|
668
|
-
|
|
765
|
+
chunkKZ2BLMS4_js.appilotsDebugLog(
|
|
669
766
|
`navigateHandler: navigation succeeded for "${payload.screenName}" (action="${payload.navigationAction}")`
|
|
670
767
|
);
|
|
671
768
|
return { success: true };
|
|
672
769
|
} catch (err) {
|
|
673
|
-
|
|
770
|
+
chunkKZ2BLMS4_js.appilotsDebugWarn(
|
|
674
771
|
`navigateHandler: navigation failed for "${payload.screenName}": ${err?.message}`
|
|
675
772
|
);
|
|
676
773
|
const msg = String(err?.message ?? "Navigation failed");
|
|
@@ -718,18 +815,18 @@ function markedItemIndexFromFiber(fiber) {
|
|
|
718
815
|
return typeof value === "number" && Number.isFinite(value) ? value : void 0;
|
|
719
816
|
}
|
|
720
817
|
function normalize2(value) {
|
|
721
|
-
return
|
|
818
|
+
return chunkKZ2BLMS4_js.foldForCompare(String(value ?? ""));
|
|
722
819
|
}
|
|
723
820
|
function hasPressHandler2(fiber) {
|
|
724
821
|
const props = fiber?.memoizedProps ?? {};
|
|
725
822
|
return typeof props.onPress === "function" || typeof props.onPressIn === "function";
|
|
726
823
|
}
|
|
727
824
|
function isPressableFiber(fiber) {
|
|
728
|
-
const typeName =
|
|
729
|
-
return
|
|
825
|
+
const typeName = chunkKZ2BLMS4_js.getTypeName(fiber.type) ?? chunkKZ2BLMS4_js.getTypeName(fiber.elementType) ?? "";
|
|
826
|
+
return chunkKZ2BLMS4_js.TOUCHABLE_NAMES.has(typeName) || hasPressHandler2(fiber);
|
|
730
827
|
}
|
|
731
828
|
function findListContainers(options = {}) {
|
|
732
|
-
const root =
|
|
829
|
+
const root = chunkKZ2BLMS4_js.getFiberRoot();
|
|
733
830
|
if (!root) return [];
|
|
734
831
|
const containers = [];
|
|
735
832
|
const visited = /* @__PURE__ */ new WeakSet();
|
|
@@ -740,17 +837,17 @@ function findListContainers(options = {}) {
|
|
|
740
837
|
if (!fiber || visited.has(fiber)) continue;
|
|
741
838
|
visited.add(fiber);
|
|
742
839
|
if (fiber.sibling) stack.push(fiber.sibling);
|
|
743
|
-
if (
|
|
744
|
-
if (
|
|
745
|
-
const minItems =
|
|
746
|
-
const items =
|
|
840
|
+
if (chunkKZ2BLMS4_js.shouldSkipSubtree(fiber)) continue;
|
|
841
|
+
if (chunkKZ2BLMS4_js.isAlwaysListContainer(fiber) || chunkKZ2BLMS4_js.isHeuristicListContainer(fiber)) {
|
|
842
|
+
const minItems = chunkKZ2BLMS4_js.isAlwaysListContainer(fiber) || options.allowSingleHeuristic ? 1 : 2;
|
|
843
|
+
const items = chunkKZ2BLMS4_js.findListItems(fiber, minItems);
|
|
747
844
|
if (items && items.length >= minItems) {
|
|
748
845
|
containers.push({
|
|
749
846
|
container: fiber,
|
|
750
847
|
items,
|
|
751
848
|
listId: listIdFromContainer(fiber),
|
|
752
849
|
listLabel: listLabelFromContainer(fiber),
|
|
753
|
-
containerType:
|
|
850
|
+
containerType: chunkKZ2BLMS4_js.getTypeName(fiber.type) ?? chunkKZ2BLMS4_js.getTypeName(fiber.elementType) ?? "List"
|
|
754
851
|
});
|
|
755
852
|
continue;
|
|
756
853
|
}
|
|
@@ -769,7 +866,7 @@ function findFirstTouchable(item) {
|
|
|
769
866
|
const { fiber, includeSibling } = stack.pop();
|
|
770
867
|
if (!fiber || visited.has(fiber)) continue;
|
|
771
868
|
visited.add(fiber);
|
|
772
|
-
if (
|
|
869
|
+
if (chunkKZ2BLMS4_js.shouldSkipSubtree(fiber)) continue;
|
|
773
870
|
if (isPressableFiber(fiber)) {
|
|
774
871
|
const props = fiber.memoizedProps ?? {};
|
|
775
872
|
if (typeof props.onPress === "function" || typeof props.onPressIn === "function") {
|
|
@@ -796,7 +893,7 @@ function findTouchableFibers(item) {
|
|
|
796
893
|
const { fiber, includeSibling } = stack.pop();
|
|
797
894
|
if (!fiber || visited.has(fiber)) continue;
|
|
798
895
|
visited.add(fiber);
|
|
799
|
-
if (
|
|
896
|
+
if (chunkKZ2BLMS4_js.shouldSkipSubtree(fiber)) continue;
|
|
800
897
|
const props = fiber.memoizedProps ?? {};
|
|
801
898
|
if (isPressableFiber(fiber) && (typeof props.onPress === "function" || typeof props.onPressIn === "function")) {
|
|
802
899
|
found.push(fiber);
|
|
@@ -840,7 +937,7 @@ function findFirstText(fiber) {
|
|
|
840
937
|
const node = stack.pop();
|
|
841
938
|
if (!node || visited.has(node)) continue;
|
|
842
939
|
visited.add(node);
|
|
843
|
-
const typeName =
|
|
940
|
+
const typeName = chunkKZ2BLMS4_js.getTypeName(node.type) ?? chunkKZ2BLMS4_js.getTypeName(node.elementType) ?? "";
|
|
844
941
|
if (typeName === "Text") {
|
|
845
942
|
const text = textFromChildren(node.memoizedProps?.children).trim();
|
|
846
943
|
if (text) return text;
|
|
@@ -859,7 +956,7 @@ function collectTexts(fiber) {
|
|
|
859
956
|
const node = stack.pop();
|
|
860
957
|
if (!node || visited.has(node)) continue;
|
|
861
958
|
visited.add(node);
|
|
862
|
-
const typeName =
|
|
959
|
+
const typeName = chunkKZ2BLMS4_js.getTypeName(node.type) ?? chunkKZ2BLMS4_js.getTypeName(node.elementType) ?? "";
|
|
863
960
|
if (typeName === "Text") {
|
|
864
961
|
const text = textFromChildren(node.memoizedProps?.children).trim();
|
|
865
962
|
if (text) out.push(text);
|
|
@@ -871,10 +968,10 @@ function collectTexts(fiber) {
|
|
|
871
968
|
}
|
|
872
969
|
function hasUsefulTouchableIdentity(fiber) {
|
|
873
970
|
const props = fiber?.memoizedProps ?? {};
|
|
874
|
-
if (
|
|
875
|
-
if (
|
|
876
|
-
if (
|
|
877
|
-
return
|
|
971
|
+
if (chunkKZ2BLMS4_js.isReferenceable(props.testID)) return true;
|
|
972
|
+
if (chunkKZ2BLMS4_js.isReferenceable(props.accessibilityLabel)) return true;
|
|
973
|
+
if (chunkKZ2BLMS4_js.isReferenceable(props.label)) return true;
|
|
974
|
+
return chunkKZ2BLMS4_js.isReferenceable(findFirstText(fiber));
|
|
878
975
|
}
|
|
879
976
|
function describeTouchable(fiber) {
|
|
880
977
|
const props = fiber?.memoizedProps ?? {};
|
|
@@ -885,10 +982,10 @@ function describeTouchable(fiber) {
|
|
|
885
982
|
}
|
|
886
983
|
function touchableLooksDestructive(fiber) {
|
|
887
984
|
const descriptor = describeTouchable(fiber);
|
|
888
|
-
if (descriptor &&
|
|
985
|
+
if (descriptor && chunkKZ2BLMS4_js.looksDestructiveActionLabel(descriptor)) return true;
|
|
889
986
|
const props = fiber?.memoizedProps ?? {};
|
|
890
987
|
const haystack = [props.testID, props.accessibilityLabel, props.accessibilityHint, props.label].filter((value) => typeof value === "string").join(" ");
|
|
891
|
-
return
|
|
988
|
+
return chunkKZ2BLMS4_js.looksDestructiveActionLabel(haystack);
|
|
892
989
|
}
|
|
893
990
|
function describeItemCandidate(listIndex, zeroBasedIndex, item) {
|
|
894
991
|
const syntheticId = `list-${listIndex}-item-${zeroBasedIndex + 1}`;
|
|
@@ -904,11 +1001,27 @@ function pressResolvedListItem(list, itemFiber, listIndex, itemIndex) {
|
|
|
904
1001
|
const safeIdentifiableTouchables = identifiableTouchables.filter(
|
|
905
1002
|
(candidate) => !touchableLooksDestructive(candidate)
|
|
906
1003
|
);
|
|
1004
|
+
const rowSwitches = findSwitchFibers(itemFiber);
|
|
1005
|
+
if (rowSwitches.length > 0) {
|
|
1006
|
+
const switchCandidates = rowSwitches.map(
|
|
1007
|
+
(fiber, index) => describeTouchable(fiber) ?? `switch ${index + 1} of "list-${listIndex}-item-${itemIndex}" (role=toggle element)`
|
|
1008
|
+
);
|
|
1009
|
+
const pressCandidates = identifiableTouchables.map(describeTouchable).filter((d) => !!d);
|
|
1010
|
+
return {
|
|
1011
|
+
ok: false,
|
|
1012
|
+
reason: "ambiguous-touchables",
|
|
1013
|
+
refusal: "row-has-switch",
|
|
1014
|
+
error: `Item "list-${listIndex}-item-${itemIndex}" contains a switch, so pressing the row would activate the row itself and leave the switch untouched. To flip the switch, emit ui_interaction action="toggle" on the row's role=toggle element id from VISIBLE STATE` + (pressCandidates.length > 0 ? "; to activate the row instead, use a specific pressable id from the candidates." : "."),
|
|
1015
|
+
containerType: list.containerType,
|
|
1016
|
+
candidates: [...switchCandidates, ...pressCandidates].slice(0, 8)
|
|
1017
|
+
};
|
|
1018
|
+
}
|
|
907
1019
|
if (identifiableTouchables.length > 0 && safeIdentifiableTouchables.length === 0) {
|
|
908
1020
|
const candidates = identifiableTouchables.map(describeTouchable).filter((d) => !!d).slice(0, 8);
|
|
909
1021
|
return {
|
|
910
1022
|
ok: false,
|
|
911
1023
|
reason: "ambiguous-touchables",
|
|
1024
|
+
refusal: "destructive-only",
|
|
912
1025
|
error: `Item "list-${listIndex}-item-${itemIndex}" only exposes destructive controls. Use the specific button id from the row (for example the cancel button id) instead of pressing the list ordinal.`,
|
|
913
1026
|
containerType: list.containerType,
|
|
914
1027
|
candidates
|
|
@@ -921,7 +1034,7 @@ function pressResolvedListItem(list, itemFiber, listIndex, itemIndex) {
|
|
|
921
1034
|
(candidate) => candidate !== touchable && containsFiber(touchable, candidate)
|
|
922
1035
|
);
|
|
923
1036
|
if (primaryWrapsNestedTargets) {
|
|
924
|
-
|
|
1037
|
+
chunkKZ2BLMS4_js.appilotsDebugLog(
|
|
925
1038
|
`listItemDispatch: item "list-${listIndex}-item-${itemIndex}" has nested pressables; pressing outer row target`
|
|
926
1039
|
);
|
|
927
1040
|
} else {
|
|
@@ -956,14 +1069,14 @@ function pressResolvedListItem(list, itemFiber, listIndex, itemIndex) {
|
|
|
956
1069
|
}
|
|
957
1070
|
return {
|
|
958
1071
|
ok: true,
|
|
959
|
-
containerType:
|
|
1072
|
+
containerType: chunkKZ2BLMS4_js.getTypeName(container.type) ?? chunkKZ2BLMS4_js.getTypeName(container.elementType) ?? list.containerType
|
|
960
1073
|
};
|
|
961
1074
|
} catch (err) {
|
|
962
1075
|
return {
|
|
963
1076
|
ok: false,
|
|
964
1077
|
reason: "press-threw",
|
|
965
1078
|
error: err?.message ?? "press handler threw",
|
|
966
|
-
containerType:
|
|
1079
|
+
containerType: chunkKZ2BLMS4_js.getTypeName(container.type) ?? chunkKZ2BLMS4_js.getTypeName(container.elementType) ?? list.containerType
|
|
967
1080
|
};
|
|
968
1081
|
}
|
|
969
1082
|
}
|
|
@@ -1019,7 +1132,7 @@ function candidateLists(containers, locator) {
|
|
|
1019
1132
|
return containers.map((list, listIndex) => ({ list, listIndex }));
|
|
1020
1133
|
}
|
|
1021
1134
|
function pressListItemAtOrdinal(listIndex, itemIndex) {
|
|
1022
|
-
if (!
|
|
1135
|
+
if (!chunkKZ2BLMS4_js.getFiberRoot()) return { ok: false, reason: "no-fiber-root" };
|
|
1023
1136
|
const containers = findListContainers({ allowSingleHeuristic: true });
|
|
1024
1137
|
if (listIndex < 0 || listIndex >= containers.length) {
|
|
1025
1138
|
return { ok: false, reason: "list-not-found" };
|
|
@@ -1033,7 +1146,7 @@ function pressListItemAtOrdinal(listIndex, itemIndex) {
|
|
|
1033
1146
|
return pressResolvedListItem(list, items[zeroBased], listIndex, itemIndex);
|
|
1034
1147
|
}
|
|
1035
1148
|
function resolveListItemByIdentity(locator) {
|
|
1036
|
-
if (!
|
|
1149
|
+
if (!chunkKZ2BLMS4_js.getFiberRoot()) return { ok: false, result: { ok: false, reason: "no-fiber-root" } };
|
|
1037
1150
|
const parsed = locator.syntheticId ? parseSyntheticListItemId(locator.syntheticId) : null;
|
|
1038
1151
|
const effective = parsed ? { ...locator, listIndex: parsed.listIndex, itemIndex: parsed.itemIndex } : locator;
|
|
1039
1152
|
const containers = findListContainers({ allowSingleHeuristic: true });
|
|
@@ -1094,9 +1207,9 @@ function findSwitchFibers(item) {
|
|
|
1094
1207
|
const { fiber, includeSibling } = stack.pop();
|
|
1095
1208
|
if (!fiber || visited.has(fiber)) continue;
|
|
1096
1209
|
visited.add(fiber);
|
|
1097
|
-
if (
|
|
1210
|
+
if (chunkKZ2BLMS4_js.shouldSkipSubtree(fiber)) continue;
|
|
1098
1211
|
const props = fiber.memoizedProps ?? {};
|
|
1099
|
-
if (
|
|
1212
|
+
if (chunkKZ2BLMS4_js.isSwitchLike(fiber, props)) {
|
|
1100
1213
|
if (props.__appilotsInternal !== true) found.push(fiber);
|
|
1101
1214
|
if (includeSibling && fiber.sibling) {
|
|
1102
1215
|
stack.push({ fiber: fiber.sibling, includeSibling: true });
|
|
@@ -1130,26 +1243,24 @@ function toggleListItemByIdentity(locator, options) {
|
|
|
1130
1243
|
}
|
|
1131
1244
|
const target = switches[0];
|
|
1132
1245
|
const props = target?.memoizedProps ?? {};
|
|
1133
|
-
const current =
|
|
1246
|
+
const current = chunkKZ2BLMS4_js.switchValue(props);
|
|
1134
1247
|
if (options?.expected !== void 0 && current === options.expected) {
|
|
1135
|
-
return { ok: true, containerType: list.containerType, value: current };
|
|
1136
|
-
}
|
|
1137
|
-
const onValueChange = props.onValueChange ?? props.onChange;
|
|
1138
|
-
if (typeof onValueChange !== "function") {
|
|
1139
|
-
return {
|
|
1140
|
-
ok: false,
|
|
1141
|
-
reason: "no-touchable",
|
|
1142
|
-
error: "The row has a switch but it exposes no onValueChange handler.",
|
|
1143
|
-
containerType: list.containerType
|
|
1144
|
-
};
|
|
1248
|
+
return { ok: true, containerType: list.containerType, value: current, noop: true };
|
|
1145
1249
|
}
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1250
|
+
const flipped = flipSwitchFiber(target, !current);
|
|
1251
|
+
if (!flipped.ok) {
|
|
1252
|
+
if (flipped.reason === "no-handler") {
|
|
1253
|
+
return {
|
|
1254
|
+
ok: false,
|
|
1255
|
+
reason: "no-touchable",
|
|
1256
|
+
error: `The row has a switch but it exposes no handler that could flip it (looked for ${SWITCH_FLIP_HANDLERS.join(", ")}).`,
|
|
1257
|
+
containerType: list.containerType
|
|
1258
|
+
};
|
|
1259
|
+
}
|
|
1149
1260
|
return {
|
|
1150
1261
|
ok: false,
|
|
1151
1262
|
reason: "press-threw",
|
|
1152
|
-
error:
|
|
1263
|
+
error: flipped.error,
|
|
1153
1264
|
containerType: list.containerType
|
|
1154
1265
|
};
|
|
1155
1266
|
}
|
|
@@ -1171,12 +1282,15 @@ function screenDiagnose(targetId, category = "component-not-found") {
|
|
|
1171
1282
|
return {
|
|
1172
1283
|
category,
|
|
1173
1284
|
targetId,
|
|
1174
|
-
screen:
|
|
1285
|
+
screen: chunkKZ2BLMS4_js.getCurrentScreen() ?? void 0
|
|
1175
1286
|
};
|
|
1176
1287
|
}
|
|
1177
1288
|
function isPressLike(action) {
|
|
1178
1289
|
return action === "press" || action === "tap" || action === "click" || action === "longPress";
|
|
1179
1290
|
}
|
|
1291
|
+
function isPlainPress(action) {
|
|
1292
|
+
return action === "press" || action === "tap" || action === "click";
|
|
1293
|
+
}
|
|
1180
1294
|
function isElementIdentifier(value) {
|
|
1181
1295
|
return value.trim().toLowerCase().startsWith("el:");
|
|
1182
1296
|
}
|
|
@@ -1188,10 +1302,10 @@ function elementLookupKey(value) {
|
|
|
1188
1302
|
return canonicalElementId(value).toLowerCase().replace(/[\s_]+/g, "-");
|
|
1189
1303
|
}
|
|
1190
1304
|
function findRegisteredElement(elementId) {
|
|
1191
|
-
const direct =
|
|
1305
|
+
const direct = chunkKZ2BLMS4_js.elementRegistry.get(elementId) ?? chunkKZ2BLMS4_js.elementRegistry.get(canonicalElementId(elementId));
|
|
1192
1306
|
if (direct) return direct;
|
|
1193
1307
|
const wanted = elementLookupKey(elementId);
|
|
1194
|
-
return
|
|
1308
|
+
return chunkKZ2BLMS4_js.elementRegistry.snapshot().find((element) => elementLookupKey(element.id) === wanted);
|
|
1195
1309
|
}
|
|
1196
1310
|
function resolveInteractionElement(elementId) {
|
|
1197
1311
|
return getLatestElement(elementId);
|
|
@@ -1287,6 +1401,54 @@ function dispatchRegisteredTarget(targetId, registry, action) {
|
|
|
1287
1401
|
diagnose: screenDiagnose(targetId)
|
|
1288
1402
|
};
|
|
1289
1403
|
}
|
|
1404
|
+
function dispatchIdentifiedToggle(targetId, action) {
|
|
1405
|
+
if (!isPressLike(action)) return null;
|
|
1406
|
+
const winner = findInteractiveByIdentifier(targetId, { minScore: IDENTITY_MATCH_SCORE });
|
|
1407
|
+
if (winner) {
|
|
1408
|
+
if (winner.kind !== "toggle" || !winner.setValue) return null;
|
|
1409
|
+
if ((winner.matchCount ?? 1) > 1) {
|
|
1410
|
+
return {
|
|
1411
|
+
success: false,
|
|
1412
|
+
error: `"${targetId}" names ${winner.matchCount} controls on this screen \u2014 aim at one of the candidates instead`,
|
|
1413
|
+
diagnose: {
|
|
1414
|
+
...screenDiagnose(targetId, "ambiguous-target"),
|
|
1415
|
+
recoverable: true,
|
|
1416
|
+
...winner.matchCandidates && winner.matchCandidates.length > 0 ? { candidates: winner.matchCandidates } : {}
|
|
1417
|
+
}
|
|
1418
|
+
};
|
|
1419
|
+
}
|
|
1420
|
+
if (!isPlainPress(action)) {
|
|
1421
|
+
if (winner.longPress?.()) return { success: true };
|
|
1422
|
+
return {
|
|
1423
|
+
success: false,
|
|
1424
|
+
error: `"${targetId}" names a switch and it declares no long-press handler. Use action="toggle" to flip it.`,
|
|
1425
|
+
diagnose: { ...screenDiagnose(targetId, "unknown"), recoverable: true }
|
|
1426
|
+
};
|
|
1427
|
+
}
|
|
1428
|
+
chunkKZ2BLMS4_js.appilotsDebugLog(
|
|
1429
|
+
`elementDispatch: "${action}" on "${targetId}" names a switch \u2014 flipping it instead of pressing, so the verb cannot land on an ancestor`
|
|
1430
|
+
);
|
|
1431
|
+
try {
|
|
1432
|
+
winner.setValue(!winner.getValue?.());
|
|
1433
|
+
return { success: true, effect: "changed" };
|
|
1434
|
+
} catch (err) {
|
|
1435
|
+
return {
|
|
1436
|
+
success: false,
|
|
1437
|
+
error: err?.message ?? `Could not flip the switch named "${targetId}"`,
|
|
1438
|
+
diagnose: screenDiagnose(targetId, "unknown")
|
|
1439
|
+
};
|
|
1440
|
+
}
|
|
1441
|
+
}
|
|
1442
|
+
const disabledToggle = findInteractiveByIdentifier(targetId, { kind: "toggle" });
|
|
1443
|
+
if (disabledToggle?.named && disabledToggle.disabled) {
|
|
1444
|
+
return {
|
|
1445
|
+
success: false,
|
|
1446
|
+
error: `The switch named "${targetId}" is currently disabled`,
|
|
1447
|
+
diagnose: screenDiagnose(targetId, "disabled")
|
|
1448
|
+
};
|
|
1449
|
+
}
|
|
1450
|
+
return null;
|
|
1451
|
+
}
|
|
1290
1452
|
function dispatchFiberTarget(targetId, action) {
|
|
1291
1453
|
const kind = action === "toggle" ? "toggle" : action === "focus" ? "field" : "target";
|
|
1292
1454
|
const handle = findInteractiveByIdentifier(targetId, { kind });
|
|
@@ -1336,6 +1498,8 @@ function dispatchLegacyTarget(targetId, registry, action) {
|
|
|
1336
1498
|
}
|
|
1337
1499
|
const registered = dispatchRegisteredTarget(targetId, registry, action);
|
|
1338
1500
|
if (registered.success) return registered;
|
|
1501
|
+
const named = dispatchIdentifiedToggle(targetId, action);
|
|
1502
|
+
if (named) return named;
|
|
1339
1503
|
const fiber = dispatchFiberTarget(targetId, action);
|
|
1340
1504
|
if (fiber.success) return fiber;
|
|
1341
1505
|
return {
|
|
@@ -1352,6 +1516,9 @@ function dispatchElement(element, registry, action) {
|
|
|
1352
1516
|
diagnose: screenDiagnose(element.id, "disabled")
|
|
1353
1517
|
};
|
|
1354
1518
|
}
|
|
1519
|
+
if (element.role === "toggle" && (action === "toggle" || isPressLike(action))) {
|
|
1520
|
+
return dispatchToggleElement(element, registry);
|
|
1521
|
+
}
|
|
1355
1522
|
if (element.listContext && isPressLike(action)) {
|
|
1356
1523
|
const pressed = pressListItemByIdentity({
|
|
1357
1524
|
...element.listContext,
|
|
@@ -1360,6 +1527,18 @@ function dispatchElement(element, registry, action) {
|
|
|
1360
1527
|
texts: element.texts
|
|
1361
1528
|
});
|
|
1362
1529
|
if (pressed.ok) return { success: true };
|
|
1530
|
+
if (pressed.refusal) {
|
|
1531
|
+
return {
|
|
1532
|
+
success: false,
|
|
1533
|
+
error: pressed.error ?? `Could not press element "${element.id}" (${pressed.reason})`,
|
|
1534
|
+
diagnose: {
|
|
1535
|
+
...screenDiagnose(element.id),
|
|
1536
|
+
category: "ambiguous-target",
|
|
1537
|
+
recoverable: true,
|
|
1538
|
+
...pressed.candidates && pressed.candidates.length > 0 ? { candidates: pressed.candidates } : {}
|
|
1539
|
+
}
|
|
1540
|
+
};
|
|
1541
|
+
}
|
|
1363
1542
|
if (element.targetId && element.targetId !== element.id) {
|
|
1364
1543
|
const fallback = dispatchLegacyTarget(element.targetId, registry, action);
|
|
1365
1544
|
if (fallback.success) return fallback;
|
|
@@ -1391,50 +1570,6 @@ function dispatchElement(element, registry, action) {
|
|
|
1391
1570
|
diagnose: { ...screenDiagnose(element.id, "unknown"), recoverable: true }
|
|
1392
1571
|
};
|
|
1393
1572
|
}
|
|
1394
|
-
if (element.role === "toggle" && (action === "toggle" || isPressLike(action))) {
|
|
1395
|
-
if (element.listContext) {
|
|
1396
|
-
const toggled = toggleListItemByIdentity(
|
|
1397
|
-
{
|
|
1398
|
-
listIndex: element.listContext.listIndex,
|
|
1399
|
-
listId: element.listContext.listId,
|
|
1400
|
-
listLabel: element.listContext.listLabel,
|
|
1401
|
-
itemIndex: element.listContext.itemIndex,
|
|
1402
|
-
itemKey: element.listContext.itemKey,
|
|
1403
|
-
reactKey: element.listContext.reactKey,
|
|
1404
|
-
syntheticId: element.listContext.syntheticId,
|
|
1405
|
-
label: element.label,
|
|
1406
|
-
texts: element.texts
|
|
1407
|
-
},
|
|
1408
|
-
// The observation's `selected` is the state BEFORE this action.
|
|
1409
|
-
// Passing the desired end state makes the flip idempotent: a
|
|
1410
|
-
// retry or a recovery hop must not undo the work and call it
|
|
1411
|
-
// success. A toggle only knows how to invert, so without this the
|
|
1412
|
-
// second attempt silently returns the row to where it started.
|
|
1413
|
-
typeof element.selected === "boolean" ? { expected: !element.selected } : void 0
|
|
1414
|
-
);
|
|
1415
|
-
if (toggled.ok) {
|
|
1416
|
-
return {
|
|
1417
|
-
success: true,
|
|
1418
|
-
// Grounded: read back off the fiber after the handler ran, not
|
|
1419
|
-
// inferred from "the call did not throw".
|
|
1420
|
-
effect: "changed"
|
|
1421
|
-
};
|
|
1422
|
-
}
|
|
1423
|
-
return {
|
|
1424
|
-
success: false,
|
|
1425
|
-
error: toggled.error ?? `Could not flip the switch in row "${element.label ?? element.id}" (${toggled.reason})`,
|
|
1426
|
-
diagnose: {
|
|
1427
|
-
...screenDiagnose(
|
|
1428
|
-
element.id,
|
|
1429
|
-
toggled.reason === "ambiguous-touchables" || toggled.reason === "ambiguous-items" ? "ambiguous-target" : "component-not-found"
|
|
1430
|
-
),
|
|
1431
|
-
...toggled.candidates && toggled.candidates.length > 0 ? { candidates: toggled.candidates } : {}
|
|
1432
|
-
}
|
|
1433
|
-
};
|
|
1434
|
-
}
|
|
1435
|
-
const targetId = element.targetId ?? element.label ?? element.id;
|
|
1436
|
-
return dispatchLegacyTarget(targetId, registry, "toggle");
|
|
1437
|
-
}
|
|
1438
1573
|
if (element.role === "input" && (action === "focus" || isPressLike(action))) {
|
|
1439
1574
|
const targetId = element.targetId ?? element.label ?? element.id;
|
|
1440
1575
|
return dispatchLegacyTarget(targetId, registry, "focus");
|
|
@@ -1449,9 +1584,57 @@ function dispatchElement(element, registry, action) {
|
|
|
1449
1584
|
diagnose: screenDiagnose(element.id, "unknown")
|
|
1450
1585
|
};
|
|
1451
1586
|
}
|
|
1587
|
+
function dispatchToggleElement(element, registry) {
|
|
1588
|
+
if (element.listContext) {
|
|
1589
|
+
const toggled = toggleListItemByIdentity(
|
|
1590
|
+
{
|
|
1591
|
+
listIndex: element.listContext.listIndex,
|
|
1592
|
+
listId: element.listContext.listId,
|
|
1593
|
+
listLabel: element.listContext.listLabel,
|
|
1594
|
+
itemIndex: element.listContext.itemIndex,
|
|
1595
|
+
itemKey: element.listContext.itemKey,
|
|
1596
|
+
reactKey: element.listContext.reactKey,
|
|
1597
|
+
syntheticId: element.listContext.syntheticId,
|
|
1598
|
+
label: element.label,
|
|
1599
|
+
texts: element.texts
|
|
1600
|
+
},
|
|
1601
|
+
// The observation's `selected` is the state BEFORE this action.
|
|
1602
|
+
// Passing the desired end state makes the flip idempotent: a
|
|
1603
|
+
// retry or a recovery hop must not undo the work and call it
|
|
1604
|
+
// success. A toggle only knows how to invert, so without this the
|
|
1605
|
+
// second attempt silently returns the row to where it started.
|
|
1606
|
+
typeof element.selected === "boolean" ? { expected: !element.selected } : void 0
|
|
1607
|
+
);
|
|
1608
|
+
if (toggled.ok) {
|
|
1609
|
+
return {
|
|
1610
|
+
success: true,
|
|
1611
|
+
// Honest split (#504): a real flip is 'changed'; the idempotent
|
|
1612
|
+
// no-op — the switch already held the requested state, nothing
|
|
1613
|
+
// was touched — is 'completed' (goal state verified), NEVER
|
|
1614
|
+
// 'changed' (nothing changed this hop) and NEVER 'none' (which
|
|
1615
|
+
// would send recovery re-flipping a switch that is already
|
|
1616
|
+
// right).
|
|
1617
|
+
effect: toggled.noop ? "completed" : "changed"
|
|
1618
|
+
};
|
|
1619
|
+
}
|
|
1620
|
+
return {
|
|
1621
|
+
success: false,
|
|
1622
|
+
error: toggled.error ?? `Could not flip the switch in row "${element.label ?? element.id}" (${toggled.reason})`,
|
|
1623
|
+
diagnose: {
|
|
1624
|
+
...screenDiagnose(
|
|
1625
|
+
element.id,
|
|
1626
|
+
toggled.reason === "ambiguous-touchables" || toggled.reason === "ambiguous-items" ? "ambiguous-target" : "component-not-found"
|
|
1627
|
+
),
|
|
1628
|
+
...toggled.candidates && toggled.candidates.length > 0 ? { candidates: toggled.candidates } : {}
|
|
1629
|
+
}
|
|
1630
|
+
};
|
|
1631
|
+
}
|
|
1632
|
+
const targetId = element.targetId ?? element.label ?? element.id;
|
|
1633
|
+
return dispatchLegacyTarget(targetId, registry, "toggle");
|
|
1634
|
+
}
|
|
1452
1635
|
function dispatchStructuredElementId(identifier, action) {
|
|
1453
1636
|
if (!isElementIdentifier(identifier) || !isPressLike(action)) return null;
|
|
1454
|
-
const parsed =
|
|
1637
|
+
const parsed = chunkKZ2BLMS4_js.parseStableElementId(identifier);
|
|
1455
1638
|
if (!parsed || parsed.role !== "option") return null;
|
|
1456
1639
|
if (!parsed.itemKey && !parsed.listId) return null;
|
|
1457
1640
|
const pressed = pressListItemByIdentity({
|
|
@@ -1461,7 +1644,7 @@ function dispatchStructuredElementId(identifier, action) {
|
|
|
1461
1644
|
texts: parsed.itemKey ? [parsed.itemKey] : void 0
|
|
1462
1645
|
});
|
|
1463
1646
|
if (pressed.ok) {
|
|
1464
|
-
|
|
1647
|
+
chunkKZ2BLMS4_js.appilotsDebugLog(
|
|
1465
1648
|
`elementDispatch: resolved stale el id "${identifier}" via structural identity (listId="${parsed.listId}", itemKey="${parsed.itemKey}")`
|
|
1466
1649
|
);
|
|
1467
1650
|
return { success: true };
|
|
@@ -1475,6 +1658,8 @@ function dispatchElementOrTarget(identifier, registry, action = "press") {
|
|
|
1475
1658
|
if (result.success) return result;
|
|
1476
1659
|
if (result.diagnose?.category === "disabled") return result;
|
|
1477
1660
|
if (element.role === "slider") return result;
|
|
1661
|
+
if (element.role === "toggle") return result;
|
|
1662
|
+
if (result.diagnose?.category === "ambiguous-target") return result;
|
|
1478
1663
|
}
|
|
1479
1664
|
const structured = dispatchStructuredElementId(identifier, action);
|
|
1480
1665
|
if (structured?.success) return structured;
|
|
@@ -1490,20 +1675,20 @@ function normalize4(value) {
|
|
|
1490
1675
|
return value.toLowerCase().normalize("NFD").replace(/[\u0300-\u036f]/g, "").replace(/[^a-z0-9]/g, "");
|
|
1491
1676
|
}
|
|
1492
1677
|
function resolveScreenForFormFields() {
|
|
1493
|
-
const activePath =
|
|
1678
|
+
const activePath = chunkKZ2BLMS4_js.getActiveRouteNames();
|
|
1494
1679
|
for (let i = activePath.length - 1; i >= 0; i--) {
|
|
1495
1680
|
const name = activePath[i];
|
|
1496
|
-
const meta = name ?
|
|
1681
|
+
const meta = name ? chunkKZ2BLMS4_js.getScreenMetadata(name) : void 0;
|
|
1497
1682
|
if (name && Array.isArray(meta?.fields) && meta.fields.length > 0) return name;
|
|
1498
1683
|
}
|
|
1499
|
-
return
|
|
1684
|
+
return chunkKZ2BLMS4_js.getCurrentScreen();
|
|
1500
1685
|
}
|
|
1501
1686
|
function collectKnownFormFields(registry) {
|
|
1502
1687
|
const registryFields = registry.snapshot().filter((entry) => entry.kind === "field" || entry.kind === "slider").map((entry) => ({ id: entry.id, label: entry.label }));
|
|
1503
1688
|
if (registryFields.length >= 2) return registryFields;
|
|
1504
1689
|
const screen = resolveScreenForFormFields();
|
|
1505
1690
|
if (screen) {
|
|
1506
|
-
const metaFields =
|
|
1691
|
+
const metaFields = chunkKZ2BLMS4_js.getScreenMetadata(screen)?.fields;
|
|
1507
1692
|
if (Array.isArray(metaFields) && metaFields.length > 0) {
|
|
1508
1693
|
return metaFields.filter((field) => !!field && typeof field.id === "string").map((field) => ({
|
|
1509
1694
|
id: field.id,
|
|
@@ -1513,7 +1698,7 @@ function collectKnownFormFields(registry) {
|
|
|
1513
1698
|
}));
|
|
1514
1699
|
}
|
|
1515
1700
|
}
|
|
1516
|
-
for (const meta of
|
|
1701
|
+
for (const meta of chunkKZ2BLMS4_js.getAllScreens()) {
|
|
1517
1702
|
if (Array.isArray(meta.fields) && meta.fields.length > 0) {
|
|
1518
1703
|
return meta.fields.filter((field) => !!field && typeof field.id === "string").map((field) => ({
|
|
1519
1704
|
id: field.id,
|
|
@@ -1626,7 +1811,7 @@ function rewriteMisplacedFormFillFields(fields, registry) {
|
|
|
1626
1811
|
const inferred = inferFieldIdForValue(String(field.value ?? ""), knownFields, used);
|
|
1627
1812
|
if (!inferred) return field;
|
|
1628
1813
|
used.add(inferred);
|
|
1629
|
-
|
|
1814
|
+
chunkKZ2BLMS4_js.appilotsDebugWarn(
|
|
1630
1815
|
`formFieldRewrite: ${field.fieldId} \u2192 ${inferred} (value=${JSON.stringify(field.value)})`
|
|
1631
1816
|
);
|
|
1632
1817
|
return { ...field, fieldId: inferred };
|
|
@@ -1634,8 +1819,8 @@ function rewriteMisplacedFormFillFields(fields, registry) {
|
|
|
1634
1819
|
}
|
|
1635
1820
|
|
|
1636
1821
|
// src/executor/formValidation.ts
|
|
1637
|
-
var FORM_VALIDATION_TEXT_RE2 =
|
|
1638
|
-
var FORM_SUCCESS_TEXT_RE =
|
|
1822
|
+
var FORM_VALIDATION_TEXT_RE2 = chunkKZ2BLMS4_js.FORM_VALIDATION_TEXT_RE;
|
|
1823
|
+
var FORM_SUCCESS_TEXT_RE = chunkKZ2BLMS4_js.FORM_WRITE_SUCCESS_TEXT_RE;
|
|
1639
1824
|
var sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
1640
1825
|
function inferValidationFieldId(message, inputs) {
|
|
1641
1826
|
const haystack = normalizeText(message);
|
|
@@ -1672,7 +1857,7 @@ function readVisibleFormSuccess(snap) {
|
|
|
1672
1857
|
return (snap.texts ?? []).find((text) => text?.trim() && FORM_SUCCESS_TEXT_RE.test(text));
|
|
1673
1858
|
}
|
|
1674
1859
|
function submitAsyncStillPending(submitTargetId) {
|
|
1675
|
-
const probe =
|
|
1860
|
+
const probe = chunkKZ2BLMS4_js.probeLoadingState(submitTargetId ?? null, chunkKZ2BLMS4_js.getCurrentScreen());
|
|
1676
1861
|
if (probe.loading) return true;
|
|
1677
1862
|
if (submitTargetId && probe.pressedFound && probe.pressedDisabled) return true;
|
|
1678
1863
|
return false;
|
|
@@ -1684,7 +1869,7 @@ function evaluatePostSubmitSnapshot(snap, activePath) {
|
|
|
1684
1869
|
}
|
|
1685
1870
|
const successText = readVisibleFormSuccess(snap);
|
|
1686
1871
|
if (successText) return { status: "success", message: successText };
|
|
1687
|
-
if (!
|
|
1872
|
+
if (!chunkKZ2BLMS4_js.snapshotShowsOpenCreateForm(snap, activePath)) {
|
|
1688
1873
|
return { status: "success" };
|
|
1689
1874
|
}
|
|
1690
1875
|
return void 0;
|
|
@@ -1700,7 +1885,7 @@ async function waitForPostSubmitOutcome(options) {
|
|
|
1700
1885
|
continue;
|
|
1701
1886
|
}
|
|
1702
1887
|
const snap2 = captureSnapshot();
|
|
1703
|
-
const activePath2 =
|
|
1888
|
+
const activePath2 = chunkKZ2BLMS4_js.getActiveRouteNames();
|
|
1704
1889
|
const outcome2 = evaluatePostSubmitSnapshot(snap2, activePath2);
|
|
1705
1890
|
if (outcome2) return outcome2;
|
|
1706
1891
|
await sleep(pollMs);
|
|
@@ -1712,7 +1897,7 @@ async function waitForPostSubmitOutcome(options) {
|
|
|
1712
1897
|
};
|
|
1713
1898
|
}
|
|
1714
1899
|
const snap = captureSnapshot();
|
|
1715
|
-
const activePath =
|
|
1900
|
+
const activePath = chunkKZ2BLMS4_js.getActiveRouteNames();
|
|
1716
1901
|
const outcome = evaluatePostSubmitSnapshot(snap, activePath);
|
|
1717
1902
|
if (outcome) return outcome;
|
|
1718
1903
|
return {
|
|
@@ -1818,16 +2003,16 @@ function findSnapshotButton(targetId) {
|
|
|
1818
2003
|
}
|
|
1819
2004
|
}
|
|
1820
2005
|
function buildUiDiagnose(targetId, cause) {
|
|
1821
|
-
const activePath =
|
|
1822
|
-
const screen = activePath[activePath.length - 1] ??
|
|
2006
|
+
const activePath = chunkKZ2BLMS4_js.getActiveRouteNames();
|
|
2007
|
+
const screen = activePath[activePath.length - 1] ?? chunkKZ2BLMS4_js.getCurrentScreen() ?? void 0;
|
|
1823
2008
|
const screenPath = activePath.length > 1 ? activePath.join("/") : screen;
|
|
1824
2009
|
const diagnose = {
|
|
1825
2010
|
category: cause === "not-found" ? "component-not-found" : cause === "disabled" ? "disabled" : "unknown",
|
|
1826
2011
|
targetId,
|
|
1827
2012
|
screen: screenPath
|
|
1828
2013
|
};
|
|
1829
|
-
if (
|
|
1830
|
-
diagnose.visibleMessage =
|
|
2014
|
+
if (chunkKZ2BLMS4_js.isOptionalStepAutomationFailure(targetId, screenPath, activePath)) {
|
|
2015
|
+
diagnose.visibleMessage = chunkKZ2BLMS4_js.OPTIONAL_STEP_AUTOMATION_HINT;
|
|
1831
2016
|
diagnose.recoverable = true;
|
|
1832
2017
|
}
|
|
1833
2018
|
return diagnose;
|
|
@@ -1885,15 +2070,15 @@ function resolveComponentId(componentId, registry, action) {
|
|
|
1885
2070
|
const snapshot = registry.snapshot();
|
|
1886
2071
|
for (const comp of snapshot) {
|
|
1887
2072
|
if (comp.id.toLowerCase() === lower) {
|
|
1888
|
-
|
|
2073
|
+
chunkKZ2BLMS4_js.appilotsDebugLog(
|
|
1889
2074
|
`resolveComponentId: case-insensitive match "${componentId}" \u2192 "${comp.id}"`
|
|
1890
2075
|
);
|
|
1891
2076
|
return comp.id;
|
|
1892
2077
|
}
|
|
1893
2078
|
}
|
|
1894
|
-
const currentScreen =
|
|
2079
|
+
const currentScreen = chunkKZ2BLMS4_js.getCurrentScreen();
|
|
1895
2080
|
if (currentScreen) {
|
|
1896
|
-
const screenMeta =
|
|
2081
|
+
const screenMeta = chunkKZ2BLMS4_js.getScreenMetadata(currentScreen);
|
|
1897
2082
|
const actions = screenMeta?.actions;
|
|
1898
2083
|
if (actions && Array.isArray(actions)) {
|
|
1899
2084
|
const metaAction = actions.find(
|
|
@@ -1902,14 +2087,14 @@ function resolveComponentId(componentId, registry, action) {
|
|
|
1902
2087
|
if (metaAction && typeof metaAction === "object" && metaAction.label) {
|
|
1903
2088
|
const metaLabel = metaAction.label;
|
|
1904
2089
|
const normalizedMetaLabel = metaLabel.toLowerCase().normalize("NFD").replace(/[\u0300-\u036f]/g, "").replace(/[^a-z0-9]/g, "");
|
|
1905
|
-
|
|
2090
|
+
chunkKZ2BLMS4_js.appilotsDebugLog(
|
|
1906
2091
|
`resolveComponentId: found screen metadata for "${componentId}" \u2192 label="${metaLabel}"`
|
|
1907
2092
|
);
|
|
1908
2093
|
for (const comp of snapshot) {
|
|
1909
2094
|
if (!comp.label) continue;
|
|
1910
2095
|
const compLabel = comp.label.toLowerCase().normalize("NFD").replace(/[\u0300-\u036f]/g, "").replace(/[^a-z0-9]/g, "");
|
|
1911
2096
|
if (compLabel === normalizedMetaLabel || compLabel.includes(normalizedMetaLabel) || normalizedMetaLabel.includes(compLabel)) {
|
|
1912
|
-
|
|
2097
|
+
chunkKZ2BLMS4_js.appilotsDebugLog(
|
|
1913
2098
|
`resolveComponentId: FOUND via metadata: "${componentId}" \u2192 "${comp.id}" (label="${comp.label}")`
|
|
1914
2099
|
);
|
|
1915
2100
|
return comp.id;
|
|
@@ -1926,7 +2111,7 @@ function resolveComponentId(componentId, registry, action) {
|
|
|
1926
2111
|
}));
|
|
1927
2112
|
const match = resolveTarget(componentId, candidates, { action });
|
|
1928
2113
|
if (match.status === "matched") {
|
|
1929
|
-
|
|
2114
|
+
chunkKZ2BLMS4_js.appilotsDebugLog(
|
|
1930
2115
|
`resolveComponentId: matched "${componentId}" -> "${match.id}" (tier=${match.tier})`
|
|
1931
2116
|
);
|
|
1932
2117
|
return match.id;
|
|
@@ -2016,7 +2201,7 @@ function setValueHandler(rawComponentId, requested, registry) {
|
|
|
2016
2201
|
try {
|
|
2017
2202
|
slider.setValue(applied);
|
|
2018
2203
|
if (applied !== requestedValue) {
|
|
2019
|
-
|
|
2204
|
+
chunkKZ2BLMS4_js.appilotsDebugLog(
|
|
2020
2205
|
`uiInteractionHandler: set_value snapped ${requestedValue} \u2192 ${applied} for "${componentId}" (step=${step})`
|
|
2021
2206
|
);
|
|
2022
2207
|
}
|
|
@@ -2051,7 +2236,7 @@ function checkModalOcclusion(rawComponentId, action) {
|
|
|
2051
2236
|
return null;
|
|
2052
2237
|
}
|
|
2053
2238
|
if (typeof rawComponentId !== "string" || rawComponentId.trim().length === 0) return null;
|
|
2054
|
-
const dialog =
|
|
2239
|
+
const dialog = chunkKZ2BLMS4_js.getOpenNativeDialog();
|
|
2055
2240
|
if (dialog) {
|
|
2056
2241
|
const needle = normalizeIdent(rawComponentId);
|
|
2057
2242
|
if (dialog.buttons.some((b) => normalizeIdent(b.label) === needle)) return null;
|
|
@@ -2061,16 +2246,16 @@ function checkModalOcclusion(rawComponentId, action) {
|
|
|
2061
2246
|
diagnose: {
|
|
2062
2247
|
category: "ambiguous-target",
|
|
2063
2248
|
targetId: rawComponentId,
|
|
2064
|
-
screen:
|
|
2249
|
+
screen: chunkKZ2BLMS4_js.getCurrentScreen() ?? void 0,
|
|
2065
2250
|
candidates: dialog.buttons.map((b) => b.label).slice(0, 8)
|
|
2066
2251
|
}
|
|
2067
2252
|
};
|
|
2068
2253
|
}
|
|
2069
|
-
const fiberRoot =
|
|
2254
|
+
const fiberRoot = chunkKZ2BLMS4_js.getFiberRoot();
|
|
2070
2255
|
if (!fiberRoot) return null;
|
|
2071
2256
|
let snap;
|
|
2072
2257
|
try {
|
|
2073
|
-
snap =
|
|
2258
|
+
snap = chunkKZ2BLMS4_js.walkFiber(fiberRoot);
|
|
2074
2259
|
} catch {
|
|
2075
2260
|
return null;
|
|
2076
2261
|
}
|
|
@@ -2132,7 +2317,7 @@ function checkModalOcclusion(rawComponentId, action) {
|
|
|
2132
2317
|
}
|
|
2133
2318
|
function uiInteractionHandler(payload, context) {
|
|
2134
2319
|
const { permissions } = context;
|
|
2135
|
-
const registry = context.registry ??
|
|
2320
|
+
const registry = context.registry ?? chunkKZ2BLMS4_js.componentRegistry;
|
|
2136
2321
|
if (!permissions.canInteractUI) {
|
|
2137
2322
|
return {
|
|
2138
2323
|
success: false,
|
|
@@ -2154,7 +2339,7 @@ function uiInteractionHandler(payload, context) {
|
|
|
2154
2339
|
if (sliderId) {
|
|
2155
2340
|
const smuggled = payload.value ?? payload.params?.value;
|
|
2156
2341
|
if (smuggled !== void 0) {
|
|
2157
|
-
|
|
2342
|
+
chunkKZ2BLMS4_js.appilotsDebugLog(
|
|
2158
2343
|
`uiInteractionHandler: "${actionStr}" on slider "${sliderId}" carried value=${JSON.stringify(smuggled)} \u2014 routing to set_value`
|
|
2159
2344
|
);
|
|
2160
2345
|
return setValueHandler(rawComponentId, smuggled, registry);
|
|
@@ -2165,23 +2350,23 @@ function uiInteractionHandler(payload, context) {
|
|
|
2165
2350
|
diagnose: { ...buildUiDiagnose(sliderId, "unknown"), recoverable: true }
|
|
2166
2351
|
};
|
|
2167
2352
|
}
|
|
2168
|
-
const openDialog =
|
|
2353
|
+
const openDialog = chunkKZ2BLMS4_js.getOpenNativeDialog();
|
|
2169
2354
|
const isPressVerb = actionStr === "press" || actionStr === "tap" || actionStr === "click";
|
|
2170
2355
|
if (openDialog && isPressVerb) {
|
|
2171
2356
|
const needle = normalizeIdent(rawComponentId);
|
|
2172
2357
|
const button = openDialog.buttons.find((b) => normalizeIdent(b.label) === needle);
|
|
2173
2358
|
if (button) {
|
|
2174
2359
|
button.press();
|
|
2175
|
-
|
|
2360
|
+
chunkKZ2BLMS4_js.appilotsDebugLog(`uiInteractionHandler: pressed native dialog button "${button.label}"`);
|
|
2176
2361
|
return { success: true, effect: "changed" };
|
|
2177
2362
|
}
|
|
2178
2363
|
}
|
|
2179
2364
|
if (!openDialog && isPressVerb) {
|
|
2180
|
-
const answered =
|
|
2365
|
+
const answered = chunkKZ2BLMS4_js.getLastAnsweredNativeDialog();
|
|
2181
2366
|
const needle = normalizeIdent(rawComponentId);
|
|
2182
2367
|
if (answered && needle) {
|
|
2183
2368
|
if (answered.answeredWith && normalizeIdent(answered.answeredWith) === needle) {
|
|
2184
|
-
|
|
2369
|
+
chunkKZ2BLMS4_js.appilotsDebugLog(
|
|
2185
2370
|
`uiInteractionHandler: native dialog button "${answered.answeredWith}" was already pressed and the dialog is closed \u2014 treating the repeat as done`
|
|
2186
2371
|
);
|
|
2187
2372
|
return { success: true, effect: "completed" };
|
|
@@ -2193,7 +2378,7 @@ function uiInteractionHandler(payload, context) {
|
|
|
2193
2378
|
diagnose: {
|
|
2194
2379
|
category: "component-not-found",
|
|
2195
2380
|
targetId: rawComponentId,
|
|
2196
|
-
screen:
|
|
2381
|
+
screen: chunkKZ2BLMS4_js.getCurrentScreen() ?? void 0,
|
|
2197
2382
|
recoverable: false
|
|
2198
2383
|
}
|
|
2199
2384
|
};
|
|
@@ -2202,7 +2387,7 @@ function uiInteractionHandler(payload, context) {
|
|
|
2202
2387
|
}
|
|
2203
2388
|
const occluded = checkModalOcclusion(rawComponentId, actionStr);
|
|
2204
2389
|
if (occluded) {
|
|
2205
|
-
|
|
2390
|
+
chunkKZ2BLMS4_js.appilotsDebugLog(
|
|
2206
2391
|
`uiInteractionHandler: blocked "${actionStr}" on "${rawComponentId}" \u2014 target is behind an open modal`
|
|
2207
2392
|
);
|
|
2208
2393
|
return occluded;
|
|
@@ -2210,26 +2395,25 @@ function uiInteractionHandler(payload, context) {
|
|
|
2210
2395
|
if (typeof rawComponentId === "string" && rawComponentId.trim().toLowerCase().startsWith("el:")) {
|
|
2211
2396
|
const result = dispatchElementOrTarget(rawComponentId, registry, actionStr);
|
|
2212
2397
|
if (result.success) {
|
|
2213
|
-
|
|
2398
|
+
chunkKZ2BLMS4_js.appilotsDebugLog(
|
|
2214
2399
|
`uiInteractionHandler: interaction element dispatch succeeded for "${rawComponentId}"`
|
|
2215
2400
|
);
|
|
2216
|
-
return { success: true };
|
|
2217
2401
|
}
|
|
2218
2402
|
return result;
|
|
2219
2403
|
}
|
|
2220
2404
|
const ordinal = parseSyntheticListItemId(rawComponentId);
|
|
2221
2405
|
if (ordinal && (action === "press" || actionStr === "tap" || actionStr === "click" || actionStr === "longPress")) {
|
|
2222
|
-
|
|
2406
|
+
chunkKZ2BLMS4_js.appilotsDebugLog(
|
|
2223
2407
|
`uiInteractionHandler: dispatching synthetic list ordinal \u2014 componentId="${rawComponentId}" list=${ordinal.listIndex} item=${ordinal.itemIndex}`
|
|
2224
2408
|
);
|
|
2225
2409
|
const result = pressListItemAtOrdinal(ordinal.listIndex, ordinal.itemIndex);
|
|
2226
2410
|
if (result.ok) {
|
|
2227
|
-
|
|
2411
|
+
chunkKZ2BLMS4_js.appilotsDebugLog(
|
|
2228
2412
|
`uiInteractionHandler: synthetic ordinal press succeeded (container=${result.containerType ?? "List"})`
|
|
2229
2413
|
);
|
|
2230
2414
|
return { success: true };
|
|
2231
2415
|
}
|
|
2232
|
-
const screen =
|
|
2416
|
+
const screen = chunkKZ2BLMS4_js.getCurrentScreen() ?? void 0;
|
|
2233
2417
|
if (result.reason === "list-not-found" || result.reason === "item-not-found") {
|
|
2234
2418
|
return {
|
|
2235
2419
|
success: false,
|
|
@@ -2245,12 +2429,12 @@ function uiInteractionHandler(payload, context) {
|
|
|
2245
2429
|
};
|
|
2246
2430
|
}
|
|
2247
2431
|
if (result.reason === "ambiguous-touchables") {
|
|
2248
|
-
const
|
|
2432
|
+
const namesConcreteChoice = result.refusal !== void 0 || /only exposes destructive controls|contains a switch/i.test(result.error ?? "");
|
|
2249
2433
|
return {
|
|
2250
2434
|
success: false,
|
|
2251
2435
|
error: result.error ?? `Synthetic list ordinal press failed (${result.reason ?? "unknown"})`,
|
|
2252
2436
|
diagnose: {
|
|
2253
|
-
category:
|
|
2437
|
+
category: namesConcreteChoice ? "ambiguous-target" : "unknown",
|
|
2254
2438
|
targetId: rawComponentId,
|
|
2255
2439
|
screen,
|
|
2256
2440
|
recoverable: true,
|
|
@@ -2270,7 +2454,7 @@ function uiInteractionHandler(payload, context) {
|
|
|
2270
2454
|
};
|
|
2271
2455
|
}
|
|
2272
2456
|
const componentId = resolveComponentId(rawComponentId, registry, actionStr);
|
|
2273
|
-
|
|
2457
|
+
chunkKZ2BLMS4_js.appilotsDebugLog(
|
|
2274
2458
|
`uiInteractionHandler: resolved componentId="${payload.componentId}" \u2192 "${componentId}"`
|
|
2275
2459
|
);
|
|
2276
2460
|
const target = registry.getTarget(componentId);
|
|
@@ -2323,9 +2507,11 @@ function uiInteractionHandler(payload, context) {
|
|
|
2323
2507
|
return { success: false, error: err?.message ?? "Focus failed" };
|
|
2324
2508
|
}
|
|
2325
2509
|
}
|
|
2326
|
-
|
|
2510
|
+
chunkKZ2BLMS4_js.appilotsDebugLog(
|
|
2327
2511
|
`uiInteractionHandler: registry miss for "${componentId}", falling back to fiber tree`
|
|
2328
2512
|
);
|
|
2513
|
+
const namedToggle = dispatchIdentifiedToggle(componentId, actionStr);
|
|
2514
|
+
if (namedToggle) return namedToggle;
|
|
2329
2515
|
const handle = findInteractiveByIdentifier(componentId, {
|
|
2330
2516
|
kind: actionStr === "toggle" ? "toggle" : actionStr === "focus" ? "field" : "target"
|
|
2331
2517
|
});
|
|
@@ -2333,15 +2519,11 @@ function uiInteractionHandler(payload, context) {
|
|
|
2333
2519
|
try {
|
|
2334
2520
|
if (actionStr === "press" && handle.kind === "target" && handle.press) {
|
|
2335
2521
|
handle.press();
|
|
2336
|
-
|
|
2522
|
+
chunkKZ2BLMS4_js.appilotsDebugLog(
|
|
2337
2523
|
`uiInteractionHandler: fiber fallback press succeeded for "${componentId}"`
|
|
2338
2524
|
);
|
|
2339
2525
|
return { success: true };
|
|
2340
2526
|
}
|
|
2341
|
-
if (actionStr === "press" && handle.kind === "toggle" && handle.setValue) {
|
|
2342
|
-
handle.setValue(!handle.getValue?.());
|
|
2343
|
-
return { success: true };
|
|
2344
|
-
}
|
|
2345
2527
|
if (actionStr === "toggle" && handle.kind === "toggle" && handle.setValue) {
|
|
2346
2528
|
handle.setValue(!handle.getValue?.());
|
|
2347
2529
|
return { success: true };
|
|
@@ -2400,7 +2582,7 @@ function submitLabelHintsSubmit(label) {
|
|
|
2400
2582
|
return SUBMIT_LABEL_HINT_RE.test(trimmed);
|
|
2401
2583
|
}
|
|
2402
2584
|
function screenDeclaresSubmitAction(screenName) {
|
|
2403
|
-
const meta =
|
|
2585
|
+
const meta = chunkKZ2BLMS4_js.getScreenMetadata(screenName);
|
|
2404
2586
|
return Array.isArray(meta?.actions) && meta.actions.some(
|
|
2405
2587
|
(action) => typeof action === "object" && action !== null && action.type === "submit"
|
|
2406
2588
|
);
|
|
@@ -2433,7 +2615,7 @@ function resolveFormScreensForSubmit(screen, activePath, registry) {
|
|
|
2433
2615
|
} else {
|
|
2434
2616
|
push(screen);
|
|
2435
2617
|
}
|
|
2436
|
-
push(
|
|
2618
|
+
push(chunkKZ2BLMS4_js.getCurrentScreen() ?? void 0);
|
|
2437
2619
|
const withSubmit = [];
|
|
2438
2620
|
const rest = [];
|
|
2439
2621
|
for (const name of ordered) {
|
|
@@ -2451,7 +2633,7 @@ function collectSubmitTargetCandidates(screens, registry) {
|
|
|
2451
2633
|
candidates.push(id);
|
|
2452
2634
|
};
|
|
2453
2635
|
for (const screenName of screens) {
|
|
2454
|
-
const meta =
|
|
2636
|
+
const meta = chunkKZ2BLMS4_js.getScreenMetadata(screenName);
|
|
2455
2637
|
const submitMeta = Array.isArray(meta?.actions) ? meta.actions.find(
|
|
2456
2638
|
(action) => typeof action === "object" && action !== null && action.type === "submit"
|
|
2457
2639
|
) : void 0;
|
|
@@ -2495,8 +2677,8 @@ function readVisibleValidation(fieldId, label) {
|
|
|
2495
2677
|
return void 0;
|
|
2496
2678
|
}
|
|
2497
2679
|
function resolveScreenContext() {
|
|
2498
|
-
const activePath =
|
|
2499
|
-
const screen = activePath[activePath.length - 1] ??
|
|
2680
|
+
const activePath = chunkKZ2BLMS4_js.getActiveRouteNames();
|
|
2681
|
+
const screen = activePath[activePath.length - 1] ?? chunkKZ2BLMS4_js.getCurrentScreen() ?? void 0;
|
|
2500
2682
|
return { screen, activePath };
|
|
2501
2683
|
}
|
|
2502
2684
|
function selectValueApplied(fieldId, requestedValue, currentValue, registry) {
|
|
@@ -2504,36 +2686,36 @@ function selectValueApplied(fieldId, requestedValue, currentValue, registry) {
|
|
|
2504
2686
|
if (!requested) return false;
|
|
2505
2687
|
const meta = getMetadataField(fieldId, registry);
|
|
2506
2688
|
const options = Array.isArray(meta?.options) ? meta.options : [];
|
|
2507
|
-
const requestedNorm =
|
|
2508
|
-
const currentNorm =
|
|
2689
|
+
const requestedNorm = chunkKZ2BLMS4_js.normalize3(requested);
|
|
2690
|
+
const currentNorm = chunkKZ2BLMS4_js.normalize3(currentValue);
|
|
2509
2691
|
if (currentNorm === requestedNorm) return true;
|
|
2510
2692
|
for (const option of options) {
|
|
2511
2693
|
const value = typeof option?.value === "string" ? option.value : "";
|
|
2512
2694
|
const label = typeof option?.label === "string" ? option.label : "";
|
|
2513
|
-
if (
|
|
2514
|
-
if (
|
|
2515
|
-
if (
|
|
2695
|
+
if (chunkKZ2BLMS4_js.normalize3(value) === requestedNorm && chunkKZ2BLMS4_js.normalize3(label) === currentNorm) return true;
|
|
2696
|
+
if (chunkKZ2BLMS4_js.normalize3(label) === requestedNorm && chunkKZ2BLMS4_js.normalize3(label) === currentNorm) return true;
|
|
2697
|
+
if (chunkKZ2BLMS4_js.normalize3(value) === requestedNorm && chunkKZ2BLMS4_js.normalize3(value) === currentNorm) return true;
|
|
2516
2698
|
}
|
|
2517
2699
|
return false;
|
|
2518
2700
|
}
|
|
2519
2701
|
function getMetadataField(fieldId, registry) {
|
|
2520
2702
|
const screens = /* @__PURE__ */ new Set();
|
|
2521
|
-
for (const name of
|
|
2522
|
-
const current =
|
|
2703
|
+
for (const name of chunkKZ2BLMS4_js.getActiveRouteNames()) screens.add(name);
|
|
2704
|
+
const current = chunkKZ2BLMS4_js.getCurrentScreen();
|
|
2523
2705
|
if (current) screens.add(current);
|
|
2524
2706
|
if (registry) {
|
|
2525
2707
|
for (const comp of registry.snapshot()) {
|
|
2526
2708
|
if (comp.kind === "field" && comp.screen) screens.add(comp.screen);
|
|
2527
2709
|
}
|
|
2528
2710
|
}
|
|
2529
|
-
const needle =
|
|
2711
|
+
const needle = chunkKZ2BLMS4_js.normalize3(fieldId);
|
|
2530
2712
|
for (const screenName of screens) {
|
|
2531
|
-
const screenMeta =
|
|
2713
|
+
const screenMeta = chunkKZ2BLMS4_js.getScreenMetadata(screenName);
|
|
2532
2714
|
const fields = Array.isArray(screenMeta?.fields) ? screenMeta.fields : [];
|
|
2533
2715
|
const match = fields.find((field) => {
|
|
2534
2716
|
if (!field || typeof field !== "object") return false;
|
|
2535
|
-
const id = typeof field.id === "string" ?
|
|
2536
|
-
const label = typeof field.label === "string" ?
|
|
2717
|
+
const id = typeof field.id === "string" ? chunkKZ2BLMS4_js.normalize3(field.id) : "";
|
|
2718
|
+
const label = typeof field.label === "string" ? chunkKZ2BLMS4_js.normalize3(field.label) : "";
|
|
2537
2719
|
return id === needle || label === needle;
|
|
2538
2720
|
});
|
|
2539
2721
|
if (match) return match;
|
|
@@ -2545,11 +2727,11 @@ function resolveSelectOption(fieldId, value, registry) {
|
|
|
2545
2727
|
if (!requested) return void 0;
|
|
2546
2728
|
const meta = getMetadataField(fieldId, registry);
|
|
2547
2729
|
const options = Array.isArray(meta?.options) ? meta.options : [];
|
|
2548
|
-
const requestedNorm =
|
|
2730
|
+
const requestedNorm = chunkKZ2BLMS4_js.normalize3(requested);
|
|
2549
2731
|
for (const option of options) {
|
|
2550
2732
|
const optionValue = typeof option?.value === "string" ? option.value : "";
|
|
2551
2733
|
const optionLabel = typeof option?.label === "string" ? option.label : "";
|
|
2552
|
-
if (
|
|
2734
|
+
if (chunkKZ2BLMS4_js.normalize3(optionValue) === requestedNorm || chunkKZ2BLMS4_js.normalize3(optionLabel) === requestedNorm) {
|
|
2553
2735
|
return { value: optionValue, label: optionLabel };
|
|
2554
2736
|
}
|
|
2555
2737
|
}
|
|
@@ -2599,12 +2781,12 @@ async function tryPressSelectOption(fieldId, value, registry, options = {}) {
|
|
|
2599
2781
|
return {
|
|
2600
2782
|
success: false,
|
|
2601
2783
|
error: `No pressable option found for select field "${fieldId}"`,
|
|
2602
|
-
diagnose: { category: "component-not-found", fieldId, screen:
|
|
2784
|
+
diagnose: { category: "component-not-found", fieldId, screen: chunkKZ2BLMS4_js.getCurrentScreen() ?? void 0 }
|
|
2603
2785
|
};
|
|
2604
2786
|
}
|
|
2605
2787
|
function normalizeFieldType(type) {
|
|
2606
2788
|
if (typeof type !== "string") return void 0;
|
|
2607
|
-
const normalized =
|
|
2789
|
+
const normalized = chunkKZ2BLMS4_js.normalize3(type);
|
|
2608
2790
|
if (normalized === "select" || normalized === "picker" || normalized === "dropdown")
|
|
2609
2791
|
return "select";
|
|
2610
2792
|
if (normalized === "toggle" || normalized === "switch" || normalized === "checkbox")
|
|
@@ -2634,7 +2816,7 @@ function fieldCueTerms(fieldId, label) {
|
|
|
2634
2816
|
);
|
|
2635
2817
|
const terms = /* @__PURE__ */ new Set();
|
|
2636
2818
|
for (const value of raw) {
|
|
2637
|
-
const normalized =
|
|
2819
|
+
const normalized = chunkKZ2BLMS4_js.normalize3(value);
|
|
2638
2820
|
if (normalized.length >= 3 && normalized !== "id") terms.add(normalized);
|
|
2639
2821
|
}
|
|
2640
2822
|
return [...terms];
|
|
@@ -2642,17 +2824,17 @@ function fieldCueTerms(fieldId, label) {
|
|
|
2642
2824
|
function snapshotHasFieldCue(snap, fieldId, label) {
|
|
2643
2825
|
const terms = fieldCueTerms(fieldId, label);
|
|
2644
2826
|
if (terms.length === 0) return false;
|
|
2645
|
-
const visible = [...snap.texts ?? [], ...(snap.buttons ?? []).map((b) => b.label ?? b.id ?? "")].map((text) =>
|
|
2827
|
+
const visible = [...snap.texts ?? [], ...(snap.buttons ?? []).map((b) => b.label ?? b.id ?? "")].map((text) => chunkKZ2BLMS4_js.normalize3(text)).filter(Boolean);
|
|
2646
2828
|
return visible.some((text) => terms.some((term) => text.includes(term) || term.includes(text)));
|
|
2647
2829
|
}
|
|
2648
2830
|
function scoreCandidateText(value, texts) {
|
|
2649
|
-
const valueNorm =
|
|
2831
|
+
const valueNorm = chunkKZ2BLMS4_js.normalize3(String(value ?? ""));
|
|
2650
2832
|
if (!valueNorm) return 0;
|
|
2651
2833
|
let best = 0;
|
|
2652
2834
|
for (const text of texts) {
|
|
2653
|
-
const textNorm =
|
|
2835
|
+
const textNorm = chunkKZ2BLMS4_js.normalize3(text);
|
|
2654
2836
|
if (!textNorm) continue;
|
|
2655
|
-
best = Math.max(best,
|
|
2837
|
+
best = Math.max(best, chunkKZ2BLMS4_js.matchScore(valueNorm, textNorm));
|
|
2656
2838
|
}
|
|
2657
2839
|
return best;
|
|
2658
2840
|
}
|
|
@@ -2666,7 +2848,7 @@ function optionTexts(option) {
|
|
|
2666
2848
|
function buildChoiceCandidates(snap, fieldId, value, allowFirstVisibleWhenNoCue, registry) {
|
|
2667
2849
|
const fieldLabel = getFieldLabel(fieldId, registry);
|
|
2668
2850
|
const fieldCueVisible = snapshotHasFieldCue(snap, fieldId, fieldLabel);
|
|
2669
|
-
const genericValue =
|
|
2851
|
+
const genericValue = chunkKZ2BLMS4_js.isGenericSelectValue(value);
|
|
2670
2852
|
const candidates = [];
|
|
2671
2853
|
let order = 0;
|
|
2672
2854
|
const choiceGroups = snap.choiceGroups ?? [];
|
|
@@ -2678,7 +2860,7 @@ function buildChoiceCandidates(snap, fieldId, value, allowFirstVisibleWhenNoCue,
|
|
|
2678
2860
|
const groupCueScore = Math.max(
|
|
2679
2861
|
globalCueScore,
|
|
2680
2862
|
...groupTexts.map((text) => {
|
|
2681
|
-
const normalized =
|
|
2863
|
+
const normalized = chunkKZ2BLMS4_js.normalize3(text);
|
|
2682
2864
|
return fieldCueTerms(fieldId, fieldLabel).some(
|
|
2683
2865
|
(term) => normalized.includes(term) || term.includes(normalized)
|
|
2684
2866
|
) ? 80 : 0;
|
|
@@ -2715,7 +2897,7 @@ function buildChoiceCandidates(snap, fieldId, value, allowFirstVisibleWhenNoCue,
|
|
|
2715
2897
|
const elementCueScore = Math.max(
|
|
2716
2898
|
fieldCueVisible && elements.length <= 12 ? 50 : 0,
|
|
2717
2899
|
...cueTexts.map((text) => {
|
|
2718
|
-
const normalized =
|
|
2900
|
+
const normalized = chunkKZ2BLMS4_js.normalize3(text);
|
|
2719
2901
|
return fieldTerms.some((term) => normalized.includes(term) || term.includes(normalized)) ? 80 : 0;
|
|
2720
2902
|
})
|
|
2721
2903
|
);
|
|
@@ -2773,7 +2955,7 @@ async function selectVisibleChoiceAsync(fieldId, value, registry, options) {
|
|
|
2773
2955
|
return {
|
|
2774
2956
|
success: false,
|
|
2775
2957
|
error: err?.message ?? "Could not capture visible choices",
|
|
2776
|
-
diagnose: { category: "unknown", fieldId, screen:
|
|
2958
|
+
diagnose: { category: "unknown", fieldId, screen: chunkKZ2BLMS4_js.getCurrentScreen() ?? void 0 }
|
|
2777
2959
|
};
|
|
2778
2960
|
}
|
|
2779
2961
|
const candidates = buildChoiceCandidates(
|
|
@@ -2791,7 +2973,7 @@ async function selectVisibleChoiceAsync(fieldId, value, registry, options) {
|
|
|
2791
2973
|
diagnose: {
|
|
2792
2974
|
category: "component-not-found",
|
|
2793
2975
|
fieldId,
|
|
2794
|
-
screen:
|
|
2976
|
+
screen: chunkKZ2BLMS4_js.getCurrentScreen() ?? void 0
|
|
2795
2977
|
}
|
|
2796
2978
|
};
|
|
2797
2979
|
}
|
|
@@ -2805,7 +2987,7 @@ async function selectVisibleChoiceAsync(fieldId, value, registry, options) {
|
|
|
2805
2987
|
}
|
|
2806
2988
|
function isContinuationButton(label) {
|
|
2807
2989
|
if (!label) return false;
|
|
2808
|
-
return /^(next|continue|proximo|prox|continuar|avancar|avançar)$/i.test(
|
|
2990
|
+
return /^(next|continue|proximo|prox|continuar|avancar|avançar)$/i.test(chunkKZ2BLMS4_js.normalize3(label));
|
|
2809
2991
|
}
|
|
2810
2992
|
function pressContinuationButton(registry) {
|
|
2811
2993
|
const snap = captureSnapshot();
|
|
@@ -2818,40 +3000,40 @@ function pressContinuationButton(registry) {
|
|
|
2818
3000
|
return {
|
|
2819
3001
|
success: false,
|
|
2820
3002
|
error: "No enabled continuation button is visible",
|
|
2821
|
-
diagnose: { category: "component-not-found", screen:
|
|
3003
|
+
diagnose: { category: "component-not-found", screen: chunkKZ2BLMS4_js.getCurrentScreen() ?? void 0 }
|
|
2822
3004
|
};
|
|
2823
3005
|
}
|
|
2824
3006
|
return pressTargetByIdOrLabel(id, registry);
|
|
2825
3007
|
}
|
|
2826
3008
|
function findField(fieldId, registry) {
|
|
2827
|
-
|
|
3009
|
+
chunkKZ2BLMS4_js.appilotsDebugLog(`findField: searching for fieldId="${fieldId}"`);
|
|
2828
3010
|
const exact = registry.getField(fieldId);
|
|
2829
3011
|
if (exact) {
|
|
2830
|
-
|
|
3012
|
+
chunkKZ2BLMS4_js.appilotsDebugLog(`findField: FOUND exact match for fieldId="${fieldId}"`);
|
|
2831
3013
|
return exact;
|
|
2832
3014
|
}
|
|
2833
3015
|
const lower = fieldId.toLowerCase();
|
|
2834
3016
|
const snapshot = registry.snapshot();
|
|
2835
3017
|
for (const comp of snapshot) {
|
|
2836
3018
|
if (comp.kind === "field" && comp.id.toLowerCase() === lower) {
|
|
2837
|
-
|
|
3019
|
+
chunkKZ2BLMS4_js.appilotsDebugLog(
|
|
2838
3020
|
`findField: FOUND case-insensitive match: registered="${comp.id}" for searched="${fieldId}"`
|
|
2839
3021
|
);
|
|
2840
3022
|
return registry.getField(comp.id);
|
|
2841
3023
|
}
|
|
2842
3024
|
}
|
|
2843
|
-
const currentScreenForTieBreak =
|
|
2844
|
-
const needle =
|
|
3025
|
+
const currentScreenForTieBreak = chunkKZ2BLMS4_js.getCurrentScreen();
|
|
3026
|
+
const needle = chunkKZ2BLMS4_js.normalize3(fieldId);
|
|
2845
3027
|
let bestComp;
|
|
2846
3028
|
let bestScore = 0;
|
|
2847
3029
|
let bestOnCurrentScreen = false;
|
|
2848
3030
|
for (const comp of snapshot) {
|
|
2849
3031
|
if (comp.kind !== "field") continue;
|
|
2850
|
-
const candidates = [
|
|
2851
|
-
if (comp.label) candidates.push(
|
|
3032
|
+
const candidates = [chunkKZ2BLMS4_js.normalize3(comp.id)];
|
|
3033
|
+
if (comp.label) candidates.push(chunkKZ2BLMS4_js.normalize3(comp.label));
|
|
2852
3034
|
let candidateScore = 0;
|
|
2853
3035
|
for (const cand of candidates) {
|
|
2854
|
-
const s =
|
|
3036
|
+
const s = chunkKZ2BLMS4_js.matchScore(needle, cand);
|
|
2855
3037
|
if (s > candidateScore) candidateScore = s;
|
|
2856
3038
|
}
|
|
2857
3039
|
if (candidateScore === 0) continue;
|
|
@@ -2864,14 +3046,14 @@ function findField(fieldId, registry) {
|
|
|
2864
3046
|
}
|
|
2865
3047
|
}
|
|
2866
3048
|
if (bestComp && bestScore >= 75) {
|
|
2867
|
-
|
|
3049
|
+
chunkKZ2BLMS4_js.appilotsDebugLog(
|
|
2868
3050
|
`findField: scored match "${fieldId}" -> "${bestComp.id}" (label="${bestComp.label}", score=${bestScore})`
|
|
2869
3051
|
);
|
|
2870
3052
|
return registry.getField(bestComp.id);
|
|
2871
3053
|
}
|
|
2872
|
-
const currentScreen =
|
|
3054
|
+
const currentScreen = chunkKZ2BLMS4_js.getCurrentScreen();
|
|
2873
3055
|
if (currentScreen) {
|
|
2874
|
-
const screenMeta =
|
|
3056
|
+
const screenMeta = chunkKZ2BLMS4_js.getScreenMetadata(currentScreen);
|
|
2875
3057
|
const fields = screenMeta?.fields;
|
|
2876
3058
|
if (fields && Array.isArray(fields)) {
|
|
2877
3059
|
const metaField = fields.find(
|
|
@@ -2879,19 +3061,19 @@ function findField(fieldId, registry) {
|
|
|
2879
3061
|
);
|
|
2880
3062
|
if (metaField && typeof metaField === "object" && metaField.label) {
|
|
2881
3063
|
const metaLabel = metaField.label;
|
|
2882
|
-
const metaNeedle =
|
|
3064
|
+
const metaNeedle = chunkKZ2BLMS4_js.normalize3(metaLabel);
|
|
2883
3065
|
let mBest;
|
|
2884
3066
|
let mBestScore = 0;
|
|
2885
3067
|
for (const comp of snapshot) {
|
|
2886
3068
|
if (comp.kind !== "field" || !comp.label) continue;
|
|
2887
|
-
const score =
|
|
3069
|
+
const score = chunkKZ2BLMS4_js.matchScore(metaNeedle, chunkKZ2BLMS4_js.normalize3(comp.label));
|
|
2888
3070
|
if (score > mBestScore) {
|
|
2889
3071
|
mBestScore = score;
|
|
2890
3072
|
mBest = comp;
|
|
2891
3073
|
}
|
|
2892
3074
|
}
|
|
2893
3075
|
if (mBest && mBestScore >= 60) {
|
|
2894
|
-
|
|
3076
|
+
chunkKZ2BLMS4_js.appilotsDebugLog(
|
|
2895
3077
|
`findField: FOUND via screen metadata translation: fieldId="${fieldId}" -> metaLabel="${metaLabel}" -> registered="${mBest.id}" (score=${mBestScore})`
|
|
2896
3078
|
);
|
|
2897
3079
|
return registry.getField(mBest.id);
|
|
@@ -2900,34 +3082,34 @@ function findField(fieldId, registry) {
|
|
|
2900
3082
|
}
|
|
2901
3083
|
}
|
|
2902
3084
|
if (bestComp && bestScore >= 40) {
|
|
2903
|
-
|
|
3085
|
+
chunkKZ2BLMS4_js.appilotsDebugLog(
|
|
2904
3086
|
`findField: weak substring match "${fieldId}" -> "${bestComp.id}" (label="${bestComp.label}", score=${bestScore})`
|
|
2905
3087
|
);
|
|
2906
3088
|
return registry.getField(bestComp.id);
|
|
2907
3089
|
}
|
|
2908
|
-
|
|
3090
|
+
chunkKZ2BLMS4_js.appilotsDebugWarn(
|
|
2909
3091
|
`findField: NOT FOUND \u2014 fieldId="${fieldId}" not in registry. Available fields: ${snapshot.filter((c) => c.kind === "field").map((c) => `"${c.id}" (label: ${c.label})`).join(", ") || "none"}`
|
|
2910
3092
|
);
|
|
2911
3093
|
return void 0;
|
|
2912
3094
|
}
|
|
2913
3095
|
function findToggle(fieldId, registry) {
|
|
2914
|
-
|
|
3096
|
+
chunkKZ2BLMS4_js.appilotsDebugLog(`findToggle: searching for fieldId="${fieldId}"`);
|
|
2915
3097
|
const exact = registry.getToggle(fieldId);
|
|
2916
3098
|
if (exact) {
|
|
2917
|
-
|
|
3099
|
+
chunkKZ2BLMS4_js.appilotsDebugLog(`findToggle: FOUND exact match for "${fieldId}"`);
|
|
2918
3100
|
return exact;
|
|
2919
3101
|
}
|
|
2920
3102
|
const lower = fieldId.toLowerCase();
|
|
2921
3103
|
const snapshot = registry.snapshot();
|
|
2922
3104
|
for (const comp of snapshot) {
|
|
2923
3105
|
if (comp.kind === "toggle" && comp.id.toLowerCase() === lower) {
|
|
2924
|
-
|
|
3106
|
+
chunkKZ2BLMS4_js.appilotsDebugLog(
|
|
2925
3107
|
`findToggle: FOUND case-insensitive match: registered="${comp.id}" for searched="${fieldId}"`
|
|
2926
3108
|
);
|
|
2927
3109
|
return registry.getToggle(comp.id);
|
|
2928
3110
|
}
|
|
2929
3111
|
}
|
|
2930
|
-
|
|
3112
|
+
chunkKZ2BLMS4_js.appilotsDebugWarn(
|
|
2931
3113
|
`findToggle: NOT FOUND \u2014 fieldId="${fieldId}" not in registry. Available toggles: ${snapshot.filter((c) => c.kind === "toggle").map((c) => `"${c.id}"`).join(", ") || "none"}`
|
|
2932
3114
|
);
|
|
2933
3115
|
return void 0;
|
|
@@ -2938,7 +3120,7 @@ function findSlider(fieldId, registry) {
|
|
|
2938
3120
|
const lower = fieldId.toLowerCase();
|
|
2939
3121
|
for (const comp of registry.snapshot()) {
|
|
2940
3122
|
if (comp.kind === "slider" && comp.id.toLowerCase() === lower) {
|
|
2941
|
-
|
|
3123
|
+
chunkKZ2BLMS4_js.appilotsDebugLog(
|
|
2942
3124
|
`findSlider: FOUND case-insensitive match: registered="${comp.id}" for searched="${fieldId}"`
|
|
2943
3125
|
);
|
|
2944
3126
|
return registry.getSlider(comp.id);
|
|
@@ -2949,7 +3131,7 @@ function findSlider(fieldId, registry) {
|
|
|
2949
3131
|
var sleep2 = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
2950
3132
|
async function formFillHandler(payload, context) {
|
|
2951
3133
|
const { permissions } = context;
|
|
2952
|
-
const registry = context.registry ??
|
|
3134
|
+
const registry = context.registry ?? chunkKZ2BLMS4_js.componentRegistry;
|
|
2953
3135
|
const { screen, activePath } = resolveScreenContext();
|
|
2954
3136
|
const screenPath = activePath.length > 1 ? activePath.join("/") : screen;
|
|
2955
3137
|
if (!permissions.canFillForms) {
|
|
@@ -2968,11 +3150,11 @@ async function formFillHandler(payload, context) {
|
|
|
2968
3150
|
}
|
|
2969
3151
|
const registrySnapshot = registry.snapshot();
|
|
2970
3152
|
if (registrySnapshot.length === 0) {
|
|
2971
|
-
|
|
3153
|
+
chunkKZ2BLMS4_js.appilotsDebugWarn(
|
|
2972
3154
|
"formFillHandler: registry is EMPTY \u2014 auto-tracking may not be active. Ensure enableAppilotsAutoTracking() runs before components mount."
|
|
2973
3155
|
);
|
|
2974
3156
|
} else {
|
|
2975
|
-
|
|
3157
|
+
chunkKZ2BLMS4_js.appilotsDebugLog(
|
|
2976
3158
|
`[Appilots formFillHandler] Registry has ${registrySnapshot.length} components:`,
|
|
2977
3159
|
registrySnapshot.map((c) => `${c.kind}:${c.id}`).join(", ")
|
|
2978
3160
|
);
|
|
@@ -2980,7 +3162,7 @@ async function formFillHandler(payload, context) {
|
|
|
2980
3162
|
const fieldResults = [];
|
|
2981
3163
|
let allSuccess = true;
|
|
2982
3164
|
let selectedChoiceThisBatch = false;
|
|
2983
|
-
|
|
3165
|
+
chunkKZ2BLMS4_js.appilotsDebugLog(`formFillHandler: processing ${payload.fields.length} fields`);
|
|
2984
3166
|
const availableFieldIds = () => registry.snapshot().filter((comp) => comp.kind === "field").map((comp) => `${comp.id}${comp.label ? ` (${comp.label})` : ""}`).slice(0, 8);
|
|
2985
3167
|
const isElementIdField = (field) => typeof field.fieldId === "string" && field.fieldId.trim().toLowerCase().startsWith("el:");
|
|
2986
3168
|
for (const field of payload.fields.filter(isElementIdField)) {
|
|
@@ -3007,13 +3189,13 @@ async function formFillHandler(payload, context) {
|
|
|
3007
3189
|
const { fieldId, fieldType, value } = field;
|
|
3008
3190
|
const effectiveFieldType = getEffectiveFieldType(fieldId, fieldType, registry);
|
|
3009
3191
|
let selectFailure;
|
|
3010
|
-
|
|
3011
|
-
`formFillHandler: looking up fieldId="${fieldId}" fieldType="${fieldType}" effectiveFieldType="${effectiveFieldType}" value=${
|
|
3192
|
+
chunkKZ2BLMS4_js.appilotsDebugLog(
|
|
3193
|
+
`formFillHandler: looking up fieldId="${fieldId}" fieldType="${fieldType}" effectiveFieldType="${effectiveFieldType}" value=${chunkKZ2BLMS4_js.describeValue(value)}`
|
|
3012
3194
|
);
|
|
3013
3195
|
const fieldEntry = findField(fieldId, registry);
|
|
3014
3196
|
if (fieldEntry) {
|
|
3015
3197
|
try {
|
|
3016
|
-
|
|
3198
|
+
chunkKZ2BLMS4_js.appilotsDebugLog(
|
|
3017
3199
|
`formFillHandler: found field "${fieldId}" via registry, calling setValue(<${String(value).length} chars>)`
|
|
3018
3200
|
);
|
|
3019
3201
|
const beforeValue = effectiveFieldType === "date" ? fieldEntry.getValue?.() ?? "" : void 0;
|
|
@@ -3044,7 +3226,7 @@ async function formFillHandler(payload, context) {
|
|
|
3044
3226
|
after = fieldEntry.getValue?.() ?? "";
|
|
3045
3227
|
}
|
|
3046
3228
|
if (!selectValueApplied(fieldId, value, after, registry)) {
|
|
3047
|
-
|
|
3229
|
+
chunkKZ2BLMS4_js.appilotsDebugWarn(
|
|
3048
3230
|
`formFillHandler: select field "${fieldId}" setValue did not stick (wrote <${String(value).length} chars>, current is <${String(after ?? "").length} chars>), trying visible choice fallback`
|
|
3049
3231
|
);
|
|
3050
3232
|
const selectResult = await selectVisibleChoice(fieldId, value, registry, {
|
|
@@ -3169,7 +3351,7 @@ async function formFillHandler(payload, context) {
|
|
|
3169
3351
|
}
|
|
3170
3352
|
if (selectResult.success) {
|
|
3171
3353
|
selectedChoiceThisBatch = true;
|
|
3172
|
-
|
|
3354
|
+
chunkKZ2BLMS4_js.appilotsDebugLog(
|
|
3173
3355
|
`formFillHandler: selected visible option for "${fieldId}"` + (selectResult.selectedLabel ? ` \u2192 "${selectResult.selectedLabel}"` : "")
|
|
3174
3356
|
);
|
|
3175
3357
|
await sleep2(120);
|
|
@@ -3178,7 +3360,7 @@ async function formFillHandler(payload, context) {
|
|
|
3178
3360
|
}
|
|
3179
3361
|
selectFailure = selectResult;
|
|
3180
3362
|
}
|
|
3181
|
-
|
|
3363
|
+
chunkKZ2BLMS4_js.appilotsDebugLog(`formFillHandler: registry miss for "${fieldId}", falling back to fiber tree`);
|
|
3182
3364
|
const handle = findInteractiveByIdentifier(fieldId, {
|
|
3183
3365
|
kind: effectiveFieldType === "toggle" ? "toggle" : "field"
|
|
3184
3366
|
});
|
|
@@ -3186,7 +3368,7 @@ async function formFillHandler(payload, context) {
|
|
|
3186
3368
|
try {
|
|
3187
3369
|
handle.focus?.();
|
|
3188
3370
|
handle.setValue(value);
|
|
3189
|
-
|
|
3371
|
+
chunkKZ2BLMS4_js.appilotsDebugLog(
|
|
3190
3372
|
`formFillHandler: fiber fallback succeeded for "${fieldId}" \u2192 label="${handle.label}"`
|
|
3191
3373
|
);
|
|
3192
3374
|
fieldResults.push({ fieldId, success: true });
|
|
@@ -3225,7 +3407,7 @@ async function formFillHandler(payload, context) {
|
|
|
3225
3407
|
if (payload.submitAfterFill === true) {
|
|
3226
3408
|
if (!allSuccess) {
|
|
3227
3409
|
const failedIds = fieldResults.filter((result) => !result.success).map((result) => result.fieldId);
|
|
3228
|
-
|
|
3410
|
+
chunkKZ2BLMS4_js.appilotsDebugWarn(
|
|
3229
3411
|
"formFillHandler: submitAfterFill=true requested but some fields failed; NOT submitting" + (failedIds.length > 0 ? ` (failed: ${failedIds.join(", ")})` : "")
|
|
3230
3412
|
);
|
|
3231
3413
|
} else {
|
|
@@ -3240,7 +3422,7 @@ async function formFillHandler(payload, context) {
|
|
|
3240
3422
|
registry
|
|
3241
3423
|
);
|
|
3242
3424
|
if (!submitResult.success) {
|
|
3243
|
-
|
|
3425
|
+
chunkKZ2BLMS4_js.appilotsDebugWarn(`formFillHandler: submitAfterFill failed \u2014 ${submitResult.error}`);
|
|
3244
3426
|
return {
|
|
3245
3427
|
success: false,
|
|
3246
3428
|
error: submitResult.error,
|
|
@@ -3252,7 +3434,7 @@ async function formFillHandler(payload, context) {
|
|
|
3252
3434
|
submitTargetId: submitResult.pressedTargetId
|
|
3253
3435
|
});
|
|
3254
3436
|
if (postSubmit.status === "pending") {
|
|
3255
|
-
|
|
3437
|
+
chunkKZ2BLMS4_js.appilotsDebugWarn(`formFillHandler: submit still pending \u2014 ${postSubmit.message}`);
|
|
3256
3438
|
return {
|
|
3257
3439
|
success: false,
|
|
3258
3440
|
error: postSubmit.message,
|
|
@@ -3261,7 +3443,7 @@ async function formFillHandler(payload, context) {
|
|
|
3261
3443
|
};
|
|
3262
3444
|
}
|
|
3263
3445
|
if (postSubmit.status === "failure") {
|
|
3264
|
-
|
|
3446
|
+
chunkKZ2BLMS4_js.appilotsDebugWarn(
|
|
3265
3447
|
`formFillHandler: submit rejected by visible validation \u2014 ${postSubmit.message}`
|
|
3266
3448
|
);
|
|
3267
3449
|
return {
|
|
@@ -3276,7 +3458,7 @@ async function formFillHandler(payload, context) {
|
|
|
3276
3458
|
}
|
|
3277
3459
|
};
|
|
3278
3460
|
}
|
|
3279
|
-
|
|
3461
|
+
chunkKZ2BLMS4_js.appilotsDebugLog("formFillHandler: submitAfterFill \u2014 submit completed");
|
|
3280
3462
|
}
|
|
3281
3463
|
}
|
|
3282
3464
|
const aggregatedDiagnose = aggregateFieldDiagnoses(fieldResults, screenPath);
|
|
@@ -3288,17 +3470,17 @@ async function formFillHandler(payload, context) {
|
|
|
3288
3470
|
};
|
|
3289
3471
|
}
|
|
3290
3472
|
function pressSubmitButton(context, registry) {
|
|
3291
|
-
const activePath = context.activePath ??
|
|
3473
|
+
const activePath = context.activePath ?? chunkKZ2BLMS4_js.getActiveRouteNames();
|
|
3292
3474
|
const hintScreen = context.screen ?? context.screenPath;
|
|
3293
3475
|
const formScreens = resolveFormScreensForSubmit(hintScreen, activePath, registry);
|
|
3294
|
-
const resolvedScreen = formScreens.find((name) => screenDeclaresSubmit(name)) ?? formScreens[0] ?? hintScreen ??
|
|
3476
|
+
const resolvedScreen = formScreens.find((name) => screenDeclaresSubmit(name)) ?? formScreens[0] ?? hintScreen ?? chunkKZ2BLMS4_js.getCurrentScreen() ?? void 0;
|
|
3295
3477
|
const candidates = collectSubmitTargetCandidates(formScreens, registry);
|
|
3296
3478
|
for (const candidate of candidates) {
|
|
3297
3479
|
const target = registry.getTarget(candidate);
|
|
3298
3480
|
if (target) {
|
|
3299
3481
|
try {
|
|
3300
3482
|
target.press();
|
|
3301
|
-
|
|
3483
|
+
chunkKZ2BLMS4_js.appilotsDebugLog(
|
|
3302
3484
|
`formFillHandler: submitAfterFill \u2014 pressed registry target "${candidate}"` + (resolvedScreen ? ` on screen "${resolvedScreen}"` : "")
|
|
3303
3485
|
);
|
|
3304
3486
|
return { success: true, pressedTargetId: candidate };
|
|
@@ -3312,7 +3494,7 @@ function pressSubmitButton(context, registry) {
|
|
|
3312
3494
|
}
|
|
3313
3495
|
}
|
|
3314
3496
|
for (const screenName of formScreens) {
|
|
3315
|
-
const screenMeta =
|
|
3497
|
+
const screenMeta = chunkKZ2BLMS4_js.getScreenMetadata(screenName);
|
|
3316
3498
|
const submitMeta = Array.isArray(screenMeta?.actions) ? screenMeta.actions.find(
|
|
3317
3499
|
(action) => typeof action === "object" && action !== null && action.type === "submit"
|
|
3318
3500
|
) : void 0;
|
|
@@ -3323,7 +3505,7 @@ function pressSubmitButton(context, registry) {
|
|
|
3323
3505
|
if (handle?.press) {
|
|
3324
3506
|
try {
|
|
3325
3507
|
handle.press();
|
|
3326
|
-
|
|
3508
|
+
chunkKZ2BLMS4_js.appilotsDebugLog(`formFillHandler: submitAfterFill \u2014 fiber fallback "${submitLabel}"`);
|
|
3327
3509
|
return { success: true, pressedTargetId: submitId ?? submitLabel };
|
|
3328
3510
|
} catch (err) {
|
|
3329
3511
|
return {
|
|
@@ -3345,7 +3527,7 @@ function pressSubmitButton(context, registry) {
|
|
|
3345
3527
|
if (id) {
|
|
3346
3528
|
const pressed = pressTargetByIdOrLabel(id, registry);
|
|
3347
3529
|
if (pressed.success) {
|
|
3348
|
-
|
|
3530
|
+
chunkKZ2BLMS4_js.appilotsDebugLog(`formFillHandler: submitAfterFill \u2014 pressed visible heuristic "${id}"`);
|
|
3349
3531
|
return { success: true, pressedTargetId: id };
|
|
3350
3532
|
}
|
|
3351
3533
|
}
|
|
@@ -3359,7 +3541,7 @@ function pressSubmitButton(context, registry) {
|
|
|
3359
3541
|
if (target) {
|
|
3360
3542
|
try {
|
|
3361
3543
|
target.press();
|
|
3362
|
-
|
|
3544
|
+
chunkKZ2BLMS4_js.appilotsDebugLog(
|
|
3363
3545
|
`formFillHandler: submitAfterFill \u2014 pressed by label heuristic "${comp.label}"`
|
|
3364
3546
|
);
|
|
3365
3547
|
return { success: true, pressedTargetId: comp.id };
|
|
@@ -3375,7 +3557,7 @@ function pressSubmitButton(context, registry) {
|
|
|
3375
3557
|
for (const fieldId of [...context.filledFieldIds ?? []].reverse()) {
|
|
3376
3558
|
const handle = findInteractiveByIdentifier(fieldId, { kind: "field" });
|
|
3377
3559
|
if (handle?.submitFromKeyboard?.()) {
|
|
3378
|
-
|
|
3560
|
+
chunkKZ2BLMS4_js.appilotsDebugLog(`formFillHandler: submitAfterFill \u2014 return key on "${fieldId}"`);
|
|
3379
3561
|
return { success: true, pressedTargetId: fieldId };
|
|
3380
3562
|
}
|
|
3381
3563
|
}
|
|
@@ -3421,12 +3603,12 @@ function buildDiagnose(category, targetId, candidates) {
|
|
|
3421
3603
|
return {
|
|
3422
3604
|
category,
|
|
3423
3605
|
targetId,
|
|
3424
|
-
screen:
|
|
3606
|
+
screen: chunkKZ2BLMS4_js.getCurrentScreen() ?? void 0,
|
|
3425
3607
|
...candidates && candidates.length > 0 ? { candidates: candidates.slice(0, 8) } : {}
|
|
3426
3608
|
};
|
|
3427
3609
|
}
|
|
3428
3610
|
function resolveListEntry(listId) {
|
|
3429
|
-
const entries =
|
|
3611
|
+
const entries = chunkKZ2BLMS4_js.listRegistry.snapshot();
|
|
3430
3612
|
if (entries.length === 0) return {};
|
|
3431
3613
|
if (listId) {
|
|
3432
3614
|
const wanted = normalizeId2(listId);
|
|
@@ -3555,9 +3737,9 @@ function hashFieldValue(value) {
|
|
|
3555
3737
|
var DISCRETE_FIELD_TYPES = /* @__PURE__ */ new Set(["select", "date"]);
|
|
3556
3738
|
function discreteFieldSignature() {
|
|
3557
3739
|
const sigs = [];
|
|
3558
|
-
for (const { id, kind } of
|
|
3740
|
+
for (const { id, kind } of chunkKZ2BLMS4_js.componentRegistry.snapshot()) {
|
|
3559
3741
|
if (kind !== "field") continue;
|
|
3560
|
-
const entry =
|
|
3742
|
+
const entry = chunkKZ2BLMS4_js.componentRegistry.getField(id);
|
|
3561
3743
|
if (!entry || !DISCRETE_FIELD_TYPES.has(entry.fieldType ?? "")) continue;
|
|
3562
3744
|
try {
|
|
3563
3745
|
sigs.push(`${id}:${hashFieldValue(String(entry.getValue() ?? ""))}`);
|
|
@@ -3568,32 +3750,32 @@ function discreteFieldSignature() {
|
|
|
3568
3750
|
}
|
|
3569
3751
|
async function waitForPostInteractionSettle(payload) {
|
|
3570
3752
|
const targetId = targetIdFromPayload(payload);
|
|
3571
|
-
const fromScreen =
|
|
3572
|
-
const baseline =
|
|
3753
|
+
const fromScreen = chunkKZ2BLMS4_js.getCurrentScreen();
|
|
3754
|
+
const baseline = chunkKZ2BLMS4_js.probeLoadingState(targetId || null, fromScreen);
|
|
3573
3755
|
const baselineFields = discreteFieldSignature();
|
|
3574
3756
|
const readable = baseline.fingerprint !== "";
|
|
3575
3757
|
await sleepMs(100);
|
|
3576
|
-
const afterPress =
|
|
3758
|
+
const afterPress = chunkKZ2BLMS4_js.probeLoadingState(targetId || null, chunkKZ2BLMS4_js.getCurrentScreen());
|
|
3577
3759
|
const modalOrLoading = afterPress.modalOpen || afterPress.loading || afterPress.pressedDisabled;
|
|
3578
3760
|
const fingerprintChanged = afterPress.fingerprint !== baseline.fingerprint;
|
|
3579
3761
|
const verdict = () => {
|
|
3580
3762
|
if (!readable) return { effect: "unknown" };
|
|
3581
|
-
const settled =
|
|
3763
|
+
const settled = chunkKZ2BLMS4_js.probeLoadingState(targetId || null, chunkKZ2BLMS4_js.getCurrentScreen());
|
|
3582
3764
|
if (settled.fingerprint === "") return { effect: "unknown" };
|
|
3583
3765
|
if (discreteFieldSignature() !== baselineFields) return { effect: "changed" };
|
|
3584
3766
|
return { effect: settled.fingerprint !== baseline.fingerprint ? "changed" : "none" };
|
|
3585
3767
|
};
|
|
3586
|
-
const capMs =
|
|
3768
|
+
const capMs = chunkKZ2BLMS4_js.isListItemPressTarget(targetId) ? 5e3 : 1e4;
|
|
3587
3769
|
if (modalOrLoading || fingerprintChanged) {
|
|
3588
|
-
await
|
|
3770
|
+
await chunkKZ2BLMS4_js.waitForLoadingSettle({
|
|
3589
3771
|
pressedComponentId: targetId || null,
|
|
3590
3772
|
fromScreen,
|
|
3591
3773
|
maxMs: capMs
|
|
3592
3774
|
});
|
|
3593
3775
|
return verdict();
|
|
3594
3776
|
}
|
|
3595
|
-
if (
|
|
3596
|
-
await
|
|
3777
|
+
if (chunkKZ2BLMS4_js.isListItemPressTarget(targetId)) {
|
|
3778
|
+
await chunkKZ2BLMS4_js.waitForLoadingSettle({
|
|
3597
3779
|
fromScreen,
|
|
3598
3780
|
maxMs: 3e3
|
|
3599
3781
|
});
|
|
@@ -3614,7 +3796,7 @@ function validateActionPayload(action) {
|
|
|
3614
3796
|
error: message,
|
|
3615
3797
|
diagnose: {
|
|
3616
3798
|
category: "validation",
|
|
3617
|
-
screen:
|
|
3799
|
+
screen: chunkKZ2BLMS4_js.getCurrentScreen() ?? void 0,
|
|
3618
3800
|
...ids ?? {}
|
|
3619
3801
|
}
|
|
3620
3802
|
});
|
|
@@ -3675,7 +3857,7 @@ function isDestructivePayload(payload) {
|
|
|
3675
3857
|
return !!params && typeof params === "object" && params.destructive === true;
|
|
3676
3858
|
}
|
|
3677
3859
|
async function executeAction(action, context) {
|
|
3678
|
-
|
|
3860
|
+
chunkKZ2BLMS4_js.appilotsDebugLog(
|
|
3679
3861
|
`executeAction called: type="${action.type}", id="${action.id}", payload=${JSON.stringify(action.payload)}`
|
|
3680
3862
|
);
|
|
3681
3863
|
const permissions = context.permissions ?? DEFAULT_PERMISSIONS;
|
|
@@ -3704,7 +3886,7 @@ async function executeAction(action, context) {
|
|
|
3704
3886
|
let result;
|
|
3705
3887
|
const validationFailure = validateActionPayload(action);
|
|
3706
3888
|
if (validationFailure) {
|
|
3707
|
-
|
|
3889
|
+
chunkKZ2BLMS4_js.appilotsDebugWarn(
|
|
3708
3890
|
`executeAction: payload validation failed for type="${action.type}" id="${action.id}": ${validationFailure.error}`
|
|
3709
3891
|
);
|
|
3710
3892
|
context.emit({
|
|
@@ -3731,14 +3913,14 @@ async function executeAction(action, context) {
|
|
|
3731
3913
|
case "form_fill":
|
|
3732
3914
|
result = await formFillHandler(action.payload, {
|
|
3733
3915
|
permissions,
|
|
3734
|
-
registry: context.registry ??
|
|
3916
|
+
registry: context.registry ?? chunkKZ2BLMS4_js.getDefaultRegistry()
|
|
3735
3917
|
});
|
|
3736
3918
|
break;
|
|
3737
3919
|
case "ui_interaction": {
|
|
3738
3920
|
const payload = action.payload;
|
|
3739
3921
|
result = uiInteractionHandler(payload, {
|
|
3740
3922
|
permissions,
|
|
3741
|
-
registry: context.registry ??
|
|
3923
|
+
registry: context.registry ?? chunkKZ2BLMS4_js.getDefaultRegistry()
|
|
3742
3924
|
});
|
|
3743
3925
|
if (result.success) {
|
|
3744
3926
|
const settle = await waitForPostInteractionSettle(payload);
|
|
@@ -3767,7 +3949,7 @@ async function executeAction(action, context) {
|
|
|
3767
3949
|
};
|
|
3768
3950
|
}
|
|
3769
3951
|
} catch (err) {
|
|
3770
|
-
|
|
3952
|
+
chunkKZ2BLMS4_js.appilotsDebugWarn(
|
|
3771
3953
|
`executeAction: exception during action type="${action.type}" id="${action.id}": ${err?.message}`
|
|
3772
3954
|
);
|
|
3773
3955
|
result = {
|
|
@@ -3775,7 +3957,7 @@ async function executeAction(action, context) {
|
|
|
3775
3957
|
error: err?.message ?? "Action execution failed unexpectedly"
|
|
3776
3958
|
};
|
|
3777
3959
|
}
|
|
3778
|
-
|
|
3960
|
+
chunkKZ2BLMS4_js.appilotsDebugLog(
|
|
3779
3961
|
`executeAction result: type="${action.type}", id="${action.id}", success=${result.success}, error=${result.error ?? "none"}`
|
|
3780
3962
|
);
|
|
3781
3963
|
context.emit({
|
|
@@ -3829,7 +4011,7 @@ var _patchedAlert = (title, message, buttons, options) => {
|
|
|
3829
4011
|
return suppression.originalAlert(title, message, buttons, options);
|
|
3830
4012
|
}
|
|
3831
4013
|
suppression.consumed = true;
|
|
3832
|
-
|
|
4014
|
+
chunkKZ2BLMS4_js.appilotsDebugLog("Suppressing native Alert during already-confirmed destructive agent action");
|
|
3833
4015
|
try {
|
|
3834
4016
|
suppression.pending = Promise.resolve(button.onPress()).then(() => void 0).catch((err) => reportHandlerFailure(err));
|
|
3835
4017
|
} catch (err) {
|
|
@@ -3882,35 +4064,35 @@ async function runWithConfirmedDestructiveContext(enabled, host, fn) {
|
|
|
3882
4064
|
// src/platform/reactNativeAdapter.ts
|
|
3883
4065
|
var POST_ACTION_LOADING_MAX_MS = 6e3;
|
|
3884
4066
|
function resolveScreenMetadata() {
|
|
3885
|
-
const activePath =
|
|
4067
|
+
const activePath = chunkKZ2BLMS4_js.getActiveRouteNames();
|
|
3886
4068
|
for (let i = activePath.length - 1; i >= 0; i--) {
|
|
3887
4069
|
const name = activePath[i];
|
|
3888
|
-
const meta = name ?
|
|
4070
|
+
const meta = name ? chunkKZ2BLMS4_js.getScreenMetadata(name) : void 0;
|
|
3889
4071
|
if (meta && (Array.isArray(meta.fields) && meta.fields.length > 0 || Array.isArray(meta.actions) && meta.actions.length > 0)) {
|
|
3890
4072
|
return meta;
|
|
3891
4073
|
}
|
|
3892
4074
|
}
|
|
3893
|
-
const screen =
|
|
3894
|
-
return screen ?
|
|
4075
|
+
const screen = chunkKZ2BLMS4_js.getCurrentScreen();
|
|
4076
|
+
return screen ? chunkKZ2BLMS4_js.getScreenMetadata(screen) : void 0;
|
|
3895
4077
|
}
|
|
3896
4078
|
function buildAgentContext(extras = {}) {
|
|
3897
4079
|
const context = {};
|
|
3898
4080
|
context.platform = "react-native";
|
|
3899
|
-
const screen =
|
|
4081
|
+
const screen = chunkKZ2BLMS4_js.getCurrentScreen();
|
|
3900
4082
|
if (screen) context.currentScreen = screen;
|
|
3901
|
-
const navigationState =
|
|
4083
|
+
const navigationState = chunkKZ2BLMS4_js.getNavigationStateSnapshot();
|
|
3902
4084
|
if (navigationState) context.navigationState = navigationState;
|
|
3903
4085
|
const screenMeta = resolveScreenMetadata();
|
|
3904
4086
|
if (screenMeta) context.screenMetadata = screenMeta;
|
|
3905
4087
|
try {
|
|
3906
4088
|
context.snapshot = captureSnapshot();
|
|
3907
4089
|
} catch (err) {
|
|
3908
|
-
|
|
4090
|
+
chunkKZ2BLMS4_js.appilotsDebugWarn("buildAgentContext: captureSnapshot failed", err);
|
|
3909
4091
|
}
|
|
3910
|
-
const registry =
|
|
4092
|
+
const registry = chunkKZ2BLMS4_js.componentRegistry.snapshot();
|
|
3911
4093
|
const filtered = screen ? registry.filter((c) => !c.screen || c.screen === screen) : registry;
|
|
3912
4094
|
if (filtered.length > 0) context.registeredComponents = filtered;
|
|
3913
|
-
const registeredLists =
|
|
4095
|
+
const registeredLists = chunkKZ2BLMS4_js.listRegistry.snapshot();
|
|
3914
4096
|
if (registeredLists.length > 0) {
|
|
3915
4097
|
context.registeredLists = registeredLists.map(
|
|
3916
4098
|
({ scrollToIndex, scrollToOffset, getScrollMetrics, dataPreview, ...rest }) => rest
|
|
@@ -3927,12 +4109,12 @@ function resolveActionHints(screen, pressedComponentId, actionPayload) {
|
|
|
3927
4109
|
}
|
|
3928
4110
|
}
|
|
3929
4111
|
if (!screen || !pressedComponentId) return void 0;
|
|
3930
|
-
const meta =
|
|
4112
|
+
const meta = chunkKZ2BLMS4_js.getScreenMetadata(screen);
|
|
3931
4113
|
const actions = meta?.actions;
|
|
3932
4114
|
if (!actions || actions.length === 0) return void 0;
|
|
3933
4115
|
for (const a of actions) {
|
|
3934
4116
|
if (typeof a === "string") continue;
|
|
3935
|
-
if (
|
|
4117
|
+
if (chunkKZ2BLMS4_js.idLooselyMatches(a.id, pressedComponentId)) {
|
|
3936
4118
|
const inferred = a.appilotsInferred;
|
|
3937
4119
|
if (inferred && typeof inferred === "object") return inferred;
|
|
3938
4120
|
return void 0;
|
|
@@ -3947,30 +4129,30 @@ async function settleTurn(input) {
|
|
|
3947
4129
|
const successById = new Map(input.results.map((r) => [r.actionId, r.success]));
|
|
3948
4130
|
const typeById = new Map(input.results.map((r) => [r.actionId, r.type]));
|
|
3949
4131
|
if (input.hadNavigate) {
|
|
3950
|
-
const settle = await
|
|
4132
|
+
const settle = await chunkKZ2BLMS4_js.waitForScreenSettle({
|
|
3951
4133
|
expectingChange: true,
|
|
3952
4134
|
fromScreen: input.preNavigateScreen ?? null,
|
|
3953
4135
|
fromSignature: input.preNavigateSignature ?? null,
|
|
3954
4136
|
targetScreen: navigateTargetScreen,
|
|
3955
4137
|
maxMs: 3500
|
|
3956
4138
|
});
|
|
3957
|
-
|
|
4139
|
+
chunkKZ2BLMS4_js.appilotsDebugLog(
|
|
3958
4140
|
`settleTurn: post-navigate settle done \u2014 screen="${settle.screen}" transitioned=${settle.transitioned} timedOut=${settle.timedOut} waitedMs=${settle.waitedMs}`
|
|
3959
4141
|
);
|
|
3960
|
-
const navigationMoved = settle.transitioned ||
|
|
4142
|
+
const navigationMoved = settle.transitioned || chunkKZ2BLMS4_js.screenDepartedBaseline(input.preNavigateScreen ?? null, input.preNavigateSignature ?? null) || !!navigateTargetScreen && !!settle.screen && chunkKZ2BLMS4_js.routesBelongToSameFeature(settle.screen, navigateTargetScreen);
|
|
3961
4143
|
if (!navigationMoved) {
|
|
3962
|
-
|
|
4144
|
+
chunkKZ2BLMS4_js.appilotsDebugWarn(
|
|
3963
4145
|
`tool-without-effect: navigate emitted but screen did not change (stayed at "${input.preNavigateScreen ?? "unknown"}", waitedMs=${settle.waitedMs}). Likely causes: target screenName missing from MCP doc, nested-nav path absent, or React Navigation rejected the route.`
|
|
3964
4146
|
);
|
|
3965
4147
|
for (const [actionId, type] of typeById) {
|
|
3966
4148
|
if (type === "navigate") toolWithoutEffectIds.add(actionId);
|
|
3967
4149
|
}
|
|
3968
4150
|
}
|
|
3969
|
-
const loadSettle = await
|
|
4151
|
+
const loadSettle = await chunkKZ2BLMS4_js.waitForLoadingSettle({
|
|
3970
4152
|
fromScreen: settle.screen ?? null,
|
|
3971
4153
|
maxMs: 3e3
|
|
3972
4154
|
});
|
|
3973
|
-
|
|
4155
|
+
chunkKZ2BLMS4_js.appilotsDebugLog(
|
|
3974
4156
|
`settleTurn: post-navigate loading settle \u2014 settled=${loadSettle.settled} loadingPending=${loadSettle.loadingPending} probes=${loadSettle.probeCount} waitedMs=${loadSettle.waitedMs}`
|
|
3975
4157
|
);
|
|
3976
4158
|
if (loadSettle.loadingPending) loadingPending = true;
|
|
@@ -3978,36 +4160,36 @@ async function settleTurn(input) {
|
|
|
3978
4160
|
const pressedAction = turnActions.find(
|
|
3979
4161
|
(a) => a.type === "ui_interaction" && a.payload?.componentId === pressedId
|
|
3980
4162
|
);
|
|
3981
|
-
const hints = resolveActionHints(
|
|
4163
|
+
const hints = resolveActionHints(chunkKZ2BLMS4_js.getCurrentScreen(), pressedId, pressedAction?.payload);
|
|
3982
4164
|
const settleCapMs = hints?.isAsyncTrigger === true ? 1e4 : POST_ACTION_LOADING_MAX_MS;
|
|
3983
|
-
const loadSettle = await
|
|
4165
|
+
const loadSettle = await chunkKZ2BLMS4_js.waitForLoadingSettle({
|
|
3984
4166
|
pressedComponentId: pressedId,
|
|
3985
|
-
fromScreen:
|
|
4167
|
+
fromScreen: chunkKZ2BLMS4_js.getCurrentScreen(),
|
|
3986
4168
|
maxMs: settleCapMs
|
|
3987
4169
|
});
|
|
3988
|
-
|
|
4170
|
+
chunkKZ2BLMS4_js.appilotsDebugLog(
|
|
3989
4171
|
`settleTurn: post-action loading settle \u2014 pressedId="${pressedId ?? ""}" settled=${loadSettle.settled} transitioned=${loadSettle.transitioned} loadingPending=${loadSettle.loadingPending} probes=${loadSettle.probeCount} waitedMs=${loadSettle.waitedMs} cap=${settleCapMs}${hints?.isAsyncTrigger ? " (mcp-inferred)" : ""}`
|
|
3990
4172
|
);
|
|
3991
4173
|
if (loadSettle.loadingPending) loadingPending = true;
|
|
3992
4174
|
const listPressActions = turnActions.filter((action) => {
|
|
3993
|
-
const target =
|
|
3994
|
-
return target ?
|
|
4175
|
+
const target = chunkKZ2BLMS4_js.actionPressTargetId(action);
|
|
4176
|
+
return target ? chunkKZ2BLMS4_js.isListItemPressTarget(target) : false;
|
|
3995
4177
|
});
|
|
3996
4178
|
if (listPressActions.length > 0) {
|
|
3997
|
-
const baselineFingerprint =
|
|
3998
|
-
const postPressSettle = await
|
|
4179
|
+
const baselineFingerprint = chunkKZ2BLMS4_js.probeLoadingState(pressedId, chunkKZ2BLMS4_js.getCurrentScreen()).fingerprint;
|
|
4180
|
+
const postPressSettle = await chunkKZ2BLMS4_js.waitForScreenSettle({
|
|
3999
4181
|
expectingChange: true,
|
|
4000
4182
|
fromScreen: input.preNavigateScreen ?? null,
|
|
4001
4183
|
fromSignature: input.preNavigateSignature ?? null,
|
|
4002
4184
|
maxMs: 2500
|
|
4003
4185
|
});
|
|
4004
|
-
await
|
|
4186
|
+
await chunkKZ2BLMS4_js.waitForLoadingSettle({
|
|
4005
4187
|
pressedComponentId: pressedId,
|
|
4006
|
-
fromScreen:
|
|
4188
|
+
fromScreen: chunkKZ2BLMS4_js.getCurrentScreen(),
|
|
4007
4189
|
maxMs: 4e3
|
|
4008
4190
|
});
|
|
4009
|
-
const afterFingerprint =
|
|
4010
|
-
|
|
4191
|
+
const afterFingerprint = chunkKZ2BLMS4_js.probeLoadingState(pressedId, chunkKZ2BLMS4_js.getCurrentScreen()).fingerprint;
|
|
4192
|
+
chunkKZ2BLMS4_js.appilotsDebugLog(
|
|
4011
4193
|
`settleTurn: post-list-press settle \u2014 screen="${postPressSettle.screen}" transitioned=${postPressSettle.transitioned} timedOut=${postPressSettle.timedOut} waitedMs=${postPressSettle.waitedMs}`
|
|
4012
4194
|
);
|
|
4013
4195
|
if (!postPressSettle.transitioned && baselineFingerprint === afterFingerprint) {
|
|
@@ -4023,15 +4205,15 @@ async function settleTurn(input) {
|
|
|
4023
4205
|
}
|
|
4024
4206
|
var reactNativeChatAdapter = {
|
|
4025
4207
|
buildContext: buildAgentContext,
|
|
4026
|
-
getCurrentScreen:
|
|
4027
|
-
getCurrentScreenSignature:
|
|
4208
|
+
getCurrentScreen: chunkKZ2BLMS4_js.getCurrentScreen,
|
|
4209
|
+
getCurrentScreenSignature: chunkKZ2BLMS4_js.getCurrentScreenSignature,
|
|
4028
4210
|
settleTurn
|
|
4029
4211
|
};
|
|
4030
4212
|
function createReactNativeActionRunner(getOptions) {
|
|
4031
4213
|
return {
|
|
4032
4214
|
async execute(action, { confirmedDestructive }) {
|
|
4033
4215
|
const { permissions, emit, navigationRef, suppressNativeConfirm } = getOptions();
|
|
4034
|
-
const navRef = navigationRef?.current ? navigationRef : { current:
|
|
4216
|
+
const navRef = navigationRef?.current ? navigationRef : { current: chunkKZ2BLMS4_js.getNavigationRef() };
|
|
4035
4217
|
return runWithConfirmedDestructiveContext(
|
|
4036
4218
|
confirmedDestructive && suppressNativeConfirm !== false,
|
|
4037
4219
|
reactNative.Alert,
|
|
@@ -4042,21 +4224,21 @@ function createReactNativeActionRunner(getOptions) {
|
|
|
4042
4224
|
})
|
|
4043
4225
|
);
|
|
4044
4226
|
},
|
|
4045
|
-
getCurrentScreen:
|
|
4046
|
-
getCurrentScreenSignature:
|
|
4227
|
+
getCurrentScreen: chunkKZ2BLMS4_js.getCurrentScreen,
|
|
4228
|
+
getCurrentScreenSignature: chunkKZ2BLMS4_js.getCurrentScreenSignature,
|
|
4047
4229
|
getScreenActionsMetadata(screen) {
|
|
4048
|
-
return
|
|
4230
|
+
return chunkKZ2BLMS4_js.getScreenMetadata(screen)?.actions;
|
|
4049
4231
|
},
|
|
4050
|
-
waitForScreenSettle:
|
|
4232
|
+
waitForScreenSettle: chunkKZ2BLMS4_js.waitForScreenSettle
|
|
4051
4233
|
};
|
|
4052
4234
|
}
|
|
4053
4235
|
|
|
4054
4236
|
// src/hooks/useAppilotsChat.ts
|
|
4055
4237
|
function useAppilotsChat(options = {}) {
|
|
4056
|
-
const { client, emit, subscribe } =
|
|
4238
|
+
const { client, emit, subscribe } = chunkKZ2BLMS4_js.useAppilotsContext();
|
|
4057
4239
|
const machine = React.useMemo(
|
|
4058
|
-
() => new
|
|
4059
|
-
{ client, adapter: reactNativeChatAdapter, emit, warn:
|
|
4240
|
+
() => new chunkKZ2BLMS4_js.ChatSessionMachine(
|
|
4241
|
+
{ client, adapter: reactNativeChatAdapter, emit, warn: chunkKZ2BLMS4_js.appilotsDebugWarn },
|
|
4060
4242
|
options
|
|
4061
4243
|
),
|
|
4062
4244
|
// A new machine per client/provider instance — options are pushed in
|
|
@@ -4099,7 +4281,7 @@ var DEFAULT_PERMISSIONS2 = {
|
|
|
4099
4281
|
canSubmitForms: true
|
|
4100
4282
|
};
|
|
4101
4283
|
function useAppilotsActions(options = {}) {
|
|
4102
|
-
const { client, subscribe, config, emit } =
|
|
4284
|
+
const { client, subscribe, config, emit } = chunkKZ2BLMS4_js.useAppilotsContext();
|
|
4103
4285
|
const { navigationRef, autoExecute = false } = options;
|
|
4104
4286
|
const runnerOptionsRef = React.useRef({
|
|
4105
4287
|
permissions: config.permissions ?? DEFAULT_PERMISSIONS2,
|
|
@@ -4114,12 +4296,12 @@ function useAppilotsActions(options = {}) {
|
|
|
4114
4296
|
suppressNativeConfirm: config.suppressNativeConfirm
|
|
4115
4297
|
};
|
|
4116
4298
|
const machine = React.useMemo(
|
|
4117
|
-
() => new
|
|
4299
|
+
() => new chunkKZ2BLMS4_js.ActionQueueMachine(
|
|
4118
4300
|
{
|
|
4119
4301
|
client,
|
|
4120
4302
|
adapter: createReactNativeActionRunner(() => runnerOptionsRef.current),
|
|
4121
4303
|
emit,
|
|
4122
|
-
warn:
|
|
4304
|
+
warn: chunkKZ2BLMS4_js.appilotsDebugWarn
|
|
4123
4305
|
},
|
|
4124
4306
|
{ autoExecute }
|
|
4125
4307
|
),
|
|
@@ -4176,7 +4358,7 @@ function shouldShowSuggestedPrompts(args) {
|
|
|
4176
4358
|
|
|
4177
4359
|
// src/hooks/useSuggestedPrompts.ts
|
|
4178
4360
|
function useSuggestedPrompts(options) {
|
|
4179
|
-
const { client } =
|
|
4361
|
+
const { client } = chunkKZ2BLMS4_js.useAppilotsContext();
|
|
4180
4362
|
const { enabled, limit = 4 } = options;
|
|
4181
4363
|
const [prompts, setPrompts] = React.useState([]);
|
|
4182
4364
|
const [isLoading, setIsLoading] = React.useState(false);
|
|
@@ -4186,8 +4368,8 @@ function useSuggestedPrompts(options) {
|
|
|
4186
4368
|
if (!enabled) return;
|
|
4187
4369
|
const requestId = ++requestIdRef.current;
|
|
4188
4370
|
let cancelled = false;
|
|
4189
|
-
const screen =
|
|
4190
|
-
const localDev = screen ? (
|
|
4371
|
+
const screen = chunkKZ2BLMS4_js.getCurrentScreen() ?? void 0;
|
|
4372
|
+
const localDev = screen ? (chunkKZ2BLMS4_js.getScreenMetadata(screen)?.suggestedPrompts ?? []).map((text) => ({
|
|
4191
4373
|
text,
|
|
4192
4374
|
source: "dev-defined"
|
|
4193
4375
|
})) : [];
|
|
@@ -4201,7 +4383,7 @@ function useSuggestedPrompts(options) {
|
|
|
4201
4383
|
if (cancelled || requestIdRef.current !== requestId) return;
|
|
4202
4384
|
setPrompts(mergePromptSources(localDev, data, limit));
|
|
4203
4385
|
}).catch((err) => {
|
|
4204
|
-
|
|
4386
|
+
chunkKZ2BLMS4_js.appilotsDebugWarn("useSuggestedPrompts: fetch failed", err);
|
|
4205
4387
|
}).finally(() => {
|
|
4206
4388
|
if (cancelled || requestIdRef.current !== requestId) return;
|
|
4207
4389
|
setIsLoading(false);
|
|
@@ -4212,9 +4394,9 @@ function useSuggestedPrompts(options) {
|
|
|
4212
4394
|
}, [client, enabled, limit, refreshTick]);
|
|
4213
4395
|
React.useEffect(() => {
|
|
4214
4396
|
if (!enabled) return;
|
|
4215
|
-
let lastScreen =
|
|
4397
|
+
let lastScreen = chunkKZ2BLMS4_js.getCurrentScreen();
|
|
4216
4398
|
const interval = setInterval(() => {
|
|
4217
|
-
const current =
|
|
4399
|
+
const current = chunkKZ2BLMS4_js.getCurrentScreen();
|
|
4218
4400
|
if (current !== lastScreen) {
|
|
4219
4401
|
lastScreen = current;
|
|
4220
4402
|
setRefreshTick((t) => t + 1);
|
|
@@ -4229,14 +4411,14 @@ function useSuggestedPrompts(options) {
|
|
|
4229
4411
|
};
|
|
4230
4412
|
}
|
|
4231
4413
|
function useAppilotsNavigation() {
|
|
4232
|
-
const { emit } =
|
|
4414
|
+
const { emit } = chunkKZ2BLMS4_js.useAppilotsContext();
|
|
4233
4415
|
const [currentScreen, setCurrentScreenState] = React.useState(null);
|
|
4234
4416
|
const [navigationHistory, setNavigationHistory] = React.useState([]);
|
|
4235
4417
|
const navigationRef = React.useRef(null);
|
|
4236
4418
|
const setCurrentScreen2 = React.useCallback(
|
|
4237
4419
|
(screenName) => {
|
|
4238
4420
|
setCurrentScreenState(screenName);
|
|
4239
|
-
|
|
4421
|
+
chunkKZ2BLMS4_js.setCurrentScreen(screenName);
|
|
4240
4422
|
setNavigationHistory((prev) => [...prev, screenName]);
|
|
4241
4423
|
emit({
|
|
4242
4424
|
type: "navigation:change",
|
|
@@ -4267,7 +4449,7 @@ function useAppilotsNavigation() {
|
|
|
4267
4449
|
|
|
4268
4450
|
// src/hooks/useAppilots.ts
|
|
4269
4451
|
function useAppilots() {
|
|
4270
|
-
const { config, client } =
|
|
4452
|
+
const { config, client } = chunkKZ2BLMS4_js.useAppilotsContext();
|
|
4271
4453
|
const chat = useAppilotsChat();
|
|
4272
4454
|
const navigation = useAppilotsNavigation();
|
|
4273
4455
|
const actions = useAppilotsActions();
|
|
@@ -4296,7 +4478,7 @@ function useAppilots() {
|
|
|
4296
4478
|
}
|
|
4297
4479
|
function useAppilotsField(id, options) {
|
|
4298
4480
|
const { value, onChangeText, ref, fieldType, label, screen } = options;
|
|
4299
|
-
const registry =
|
|
4481
|
+
const registry = chunkKZ2BLMS4_js.useResolvedRegistry();
|
|
4300
4482
|
const valueRef = React.useRef(value);
|
|
4301
4483
|
const onChangeRef = React.useRef(onChangeText);
|
|
4302
4484
|
valueRef.current = value;
|
|
@@ -4324,7 +4506,7 @@ function useAppilotsField(id, options) {
|
|
|
4324
4506
|
}
|
|
4325
4507
|
function useAppilotsTarget(id, options) {
|
|
4326
4508
|
const { onPress, onLongPress, onScrollTo, label, screen } = options;
|
|
4327
|
-
const registry =
|
|
4509
|
+
const registry = chunkKZ2BLMS4_js.useResolvedRegistry();
|
|
4328
4510
|
const onPressRef = React.useRef(onPress);
|
|
4329
4511
|
const onLongPressRef = React.useRef(onLongPress);
|
|
4330
4512
|
const onScrollToRef = React.useRef(onScrollTo);
|
|
@@ -4351,7 +4533,7 @@ function useAppilotsTarget(id, options) {
|
|
|
4351
4533
|
}
|
|
4352
4534
|
function useAppilotsToggle(id, options) {
|
|
4353
4535
|
const { value, onValueChange, label, screen } = options;
|
|
4354
|
-
const registry =
|
|
4536
|
+
const registry = chunkKZ2BLMS4_js.useResolvedRegistry();
|
|
4355
4537
|
const valueRef = React.useRef(value);
|
|
4356
4538
|
const onChangeRef = React.useRef(onValueChange);
|
|
4357
4539
|
valueRef.current = value;
|
|
@@ -4374,7 +4556,7 @@ function useAppilotsToggle(id, options) {
|
|
|
4374
4556
|
}
|
|
4375
4557
|
function useAppilotsSlider(id, options) {
|
|
4376
4558
|
const { value, onValueChange, min, max, step, label, screen } = options;
|
|
4377
|
-
const registry =
|
|
4559
|
+
const registry = chunkKZ2BLMS4_js.useResolvedRegistry();
|
|
4378
4560
|
const valueRef = React.useRef(value);
|
|
4379
4561
|
const onChangeRef = React.useRef(onValueChange);
|
|
4380
4562
|
valueRef.current = value;
|