react-native-tapline 0.0.0-stage → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (88) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +86 -2
  3. package/TaplineNative.podspec +14 -0
  4. package/dist/actions.d.ts +203 -0
  5. package/dist/actions.js +1991 -0
  6. package/dist/actions.js.map +1 -0
  7. package/dist/agent.d.ts +117 -0
  8. package/dist/agent.js +352 -0
  9. package/dist/agent.js.map +1 -0
  10. package/dist/alerts.d.ts +35 -0
  11. package/dist/alerts.js +437 -0
  12. package/dist/alerts.js.map +1 -0
  13. package/dist/awake.d.ts +2 -0
  14. package/dist/awake.js +53 -0
  15. package/dist/awake.js.map +1 -0
  16. package/dist/checks.d.ts +35 -0
  17. package/dist/checks.js +501 -0
  18. package/dist/checks.js.map +1 -0
  19. package/dist/client.d.ts +111 -0
  20. package/dist/client.js +446 -0
  21. package/dist/client.js.map +1 -0
  22. package/dist/commands.d.ts +24 -0
  23. package/dist/commands.js +111 -0
  24. package/dist/commands.js.map +1 -0
  25. package/dist/events.d.ts +5 -0
  26. package/dist/events.js +22 -0
  27. package/dist/events.js.map +1 -0
  28. package/dist/feed.d.ts +117 -0
  29. package/dist/feed.js +440 -0
  30. package/dist/feed.js.map +1 -0
  31. package/dist/fiber.d.ts +43 -0
  32. package/dist/fiber.js +100 -0
  33. package/dist/fiber.js.map +1 -0
  34. package/dist/index.d.ts +50 -0
  35. package/dist/index.js +181 -0
  36. package/dist/index.js.map +1 -0
  37. package/dist/inspect.d.ts +249 -0
  38. package/dist/inspect.js +1354 -0
  39. package/dist/inspect.js.map +1 -0
  40. package/dist/keyboard.d.ts +10 -0
  41. package/dist/keyboard.js +63 -0
  42. package/dist/keyboard.js.map +1 -0
  43. package/dist/link.d.ts +21 -0
  44. package/dist/link.js +63 -0
  45. package/dist/link.js.map +1 -0
  46. package/dist/live.d.ts +30 -0
  47. package/dist/live.js +279 -0
  48. package/dist/live.js.map +1 -0
  49. package/dist/logs.d.ts +16 -0
  50. package/dist/logs.js +171 -0
  51. package/dist/logs.js.map +1 -0
  52. package/dist/methods.d.ts +3 -0
  53. package/dist/methods.js +49 -0
  54. package/dist/methods.js.map +1 -0
  55. package/dist/native.d.ts +34 -0
  56. package/dist/native.js +63 -0
  57. package/dist/native.js.map +1 -0
  58. package/dist/network.d.ts +27 -0
  59. package/dist/network.js +238 -0
  60. package/dist/network.js.map +1 -0
  61. package/dist/register.d.ts +24 -0
  62. package/dist/register.js +180 -0
  63. package/dist/register.js.map +1 -0
  64. package/dist/settle.d.ts +27 -0
  65. package/dist/settle.js +70 -0
  66. package/dist/settle.js.map +1 -0
  67. package/dist/source.d.ts +60 -0
  68. package/dist/source.js +214 -0
  69. package/dist/source.js.map +1 -0
  70. package/dist/storage.d.ts +10 -0
  71. package/dist/storage.js +45 -0
  72. package/dist/storage.js.map +1 -0
  73. package/dist/touches.d.ts +15 -0
  74. package/dist/touches.js +89 -0
  75. package/dist/touches.js.map +1 -0
  76. package/dist/types.d.ts +168 -0
  77. package/dist/types.js +32 -0
  78. package/dist/types.js.map +1 -0
  79. package/dist/wait.d.ts +8 -0
  80. package/dist/wait.js +99 -0
  81. package/dist/wait.js.map +1 -0
  82. package/expo-module.config.json +7 -0
  83. package/ios/TaplineNativeModule.swift +79 -0
  84. package/metro.d.ts +26 -0
  85. package/metro.js +146 -0
  86. package/package.json +100 -4
  87. package/register.d.ts +1 -0
  88. package/register.js +3 -0
@@ -0,0 +1,180 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.commitRevision = commitRevision;
4
+ exports.onCommit = onCommit;
5
+ exports.installHook = installHook;
6
+ exports.getRoots = getRoots;
7
+ exports.resetRegistry = resetRegistry;
8
+ /**
9
+ * Import this FIRST in the app's entry file, before React / React Native:
10
+ *
11
+ * import 'react-native-tapline/register';
12
+ *
13
+ * It installs a minimal React DevTools global hook (or wraps the existing one,
14
+ * chaining every call) so Tapline can see the app's fiber roots. This file must
15
+ * not import react or react-native.
16
+ */
17
+ const fiber_1 = require("./fiber");
18
+ const types_1 = require("./types");
19
+ const WRAPPED = Symbol.for('tapline.hookWrapped');
20
+ /** renderer id -> roots seen via onCommitFiberRoot */
21
+ const rootsByRenderer = new Map();
22
+ let installedHook = null;
23
+ /** How many React commits have happened: the screen's revision, for the live viewer. */
24
+ let revision = 0;
25
+ const commitListeners = new Set();
26
+ function committed() {
27
+ revision += 1;
28
+ for (const listener of commitListeners)
29
+ safely(() => listener(revision));
30
+ }
31
+ /** The number of React commits so far; it changes whenever the UI may have changed. */
32
+ function commitRevision() {
33
+ return revision;
34
+ }
35
+ /** Called after every React commit with the new revision; returns a function that stops it. */
36
+ function onCommit(listener) {
37
+ commitListeners.add(listener);
38
+ return () => {
39
+ commitListeners.delete(listener);
40
+ };
41
+ }
42
+ function record(rendererId, root) {
43
+ if (!(0, fiber_1.isFiberRoot)(root))
44
+ return;
45
+ let set = rootsByRenderer.get(rendererId);
46
+ if (!set) {
47
+ set = new Set();
48
+ rootsByRenderer.set(rendererId, set);
49
+ }
50
+ // A root with no children has been unmounted.
51
+ if (root.current.child === null)
52
+ set.delete(root);
53
+ else
54
+ set.add(root);
55
+ }
56
+ function forgetByFiber(fiber) {
57
+ if (!(0, fiber_1.isFiber)(fiber) || fiber.tag !== fiber_1.HostRoot)
58
+ return;
59
+ for (const set of rootsByRenderer.values()) {
60
+ for (const root of set) {
61
+ if (root.current === fiber || root.current.alternate === fiber || root === fiber.stateNode) {
62
+ set.delete(root);
63
+ }
64
+ }
65
+ }
66
+ }
67
+ function numberArg(value) {
68
+ return typeof value === 'number' ? value : 0;
69
+ }
70
+ function safely(fn) {
71
+ try {
72
+ fn();
73
+ }
74
+ catch {
75
+ // never break React because of Tapline
76
+ }
77
+ }
78
+ function wrap(hook, name, before) {
79
+ const previous = hook[name];
80
+ const wrapped = function (...args) {
81
+ safely(() => before(args));
82
+ return typeof previous === 'function' ? previous.apply(hook, args) : undefined;
83
+ };
84
+ hook[name] = wrapped;
85
+ }
86
+ function createHook() {
87
+ let nextId = 1;
88
+ const hook = {
89
+ supportsFiber: true,
90
+ renderers: new Map(),
91
+ inject(renderer) {
92
+ const id = nextId++;
93
+ hook.renderers?.set(id, renderer);
94
+ return id;
95
+ },
96
+ onCommitFiberRoot() { },
97
+ onCommitFiberUnmount() { },
98
+ onPostCommitFiberRoot() { },
99
+ checkDCE() { },
100
+ onScheduleFiberRoot() { },
101
+ setStrictMode() { },
102
+ sub() {
103
+ return () => { };
104
+ },
105
+ on() { },
106
+ off() { },
107
+ emit() { },
108
+ getFiberRoots(rendererId) {
109
+ return rootsByRenderer.get(rendererId) ?? new Set();
110
+ },
111
+ };
112
+ return hook;
113
+ }
114
+ /**
115
+ * Install (or wrap) the hook on `target` (default: globalThis). Idempotent per
116
+ * hook object. Returns the hook in effect.
117
+ */
118
+ function installHook(target = globalThis) {
119
+ const holder = target;
120
+ const existing = holder.__REACT_DEVTOOLS_GLOBAL_HOOK__;
121
+ let hook;
122
+ if ((0, types_1.isRecord)(existing)) {
123
+ hook = existing;
124
+ if (Object.prototype.hasOwnProperty.call(hook, WRAPPED)) {
125
+ installedHook = hook;
126
+ return hook;
127
+ }
128
+ }
129
+ else {
130
+ hook = createHook();
131
+ try {
132
+ Object.defineProperty(target, '__REACT_DEVTOOLS_GLOBAL_HOOK__', {
133
+ configurable: true,
134
+ enumerable: false,
135
+ writable: true,
136
+ value: hook,
137
+ });
138
+ }
139
+ catch {
140
+ holder.__REACT_DEVTOOLS_GLOBAL_HOOK__ = hook;
141
+ }
142
+ }
143
+ wrap(hook, 'onCommitFiberRoot', (args) => {
144
+ record(numberArg(args[0]), args[1]);
145
+ committed();
146
+ });
147
+ wrap(hook, 'onCommitFiberUnmount', (args) => forgetByFiber(args[1]));
148
+ Object.defineProperty(hook, WRAPPED, { value: true, enumerable: false });
149
+ installedHook = hook;
150
+ return hook;
151
+ }
152
+ /** All live fiber roots known to Tapline. */
153
+ function getRoots() {
154
+ const found = new Set();
155
+ for (const set of rootsByRenderer.values())
156
+ for (const root of set)
157
+ found.add(root);
158
+ // An already-present DevTools hook may know roots committed before we wrapped it.
159
+ const hook = installedHook;
160
+ if (hook && hook.renderers instanceof Map && typeof hook.getFiberRoots === 'function') {
161
+ for (const id of hook.renderers.keys()) {
162
+ safely(() => {
163
+ const roots = hook.getFiberRoots?.(id);
164
+ if (roots instanceof Set) {
165
+ for (const root of roots)
166
+ if ((0, fiber_1.isFiberRoot)(root))
167
+ found.add(root);
168
+ }
169
+ });
170
+ }
171
+ }
172
+ return [...found].filter((root) => root.current.child !== null);
173
+ }
174
+ /** Test helper: forget recorded roots and the installed-hook memory. */
175
+ function resetRegistry() {
176
+ rootsByRenderer.clear();
177
+ installedHook = null;
178
+ }
179
+ installHook();
180
+ //# sourceMappingURL=register.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"register.js","sourceRoot":"","sources":["../src/register.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * AGENT-TOOLS §6: the screen counts as still after `quietMs` without a React commit, with a cap.
3
+ * Resolves with the milliseconds waited. Native-driver animations don't commit, so the tree can be
4
+ * still while pixels move; that's fine for an element list.
5
+ */
6
+ export declare function waitUntilStill(options: {
7
+ quietMs: number;
8
+ capMs: number;
9
+ onCommit: (listener: () => void) => () => void;
10
+ now: () => number;
11
+ /** Called when the wait ended at the cap, with the screen still changing. */
12
+ onCap?: () => void;
13
+ }): Promise<number>;
14
+ /**
15
+ * After the commits stop, a native-driver animation (a sheet sliding up) can still be moving.
16
+ * Polls `measure` every `pollMs` and resolves with the milliseconds waited once two readings in a
17
+ * row agree within 1 pt in x and y, or at `capMs`. A null reading (can't be measured) ends the wait.
18
+ */
19
+ export declare function waitUntilSteady(measure: () => Promise<{
20
+ x: number;
21
+ y: number;
22
+ } | null>, options: {
23
+ pollMs: number;
24
+ capMs: number;
25
+ now: () => number;
26
+ onCap?: () => void;
27
+ }): Promise<number>;
package/dist/settle.js ADDED
@@ -0,0 +1,70 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.waitUntilStill = waitUntilStill;
4
+ exports.waitUntilSteady = waitUntilSteady;
5
+ /**
6
+ * AGENT-TOOLS §6: the screen counts as still after `quietMs` without a React commit, with a cap.
7
+ * Resolves with the milliseconds waited. Native-driver animations don't commit, so the tree can be
8
+ * still while pixels move; that's fine for an element list.
9
+ */
10
+ function waitUntilStill(options) {
11
+ const started = options.now();
12
+ return new Promise((resolve) => {
13
+ let done = false;
14
+ let quiet;
15
+ let unsubscribe = () => undefined;
16
+ const finish = () => {
17
+ if (done)
18
+ return;
19
+ done = true;
20
+ if (quiet !== undefined)
21
+ clearTimeout(quiet);
22
+ clearTimeout(cap);
23
+ unsubscribe();
24
+ resolve(Math.max(0, Math.min(options.capMs, options.now() - started)));
25
+ };
26
+ const cap = setTimeout(() => {
27
+ if (!done)
28
+ options.onCap?.();
29
+ finish();
30
+ }, options.capMs);
31
+ const restart = () => {
32
+ if (done)
33
+ return;
34
+ if (quiet !== undefined)
35
+ clearTimeout(quiet);
36
+ quiet = setTimeout(finish, options.quietMs);
37
+ };
38
+ unsubscribe = options.onCommit(restart);
39
+ restart();
40
+ });
41
+ }
42
+ /**
43
+ * After the commits stop, a native-driver animation (a sheet sliding up) can still be moving.
44
+ * Polls `measure` every `pollMs` and resolves with the milliseconds waited once two readings in a
45
+ * row agree within 1 pt in x and y, or at `capMs`. A null reading (can't be measured) ends the wait.
46
+ */
47
+ async function waitUntilSteady(measure, options) {
48
+ const started = options.now();
49
+ const elapsed = () => Math.max(0, Math.min(options.capMs, options.now() - started));
50
+ if (options.capMs <= 0)
51
+ return 0;
52
+ let previous = await measure();
53
+ if (previous === null)
54
+ return 0;
55
+ for (;;) {
56
+ const left = options.capMs - (options.now() - started);
57
+ if (left <= 0) {
58
+ options.onCap?.();
59
+ return elapsed();
60
+ }
61
+ await new Promise((resolve) => setTimeout(resolve, Math.min(options.pollMs, left)));
62
+ const next = await measure();
63
+ if (next === null)
64
+ return elapsed();
65
+ if (Math.abs(next.x - previous.x) <= 1 && Math.abs(next.y - previous.y) <= 1)
66
+ return elapsed();
67
+ previous = next;
68
+ }
69
+ }
70
+ //# sourceMappingURL=settle.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"settle.js","sourceRoot":"","sources":["../src/settle.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,60 @@
1
+ import { type Fiber } from './fiber';
2
+ /**
3
+ * Source locations (Tapline 1.1, development builds): which component draws an element and which line of
4
+ * the app's code wrote it. React 19 keeps, on every fiber, the stack captured where its JSX element was
5
+ * created (`_debugStack`). The frames point into the bundle Metro serves; Metro's own `/symbolicate`
6
+ * turns them back into the app's files and lines. The first frame outside node_modules is the line that
7
+ * wrote the element. Nothing here runs unless the agent asks.
8
+ */
9
+ export interface SourceLocation {
10
+ /** The file as Metro reports it (absolute on the computer that serves the bundle). */
11
+ file: string;
12
+ line: number;
13
+ column: number;
14
+ /** The component whose render wrote the element, e.g. "SignUpScreen". */
15
+ component: string | null;
16
+ /** True when this is the element's own line; false when a library drew it and this is the app line around it. */
17
+ direct: boolean;
18
+ }
19
+ export interface ElementSource {
20
+ /** Components from the screen down to the element, app components first (at most 6). */
21
+ components: string[];
22
+ /** Where the app's code wrote this element (or its nearest ancestor the app wrote); null when unknown. */
23
+ location: SourceLocation | null;
24
+ /**
25
+ * When `location` is inside one of the app's own components (a shared button): where the screen uses that
26
+ * component, so a developer goes straight to the use as well as to the inside. Absent otherwise.
27
+ */
28
+ usedAt?: SourceLocation[];
29
+ /** The props of the component the app wrote, in short: strings, numbers, booleans, handler names. */
30
+ props: Record<string, string>;
31
+ }
32
+ interface Frame {
33
+ file: string;
34
+ lineNumber: number;
35
+ column: number;
36
+ methodName: string;
37
+ }
38
+ type FetchLike = (url: string, init: {
39
+ method: string;
40
+ headers: Record<string, string>;
41
+ body: string;
42
+ }) => Promise<{
43
+ ok: boolean;
44
+ json(): Promise<unknown>;
45
+ }>;
46
+ /** Replace the HTTP client (tests); null restores the global fetch. */
47
+ export declare function setSourceFetch(next: FetchLike | null): void;
48
+ /** The stack React captured where this fiber's element was created, as frames; empty when there is none. */
49
+ export declare function framesOf(fiber: Fiber): Frame[];
50
+ /** A file of the app's own code (not a library, not React's internals). */
51
+ export declare function isAppFile(file: string): boolean;
52
+ /**
53
+ * Where the app wrote these elements. One request to Metro for all of them. `fibers` are the host fibers
54
+ * of the elements; for one written inside a library component (a TextInput's native view), the nearest
55
+ * ancestor the app's code wrote is used.
56
+ */
57
+ export declare function sourcesOf(fibers: Fiber[]): Promise<ElementSource[]>;
58
+ /** Forget mapped positions (after a reload the bundle's lines change; tests). */
59
+ export declare function clearSourceCache(): void;
60
+ export {};
package/dist/source.js ADDED
@@ -0,0 +1,214 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.setSourceFetch = setSourceFetch;
4
+ exports.framesOf = framesOf;
5
+ exports.isAppFile = isAppFile;
6
+ exports.sourcesOf = sourcesOf;
7
+ exports.clearSourceCache = clearSourceCache;
8
+ const fiber_1 = require("./fiber");
9
+ const types_1 = require("./types");
10
+ let fetcher = null;
11
+ /** Replace the HTTP client (tests); null restores the global fetch. */
12
+ function setSourceFetch(next) {
13
+ fetcher = next;
14
+ }
15
+ function http() {
16
+ if (fetcher)
17
+ return fetcher;
18
+ const global = globalThis.fetch;
19
+ return typeof global === 'function' ? global : null;
20
+ }
21
+ /** The stack React captured where this fiber's element was created, as frames; empty when there is none. */
22
+ function framesOf(fiber) {
23
+ const stack = fiber._debugStack;
24
+ const text = (0, types_1.isRecord)(stack) && typeof stack.stack === 'string' ? stack.stack : typeof stack === 'string' ? stack : '';
25
+ const frames = [];
26
+ for (const line of text.split('\n')) {
27
+ // Hermes and V8: "at name (url:line:col)" or "at url:line:col"
28
+ const m = /^\s*at\s+(?:(.*?)\s+\()?(.+?):(\d+):(\d+)\)?\s*$/.exec(line);
29
+ if (!m)
30
+ continue;
31
+ const file = m[2].replace(/^address at\s+/, '');
32
+ frames.push({ methodName: m[1] ?? '', file, lineNumber: Number(m[3]), column: Number(m[4]) });
33
+ }
34
+ return frames;
35
+ }
36
+ /** Metro's address, from a bundle URL in a frame: "http://192.168.1.20:8081". */
37
+ function metroOrigin(frames) {
38
+ for (const frame of frames) {
39
+ const m = /^(https?:\/\/[^/]+)\//.exec(frame.file);
40
+ if (m)
41
+ return m[1];
42
+ }
43
+ return null;
44
+ }
45
+ const cache = new Map();
46
+ const keyOf = (f) => `${f.file}:${f.lineNumber}:${f.column}`;
47
+ /** Asks Metro for the original positions of these frames; frames it can't map come back null. */
48
+ async function symbolicate(frames) {
49
+ const missing = frames.filter((f) => !cache.has(keyOf(f)));
50
+ const origin = metroOrigin(missing);
51
+ const client = http();
52
+ if (missing.length > 0 && origin && client) {
53
+ try {
54
+ const res = await client(`${origin}/symbolicate`, {
55
+ method: 'POST',
56
+ headers: { 'Content-Type': 'application/json' },
57
+ body: JSON.stringify({ stack: missing }),
58
+ });
59
+ const body = res.ok ? await res.json() : null;
60
+ const out = (0, types_1.isRecord)(body) && Array.isArray(body.stack) ? body.stack : [];
61
+ missing.forEach((frame, i) => {
62
+ const mapped = out[i];
63
+ cache.set(keyOf(frame), (0, types_1.isRecord)(mapped) && typeof mapped.file === 'string' && typeof mapped.lineNumber === 'number'
64
+ ? {
65
+ file: mapped.file,
66
+ lineNumber: mapped.lineNumber,
67
+ column: typeof mapped.column === 'number' ? mapped.column : 0,
68
+ methodName: typeof mapped.methodName === 'string' ? mapped.methodName : '',
69
+ }
70
+ : null);
71
+ });
72
+ }
73
+ catch {
74
+ // Metro unreachable: no locations this time; try again next call.
75
+ return frames.map(() => null);
76
+ }
77
+ }
78
+ return frames.map((f) => cache.get(keyOf(f)) ?? null);
79
+ }
80
+ /** A file of the app's own code (not a library, not React's internals). */
81
+ function isAppFile(file) {
82
+ return !/[\\/]node_modules[\\/]/.test(file) && !/^https?:/.test(file) && !/^\[native code\]$/.test(file);
83
+ }
84
+ const INTERNAL = /^(View|Text|RCT|Animated|Virtualized|ScrollView|Pressable|TouchableOpacity|TouchableHighlight|TouchableWithoutFeedback|TextInput|Image|Context|Provider|Consumer|Fragment)/;
85
+ /** The composite components above a fiber, nearest first. */
86
+ function compositesAbove(fiber, limit) {
87
+ const out = [];
88
+ for (let f = fiber; f && out.length < limit; f = f.return) {
89
+ if ((0, fiber_1.isCompositeTag)(f.tag))
90
+ out.push(f);
91
+ }
92
+ return out;
93
+ }
94
+ function shortProps(fiber) {
95
+ const out = {};
96
+ for (const [key, value] of Object.entries((0, fiber_1.propsOf)(fiber))) {
97
+ if (key === 'children' || key === 'style' || Object.keys(out).length >= 8)
98
+ continue;
99
+ if (typeof value === 'string')
100
+ out[key] = JSON.stringify(value.length > 40 ? `${value.slice(0, 40)}…` : value);
101
+ else if (typeof value === 'number' || typeof value === 'boolean')
102
+ out[key] = String(value);
103
+ else if (typeof value === 'function')
104
+ out[key] = `${value.name || 'function'}()`;
105
+ }
106
+ return out;
107
+ }
108
+ /**
109
+ * Whether the component the app wrote is the element itself, wrapped: it was given the element's own
110
+ * testID, accessibility label or text (a Pressable, a TextInput, a Text). A tab bar button gets its testID
111
+ * from the navigator's options instead, so the navigator's line is only the line around it.
112
+ */
113
+ function sameIdentity(host, wrote) {
114
+ const own = (0, fiber_1.propsOf)(host);
115
+ const given = (0, fiber_1.propsOf)(wrote);
116
+ for (const key of ['testID', 'nativeID', 'accessibilityLabel', 'aria-label']) {
117
+ const value = own[key];
118
+ if (typeof value === 'string' && value !== '' && given[key] === value)
119
+ return true;
120
+ }
121
+ return typeof own.children === 'string' && own.children !== '' && given.children === own.children;
122
+ }
123
+ /**
124
+ * Where the app wrote these elements. One request to Metro for all of them. `fibers` are the host fibers
125
+ * of the elements; for one written inside a library component (a TextInput's native view), the nearest
126
+ * ancestor the app's code wrote is used.
127
+ */
128
+ async function sourcesOf(fibers) {
129
+ // For each element: the fibers to try, nearest first (the host fiber, then the composites above it, up to
130
+ // the screen). An element a library drew (a tab bar button) maps to the app line that set the library up.
131
+ const chains = fibers.map((fiber) => [fiber, ...compositesAbove(fiber.return ?? fiber, 60)]);
132
+ const allFrames = [];
133
+ const spans = chains.map((chain) => chain.map((f) => {
134
+ const frames = framesOf(f).slice(0, 4);
135
+ const start = allFrames.length;
136
+ allFrames.push(...frames);
137
+ return { fiber: f, start, count: frames.length };
138
+ }));
139
+ const mapped = await symbolicate(allFrames);
140
+ /** The first frame of the app's own code in a fiber's stack: the app line that created that fiber's element. */
141
+ const appFrame = (span) => {
142
+ for (let k = span.start; k < span.start + span.count; k++) {
143
+ const frame = mapped[k];
144
+ if (frame && isAppFile(frame.file))
145
+ return frame;
146
+ }
147
+ return null;
148
+ };
149
+ return fibers.map((fiber, i) => {
150
+ let location = null;
151
+ let wrote = null;
152
+ // The app's own components, nearest first: the ones whose render wrote an element on this path.
153
+ const names = [];
154
+ for (const [n, span] of spans[i].entries()) {
155
+ const frame = appFrame(span);
156
+ if (frame === null)
157
+ continue;
158
+ if (frame.methodName !== '' && !INTERNAL.test(frame.methodName))
159
+ names.push(frame.methodName);
160
+ if (location === null) {
161
+ location = {
162
+ file: frame.file,
163
+ line: frame.lineNumber,
164
+ column: frame.column,
165
+ component: frame.methodName || null,
166
+ // the element's own line, or (a library drew it) the app line around it
167
+ direct: n <= 1 || sameIdentity(fiber, span.fiber),
168
+ };
169
+ wrote = span.fiber;
170
+ }
171
+ else if (location.direct && wrote !== null && sameIdentity(fiber, span.fiber)) {
172
+ // The app's own wrapper component got the same identity from further up (a shared <Button testID>
173
+ // used on a screen): the line that wrote the value is that call site, not the wrapper's inside.
174
+ location = { file: frame.file, line: frame.lineNumber, column: frame.column, component: frame.methodName || null, direct: true };
175
+ wrote = span.fiber;
176
+ }
177
+ }
178
+ const components = [...new Set(names)].slice(0, 6).reverse();
179
+ const propsFrom = wrote && (0, fiber_1.isCompositeTag)(wrote.tag) ? wrote : compositesAbove(fiber, 1)[0] ?? null;
180
+ // Inside an app component (LabButton): the first app line further up written by another component is
181
+ // where that component is used (<LabButton …> in LabScreen).
182
+ // Up to four call sites further up, nearest first: a shared component may sit inside another one
183
+ // (PressButton › LabButton), and the host picks the line that names the element.
184
+ const usedAt = [];
185
+ const chosen = location;
186
+ if (chosen !== null && chosen.direct && chosen.component !== null) {
187
+ let past = false;
188
+ let last = chosen.component;
189
+ for (const span of spans[i]) {
190
+ if (span.fiber === wrote) {
191
+ past = true;
192
+ continue;
193
+ }
194
+ if (!past)
195
+ continue;
196
+ const frame = appFrame(span);
197
+ if (frame === null || frame.methodName === '' || INTERNAL.test(frame.methodName))
198
+ continue;
199
+ if (frame.methodName === last)
200
+ continue;
201
+ usedAt.push({ file: frame.file, line: frame.lineNumber, column: frame.column, component: frame.methodName, direct: true });
202
+ last = frame.methodName;
203
+ if (usedAt.length >= 4)
204
+ break;
205
+ }
206
+ }
207
+ return { components, location, ...(usedAt.length > 0 ? { usedAt } : {}), props: propsFrom ? shortProps(propsFrom) : {} };
208
+ });
209
+ }
210
+ /** Forget mapped positions (after a reload the bundle's lines change; tests). */
211
+ function clearSourceCache() {
212
+ cache.clear();
213
+ }
214
+ //# sourceMappingURL=source.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"source.js","sourceRoot":"","sources":["../src/source.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ /** Where Tapline remembers the paired computer and this install's id. */
2
+ export interface TaplineStorage {
3
+ getItem(key: string): Promise<string | null>;
4
+ setItem(key: string, value: string): Promise<void>;
5
+ removeItem(key: string): Promise<void>;
6
+ }
7
+ /** expo-secure-store when the app has it (keychain on iOS), else null. */
8
+ export declare function secureStoreStorage(): TaplineStorage | null;
9
+ /** Kept only while the app runs. */
10
+ export declare function memoryStorage(): TaplineStorage;
@@ -0,0 +1,45 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.secureStoreStorage = secureStoreStorage;
4
+ exports.memoryStorage = memoryStorage;
5
+ const types_1 = require("./types");
6
+ function isSecureStore(value) {
7
+ return ((0, types_1.isRecord)(value) &&
8
+ typeof value.getItemAsync === 'function' &&
9
+ typeof value.setItemAsync === 'function' &&
10
+ typeof value.deleteItemAsync === 'function');
11
+ }
12
+ /** expo-secure-store when the app has it (keychain on iOS), else null. */
13
+ function secureStoreStorage() {
14
+ let loaded;
15
+ try {
16
+ loaded = require('expo-secure-store');
17
+ }
18
+ catch {
19
+ return null;
20
+ }
21
+ const store = (0, types_1.isRecord)(loaded) && isSecureStore(loaded.default) ? loaded.default : loaded;
22
+ if (!isSecureStore(store))
23
+ return null;
24
+ return {
25
+ getItem: (key) => store.getItemAsync(key),
26
+ setItem: (key, value) => store.setItemAsync(key, value),
27
+ removeItem: (key) => store.deleteItemAsync(key),
28
+ };
29
+ }
30
+ /** Kept only while the app runs. */
31
+ function memoryStorage() {
32
+ const items = new Map();
33
+ return {
34
+ getItem: (key) => Promise.resolve(items.get(key) ?? null),
35
+ setItem: (key, value) => {
36
+ items.set(key, value);
37
+ return Promise.resolve();
38
+ },
39
+ removeItem: (key) => {
40
+ items.delete(key);
41
+ return Promise.resolve();
42
+ },
43
+ };
44
+ }
45
+ //# sourceMappingURL=storage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"storage.js","sourceRoot":"","sources":["../src/storage.ts"],"names":[],"mappings":";;AAyBA,gDAcC;AAGD,sCAaC;AAvDD,mCAAmC;AAenC,SAAS,aAAa,CAAC,KAAc;IACnC,OAAO,CACL,IAAA,gBAAQ,EAAC,KAAK,CAAC;QACf,OAAO,KAAK,CAAC,YAAY,KAAK,UAAU;QACxC,OAAO,KAAK,CAAC,YAAY,KAAK,UAAU;QACxC,OAAO,KAAK,CAAC,eAAe,KAAK,UAAU,CAC5C,CAAC;AACJ,CAAC;AAED,0EAA0E;AAC1E,SAAgB,kBAAkB;IAChC,IAAI,MAAe,CAAC;IACpB,IAAI,CAAC;QACH,MAAM,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAAC;IACxC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,KAAK,GAAG,IAAA,gBAAQ,EAAC,MAAM,CAAC,IAAI,aAAa,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC;IAC1F,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IACvC,OAAO;QACL,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,KAAK,CAAC,YAAY,CAAC,GAAG,CAAC;QACzC,OAAO,EAAE,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,YAAY,CAAC,GAAG,EAAE,KAAK,CAAC;QACvD,UAAU,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,KAAK,CAAC,eAAe,CAAC,GAAG,CAAC;KAChD,CAAC;AACJ,CAAC;AAED,oCAAoC;AACpC,SAAgB,aAAa;IAC3B,MAAM,KAAK,GAAG,IAAI,GAAG,EAAkB,CAAC;IACxC,OAAO;QACL,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC;QACzD,OAAO,EAAE,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE;YACtB,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;YACtB,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC;QAC3B,CAAC;QACD,UAAU,EAAE,CAAC,GAAG,EAAE,EAAE;YAClB,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YAClB,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC;QAC3B,CAAC;KACF,CAAC;AACJ,CAAC"}