@treelocator/runtime 0.4.7 → 0.6.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.
- package/.eslintignore +1 -0
- package/dist/_generated_styles.d.ts +1 -1
- package/dist/_generated_styles.js +20 -0
- package/dist/_generated_tree_icon.d.ts +1 -1
- package/dist/adapters/HtmlElementTreeNode.d.ts +2 -2
- package/dist/adapters/HtmlElementTreeNode.js +4 -6
- package/dist/adapters/createTreeNode.js +17 -44
- package/dist/adapters/detectFramework.d.ts +8 -0
- package/dist/adapters/detectFramework.js +25 -0
- package/dist/adapters/detectFramework.test.d.ts +1 -0
- package/dist/adapters/detectFramework.test.js +60 -0
- package/dist/adapters/jsx/jsxAdapter.js +54 -89
- package/dist/adapters/jsx/jsxAdapter.test.d.ts +1 -0
- package/dist/adapters/jsx/jsxAdapter.test.js +273 -0
- package/dist/adapters/nextjs/parseNextjsDataAttributes.js +1 -1
- package/dist/adapters/nextjs/parseNextjsDataAttributes.test.d.ts +1 -0
- package/dist/adapters/nextjs/parseNextjsDataAttributes.test.js +158 -0
- package/dist/adapters/react/findFiberByHtmlElement.d.ts +1 -1
- package/dist/adapters/react/findFiberByHtmlElement.js +1 -1
- package/dist/adapters/react/getAllParentsElementsAndRootComponent.js +4 -0
- package/dist/adapters/resolveAdapter.d.ts +1 -1
- package/dist/adapters/resolveAdapter.js +4 -8
- package/dist/adapters/svelte/svelteAdapter.test.d.ts +1 -0
- package/dist/adapters/svelte/svelteAdapter.test.js +280 -0
- package/dist/adapters/vue/vueAdapter.test.d.ts +1 -0
- package/dist/adapters/vue/vueAdapter.test.js +222 -0
- package/dist/browserApi.d.ts +148 -0
- package/dist/browserApi.js +146 -5
- package/dist/browserApi.test.d.ts +1 -0
- package/dist/browserApi.test.js +287 -0
- package/dist/components/RecordingPillButton.d.ts +11 -0
- package/dist/components/RecordingPillButton.js +202 -0
- package/dist/components/RecordingResults.d.ts +2 -0
- package/dist/components/RecordingResults.js +213 -78
- package/dist/components/Runtime.js +161 -554
- package/dist/components/SettingsPanel.d.ts +5 -0
- package/dist/components/SettingsPanel.js +312 -0
- package/dist/consoleCapture.d.ts +9 -0
- package/dist/consoleCapture.js +95 -0
- package/dist/dejitter/recorder.d.ts +7 -1
- package/dist/dejitter/recorder.js +64 -1
- package/dist/functions/cssRuleInspector.d.ts +83 -0
- package/dist/functions/cssRuleInspector.js +608 -0
- package/dist/functions/cssRuleInspector.test.d.ts +1 -0
- package/dist/functions/cssRuleInspector.test.js +439 -0
- package/dist/functions/deduplicateLabels.test.d.ts +1 -0
- package/dist/functions/deduplicateLabels.test.js +178 -0
- package/dist/functions/enrichAncestrySourceMaps.js +0 -1
- package/dist/functions/extractComputedStyles.d.ts +51 -0
- package/dist/functions/extractComputedStyles.js +447 -0
- package/dist/functions/extractComputedStyles.test.d.ts +1 -0
- package/dist/functions/extractComputedStyles.test.js +549 -0
- package/dist/functions/formatAncestryChain.d.ts +8 -0
- package/dist/functions/formatAncestryChain.js +21 -1
- package/dist/functions/formatAncestryChain.test.js +18 -0
- package/dist/functions/getUsableName.test.d.ts +1 -0
- package/dist/functions/getUsableName.test.js +219 -0
- package/dist/functions/isCombinationModifiersPressed.test.d.ts +1 -0
- package/dist/functions/isCombinationModifiersPressed.test.js +192 -0
- package/dist/functions/mergeRects.test.js +210 -1
- package/dist/functions/namedSnapshots.d.ts +52 -0
- package/dist/functions/namedSnapshots.js +161 -0
- package/dist/functions/namedSnapshots.test.d.ts +1 -0
- package/dist/functions/namedSnapshots.test.js +85 -0
- package/dist/functions/normalizeFilePath.test.d.ts +1 -0
- package/dist/functions/normalizeFilePath.test.js +66 -0
- package/dist/functions/parseDataId.test.d.ts +1 -0
- package/dist/functions/parseDataId.test.js +101 -0
- package/dist/hooks/getStorage.d.ts +3 -0
- package/dist/hooks/getStorage.js +17 -0
- package/dist/hooks/useEventListeners.d.ts +15 -0
- package/dist/hooks/useEventListeners.js +56 -0
- package/dist/hooks/useLocatorStorage.d.ts +18 -0
- package/dist/hooks/useLocatorStorage.js +41 -0
- package/dist/hooks/useLocatorStorage.test.d.ts +1 -0
- package/dist/hooks/useLocatorStorage.test.js +124 -0
- package/dist/hooks/useRecordingState.d.ts +43 -0
- package/dist/hooks/useRecordingState.js +387 -0
- package/dist/hooks/useSettings.d.ts +13 -0
- package/dist/hooks/useSettings.js +66 -0
- package/dist/index.d.ts +5 -2
- package/dist/index.js +4 -2
- package/dist/initRuntime.d.ts +3 -1
- package/dist/initRuntime.js +4 -1
- package/dist/mcpBridge.d.ts +61 -0
- package/dist/mcpBridge.js +534 -0
- package/dist/mcpBridge.test.d.ts +1 -0
- package/dist/mcpBridge.test.js +248 -0
- package/dist/output.css +20 -0
- package/dist/visualDiff/diff.d.ts +9 -0
- package/dist/visualDiff/diff.js +209 -0
- package/dist/visualDiff/diff.test.d.ts +1 -0
- package/dist/visualDiff/diff.test.js +253 -0
- package/dist/visualDiff/settle.d.ts +3 -0
- package/dist/visualDiff/settle.js +50 -0
- package/dist/visualDiff/settle.test.d.ts +1 -0
- package/dist/visualDiff/settle.test.js +65 -0
- package/dist/visualDiff/snapshot.d.ts +4 -0
- package/dist/visualDiff/snapshot.js +84 -0
- package/dist/visualDiff/snapshot.test.d.ts +1 -0
- package/dist/visualDiff/snapshot.test.js +245 -0
- package/dist/visualDiff/types.d.ts +37 -0
- package/dist/visualDiff/types.js +1 -0
- package/package.json +2 -2
- package/scripts/wrapCSS.js +1 -1
- package/scripts/wrapImage.js +1 -1
- package/src/_generated_styles.ts +21 -1
- package/src/_generated_tree_icon.ts +1 -1
- package/src/adapters/HtmlElementTreeNode.ts +10 -7
- package/src/adapters/createTreeNode.ts +12 -51
- package/src/adapters/detectFramework.test.ts +73 -0
- package/src/adapters/detectFramework.ts +28 -0
- package/src/adapters/jsx/jsxAdapter.test.ts +240 -0
- package/src/adapters/jsx/jsxAdapter.ts +53 -106
- package/src/adapters/nextjs/parseNextjsDataAttributes.test.ts +212 -0
- package/src/adapters/nextjs/parseNextjsDataAttributes.ts +1 -1
- package/src/adapters/react/findDebugSource.ts +5 -6
- package/src/adapters/react/findFiberByHtmlElement.ts +3 -3
- package/src/adapters/react/getAllParentsElementsAndRootComponent.ts +3 -0
- package/src/adapters/react/reactAdapter.ts +1 -2
- package/src/adapters/resolveAdapter.ts +4 -14
- package/src/adapters/svelte/svelteAdapter.test.ts +334 -0
- package/src/adapters/vue/vueAdapter.test.ts +259 -0
- package/src/browserApi.test.ts +329 -0
- package/src/browserApi.ts +351 -4
- package/src/components/RecordingPillButton.tsx +301 -0
- package/src/components/RecordingResults.tsx +114 -13
- package/src/components/Runtime.tsx +176 -621
- package/src/components/SettingsPanel.tsx +339 -0
- package/src/consoleCapture.ts +113 -0
- package/src/dejitter/recorder.ts +67 -3
- package/src/functions/cssRuleInspector.test.ts +517 -0
- package/src/functions/cssRuleInspector.ts +708 -0
- package/src/functions/deduplicateLabels.test.ts +115 -0
- package/src/functions/enrichAncestrySourceMaps.ts +6 -3
- package/src/functions/extractComputedStyles.test.ts +681 -0
- package/src/functions/extractComputedStyles.ts +768 -0
- package/src/functions/formatAncestryChain.test.ts +23 -1
- package/src/functions/formatAncestryChain.ts +22 -1
- package/src/functions/getUsableName.test.ts +242 -0
- package/src/functions/isCombinationModifiersPressed.test.ts +156 -0
- package/src/functions/mergeRects.test.ts +111 -1
- package/src/functions/namedSnapshots.test.ts +106 -0
- package/src/functions/namedSnapshots.ts +232 -0
- package/src/functions/normalizeFilePath.test.ts +80 -0
- package/src/functions/parseDataId.test.ts +125 -0
- package/src/hooks/getStorage.ts +26 -0
- package/src/hooks/useEventListeners.ts +97 -0
- package/src/hooks/useLocatorStorage.test.ts +127 -0
- package/src/hooks/useLocatorStorage.ts +60 -0
- package/src/hooks/useRecordingState.ts +516 -0
- package/src/hooks/useSettings.ts +83 -0
- package/src/index.ts +10 -5
- package/src/initRuntime.ts +5 -0
- package/src/mcpBridge.test.ts +260 -0
- package/src/mcpBridge.ts +677 -0
- package/src/visualDiff/diff.test.ts +167 -0
- package/src/visualDiff/diff.ts +242 -0
- package/src/visualDiff/settle.test.ts +77 -0
- package/src/visualDiff/settle.ts +62 -0
- package/src/visualDiff/snapshot.test.ts +200 -0
- package/src/visualDiff/snapshot.ts +119 -0
- package/src/visualDiff/types.ts +40 -0
- package/tsconfig.json +3 -1
- package/vitest.config.ts +18 -0
- package/jest.config.ts +0 -195
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { describe, expect, test } from "vitest";
|
|
2
|
+
import { deduplicateLabels } from "./deduplicateLabels";
|
|
3
|
+
import { LabelData } from "../types/LabelData";
|
|
4
|
+
|
|
5
|
+
describe("deduplicateLabels", () => {
|
|
6
|
+
test("returns empty array for empty input", () => {
|
|
7
|
+
const result = deduplicateLabels([]);
|
|
8
|
+
expect(result).toEqual([]);
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
test("returns same array when no duplicates", () => {
|
|
12
|
+
const labels: LabelData[] = [
|
|
13
|
+
{ label: "Button", link: null },
|
|
14
|
+
{ label: "Header", link: null },
|
|
15
|
+
];
|
|
16
|
+
const result = deduplicateLabels(labels);
|
|
17
|
+
expect(result).toEqual(labels);
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
test("removes duplicate labels with same link", () => {
|
|
21
|
+
const label1: LabelData = { label: "Button", link: null };
|
|
22
|
+
const label2: LabelData = { label: "Button", link: null };
|
|
23
|
+
const labels = [label1, label2];
|
|
24
|
+
const result = deduplicateLabels(labels);
|
|
25
|
+
expect(result).toHaveLength(1);
|
|
26
|
+
expect(result[0]).toEqual(label1);
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
test("keeps labels with different link properties", () => {
|
|
30
|
+
const link1 = { filePath: "Button.tsx", projectPath: "/src", line: 1, column: 1 };
|
|
31
|
+
const link2 = { filePath: "Header.tsx", projectPath: "/src", line: 1, column: 1 };
|
|
32
|
+
const labels: LabelData[] = [
|
|
33
|
+
{ label: "Button", link: link1 },
|
|
34
|
+
{ label: "Button", link: link2 },
|
|
35
|
+
];
|
|
36
|
+
const result = deduplicateLabels(labels);
|
|
37
|
+
expect(result).toHaveLength(2);
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
test("removes duplicate labels with same link object", () => {
|
|
41
|
+
const link = { filePath: "Button.tsx", projectPath: "/src", line: 1, column: 1 };
|
|
42
|
+
const labels: LabelData[] = [
|
|
43
|
+
{ label: "Button", link },
|
|
44
|
+
{ label: "Button", link },
|
|
45
|
+
];
|
|
46
|
+
const result = deduplicateLabels(labels);
|
|
47
|
+
expect(result).toHaveLength(1);
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
test("handles multiple duplicates", () => {
|
|
51
|
+
const labels: LabelData[] = [
|
|
52
|
+
{ label: "Button", link: null },
|
|
53
|
+
{ label: "Button", link: null },
|
|
54
|
+
{ label: "Header", link: null },
|
|
55
|
+
{ label: "Header", link: null },
|
|
56
|
+
{ label: "Button", link: null },
|
|
57
|
+
];
|
|
58
|
+
const result = deduplicateLabels(labels);
|
|
59
|
+
expect(result).toHaveLength(2);
|
|
60
|
+
expect(result.map((l) => l.label)).toEqual(["Button", "Header"]);
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
test("preserves order of first occurrence", () => {
|
|
64
|
+
const labels: LabelData[] = [
|
|
65
|
+
{ label: "C", link: null },
|
|
66
|
+
{ label: "A", link: null },
|
|
67
|
+
{ label: "B", link: null },
|
|
68
|
+
{ label: "A", link: null },
|
|
69
|
+
{ label: "C", link: null },
|
|
70
|
+
];
|
|
71
|
+
const result = deduplicateLabels(labels);
|
|
72
|
+
expect(result.map((l) => l.label)).toEqual(["C", "A", "B"]);
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
test("handles complex link objects with same values", () => {
|
|
76
|
+
const labels: LabelData[] = [
|
|
77
|
+
{
|
|
78
|
+
label: "Component",
|
|
79
|
+
link: { filePath: "App.tsx", projectPath: "/src", line: 10, column: 5 },
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
label: "Component",
|
|
83
|
+
link: { filePath: "App.tsx", projectPath: "/src", line: 10, column: 5 },
|
|
84
|
+
},
|
|
85
|
+
];
|
|
86
|
+
const result = deduplicateLabels(labels);
|
|
87
|
+
expect(result).toHaveLength(1);
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
test("distinguishes between link null and link with values", () => {
|
|
91
|
+
const labels: LabelData[] = [
|
|
92
|
+
{ label: "Button", link: null },
|
|
93
|
+
{ label: "Button", link: { filePath: "Button.tsx", projectPath: "/src", line: 1, column: 1 } },
|
|
94
|
+
];
|
|
95
|
+
const result = deduplicateLabels(labels);
|
|
96
|
+
expect(result).toHaveLength(2);
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
test("handles single label", () => {
|
|
100
|
+
const labels: LabelData[] = [{ label: "Button", link: null }];
|
|
101
|
+
const result = deduplicateLabels(labels);
|
|
102
|
+
expect(result).toEqual(labels);
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
test("returns correct instances", () => {
|
|
106
|
+
const label1: LabelData = { label: "Button", link: null };
|
|
107
|
+
const label2: LabelData = { label: "Header", link: null };
|
|
108
|
+
const label3: LabelData = { label: "Button", link: null };
|
|
109
|
+
const labels = [label1, label2, label3];
|
|
110
|
+
const result = deduplicateLabels(labels);
|
|
111
|
+
expect(result).toHaveLength(2);
|
|
112
|
+
expect(result[0]).toBe(label1);
|
|
113
|
+
expect(result[1]).toBe(label2);
|
|
114
|
+
});
|
|
115
|
+
});
|
|
@@ -1,7 +1,10 @@
|
|
|
1
|
+
import { Fiber } from "@locator/shared";
|
|
1
2
|
import { AncestryItem } from "./formatAncestryChain";
|
|
2
3
|
import { resolveSourceLocation, parseDebugStack } from "../adapters/react/resolveSourceMap";
|
|
3
4
|
import { normalizeFilePath } from "./normalizeFilePath";
|
|
4
5
|
|
|
6
|
+
type React19Fiber = Fiber & { _debugStack?: { stack?: string } };
|
|
7
|
+
|
|
5
8
|
/**
|
|
6
9
|
* Check if any DOM element has React 19 fibers (with _debugStack instead of _debugSource).
|
|
7
10
|
* Must walk the _debugOwner chain because DOM element fibers (HostComponent) never have
|
|
@@ -14,10 +17,10 @@ function isReact19Environment(): boolean {
|
|
|
14
17
|
const fiberKey = Object.keys(el).find((k) => k.startsWith("__reactFiber$"));
|
|
15
18
|
if (!fiberKey) return false;
|
|
16
19
|
|
|
17
|
-
let fiber = (el as
|
|
20
|
+
let fiber = (el as unknown as Record<string, React19Fiber>)[fiberKey] as React19Fiber | null;
|
|
18
21
|
while (fiber) {
|
|
19
22
|
if (fiber._debugSource) return false; // React 18
|
|
20
|
-
if (
|
|
23
|
+
if (fiber._debugStack) return true; // React 19
|
|
21
24
|
fiber = fiber._debugOwner || null;
|
|
22
25
|
}
|
|
23
26
|
return false;
|
|
@@ -37,7 +40,7 @@ function collectFiberStacks(
|
|
|
37
40
|
);
|
|
38
41
|
if (!fiberKey) return stacks;
|
|
39
42
|
|
|
40
|
-
let fiber = (element as
|
|
43
|
+
let fiber = (element as unknown as Record<string, React19Fiber>)[fiberKey] as React19Fiber | null;
|
|
41
44
|
|
|
42
45
|
// Collect stacks from the fiber itself and its _debugOwner chain
|
|
43
46
|
while (fiber) {
|