react-native-tapline 1.5.0 → 1.6.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.
Files changed (62) hide show
  1. package/TaplineNative.podspec +3 -1
  2. package/dist/actions.d.ts +22 -2
  3. package/dist/actions.js +186 -16
  4. package/dist/actions.js.map +1 -1
  5. package/dist/alerts.d.ts +2 -0
  6. package/dist/alerts.js +5 -0
  7. package/dist/alerts.js.map +1 -1
  8. package/dist/anim.d.ts +25 -0
  9. package/dist/anim.js +311 -0
  10. package/dist/anim.js.map +1 -0
  11. package/dist/appinfo.d.ts +12 -0
  12. package/dist/appinfo.js +78 -0
  13. package/dist/appinfo.js.map +1 -0
  14. package/dist/client.d.ts +2 -0
  15. package/dist/client.js +25 -2
  16. package/dist/client.js.map +1 -1
  17. package/dist/commands.js +28 -0
  18. package/dist/commands.js.map +1 -1
  19. package/dist/guard.d.ts +17 -0
  20. package/dist/guard.js +44 -0
  21. package/dist/guard.js.map +1 -0
  22. package/dist/idle.d.ts +43 -0
  23. package/dist/idle.js +379 -0
  24. package/dist/idle.js.map +1 -0
  25. package/dist/index.d.ts +6 -0
  26. package/dist/index.js +3 -0
  27. package/dist/index.js.map +1 -1
  28. package/dist/inspect.d.ts +11 -0
  29. package/dist/inspect.js +36 -7
  30. package/dist/inspect.js.map +1 -1
  31. package/dist/loading.d.ts +17 -0
  32. package/dist/loading.js +96 -0
  33. package/dist/loading.js.map +1 -0
  34. package/dist/locale.js +1 -1
  35. package/dist/locale.js.map +1 -1
  36. package/dist/methods.js +8 -0
  37. package/dist/methods.js.map +1 -1
  38. package/dist/move.d.ts +40 -0
  39. package/dist/move.js +125 -0
  40. package/dist/move.js.map +1 -0
  41. package/dist/native.d.ts +5 -0
  42. package/dist/native.js.map +1 -1
  43. package/dist/network.d.ts +4 -0
  44. package/dist/network.js +29 -0
  45. package/dist/network.js.map +1 -1
  46. package/dist/place.d.ts +23 -0
  47. package/dist/place.js +66 -0
  48. package/dist/place.js.map +1 -0
  49. package/dist/placekey.d.ts +29 -0
  50. package/dist/placekey.js +134 -0
  51. package/dist/placekey.js.map +1 -0
  52. package/dist/routetree.d.ts +27 -0
  53. package/dist/routetree.js +216 -0
  54. package/dist/routetree.js.map +1 -0
  55. package/dist/types.d.ts +23 -2
  56. package/dist/types.js +5 -1
  57. package/dist/types.js.map +1 -1
  58. package/dist/wait.d.ts +5 -0
  59. package/dist/wait.js +4 -0
  60. package/dist/wait.js.map +1 -1
  61. package/ios/TaplineNativeModule.swift +61 -0
  62. package/package.json +1 -1
@@ -0,0 +1,23 @@
1
+ import type { PlaceState } from './types';
2
+ export { routePattern } from './placekey';
3
+ export type { PlaceState } from './types';
4
+ /**
5
+ * AGENT-TOOLS 1.13 §18.1 and §18.11. Where the app is, as a route key: pattern names, the selected
6
+ * tab and what lies on top. Never a param's value and never text from the screen.
7
+ */
8
+ /** The wire form of a place: the key and when it was read. Answers the `place` request and is the `place` event's data. */
9
+ export interface PlaceData extends PlaceState {
10
+ seenAt: number;
11
+ }
12
+ /** The place now; null when the app has no React roots yet. A walk that fails answers null, never throws. */
13
+ export declare function currentPlace(): PlaceState | null;
14
+ /** The `place` request: no router (or no roots) gives an empty route. */
15
+ export declare function placeData(now?: () => number): PlaceData;
16
+ /**
17
+ * Sends a `place` event now and again whenever the route, the tab or the layer changes, after the commit
18
+ * that changed it (one event per burst of commits, none on a repeat). Returns a function that stops it.
19
+ */
20
+ export declare function startPlaceEvents(options?: {
21
+ debounceMs?: number;
22
+ now?: () => number;
23
+ }): () => void;
package/dist/place.js ADDED
@@ -0,0 +1,66 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.routePattern = void 0;
4
+ exports.currentPlace = currentPlace;
5
+ exports.placeData = placeData;
6
+ exports.startPlaceEvents = startPlaceEvents;
7
+ const alerts_1 = require("./alerts");
8
+ const events_1 = require("./events");
9
+ const inspect_1 = require("./inspect");
10
+ const placekey_1 = require("./placekey");
11
+ const register_1 = require("./register");
12
+ var placekey_2 = require("./placekey");
13
+ Object.defineProperty(exports, "routePattern", { enumerable: true, get: function () { return placekey_2.routePattern; } });
14
+ /** After a commit the app is given this long to finish committing before the place is read (one read per burst). */
15
+ const DEBOUNCE_MS = 40;
16
+ /** The place now; null when the app has no React roots yet. A walk that fails answers null, never throws. */
17
+ function currentPlace() {
18
+ try {
19
+ const parts = (0, inspect_1.placeParts)();
20
+ return parts === null ? null : (0, placekey_1.placeFrom)(parts);
21
+ }
22
+ catch {
23
+ return null;
24
+ }
25
+ }
26
+ /** The `place` request: no router (or no roots) gives an empty route. */
27
+ function placeData(now = Date.now) {
28
+ return { ...(currentPlace() ?? { route: [] }), seenAt: now() };
29
+ }
30
+ /**
31
+ * Sends a `place` event now and again whenever the route, the tab or the layer changes, after the commit
32
+ * that changed it (one event per burst of commits, none on a repeat). Returns a function that stops it.
33
+ */
34
+ function startPlaceEvents(options = {}) {
35
+ const wait = options.debounceMs ?? DEBOUNCE_MS;
36
+ const now = options.now ?? Date.now;
37
+ let last = null;
38
+ let timer;
39
+ let stopped = false;
40
+ const check = () => {
41
+ timer = undefined;
42
+ if (stopped)
43
+ return;
44
+ const place = currentPlace() ?? { route: [] };
45
+ if (last !== null && (0, placekey_1.samePlace)(last, place))
46
+ return;
47
+ last = place;
48
+ (0, events_1.emitEvent)('place', { ...place, seenAt: now() });
49
+ };
50
+ const schedule = () => {
51
+ if (stopped || timer !== undefined)
52
+ return;
53
+ timer = setTimeout(check, wait);
54
+ };
55
+ const stopCommits = (0, register_1.onCommit)(schedule);
56
+ const stopAlerts = (0, alerts_1.onAlertsChange)(schedule);
57
+ check();
58
+ return () => {
59
+ stopped = true;
60
+ if (timer !== undefined)
61
+ clearTimeout(timer);
62
+ stopCommits();
63
+ stopAlerts();
64
+ };
65
+ }
66
+ //# sourceMappingURL=place.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"place.js","sourceRoot":"","sources":["../src/place.ts"],"names":[],"mappings":";;;AAwBA,oCAOC;AAGD,8BAEC;AAMD,4CA6BC;AAvED,qCAA0C;AAC1C,qCAAqC;AACrC,uCAAuC;AACvC,yCAAkD;AAClD,yCAAsC;AAGtC,uCAA0C;AAAjC,wGAAA,YAAY,OAAA;AAarB,oHAAoH;AACpH,MAAM,WAAW,GAAG,EAAE,CAAC;AAEvB,6GAA6G;AAC7G,SAAgB,YAAY;IAC1B,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,IAAA,oBAAU,GAAE,CAAC;QAC3B,OAAO,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAA,oBAAS,EAAC,KAAK,CAAC,CAAC;IAClD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,yEAAyE;AACzE,SAAgB,SAAS,CAAC,MAAoB,IAAI,CAAC,GAAG;IACpD,OAAO,EAAE,GAAG,CAAC,YAAY,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,EAAE,MAAM,EAAE,GAAG,EAAE,EAAE,CAAC;AACjE,CAAC;AAED;;;GAGG;AACH,SAAgB,gBAAgB,CAAC,UAAuD,EAAE;IACxF,MAAM,IAAI,GAAG,OAAO,CAAC,UAAU,IAAI,WAAW,CAAC;IAC/C,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC;IACpC,IAAI,IAAI,GAAsB,IAAI,CAAC;IACnC,IAAI,KAAgD,CAAC;IACrD,IAAI,OAAO,GAAG,KAAK,CAAC;IAEpB,MAAM,KAAK,GAAG,GAAS,EAAE;QACvB,KAAK,GAAG,SAAS,CAAC;QAClB,IAAI,OAAO;YAAE,OAAO;QACpB,MAAM,KAAK,GAAG,YAAY,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC;QAC9C,IAAI,IAAI,KAAK,IAAI,IAAI,IAAA,oBAAS,EAAC,IAAI,EAAE,KAAK,CAAC;YAAE,OAAO;QACpD,IAAI,GAAG,KAAK,CAAC;QACb,IAAA,kBAAS,EAAC,OAAO,EAAE,EAAE,GAAG,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC;IAClD,CAAC,CAAC;IACF,MAAM,QAAQ,GAAG,GAAS,EAAE;QAC1B,IAAI,OAAO,IAAI,KAAK,KAAK,SAAS;YAAE,OAAO;QAC3C,KAAK,GAAG,UAAU,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;IAClC,CAAC,CAAC;IAEF,MAAM,WAAW,GAAG,IAAA,mBAAQ,EAAC,QAAQ,CAAC,CAAC;IACvC,MAAM,UAAU,GAAG,IAAA,uBAAc,EAAC,QAAQ,CAAC,CAAC;IAC5C,KAAK,EAAE,CAAC;IACR,OAAO,GAAG,EAAE;QACV,OAAO,GAAG,IAAI,CAAC;QACf,IAAI,KAAK,KAAK,SAAS;YAAE,YAAY,CAAC,KAAK,CAAC,CAAC;QAC7C,WAAW,EAAE,CAAC;QACd,UAAU,EAAE,CAAC;IACf,CAAC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,29 @@
1
+ import { type Fiber } from './fiber';
2
+ import type { RouteFound, TabFound } from './inspect';
3
+ import { type PlaceState } from './types';
4
+ /**
5
+ * AGENT-TOOLS 1.13 §18.1: a place as a route key. Pure: it reads what the tree walk found and
6
+ * nothing else, so `tree` and the `place` event agree. Never a param's value, never screen text.
7
+ */
8
+ /** What a walk of the tree found that a place is made of. */
9
+ export interface PlaceParts {
10
+ routes: RouteFound[];
11
+ tabs: TabFound[];
12
+ /** The topmost open `Modal`'s host fiber, when one is open. */
13
+ modal: Fiber | null;
14
+ }
15
+ /** Splits each route name on "/" so "trips/[id]" and ["trips","[id]"] agree (answer 12); empty pieces go. */
16
+ export declare function routePattern(names: string[]): string[];
17
+ /**
18
+ * A native tab's route name from its `screenKey`. React Navigation keys are `<route name>-<21-character id>`, so the
19
+ * id is cut only when it is there; a key such as "home-tab" is a name with no id (and a name may hold a hyphen).
20
+ */
21
+ export declare function tabNameFromKey(key: string): string;
22
+ /**
23
+ * Whether a piece of a place looks like a value (an id, a number, a UUID, long hex) and not a name. A place holds
24
+ * patterns, never values (AGENT-TOOLS 1.13 §18.1). The host applies the same rule.
25
+ */
26
+ export declare function looksLikeValue(piece: string): boolean;
27
+ export declare function placeFrom(parts: PlaceParts): PlaceState;
28
+ /** Whether two places are the same key. */
29
+ export declare function samePlace(a: PlaceState | null, b: PlaceState | null): boolean;
@@ -0,0 +1,134 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.routePattern = routePattern;
4
+ exports.tabNameFromKey = tabNameFromKey;
5
+ exports.looksLikeValue = looksLikeValue;
6
+ exports.placeFrom = placeFrom;
7
+ exports.samePlace = samePlace;
8
+ const alerts_1 = require("./alerts");
9
+ const fiber_1 = require("./fiber");
10
+ const types_1 = require("./types");
11
+ /** Splits each route name on "/" so "trips/[id]" and ["trips","[id]"] agree (answer 12); empty pieces go. */
12
+ function routePattern(names) {
13
+ const out = [];
14
+ for (const name of names) {
15
+ for (const piece of name.split('/'))
16
+ if (piece !== '')
17
+ out.push(piece);
18
+ }
19
+ return out;
20
+ }
21
+ const SHEET_PRESENTATIONS = new Set(['formSheet', 'pageSheet', 'sheet']);
22
+ /** The deepest focused route, the last on ties (the same rule as `currentRoute`). */
23
+ function focusedRoute(routes) {
24
+ let best = null;
25
+ for (const route of routes) {
26
+ if (!route.focused)
27
+ continue;
28
+ if (best === null || route.chain.length >= best.chain.length)
29
+ best = route;
30
+ }
31
+ return best;
32
+ }
33
+ /**
34
+ * A native tab's route name from its `screenKey`. React Navigation keys are `<route name>-<21-character id>`, so the
35
+ * id is cut only when it is there; a key such as "home-tab" is a name with no id (and a name may hold a hyphen).
36
+ */
37
+ function tabNameFromKey(key) {
38
+ const match = /^(.+)-[A-Za-z0-9_-]{21}$/.exec(key);
39
+ return match?.[1] ?? key;
40
+ }
41
+ /** Whether `chain` starts with `prefix`. */
42
+ function startsWith(chain, prefix) {
43
+ return prefix.length <= chain.length && prefix.every((name, i) => chain[i] === name);
44
+ }
45
+ /** The root `testID` of a bare Modal's content, or undefined. */
46
+ function modalName(modal) {
47
+ const root = (0, fiber_1.firstHostChild)(modal);
48
+ const id = root ? (0, fiber_1.propsOf)(root).testID : undefined;
49
+ return typeof id === 'string' && id !== '' ? id : undefined;
50
+ }
51
+ /** `/` and `:` never appear in a layer name, so a key stays one piece. */
52
+ function plain(name) {
53
+ return name.replace(/[:/]/g, '_');
54
+ }
55
+ /**
56
+ * Whether a piece of a place looks like a value (an id, a number, a UUID, long hex) and not a name. A place holds
57
+ * patterns, never values (AGENT-TOOLS 1.13 §18.1). The host applies the same rule.
58
+ */
59
+ function looksLikeValue(piece) {
60
+ return (/^\d+$/.test(piece) ||
61
+ /\d{4,}/.test(piece) ||
62
+ /[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/i.test(piece) ||
63
+ /[0-9a-f]{16,}/i.test(piece));
64
+ }
65
+ /** A layer: its kind and, when the name isn't a value, its name. */
66
+ function layerOf(kind, name) {
67
+ return name === undefined || looksLikeValue(name) ? kind : `${kind}:${plain(name)}`;
68
+ }
69
+ /** Whether `fiber` lies inside `outer` (either copy of it). */
70
+ function inside(fiber, outer) {
71
+ for (let up = fiber.return; up; up = up.return) {
72
+ if (up === outer || up === outer.alternate)
73
+ return true;
74
+ }
75
+ return false;
76
+ }
77
+ /**
78
+ * Whether a bare Modal lies above a presented route: the Modal is inside that route's screen (opened from it) and the
79
+ * route is not inside the Modal. When the order can't be told, the route stays the layer, as before.
80
+ */
81
+ function modalAbove(modal, route) {
82
+ return route.fiber !== undefined && inside(modal, route.fiber) && !inside(route.fiber, modal);
83
+ }
84
+ function placeFrom(parts) {
85
+ const current = focusedRoute(parts.routes);
86
+ const chain = current ? current.chain : [];
87
+ const route = routePattern(chain);
88
+ // A route piece that looks like a value can't be a pattern: no route, and the host falls back to its signature.
89
+ const place = { route: route.some(looksLikeValue) ? [] : route };
90
+ const onPath = parts.routes.filter((route) => route.focused && startsWith(chain, route.chain));
91
+ // The selected tab: a tab navigator's selected route, else a native tab bar's selected tab (by its key, never its title).
92
+ for (const route of onPath) {
93
+ let type;
94
+ try {
95
+ const state = route.navigation.getState?.();
96
+ type = (0, types_1.isRecord)(state) ? state.type : undefined;
97
+ }
98
+ catch {
99
+ type = undefined;
100
+ }
101
+ if (type === 'tab') {
102
+ place.tab = route.name;
103
+ break;
104
+ }
105
+ }
106
+ if (place.tab === undefined) {
107
+ const selected = parts.tabs.find((tab) => tab.selected && tab.screenKey !== null);
108
+ if (selected?.screenKey)
109
+ place.tab = tabNameFromKey(selected.screenKey);
110
+ }
111
+ // What lies on top: an alert, else a modal or sheet (a navigation route's name, else a bare Modal's root testID).
112
+ if ((0, alerts_1.openAlerts)().length > 0) {
113
+ place.layer = 'alert';
114
+ }
115
+ else {
116
+ const presented = [...onPath].reverse().find((route) => route.presentation !== undefined);
117
+ if (presented?.presentation !== undefined && !(parts.modal && modalAbove(parts.modal, presented))) {
118
+ place.layer = layerOf(SHEET_PRESENTATIONS.has(presented.presentation) ? 'sheet' : 'modal', presented.name);
119
+ }
120
+ else if (parts.modal) {
121
+ place.layer = layerOf('modal', modalName(parts.modal));
122
+ }
123
+ }
124
+ if (place.tab !== undefined && looksLikeValue(place.tab))
125
+ delete place.tab;
126
+ return place;
127
+ }
128
+ /** Whether two places are the same key. */
129
+ function samePlace(a, b) {
130
+ if (a === null || b === null)
131
+ return a === b;
132
+ return a.tab === b.tab && a.layer === b.layer && a.route.length === b.route.length && a.route.every((name, i) => name === b.route[i]);
133
+ }
134
+ //# sourceMappingURL=placekey.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"placekey.js","sourceRoot":"","sources":["../src/placekey.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * AGENT-TOOLS 1.13 §18.1 ("Known before any visit"): the places an app has, listed from its own route tree. Expo Router's
3
+ * store is an internal API, so it is read behind a guard and any failure answers `source: "none"` (plan answer 21).
4
+ * Values of params never appear here, only their names.
5
+ */
6
+ export interface KnownPlace {
7
+ route: string[];
8
+ /** `<scheme>://<path>`, with `[id]` where a param goes; absent when the app has no scheme or the screen has no path. */
9
+ link?: string;
10
+ /** Param names such as "id"; values never. */
11
+ params: string[];
12
+ }
13
+ export interface KnownPlaces {
14
+ source: 'expo-router' | 'react-navigation' | 'none';
15
+ places: KnownPlace[];
16
+ }
17
+ /**
18
+ * The places in an Expo Router route tree (its `routeNode`): every leaf route, keyed by the layout and route names down to
19
+ * it. Exported for tests; the shape is read defensively, since it is Expo Router's own.
20
+ */
21
+ export declare function placesFromExpoTree(root: unknown, scheme: string | undefined): KnownPlace[];
22
+ /** A custom scheme beats an `https` prefix (the app opens from it directly); wildcard prefixes can't be used. */
23
+ export declare function pickPrefix(prefixes: unknown): string | undefined;
24
+ /** The places in a React Navigation `linking.config`: each leaf screen, keyed by the screen names down to it. Exported for tests. */
25
+ export declare function placesFromLinking(linking: unknown): KnownPlace[];
26
+ /** The `places` request: what the app's own route tree says it has, before any visit. Never throws. */
27
+ export declare function knownPlaces(): KnownPlaces;
@@ -0,0 +1,216 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.placesFromExpoTree = placesFromExpoTree;
4
+ exports.pickPrefix = pickPrefix;
5
+ exports.placesFromLinking = placesFromLinking;
6
+ exports.knownPlaces = knownPlaces;
7
+ const appinfo_1 = require("./appinfo");
8
+ const fiber_1 = require("./fiber");
9
+ const placekey_1 = require("./placekey");
10
+ const register_1 = require("./register");
11
+ const types_1 = require("./types");
12
+ /** Never go deeper than this: a route tree is a few levels; a cycle must not hang the app. */
13
+ const MAX_DEPTH = 12;
14
+ const MAX_PLACES = 500;
15
+ /* -------------------------------------------------------------------------- */
16
+ /* Expo Router */
17
+ /* -------------------------------------------------------------------------- */
18
+ const EXPO_PARAM = /^\[(?:\.\.\.)?([^\]]+)\]$/;
19
+ /** A group segment such as "(tabs)": part of the route key, not of the path. */
20
+ function isGroup(segment) {
21
+ return /^\(.*\)$/.test(segment);
22
+ }
23
+ /** Special files that aren't places a person navigates to: `+not-found`, `_sitemap` and the like. */
24
+ function isSpecial(name) {
25
+ return name.startsWith('+') || name.startsWith('_');
26
+ }
27
+ /**
28
+ * The places in an Expo Router route tree (its `routeNode`): every leaf route, keyed by the layout and route names down to
29
+ * it. Exported for tests; the shape is read defensively, since it is Expo Router's own.
30
+ */
31
+ function placesFromExpoTree(root, scheme) {
32
+ const places = [];
33
+ const visit = (node, names, depth) => {
34
+ if (!(0, types_1.isRecord)(node) || depth > MAX_DEPTH || places.length >= MAX_PLACES)
35
+ return;
36
+ const name = typeof node.route === 'string' ? node.route : '';
37
+ if (isSpecial(name) || node.type === 'api' || node.type === 'redirect' || node.type === 'rewrite')
38
+ return;
39
+ const here = name === '' ? names : [...names, name];
40
+ const children = Array.isArray(node.children) ? node.children : [];
41
+ if (children.length > 0) {
42
+ for (const child of children)
43
+ visit(child, here, depth + 1);
44
+ return;
45
+ }
46
+ if (node.type === 'layout' || here.length === 0)
47
+ return; // a layout with no screens is not a place
48
+ const route = (0, placekey_1.routePattern)(here);
49
+ const params = [];
50
+ for (const segment of route) {
51
+ const match = EXPO_PARAM.exec(segment);
52
+ if (match?.[1] !== undefined && !params.includes(match[1]))
53
+ params.push(match[1]);
54
+ }
55
+ const path = route.filter((segment) => !isGroup(segment) && segment !== 'index');
56
+ const place = { route, params };
57
+ if (scheme !== undefined)
58
+ place.link = `${scheme}://${path.join('/')}`;
59
+ places.push(place);
60
+ };
61
+ visit(root, [], 0);
62
+ return places;
63
+ }
64
+ /**
65
+ * Expo Router 58: the route tree is `routerConfig.routeNode`, the value of `RouterConfigContext`'s provider, which sits
66
+ * above the navigation container. Found through the fibers, the way the linking prop is.
67
+ */
68
+ function findRouterConfigNode() {
69
+ return findInFibers((props) => {
70
+ const value = props.value;
71
+ return (0, types_1.isRecord)(value) && (0, types_1.isRecord)(value.routeNode) && Array.isArray(value.routeNode.children) ? value.routeNode : undefined;
72
+ });
73
+ }
74
+ /** Expo Router 55: `routeNode` from its store, or null. Any failure (not installed, another version) is null. */
75
+ function expoStoreRouteNode() {
76
+ try {
77
+ // The `.js` matters: the package's exports map refuses an extensionless deep path.
78
+ const loaded = require('expo-router/build/global-state/router-store.js');
79
+ const store = (0, types_1.isRecord)(loaded) ? loaded.store : undefined;
80
+ if (!(0, types_1.isRecord)(store))
81
+ return null;
82
+ return store.routeNode ?? null;
83
+ }
84
+ catch {
85
+ return null;
86
+ }
87
+ }
88
+ /* -------------------------------------------------------------------------- */
89
+ /* React Navigation */
90
+ /* -------------------------------------------------------------------------- */
91
+ const NAVIGATION_PARAM = /^:([A-Za-z0-9_]+)\??$/;
92
+ /** A custom scheme beats an `https` prefix (the app opens from it directly); wildcard prefixes can't be used. */
93
+ function pickPrefix(prefixes) {
94
+ if (!Array.isArray(prefixes))
95
+ return undefined;
96
+ const usable = prefixes.filter((prefix) => typeof prefix === 'string' && prefix !== '' && !prefix.includes('*'));
97
+ const custom = usable.find((prefix) => !/^https?:/i.test(prefix));
98
+ return custom ?? usable[0];
99
+ }
100
+ /** `<prefix>/<path>`; a prefix that is only a scheme ("wayfare://") takes the path right after it. */
101
+ function linkFor(prefix, path) {
102
+ const scheme = /^([A-Za-z][A-Za-z0-9+.-]*):\/*$/.exec(prefix);
103
+ if (scheme)
104
+ return `${scheme[1]}://${path}`;
105
+ const base = prefix.replace(/\/+$/, '');
106
+ return path === '' ? base : `${base}/${path}`;
107
+ }
108
+ function joinPath(base, next, exact) {
109
+ const clean = next.replace(/^\/+|\/+$/g, '');
110
+ if (exact || base === '')
111
+ return clean;
112
+ return clean === '' ? base : `${base}/${clean}`;
113
+ }
114
+ /** The places in a React Navigation `linking.config`: each leaf screen, keyed by the screen names down to it. Exported for tests. */
115
+ function placesFromLinking(linking) {
116
+ if (!(0, types_1.isRecord)(linking) || !(0, types_1.isRecord)(linking.config))
117
+ return [];
118
+ const prefix = pickPrefix(linking.prefixes);
119
+ const places = [];
120
+ const visit = (screens, names, base, depth) => {
121
+ if (!(0, types_1.isRecord)(screens) || depth > MAX_DEPTH)
122
+ return;
123
+ for (const [name, entry] of Object.entries(screens)) {
124
+ if (places.length >= MAX_PLACES)
125
+ return;
126
+ const here = [...names, name];
127
+ let path = base;
128
+ let nestedScreens;
129
+ if (typeof entry === 'string') {
130
+ path = joinPath(base, entry, false);
131
+ }
132
+ else if ((0, types_1.isRecord)(entry)) {
133
+ if (typeof entry.path === 'string')
134
+ path = joinPath(base, entry.path, entry.exact === true);
135
+ nestedScreens = entry.screens;
136
+ }
137
+ if ((0, types_1.isRecord)(nestedScreens) && Object.keys(nestedScreens).length > 0) {
138
+ visit(nestedScreens, here, path, depth + 1);
139
+ continue;
140
+ }
141
+ const params = [];
142
+ for (const segment of path.split('/')) {
143
+ const match = NAVIGATION_PARAM.exec(segment);
144
+ if (match?.[1] !== undefined && !params.includes(match[1]))
145
+ params.push(match[1]);
146
+ }
147
+ const place = { route: (0, placekey_1.routePattern)(here), params };
148
+ // A path that is only the base prefix is the app's root; a screen with no path at all has no link.
149
+ const hasPath = typeof entry === 'string' || ((0, types_1.isRecord)(entry) && typeof entry.path === 'string');
150
+ if (prefix !== undefined && hasPath) {
151
+ place.link = linkFor(prefix, path.replace(/:([A-Za-z0-9_]+)\??/g, '[$1]'));
152
+ }
153
+ places.push(place);
154
+ }
155
+ };
156
+ visit(linking.config.screens, [], '', 0);
157
+ return places;
158
+ }
159
+ /** The first thing `pick` returns for a fiber's props, walking the tree from the root, child first; null when none. */
160
+ function findInFibers(pick) {
161
+ for (const root of (0, register_1.getRoots)()) {
162
+ const stack = root.current.child ? [root.current.child] : [];
163
+ let visited = 0;
164
+ for (let fiber = stack.pop(); fiber && visited < 5000; fiber = stack.pop()) {
165
+ visited += 1;
166
+ const found = pick((0, fiber_1.propsOf)(fiber));
167
+ if (found !== undefined)
168
+ return found;
169
+ if (fiber.sibling)
170
+ stack.push(fiber.sibling);
171
+ if (fiber.child)
172
+ stack.push(fiber.child);
173
+ }
174
+ }
175
+ return null;
176
+ }
177
+ /** The `linking` prop of the app's `NavigationContainer`, found through the fibers. */
178
+ function findLinking() {
179
+ return findInFibers((props) => ((0, types_1.isRecord)(props.linking) && (0, types_1.isRecord)(props.linking.config) ? props.linking : undefined));
180
+ }
181
+ /* -------------------------------------------------------------------------- */
182
+ /* The request */
183
+ /* -------------------------------------------------------------------------- */
184
+ /** The `places` request: what the app's own route tree says it has, before any visit. Never throws. */
185
+ function knownPlaces() {
186
+ try {
187
+ const scheme = (0, appinfo_1.appScheme)();
188
+ for (const read of [findRouterConfigNode, expoStoreRouteNode]) {
189
+ let node = null;
190
+ try {
191
+ node = read();
192
+ }
193
+ catch {
194
+ node = null; // an internal API that changed: try the next way
195
+ }
196
+ if (node === null)
197
+ continue;
198
+ const places = placesFromExpoTree(node, scheme);
199
+ if (places.length > 0)
200
+ return { source: 'expo-router', places };
201
+ }
202
+ }
203
+ catch {
204
+ // fall through
205
+ }
206
+ try {
207
+ const places = placesFromLinking(findLinking());
208
+ if (places.length > 0)
209
+ return { source: 'react-navigation', places };
210
+ }
211
+ catch {
212
+ // not a navigation app
213
+ }
214
+ return { source: 'none', places: [] };
215
+ }
216
+ //# sourceMappingURL=routetree.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"routetree.js","sourceRoot":"","sources":["../src/routetree.ts"],"names":[],"mappings":"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"}
package/dist/types.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  /** Wire-protocol and shared types (see docs/PROTOCOL.md, version 1). */
2
2
  export declare const PROTOCOL_VERSION = 1;
3
- export type ErrorCode = 'not_found' | 'ambiguous' | 'not_actionable' | 'unsupported' | 'bad_params' | 'timeout' | 'internal';
3
+ export type ErrorCode = 'not_found' | 'ambiguous' | 'not_actionable' | 'unsupported' | 'bad_params' | 'timeout' | 'stale' | 'internal';
4
4
  export interface WireError {
5
5
  code: ErrorCode;
6
6
  message: string;
@@ -8,13 +8,22 @@ export interface WireError {
8
8
  refs?: string[];
9
9
  /** The candidates as elements (role, id, actions, frame), only for `ambiguous`. */
10
10
  candidates?: TaplineElement[];
11
+ /** Facts about a refusal that carry no text from the app (whether a field is secure, never its value). */
12
+ data?: {
13
+ secure: boolean;
14
+ };
11
15
  }
12
16
  /** An error that maps 1:1 onto a protocol error response. */
13
17
  export declare class TaplineError extends Error {
14
18
  readonly code: ErrorCode;
15
19
  readonly refs: string[] | undefined;
16
20
  readonly candidates: TaplineElement[] | undefined;
17
- constructor(code: ErrorCode, message: string, refs?: string[], candidates?: TaplineElement[]);
21
+ readonly data: {
22
+ secure: boolean;
23
+ } | undefined;
24
+ constructor(code: ErrorCode, message: string, refs?: string[], candidates?: TaplineElement[], data?: {
25
+ secure: boolean;
26
+ });
18
27
  toWire(): WireError;
19
28
  }
20
29
  export interface Frame {
@@ -45,6 +54,8 @@ export interface TaplineElement {
45
54
  selected: boolean;
46
55
  /** true / false / 'mixed' for checkable controls (Switch, checkbox role), else null. */
47
56
  checked: boolean | 'mixed' | null;
57
+ /** Inside a virtualized list's item: its text is content, so the host never saves it (AGENT-TOOLS 1.13 §18.2). */
58
+ row?: true;
48
59
  }
49
60
  export interface ScreenInfo {
50
61
  width: number;
@@ -119,12 +130,22 @@ export interface TreeResult {
119
130
  inFlight?: number;
120
131
  condition?: 'offline' | '3g' | 'lossy';
121
132
  };
133
+ /** Present (as "fast") while the `animations` command has fast-forwarded animations. */
134
+ animations?: 'fast';
122
135
  /** True while the software keyboard is up; absent when it is down or isn't known. */
123
136
  keyboard?: true;
124
137
  /** The focused screen, when the app uses React Navigation (Expo Router included). */
125
138
  route?: RouteInfo;
126
139
  /** With `changes: true` and a previous tree: what changed since then. */
127
140
  changes?: TreeChanges;
141
+ /** Where the app is: route pattern, tab and layer, never params (AGENT-TOOLS 1.13 §18.1). Always present: `route` is empty without a router. */
142
+ place?: PlaceState;
143
+ }
144
+ /** A place as a route key: route patterns only, never a param's value or any screen text. */
145
+ export interface PlaceState {
146
+ route: string[];
147
+ tab?: string;
148
+ layer?: string;
128
149
  }
129
150
  export type Target = {
130
151
  ref: string;
package/dist/types.js CHANGED
@@ -9,12 +9,14 @@ class TaplineError extends Error {
9
9
  code;
10
10
  refs;
11
11
  candidates;
12
- constructor(code, message, refs, candidates) {
12
+ data;
13
+ constructor(code, message, refs, candidates, data) {
13
14
  super(message);
14
15
  this.name = 'TaplineError';
15
16
  this.code = code;
16
17
  this.refs = refs;
17
18
  this.candidates = candidates;
19
+ this.data = data;
18
20
  }
19
21
  toWire() {
20
22
  const wire = { code: this.code, message: this.message };
@@ -22,6 +24,8 @@ class TaplineError extends Error {
22
24
  wire.refs = this.refs;
23
25
  if (this.candidates)
24
26
  wire.candidates = this.candidates;
27
+ if (this.data)
28
+ wire.data = this.data;
25
29
  return wire;
26
30
  }
27
31
  }
package/dist/types.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":";AAAA,wEAAwE;;;AA6LxE,4BAEC;AA7LY,QAAA,gBAAgB,GAAG,CAAC,CAAC;AAoBlC,6DAA6D;AAC7D,MAAa,YAAa,SAAQ,KAAK;IAC5B,IAAI,CAAY;IAChB,IAAI,CAAuB;IAC3B,UAAU,CAA+B;IAElD,YAAY,IAAe,EAAE,OAAe,EAAE,IAAe,EAAE,UAA6B;QAC1F,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,cAAc,CAAC;QAC3B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;IAC/B,CAAC;IAED,MAAM;QACJ,MAAM,IAAI,GAAc,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC;QACnE,IAAI,IAAI,CAAC,IAAI;YAAE,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;QACrC,IAAI,IAAI,CAAC,UAAU;YAAE,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC;QACvD,OAAO,IAAI,CAAC;IACd,CAAC;CACF;AAnBD,oCAmBC;AAmJD,SAAgB,QAAQ,CAAC,KAAc;IACrC,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;AAC9E,CAAC"}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":";AAAA,wEAAwE;;;AAgNxE,4BAEC;AAhNY,QAAA,gBAAgB,GAAG,CAAC,CAAC;AAuBlC,6DAA6D;AAC7D,MAAa,YAAa,SAAQ,KAAK;IAC5B,IAAI,CAAY;IAChB,IAAI,CAAuB;IAC3B,UAAU,CAA+B;IACzC,IAAI,CAAkC;IAE/C,YAAY,IAAe,EAAE,OAAe,EAAE,IAAe,EAAE,UAA6B,EAAE,IAA0B;QACtH,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,cAAc,CAAC;QAC3B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;QAC7B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACnB,CAAC;IAED,MAAM;QACJ,MAAM,IAAI,GAAc,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC;QACnE,IAAI,IAAI,CAAC,IAAI;YAAE,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;QACrC,IAAI,IAAI,CAAC,UAAU;YAAE,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC;QACvD,IAAI,IAAI,CAAC,IAAI;YAAE,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;QACrC,OAAO,IAAI,CAAC;IACd,CAAC;CACF;AAtBD,oCAsBC;AAgKD,SAAgB,QAAQ,CAAC,KAAc;IACrC,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;AAC9E,CAAC"}
package/dist/wait.d.ts CHANGED
@@ -1,6 +1,11 @@
1
1
  type IdleProvider = () => boolean;
2
2
  /** Where "the network is quiet" comes from (the network tracker; tests). Null restores "always quiet". */
3
3
  export declare function setNetworkIdleProvider(provider: IdleProvider | null): void;
4
+ export declare function waitFor(raw: {
5
+ once: true;
6
+ } & Record<string, unknown>): Promise<{
7
+ found: boolean;
8
+ }>;
4
9
  export declare function waitFor(raw: unknown): Promise<{
5
10
  met: true;
6
11
  waitedMs: number;