@pinagent/react-native 0.2.2 → 0.2.3
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/native/inspector.d.ts +34 -1
- package/package.json +3 -3
- package/src/native/inspector.ts +63 -5
|
@@ -57,10 +57,43 @@ interface RawInspectorData {
|
|
|
57
57
|
} | null;
|
|
58
58
|
/** Some versions surface the resolved source straight on the payload. */
|
|
59
59
|
source?: RawFiberLike | null;
|
|
60
|
-
/**
|
|
60
|
+
/**
|
|
61
|
+
* NOT the tapped leaf's props. RN fills this from the nearest authored
|
|
62
|
+
* *composite owner's* FIRST host descendant (`getHostProps` →
|
|
63
|
+
* `findCurrentHostFiber`) — i.e. that component's outermost view — so a tap
|
|
64
|
+
* on a nested child surfaces its container here, not the element under the
|
|
65
|
+
* finger. Used only as a fallback; `closestPublicInstance` pins the leaf.
|
|
66
|
+
*/
|
|
61
67
|
props?: RawProps;
|
|
68
|
+
/**
|
|
69
|
+
* The public instance of the host view actually under the finger — the
|
|
70
|
+
* deepest hit-tested node. Fabric only; Paper passes a numeric view tag we
|
|
71
|
+
* can't bridge, so we degrade to `props`. Its fiber's `memoizedProps` carry
|
|
72
|
+
* the leaf's own `data-pa-loc`. See {@link tappedLeafLoc}.
|
|
73
|
+
*/
|
|
74
|
+
closestPublicInstance?: unknown;
|
|
75
|
+
}
|
|
76
|
+
interface FiberLike {
|
|
77
|
+
tag?: number;
|
|
78
|
+
return?: FiberLike | null;
|
|
79
|
+
stateNode?: {
|
|
80
|
+
canonical?: {
|
|
81
|
+
publicInstance?: unknown;
|
|
82
|
+
};
|
|
83
|
+
} | null;
|
|
84
|
+
/** Host fibers carry the committed props — where `data-pa-loc` rides. */
|
|
85
|
+
memoizedProps?: RawProps;
|
|
62
86
|
}
|
|
63
87
|
type Loc = NonNullable<PickResult['loc']>;
|
|
88
|
+
/**
|
|
89
|
+
* Walk a host fiber's render-tree parent (`return`) chain, returning the first
|
|
90
|
+
* `data-pa-loc` found on a fiber's `memoizedProps` — the tapped element itself,
|
|
91
|
+
* or, when that exact host is untagged (a 3rd-party / RN-internal view), the
|
|
92
|
+
* nearest authored element enclosing it. Capped against a malformed `return`
|
|
93
|
+
* cycle. Pure over a fiber-like chain; exported for unit testing without an RN
|
|
94
|
+
* runtime.
|
|
95
|
+
*/
|
|
96
|
+
export declare function nearestPaLocUp(fiber: FiberLike | null): Loc | null;
|
|
64
97
|
/**
|
|
65
98
|
* Keep only authored React components in the breadcrumb. Two kinds of noise
|
|
66
99
|
* are hidden because clicking them is meaningless — they map to no source the
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pinagent/react-native",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.3",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"description": "React Native & Expo plugin for Pinagent — tap a view, leave a comment, and a coding agent fixes it with file:line + a screenshot. The native widget ships as source for Metro; the dev-server middleware and Babel source-tagging plugin are built for Node.",
|
|
6
6
|
"keywords": [
|
|
@@ -80,8 +80,8 @@
|
|
|
80
80
|
"@types/ws": "^8.18.1",
|
|
81
81
|
"tsdown": "^0.22.0",
|
|
82
82
|
"typescript": "^6.0.3",
|
|
83
|
-
"@pinagent/
|
|
84
|
-
"@pinagent/
|
|
83
|
+
"@pinagent/db": "0.0.1",
|
|
84
|
+
"@pinagent/agent-runner": "0.0.0"
|
|
85
85
|
},
|
|
86
86
|
"scripts": {
|
|
87
87
|
"prebuild": "node scripts/copy-drizzle.mjs",
|
package/src/native/inspector.ts
CHANGED
|
@@ -80,8 +80,21 @@ interface RawInspectorData {
|
|
|
80
80
|
closestInstance?: { _debugSource?: RawFiberLike } | null;
|
|
81
81
|
/** Some versions surface the resolved source straight on the payload. */
|
|
82
82
|
source?: RawFiberLike | null;
|
|
83
|
-
/**
|
|
83
|
+
/**
|
|
84
|
+
* NOT the tapped leaf's props. RN fills this from the nearest authored
|
|
85
|
+
* *composite owner's* FIRST host descendant (`getHostProps` →
|
|
86
|
+
* `findCurrentHostFiber`) — i.e. that component's outermost view — so a tap
|
|
87
|
+
* on a nested child surfaces its container here, not the element under the
|
|
88
|
+
* finger. Used only as a fallback; `closestPublicInstance` pins the leaf.
|
|
89
|
+
*/
|
|
84
90
|
props?: RawProps;
|
|
91
|
+
/**
|
|
92
|
+
* The public instance of the host view actually under the finger — the
|
|
93
|
+
* deepest hit-tested node. Fabric only; Paper passes a numeric view tag we
|
|
94
|
+
* can't bridge, so we degrade to `props`. Its fiber's `memoizedProps` carry
|
|
95
|
+
* the leaf's own `data-pa-loc`. See {@link tappedLeafLoc}.
|
|
96
|
+
*/
|
|
97
|
+
closestPublicInstance?: unknown;
|
|
85
98
|
}
|
|
86
99
|
|
|
87
100
|
let cachedFn: InspectorFn | null | undefined;
|
|
@@ -128,6 +141,8 @@ interface FiberLike {
|
|
|
128
141
|
tag?: number;
|
|
129
142
|
return?: FiberLike | null;
|
|
130
143
|
stateNode?: { canonical?: { publicInstance?: unknown } } | null;
|
|
144
|
+
/** Host fibers carry the committed props — where `data-pa-loc` rides. */
|
|
145
|
+
memoizedProps?: RawProps;
|
|
131
146
|
}
|
|
132
147
|
|
|
133
148
|
let cachedGetHandle: ((instance: unknown) => FiberLike | null) | null | undefined;
|
|
@@ -209,14 +224,57 @@ function paLocOf(props: RawProps): Loc | null {
|
|
|
209
224
|
return parsePaLoc(props?.['data-pa-loc']);
|
|
210
225
|
}
|
|
211
226
|
|
|
227
|
+
/**
|
|
228
|
+
* Walk a host fiber's render-tree parent (`return`) chain, returning the first
|
|
229
|
+
* `data-pa-loc` found on a fiber's `memoizedProps` — the tapped element itself,
|
|
230
|
+
* or, when that exact host is untagged (a 3rd-party / RN-internal view), the
|
|
231
|
+
* nearest authored element enclosing it. Capped against a malformed `return`
|
|
232
|
+
* cycle. Pure over a fiber-like chain; exported for unit testing without an RN
|
|
233
|
+
* runtime.
|
|
234
|
+
*/
|
|
235
|
+
export function nearestPaLocUp(fiber: FiberLike | null): Loc | null {
|
|
236
|
+
for (let i = 0; fiber && i < 10_000; i++) {
|
|
237
|
+
const loc = paLocOf(fiber.memoizedProps);
|
|
238
|
+
if (loc) return loc;
|
|
239
|
+
fiber = fiber.return ?? null;
|
|
240
|
+
}
|
|
241
|
+
return null;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
/**
|
|
245
|
+
* The source of the host view actually under the finger.
|
|
246
|
+
*
|
|
247
|
+
* RN's `data.props` is NOT the tapped leaf — it's the nearest authored
|
|
248
|
+
* composite owner's first host descendant (its outer container), so a tap on a
|
|
249
|
+
* nested child resolves to its parent. To land on the leaf, start from the
|
|
250
|
+
* hit-tested host (`data.closestPublicInstance`), bridge it to its fiber, and
|
|
251
|
+
* walk the render-tree parents for the nearest `data-pa-loc`. This mirrors the
|
|
252
|
+
* web widget walking up the DOM from the clicked node.
|
|
253
|
+
*
|
|
254
|
+
* Returns null when the instance can't be bridged (Paper, which surfaces only a
|
|
255
|
+
* numeric view tag) — `pickLoc` then falls back to `data.props`.
|
|
256
|
+
*/
|
|
257
|
+
function tappedLeafLoc(data: RawInspectorData): Loc | null {
|
|
258
|
+
return nearestPaLocUp(getHandleFromPublicInstance(data.closestPublicInstance));
|
|
259
|
+
}
|
|
260
|
+
|
|
212
261
|
/**
|
|
213
262
|
* Resolve the source location. Preferred path: the build-time `data-pa-loc`
|
|
214
|
-
* prop our babel plugin splices on
|
|
215
|
-
*
|
|
216
|
-
*
|
|
263
|
+
* prop our babel plugin splices on — read first from the host view actually
|
|
264
|
+
* under the finger ({@link tappedLeafLoc}), then from `data.props` and each
|
|
265
|
+
* owner outward. Fallback: RN's legacy `_debugSource` / inspector `source`
|
|
266
|
+
* field, for older RN/React where they still exist.
|
|
217
267
|
*/
|
|
218
268
|
function pickLoc(data: RawInspectorData, projectRoot: string): Loc | null {
|
|
219
|
-
//
|
|
269
|
+
// 0. The host view actually under the finger. MUST come first: `data.props`
|
|
270
|
+
// (step 1) is the nearest composite owner's first host — an outer
|
|
271
|
+
// container — so without this a tap on a nested child resolves to its
|
|
272
|
+
// parent (e.g. a card's content tapped, but its screen layout returned).
|
|
273
|
+
const leaf = tappedLeafLoc(data);
|
|
274
|
+
if (leaf) return leaf;
|
|
275
|
+
|
|
276
|
+
// 1. `data-pa-loc` on `data.props` — the nearest authored owner's first host.
|
|
277
|
+
// Fallback for when the touched host can't be bridged to a fiber (Paper).
|
|
220
278
|
const direct = paLocOf(data.props);
|
|
221
279
|
if (direct) return direct;
|
|
222
280
|
|