@replohq/sandbox-runtime 1.20.0 → 1.21.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 (46) hide show
  1. package/_vendor/schemas/comments.d.ts +898 -0
  2. package/_vendor/schemas/commentsOverlayRpc.d.ts +348 -0
  3. package/_vendor/schemas/commentsOverlayRpc.mjs +92 -0
  4. package/_vendor/schemas/generated/comments.d.ts +237 -0
  5. package/_vendor/schemas/generated/commentsOverlayRpc.d.ts +18 -0
  6. package/_vendor/schemas/generated/selectMode.d.ts +3 -1
  7. package/_vendor/schemas/selectMode.d.ts +113 -0
  8. package/_vendor/schemas/selectMode.mjs +1 -1
  9. package/_vendor/schemas/selectModeIframeRpc.d.ts +226 -0
  10. package/_vendor/schemas/selectModeIframeRpc.mjs +1 -1
  11. package/buildMetadata.js +3 -3
  12. package/chunk-NVOBD46N.mjs +541 -0
  13. package/comments-overlay/CommentsOverlayMount.d.ts +1 -0
  14. package/comments-overlay/CommentsOverlayMount.js +44 -0
  15. package/comments-overlay/LICENSE-THIRD-PARTY.md +45 -0
  16. package/comments-overlay/bridge.d.ts +11 -0
  17. package/comments-overlay/bridge.js +136 -0
  18. package/comments-overlay/capture.d.ts +55 -0
  19. package/comments-overlay/capture.js +250 -0
  20. package/comments-overlay/originGate.d.ts +1 -0
  21. package/comments-overlay/originGate.js +11 -0
  22. package/comments-overlay/overlay.d.ts +52 -0
  23. package/comments-overlay/overlay.js +781 -0
  24. package/comments-overlay/resolve.d.ts +27 -0
  25. package/comments-overlay/resolve.js +201 -0
  26. package/comments-overlay/sourceLookup.d.ts +11 -0
  27. package/comments-overlay/sourceLookup.js +63 -0
  28. package/comments-overlay/textQuote.d.ts +17 -0
  29. package/comments-overlay/textQuote.js +87 -0
  30. package/comments-overlay/vendor/bippy.d.ts +53 -0
  31. package/comments-overlay/vendor/bippy.js +402 -0
  32. package/comments-overlay/vendor/elementAnchors.d.ts +9 -0
  33. package/comments-overlay/vendor/elementAnchors.js +144 -0
  34. package/comments-overlay/vendor/fiberElement.d.ts +21 -0
  35. package/comments-overlay/vendor/fiberElement.js +251 -0
  36. package/comments-overlay/vendor/htmlPreview.d.ts +13 -0
  37. package/comments-overlay/vendor/htmlPreview.js +179 -0
  38. package/comments-overlay/vendor/selector.d.ts +38 -0
  39. package/comments-overlay/vendor/selector.js +372 -0
  40. package/package.json +4 -4
  41. package/sandbox-runtime.js +2 -0
  42. package/select-mode/descriptor/elementDescriptor.d.ts +4 -3
  43. package/select-mode/descriptor/elementDescriptor.js +20 -30
  44. package/select-mode/iframeRpcChannel.d.ts +84 -0
  45. package/select-mode/symbolicate.js +25 -7
  46. package/chunk-QTGDSYSU.mjs +0 -249
@@ -0,0 +1,402 @@
1
+ /*!
2
+ * Copyright (c) 2024-present Aiden Bai
3
+ * SPDX-License-Identifier: MIT
4
+ * https://github.com/aidenybai/bippy
5
+ */
6
+ const FUNCTION_COMPONENT_TAG = 0;
7
+ const CLASS_COMPONENT_TAG = 1;
8
+ const HOST_ROOT_TAG = 3;
9
+ const HOST_COMPONENT_TAG = 5;
10
+ const FORWARD_REF_TAG = 11;
11
+ const MEMO_COMPONENT_TAG = 14;
12
+ const SIMPLE_MEMO_COMPONENT_TAG = 15;
13
+ const HOST_HOISTABLE_TAG = 26;
14
+ const HOST_SINGLETON_TAG = 27;
15
+ const COMPOSITE_TAGS = /* @__PURE__ */ new Set([
16
+ FUNCTION_COMPONENT_TAG,
17
+ CLASS_COMPONENT_TAG,
18
+ FORWARD_REF_TAG,
19
+ MEMO_COMPONENT_TAG,
20
+ SIMPLE_MEMO_COMPONENT_TAG
21
+ ]);
22
+ const HOST_TAGS = /* @__PURE__ */ new Set([
23
+ HOST_COMPONENT_TAG,
24
+ HOST_HOISTABLE_TAG,
25
+ HOST_SINGLETON_TAG
26
+ ]);
27
+ const MAX_ROOT_CLIMB_DEPTH = 1e3;
28
+ const MAX_CURRENT_TREE_SCAN = 5e4;
29
+ const MAX_OWNED_CHILD_SCAN = 2e3;
30
+ function isObject(value) {
31
+ return typeof value === "object" && value !== null;
32
+ }
33
+ function isFiber(value) {
34
+ return isObject(value) && typeof value.tag === "number" && "stateNode" in value;
35
+ }
36
+ function isCompositeFiber(fiber) {
37
+ return COMPOSITE_TAGS.has(fiber.tag);
38
+ }
39
+ function isHostFiber(fiber) {
40
+ return HOST_TAGS.has(fiber.tag) || typeof fiber.type === "string";
41
+ }
42
+ function getFiberFromHostInstance(element) {
43
+ for (const key of Object.keys(element)) {
44
+ if (key.startsWith("__reactFiber$") || key.startsWith("__reactInternalInstance$")) {
45
+ const fiber = Reflect.get(element, key);
46
+ return isFiber(fiber) ? fiber : null;
47
+ }
48
+ }
49
+ return null;
50
+ }
51
+ function getDisplayName(type) {
52
+ if (typeof type === "function") {
53
+ const displayName = Reflect.get(type, "displayName");
54
+ if (typeof displayName === "string" && displayName) {
55
+ return displayName;
56
+ }
57
+ return type.name || null;
58
+ }
59
+ if (!isObject(type)) {
60
+ return null;
61
+ }
62
+ if (typeof type.displayName === "string" && type.displayName) {
63
+ return type.displayName;
64
+ }
65
+ if (typeof type.name === "string" && type.name) {
66
+ return type.name;
67
+ }
68
+ return getDisplayName(type.type ?? type.render);
69
+ }
70
+ function getLatestFiber(fiber) {
71
+ const alternate = fiber.alternate;
72
+ if (!alternate) {
73
+ return fiber;
74
+ }
75
+ let root = fiber;
76
+ for (let depth = 0; root.return && depth < MAX_ROOT_CLIMB_DEPTH; depth++) {
77
+ root = root.return;
78
+ }
79
+ const fiberRoot = root.tag === HOST_ROOT_TAG ? root.stateNode : null;
80
+ const current = isObject(fiberRoot) ? fiberRoot.current : null;
81
+ if (!isFiber(current)) {
82
+ return fiber;
83
+ }
84
+ const stack = [current];
85
+ for (let scanned = 0; stack.length > 0 && scanned < MAX_CURRENT_TREE_SCAN; scanned++) {
86
+ const node = stack.pop();
87
+ if (!node) {
88
+ continue;
89
+ }
90
+ if (node === fiber || node === alternate) {
91
+ return node;
92
+ }
93
+ if (node.sibling) {
94
+ stack.push(node.sibling);
95
+ }
96
+ if (node.child) {
97
+ stack.push(node.child);
98
+ }
99
+ }
100
+ return fiber;
101
+ }
102
+ const REACT_STACK_BOTTOM_FRAME_PATTERNS = [
103
+ "react_stack_bottom_frame",
104
+ "react-stack-bottom-frame"
105
+ ];
106
+ const JSX_FACTORY_FRAME_COUNT = 1;
107
+ const FIREFOX_SAFARI_STACK_REGEXP = /(^|@)\S+:\d+/;
108
+ const CHROME_STACK_REGEXP = /^\s*at .*(\S+:\d+|\(native\))/;
109
+ function extractLocation(urlLike) {
110
+ const isWrapped = urlLike.startsWith("(") && /:\d+\)$/.test(urlLike);
111
+ const location = isWrapped ? urlLike.slice(1, -1) : urlLike;
112
+ const parts = /(.+?)(?::(\d+))?(?::(\d+))?$/.exec(location);
113
+ if (!parts?.[1]) {
114
+ return [location, void 0, void 0];
115
+ }
116
+ return [
117
+ parts[1],
118
+ parts[2] ? Number(parts[2]) : void 0,
119
+ parts[3] ? Number(parts[3]) : void 0
120
+ ];
121
+ }
122
+ function parseV8Line(line) {
123
+ if (!CHROME_STACK_REGEXP.test(line)) {
124
+ return null;
125
+ }
126
+ let sanitized = line.replace(/^\s+/, "").replace(/\(eval code/g, "(").replace(/^.*?\s+/, "");
127
+ const locationMatch = sanitized.match(/ (\(.+\)$)/);
128
+ sanitized = locationMatch ? sanitized.replace(locationMatch[0], "") : sanitized;
129
+ const [fileName, lineNumber, columnNumber] = extractLocation(
130
+ locationMatch?.[1] ?? sanitized
131
+ );
132
+ return {
133
+ functionName: locationMatch && sanitized || void 0,
134
+ fileName: ["eval", "<anonymous>", "(native)"].includes(fileName) ? void 0 : fileName,
135
+ lineNumber,
136
+ columnNumber
137
+ };
138
+ }
139
+ function parseFirefoxSafariLine(line) {
140
+ if (!FIREFOX_SAFARI_STACK_REGEXP.test(line)) {
141
+ return null;
142
+ }
143
+ const atIndex = line.lastIndexOf("@");
144
+ const functionName = atIndex > 0 ? line.slice(0, atIndex) : void 0;
145
+ const [fileName, lineNumber, columnNumber] = extractLocation(
146
+ line.slice(atIndex + 1)
147
+ );
148
+ return { functionName, fileName, lineNumber, columnNumber };
149
+ }
150
+ function parseStack(stackString) {
151
+ const frames = [];
152
+ for (const line of stackString.split("\n")) {
153
+ const frame = /^\s*at\s+/.test(line) ? parseV8Line(line) : parseFirefoxSafariLine(line);
154
+ if (frame) {
155
+ frames.push(frame);
156
+ }
157
+ }
158
+ return frames;
159
+ }
160
+ function readStackString(debugStack) {
161
+ if (typeof debugStack === "string") {
162
+ return debugStack;
163
+ }
164
+ if (isObject(debugStack) && typeof debugStack.stack === "string") {
165
+ return debugStack.stack;
166
+ }
167
+ return null;
168
+ }
169
+ function parseDebugStack(debugStack) {
170
+ const stackString = readStackString(debugStack);
171
+ if (!stackString) {
172
+ return { frames: [], isTrusted: false };
173
+ }
174
+ let bottomFrameIndex = -1;
175
+ for (const pattern of REACT_STACK_BOTTOM_FRAME_PATTERNS) {
176
+ bottomFrameIndex = stackString.indexOf(pattern);
177
+ if (bottomFrameIndex !== -1) {
178
+ break;
179
+ }
180
+ }
181
+ const trimmed = bottomFrameIndex === -1 ? stackString : stackString.slice(0, stackString.lastIndexOf("\n", bottomFrameIndex));
182
+ return {
183
+ frames: parseStack(trimmed).slice(JSX_FACTORY_FRAME_COUNT),
184
+ isTrusted: bottomFrameIndex !== -1
185
+ };
186
+ }
187
+ const INTERNAL_SCHEME_PREFIXES = [
188
+ "rsc://",
189
+ "file:///",
190
+ "webpack-internal://",
191
+ "webpack://",
192
+ "node:",
193
+ "turbopack://",
194
+ "metro://",
195
+ "/app-pages-browser/",
196
+ "/(app-pages-browser)/"
197
+ ];
198
+ const ABOUT_REACT_PREFIX = "about://React/";
199
+ const SCHEME_REGEX = /^[a-zA-Z][a-zA-Z\d+\-.]*:/;
200
+ const QUERY_PARAMETER_PATTERN_REGEX = /^\?[\w~.-]+(?:=[^&#]*)?(?:&[\w~.-]+(?:=[^&#]*)?)*$/;
201
+ function normalizeFileName(fileName) {
202
+ if (!fileName || fileName === "<anonymous>" || fileName === "eval") {
203
+ return "";
204
+ }
205
+ let normalized = fileName;
206
+ const isWindowsDrivePath = /^[a-zA-Z]:[\\/]/.test(normalized);
207
+ if (normalized.startsWith("http://") || normalized.startsWith("https://")) {
208
+ try {
209
+ normalized = new URL(normalized).pathname;
210
+ } catch {
211
+ }
212
+ }
213
+ if (normalized.startsWith(ABOUT_REACT_PREFIX)) {
214
+ const remainder = normalized.slice(ABOUT_REACT_PREFIX.length);
215
+ const slashIndex = remainder.indexOf("/");
216
+ const colonIndex = remainder.indexOf(":");
217
+ normalized = slashIndex !== -1 && (colonIndex === -1 || slashIndex < colonIndex) ? remainder.slice(slashIndex + 1) : remainder;
218
+ }
219
+ let didStripPrefix = true;
220
+ while (didStripPrefix) {
221
+ didStripPrefix = false;
222
+ for (const prefix of INTERNAL_SCHEME_PREFIXES) {
223
+ if (normalized.startsWith(prefix)) {
224
+ normalized = normalized.slice(prefix.length);
225
+ if (prefix === "file:///") {
226
+ normalized = `/${normalized.replace(/^\/+/, "")}`;
227
+ }
228
+ didStripPrefix = true;
229
+ break;
230
+ }
231
+ }
232
+ }
233
+ if (!isWindowsDrivePath) {
234
+ const schemeMatch = normalized.match(SCHEME_REGEX);
235
+ if (schemeMatch) {
236
+ normalized = normalized.slice(schemeMatch[0].length);
237
+ }
238
+ }
239
+ if (normalized.startsWith("//")) {
240
+ const firstPathSlashIndex = normalized.indexOf("/", 2);
241
+ normalized = firstPathSlashIndex === -1 ? "" : normalized.slice(firstPathSlashIndex);
242
+ }
243
+ const queryIndex = normalized.indexOf("?");
244
+ if (queryIndex !== -1 && QUERY_PARAMETER_PATTERN_REGEX.test(normalized.slice(queryIndex))) {
245
+ normalized = normalized.slice(0, queryIndex);
246
+ }
247
+ return normalized;
248
+ }
249
+ function hasDebugSource(fiber) {
250
+ const debugSource = fiber._debugSource;
251
+ return isObject(debugSource) && typeof debugSource.fileName === "string" && debugSource.fileName !== "(native)" && typeof debugSource.lineNumber === "number";
252
+ }
253
+ function getUsageFrameFromDebugStack(fiber) {
254
+ const { frames, isTrusted } = parseDebugStack(fiber._debugStack);
255
+ if (!isTrusted) {
256
+ return null;
257
+ }
258
+ return frames.find((frame) => Boolean(frame.fileName)) ?? null;
259
+ }
260
+ function getDefinitionFrameFromOwnedChild(fiber) {
261
+ const stack = fiber.child ? [fiber.child] : [];
262
+ for (let scanned = 0; stack.length > 0 && scanned < MAX_OWNED_CHILD_SCAN; scanned++) {
263
+ const child = stack.pop();
264
+ if (!child) {
265
+ continue;
266
+ }
267
+ const owner = child._debugOwner;
268
+ if ((owner === fiber || fiber.alternate !== null && owner === fiber.alternate) && readStackString(child._debugStack)) {
269
+ const { frames, isTrusted } = parseDebugStack(child._debugStack);
270
+ if (!isTrusted) {
271
+ return null;
272
+ }
273
+ for (let index = frames.length - 1; index >= 0; index--) {
274
+ const frame = frames[index];
275
+ if (frame?.fileName) {
276
+ return frame;
277
+ }
278
+ }
279
+ return null;
280
+ }
281
+ if (child.sibling) {
282
+ stack.push(child.sibling);
283
+ }
284
+ if (child.child) {
285
+ stack.push(child.child);
286
+ }
287
+ }
288
+ return null;
289
+ }
290
+ function getDispatcherKey(ref) {
291
+ return "H" in ref ? "H" : "current";
292
+ }
293
+ function getRendererDispatcherRefs() {
294
+ const hook = typeof window === "undefined" ? void 0 : Reflect.get(window, "__REACT_DEVTOOLS_GLOBAL_HOOK__");
295
+ const renderers = isObject(hook) ? hook.renderers : void 0;
296
+ if (!(renderers instanceof Map)) {
297
+ return [];
298
+ }
299
+ const refs = [];
300
+ for (const renderer of renderers.values()) {
301
+ const ref = isObject(renderer) ? renderer.currentDispatcherRef : void 0;
302
+ if (isObject(ref) && !refs.includes(ref)) {
303
+ refs.push(ref);
304
+ }
305
+ }
306
+ return refs;
307
+ }
308
+ const componentFrameCache = /* @__PURE__ */ new WeakMap();
309
+ let isDescribingComponent = false;
310
+ function describeComponentFrame(component) {
311
+ if (typeof component !== "function" || isDescribingComponent) {
312
+ return null;
313
+ }
314
+ const cached = componentFrameCache.get(component);
315
+ if (cached !== void 0) {
316
+ return cached;
317
+ }
318
+ const dispatcherRefs = getRendererDispatcherRefs();
319
+ if (dispatcherRefs.length === 0) {
320
+ return null;
321
+ }
322
+ const snapshots = dispatcherRefs.map((ref) => {
323
+ const key = getDispatcherKey(ref);
324
+ const value = ref[key];
325
+ ref[key] = null;
326
+ return { ref, key, value };
327
+ });
328
+ const previousConsoleError = console.error;
329
+ const previousConsoleWarn = console.warn;
330
+ console.error = () => {
331
+ };
332
+ console.warn = () => {
333
+ };
334
+ isDescribingComponent = true;
335
+ let frame = null;
336
+ try {
337
+ const runInRootFrame = {
338
+ DetermineComponentFrameRoot() {
339
+ try {
340
+ const result = Reflect.apply(component, void 0, [{}]);
341
+ if (isObject(result) && typeof result.catch === "function") {
342
+ Reflect.apply(result.catch, result, [() => void 0]);
343
+ }
344
+ } catch (sample) {
345
+ return readStackString(sample);
346
+ }
347
+ return null;
348
+ }
349
+ };
350
+ const sampleStack = runInRootFrame.DetermineComponentFrameRoot();
351
+ if (sampleStack) {
352
+ const frames = parseStack(sampleStack);
353
+ const rootIndex = frames.findIndex((candidate) => {
354
+ return Boolean(
355
+ candidate.functionName?.includes("DetermineComponentFrameRoot")
356
+ );
357
+ });
358
+ const componentFrame = rootIndex > 0 ? frames[rootIndex - 1] : null;
359
+ frame = componentFrame?.fileName ? componentFrame : null;
360
+ }
361
+ } finally {
362
+ isDescribingComponent = false;
363
+ console.error = previousConsoleError;
364
+ console.warn = previousConsoleWarn;
365
+ for (const { ref, key, value } of snapshots) {
366
+ ref[key] = value;
367
+ }
368
+ }
369
+ componentFrameCache.set(component, frame);
370
+ return frame;
371
+ }
372
+ function toDebugSource(frame) {
373
+ return frame?.fileName ? {
374
+ fileName: frame.fileName,
375
+ lineNumber: frame.lineNumber,
376
+ columnNumber: frame.columnNumber
377
+ } : null;
378
+ }
379
+ function getFiberSource(fiber) {
380
+ if (hasDebugSource(fiber)) {
381
+ return fiber._debugSource;
382
+ }
383
+ const debugStackSource = toDebugSource(
384
+ getUsageFrameFromDebugStack(fiber) ?? (isCompositeFiber(fiber) ? getDefinitionFrameFromOwnedChild(fiber) : null)
385
+ );
386
+ if (debugStackSource) {
387
+ return debugStackSource;
388
+ }
389
+ return isCompositeFiber(fiber) ? toDebugSource(describeComponentFrame(fiber.type)) : null;
390
+ }
391
+ export {
392
+ getDisplayName,
393
+ getFiberFromHostInstance,
394
+ getFiberSource,
395
+ getLatestFiber,
396
+ isCompositeFiber,
397
+ isFiber,
398
+ isHostFiber,
399
+ normalizeFileName,
400
+ parseDebugStack,
401
+ parseStack
402
+ };
@@ -0,0 +1,9 @@
1
+ /*!
2
+ * Copyright (c) 2025 Aiden Bai
3
+ * SPDX-License-Identifier: MIT
4
+ * https://github.com/aidenybai/react-grab
5
+ */
6
+ /** Records how to recover `element` after a DOM swap; cheap when nothing moved. */
7
+ export declare function trackElementAnchor(element: Element): void;
8
+ /** The live replacement of a tracked element that React swapped out, if any. */
9
+ export declare function resolveLiveElement(element: Element): Element | null;
@@ -0,0 +1,144 @@
1
+ /*!
2
+ * Copyright (c) 2025 Aiden Bai
3
+ * SPDX-License-Identifier: MIT
4
+ * https://github.com/aidenybai/react-grab
5
+ */
6
+ import { getFiberFromHostInstance, getLatestFiber, isHostFiber } from "./bippy";
7
+ const anchorByElement = /* @__PURE__ */ new WeakMap();
8
+ function indexInParent(element) {
9
+ let index = 0;
10
+ let sibling = element.previousElementSibling;
11
+ while (sibling) {
12
+ index += 1;
13
+ sibling = sibling.previousElementSibling;
14
+ }
15
+ return index;
16
+ }
17
+ function isShadowRoot(node) {
18
+ return typeof ShadowRoot !== "undefined" && node instanceof ShadowRoot;
19
+ }
20
+ function findNearestHostElementWithTag(parentFiber, tagName) {
21
+ let fiber = parentFiber.child;
22
+ while (fiber) {
23
+ if (isHostFiber(fiber)) {
24
+ const node = fiber.stateNode;
25
+ if (node instanceof Element && node.isConnected && node.tagName === tagName) {
26
+ return node;
27
+ }
28
+ } else if (fiber.child) {
29
+ fiber = fiber.child;
30
+ continue;
31
+ }
32
+ while (fiber !== parentFiber && !fiber.sibling) {
33
+ fiber = fiber.return;
34
+ if (!fiber) {
35
+ return null;
36
+ }
37
+ }
38
+ if (fiber === parentFiber) {
39
+ return null;
40
+ }
41
+ fiber = fiber.sibling;
42
+ }
43
+ return null;
44
+ }
45
+ function resolveLiveAnchor(anchor) {
46
+ if (anchor.anchorElement.isConnected) {
47
+ return anchor.anchorElement;
48
+ }
49
+ const tagName = anchor.anchorElement.tagName;
50
+ const parentFiber = getLatestFiber(anchor.anchorParentFiber);
51
+ if (isHostFiber(parentFiber)) {
52
+ const parentNode = parentFiber.stateNode;
53
+ if (!(parentNode instanceof Element) || !parentNode.isConnected) {
54
+ return null;
55
+ }
56
+ const candidate = parentNode.children[anchor.anchorIndexInParent];
57
+ return candidate && candidate.tagName === tagName ? candidate : null;
58
+ }
59
+ return findNearestHostElementWithTag(parentFiber, tagName);
60
+ }
61
+ function followDomPath(root, domPath) {
62
+ let node = root;
63
+ for (const step of domPath) {
64
+ const children = step.isShadowChild ? node.shadowRoot?.children : node.children;
65
+ const child = children?.[step.childIndex];
66
+ if (!child) {
67
+ return null;
68
+ }
69
+ node = child;
70
+ }
71
+ return node;
72
+ }
73
+ function findAnchor(element) {
74
+ const domPath = [];
75
+ let anchorElement = element;
76
+ let anchorFiber = getFiberFromHostInstance(element);
77
+ while (anchorElement && !anchorFiber) {
78
+ const parentElement = anchorElement.parentElement;
79
+ if (parentElement) {
80
+ domPath.unshift({
81
+ childIndex: indexInParent(anchorElement),
82
+ isShadowChild: false
83
+ });
84
+ anchorElement = parentElement;
85
+ } else {
86
+ const rootNode = anchorElement.getRootNode();
87
+ if (!isShadowRoot(rootNode)) {
88
+ break;
89
+ }
90
+ domPath.unshift({
91
+ childIndex: indexInParent(anchorElement),
92
+ isShadowChild: true
93
+ });
94
+ anchorElement = rootNode.host;
95
+ }
96
+ anchorFiber = getFiberFromHostInstance(anchorElement);
97
+ }
98
+ const anchorParentFiber = anchorFiber?.return;
99
+ if (!anchorElement || !anchorParentFiber) {
100
+ return null;
101
+ }
102
+ return {
103
+ anchorElement,
104
+ anchorParentFiber,
105
+ anchorIndexInParent: indexInParent(anchorElement),
106
+ domPath,
107
+ targetTagName: element.tagName
108
+ };
109
+ }
110
+ function isAnchorFresh(anchor, element) {
111
+ return anchor.anchorElement.isConnected && anchor.anchorIndexInParent === indexInParent(anchor.anchorElement) && followDomPath(anchor.anchorElement, anchor.domPath) === element;
112
+ }
113
+ function trackElementAnchor(element) {
114
+ if (!element.isConnected) {
115
+ return;
116
+ }
117
+ const existing = anchorByElement.get(element);
118
+ if (existing && isAnchorFresh(existing, element)) {
119
+ return;
120
+ }
121
+ const anchor = findAnchor(element);
122
+ if (anchor) {
123
+ anchorByElement.set(element, anchor);
124
+ }
125
+ }
126
+ function resolveLiveElement(element) {
127
+ if (element.isConnected) {
128
+ return element;
129
+ }
130
+ const anchor = anchorByElement.get(element);
131
+ if (!anchor) {
132
+ return null;
133
+ }
134
+ const liveAnchor = resolveLiveAnchor(anchor);
135
+ if (!liveAnchor) {
136
+ return null;
137
+ }
138
+ const recovered = followDomPath(liveAnchor, anchor.domPath);
139
+ return recovered?.isConnected && recovered.tagName === anchor.targetTagName ? recovered : null;
140
+ }
141
+ export {
142
+ resolveLiveElement,
143
+ trackElementAnchor
144
+ };
@@ -0,0 +1,21 @@
1
+ /*!
2
+ * Copyright (c) 2025 Aiden Bai
3
+ * SPDX-License-Identifier: MIT
4
+ * https://github.com/aidenybai/react-grab
5
+ */
6
+ import type { Fiber } from "./bippy";
7
+ /** Climbs to the nearest host element React manages, crossing shadow roots. */
8
+ export declare function findNearestFiberElement(element: Element): Element;
9
+ export declare function getElementFiber(element: Element): Fiber | null;
10
+ export declare function findNearestListItemKey(startingFiber: Fiber | null): string | null;
11
+ export declare function isUsefulComponentName(name: string, isNextProject: boolean): boolean;
12
+ export declare function isNextProjectRuntime(): boolean;
13
+ export declare function normalizeFilePath(fileName: string): string;
14
+ /**
15
+ * Useful component names on the owner stack of a host fiber, nearest first.
16
+ * Falls back to composite `return` ancestors when React recorded no owners
17
+ * (production builds).
18
+ */
19
+ export declare function getComponentChain(fiber: Fiber): string[];
20
+ /** The fiber whose source describes a host fiber: itself, else its owner. */
21
+ export declare function getNearestOwnerFiber(fiber: Fiber): Fiber | null;