@reticlehq/browser 2.0.1 → 2.2.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/NOTICE +5 -0
- package/dist/actions/actions-dom.d.ts.map +1 -1
- package/dist/actions/actions-dom.js +3 -20
- package/dist/actions/actions-dom.js.map +1 -1
- package/dist/actions/actions.d.ts +1 -1
- package/dist/actions/actions.d.ts.map +1 -1
- package/dist/actions/actions.js +37 -19
- package/dist/actions/actions.js.map +1 -1
- package/dist/commands/commands.d.ts +2 -0
- package/dist/commands/commands.d.ts.map +1 -1
- package/dist/commands/commands.js +30 -31
- package/dist/commands/commands.js.map +1 -1
- package/dist/dom/a11y.d.ts +17 -6
- package/dist/dom/a11y.d.ts.map +1 -1
- package/dist/dom/a11y.js +68 -32
- package/dist/dom/a11y.js.map +1 -1
- package/dist/dom/auto-anchor.d.ts +10 -10
- package/dist/dom/auto-anchor.js +10 -10
- package/dist/dom/blind-spots.d.ts +14 -0
- package/dist/dom/blind-spots.d.ts.map +1 -0
- package/dist/dom/blind-spots.js +30 -0
- package/dist/dom/blind-spots.js.map +1 -0
- package/dist/dom/chart.d.ts +93 -0
- package/dist/dom/chart.d.ts.map +1 -0
- package/dist/dom/chart.js +119 -0
- package/dist/dom/chart.js.map +1 -0
- package/dist/dom/dom-ignore.d.ts +2 -0
- package/dist/dom/dom-ignore.d.ts.map +1 -1
- package/dist/dom/dom-ignore.js +17 -2
- package/dist/dom/dom-ignore.js.map +1 -1
- package/dist/dom/occlusion.d.ts +9 -0
- package/dist/dom/occlusion.d.ts.map +1 -0
- package/dist/dom/occlusion.js +21 -0
- package/dist/dom/occlusion.js.map +1 -0
- package/dist/dom/query.d.ts +17 -4
- package/dist/dom/query.d.ts.map +1 -1
- package/dist/dom/query.js +185 -30
- package/dist/dom/query.js.map +1 -1
- package/dist/dom/refs.d.ts +26 -3
- package/dist/dom/refs.d.ts.map +1 -1
- package/dist/dom/refs.js +79 -4
- package/dist/dom/refs.js.map +1 -1
- package/dist/dom/snapshot.d.ts +7 -1
- package/dist/dom/snapshot.d.ts.map +1 -1
- package/dist/dom/snapshot.js +43 -16
- package/dist/dom/snapshot.js.map +1 -1
- package/dist/dom/source.d.ts +40 -0
- package/dist/dom/source.d.ts.map +1 -0
- package/dist/dom/source.js +59 -0
- package/dist/dom/source.js.map +1 -0
- package/dist/dom/theme.js +2 -2
- package/dist/dom/theme.js.map +1 -1
- package/dist/index.d.ts +6 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +9 -1
- package/dist/index.js.map +1 -1
- package/dist/observers/animation.d.ts +1 -1
- package/dist/observers/animation.d.ts.map +1 -1
- package/dist/observers/animation.js +1 -1
- package/dist/observers/animation.js.map +1 -1
- package/dist/observers/blind-spots.d.ts +19 -0
- package/dist/observers/blind-spots.d.ts.map +1 -0
- package/dist/observers/blind-spots.js +89 -0
- package/dist/observers/blind-spots.js.map +1 -0
- package/dist/observers/console.d.ts.map +1 -1
- package/dist/observers/console.js +39 -6
- package/dist/observers/console.js.map +1 -1
- package/dist/observers/dom.d.ts +1 -1
- package/dist/observers/dom.d.ts.map +1 -1
- package/dist/observers/dom.js +69 -10
- package/dist/observers/dom.js.map +1 -1
- package/dist/observers/focus.d.ts +10 -0
- package/dist/observers/focus.d.ts.map +1 -0
- package/dist/observers/focus.js +49 -0
- package/dist/observers/focus.js.map +1 -0
- package/dist/observers/network-body.d.ts +19 -0
- package/dist/observers/network-body.d.ts.map +1 -0
- package/dist/observers/network-body.js +143 -0
- package/dist/observers/network-body.js.map +1 -0
- package/dist/observers/network-redact.d.ts +8 -0
- package/dist/observers/network-redact.d.ts.map +1 -0
- package/dist/observers/network-redact.js +66 -0
- package/dist/observers/network-redact.js.map +1 -0
- package/dist/observers/network.d.ts +19 -7
- package/dist/observers/network.d.ts.map +1 -1
- package/dist/observers/network.js +439 -53
- package/dist/observers/network.js.map +1 -1
- package/dist/observers/perf.d.ts +13 -0
- package/dist/observers/perf.d.ts.map +1 -0
- package/dist/observers/perf.js +62 -0
- package/dist/observers/perf.js.map +1 -0
- package/dist/observers/route.d.ts.map +1 -1
- package/dist/observers/route.js +19 -10
- package/dist/observers/route.js.map +1 -1
- package/dist/observers/scroll.d.ts +1 -1
- package/dist/observers/scroll.d.ts.map +1 -1
- package/dist/observers/scroll.js +36 -9
- package/dist/observers/scroll.js.map +1 -1
- package/dist/observers/state.d.ts +20 -0
- package/dist/observers/state.d.ts.map +1 -0
- package/dist/observers/state.js +87 -0
- package/dist/observers/state.js.map +1 -0
- package/dist/observers/storage.d.ts +23 -0
- package/dist/observers/storage.d.ts.map +1 -0
- package/dist/observers/storage.js +177 -0
- package/dist/observers/storage.js.map +1 -0
- package/dist/observers/types.d.ts +15 -0
- package/dist/observers/types.d.ts.map +1 -1
- package/dist/observers/types.js +29 -1
- package/dist/observers/types.js.map +1 -1
- package/dist/patching/capture-method.d.ts +27 -0
- package/dist/patching/capture-method.d.ts.map +1 -0
- package/dist/patching/capture-method.js +37 -0
- package/dist/patching/capture-method.js.map +1 -0
- package/dist/presenter/presenter-config.d.ts +3 -3
- package/dist/presenter/presenter-config.d.ts.map +1 -1
- package/dist/presenter/presenter-config.js +3 -3
- package/dist/presenter/presenter-config.js.map +1 -1
- package/dist/presenter/presenter-controls.d.ts +1 -1
- package/dist/presenter/presenter-controls.d.ts.map +1 -1
- package/dist/presenter/presenter-controls.js +3 -3
- package/dist/presenter/presenter-controls.js.map +1 -1
- package/dist/presenter/presenter-glow.d.ts +1 -1
- package/dist/presenter/presenter-glow.js +1 -1
- package/dist/presenter/presenter-styles.d.ts +1 -1
- package/dist/presenter/presenter-styles.d.ts.map +1 -1
- package/dist/presenter/presenter-styles.js +12 -3
- package/dist/presenter/presenter-styles.js.map +1 -1
- package/dist/presenter/presenter-test-helpers.d.ts +16 -0
- package/dist/presenter/presenter-test-helpers.d.ts.map +1 -0
- package/dist/presenter/presenter-test-helpers.js +42 -0
- package/dist/presenter/presenter-test-helpers.js.map +1 -0
- package/dist/presenter/presenter.d.ts +4 -6
- package/dist/presenter/presenter.d.ts.map +1 -1
- package/dist/presenter/presenter.js +5 -9
- package/dist/presenter/presenter.js.map +1 -1
- package/dist/recorder/recorder.d.ts +8 -8
- package/dist/recorder/recorder.d.ts.map +1 -1
- package/dist/recorder/recorder.js +22 -9
- package/dist/recorder/recorder.js.map +1 -1
- package/dist/registry/capabilities.d.ts +2 -2
- package/dist/registry/capabilities.d.ts.map +1 -1
- package/dist/registry/capabilities.js +1 -1
- package/dist/registry/capabilities.js.map +1 -1
- package/dist/registry/domains.d.ts +1 -1
- package/dist/registry/domains.js +1 -1
- package/dist/registry/emitter.d.ts +2 -2
- package/dist/registry/emitter.js +2 -2
- package/dist/registry/store-adapters.d.ts +128 -0
- package/dist/registry/store-adapters.d.ts.map +1 -0
- package/dist/registry/store-adapters.js +135 -0
- package/dist/registry/store-adapters.js.map +1 -0
- package/dist/registry/stores.d.ts +45 -3
- package/dist/registry/stores.d.ts.map +1 -1
- package/dist/registry/stores.js +121 -8
- package/dist/registry/stores.js.map +1 -1
- package/dist/reticle.d.ts +28 -4
- package/dist/reticle.d.ts.map +1 -1
- package/dist/reticle.js +83 -15
- package/dist/reticle.js.map +1 -1
- package/dist/review/annotator.d.ts.map +1 -1
- package/dist/review/annotator.js +4 -2
- package/dist/review/annotator.js.map +1 -1
- package/dist/review/mark-anchor.d.ts.map +1 -1
- package/dist/review/mark-anchor.js +1 -21
- package/dist/review/mark-anchor.js.map +1 -1
- package/dist/security/serialization.d.ts +29 -1
- package/dist/security/serialization.d.ts.map +1 -1
- package/dist/security/serialization.js +172 -20
- package/dist/security/serialization.js.map +1 -1
- package/dist/timers/clock.d.ts +13 -0
- package/dist/timers/clock.d.ts.map +1 -1
- package/dist/timers/clock.js +76 -6
- package/dist/timers/clock.js.map +1 -1
- package/dist/transport/transport.d.ts +1 -1
- package/dist/transport/transport.d.ts.map +1 -1
- package/dist/transport/transport.js +49 -8
- package/dist/transport/transport.js.map +1 -1
- package/package.json +7 -3
package/dist/dom/snapshot.js
CHANGED
|
@@ -35,7 +35,8 @@ function directText(el) {
|
|
|
35
35
|
const collapsed = out.replace(/\s+/g, ' ').trim();
|
|
36
36
|
return collapsed.length > TEXT_MAX ? `${collapsed.slice(0, TEXT_MAX)}…` : collapsed;
|
|
37
37
|
}
|
|
38
|
-
|
|
38
|
+
/** Cheap skips that need no computed style (tags, overlays, aria-hidden, [hidden]). */
|
|
39
|
+
function skipEarly(el) {
|
|
39
40
|
if (SKIP_TAGS.has(el.tagName.toLowerCase()))
|
|
40
41
|
return true;
|
|
41
42
|
if (isIgnored(el))
|
|
@@ -44,12 +45,6 @@ function skip(el) {
|
|
|
44
45
|
return true;
|
|
45
46
|
if (el instanceof HTMLElement && el.hidden)
|
|
46
47
|
return true;
|
|
47
|
-
const view = el.ownerDocument.defaultView;
|
|
48
|
-
if (view !== null) {
|
|
49
|
-
const style = view.getComputedStyle(el);
|
|
50
|
-
if (style.display === 'none')
|
|
51
|
-
return true;
|
|
52
|
-
}
|
|
53
48
|
return false;
|
|
54
49
|
}
|
|
55
50
|
function stateSuffix(el) {
|
|
@@ -77,11 +72,9 @@ function formatTextLine(depth, text) {
|
|
|
77
72
|
* regression (e.g. grid columns 2 -> 3) leaves the role+text tree identical, so a role-only
|
|
78
73
|
* snapshot is blind to it; this line makes it visible. Empty for non-container elements.
|
|
79
74
|
*/
|
|
80
|
-
function layoutSignature(
|
|
81
|
-
|
|
82
|
-
if (view === null)
|
|
75
|
+
function layoutSignature(style) {
|
|
76
|
+
if (style === null)
|
|
83
77
|
return '';
|
|
84
|
-
const style = view.getComputedStyle(el);
|
|
85
78
|
const display = style.display;
|
|
86
79
|
// Grid track templates are the high-signal CLS case (column/row count + sizing) and there are
|
|
87
80
|
// few grid containers per page. Flex is intentionally excluded: nearly every row is a flex
|
|
@@ -92,15 +85,44 @@ function layoutSignature(el) {
|
|
|
92
85
|
}
|
|
93
86
|
return '';
|
|
94
87
|
}
|
|
88
|
+
/**
|
|
89
|
+
* The children to walk under `parent`, piercing boundaries a plain `.children` misses: an OPEN shadow
|
|
90
|
+
* root renders as part of the element (web components / design systems), and a SAME-ORIGIN iframe's
|
|
91
|
+
* body is real content. Cross-origin frames throw on access and are skipped by design. Without this,
|
|
92
|
+
* an entire category of modern apps is invisible to reticle_snapshot (systematic false negative).
|
|
93
|
+
*/
|
|
94
|
+
function pierceChildren(parent) {
|
|
95
|
+
const out = [...parent.children];
|
|
96
|
+
const shadow = parent.shadowRoot;
|
|
97
|
+
if (shadow !== null)
|
|
98
|
+
out.push(...shadow.children);
|
|
99
|
+
if (parent instanceof HTMLIFrameElement) {
|
|
100
|
+
try {
|
|
101
|
+
const body = parent.contentDocument?.body;
|
|
102
|
+
if (body !== null && body !== undefined)
|
|
103
|
+
out.push(...body.children);
|
|
104
|
+
}
|
|
105
|
+
catch {
|
|
106
|
+
/* cross-origin frame — inaccessible by design */
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
return out;
|
|
110
|
+
}
|
|
95
111
|
function walk(parent, depth, ctx) {
|
|
96
112
|
if (depth > ctx.maxDepth)
|
|
97
113
|
return;
|
|
98
|
-
for (const child of parent
|
|
114
|
+
for (const child of pierceChildren(parent)) {
|
|
99
115
|
if (ctx.nodes >= ctx.maxNodes) {
|
|
100
116
|
ctx.truncated = true;
|
|
101
117
|
return;
|
|
102
118
|
}
|
|
103
|
-
if (
|
|
119
|
+
if (skipEarly(child))
|
|
120
|
+
continue;
|
|
121
|
+
// Resolve computed style ONCE per node (the dominant snapshot cost) and thread it into both the
|
|
122
|
+
// display-none skip and the layout signature — was two forced style resolutions per node.
|
|
123
|
+
const view = child.ownerDocument.defaultView;
|
|
124
|
+
const style = view !== null ? view.getComputedStyle(child) : null;
|
|
125
|
+
if (style !== null && style.display === 'none')
|
|
104
126
|
continue;
|
|
105
127
|
const role = getRole(child);
|
|
106
128
|
const name = getAccessibleName(child);
|
|
@@ -110,7 +132,7 @@ function walk(parent, depth, ctx) {
|
|
|
110
132
|
const lean = ctx.mode === SnapshotMode.INTERACTIVE;
|
|
111
133
|
const text = !lean && role === 'generic' && name.length === 0 ? directText(child) : '';
|
|
112
134
|
// Layout signature for grid/flex containers — makes CLS/layout regressions visible.
|
|
113
|
-
const layout = lean ? '' : layoutSignature(
|
|
135
|
+
const layout = lean ? '' : layoutSignature(style);
|
|
114
136
|
const meaningful = interactive || role !== 'generic' || name.length > 0 || text.length > 0 || layout.length > 0;
|
|
115
137
|
const include = lean ? interactive : meaningful;
|
|
116
138
|
if (include) {
|
|
@@ -141,14 +163,19 @@ function buildStatus(root) {
|
|
|
141
163
|
visibleDialogs: collectDialogs(root),
|
|
142
164
|
};
|
|
143
165
|
}
|
|
144
|
-
/** Build the semantic accessibility snapshot of the page or a subtree
|
|
166
|
+
/** Build the semantic accessibility snapshot of the page or a subtree. */
|
|
145
167
|
export function buildSnapshot(options = {}) {
|
|
146
168
|
const mode = options.mode ?? SnapshotMode.FULL;
|
|
147
169
|
const scopeEl = options.scope !== undefined
|
|
148
170
|
? (refs.resolve(options.scope) ?? document.querySelector(options.scope))
|
|
149
171
|
: document.body;
|
|
150
|
-
|
|
172
|
+
// A given-but-missing scope snapshots NOTHING and says so — never a silent whole-page fallback.
|
|
173
|
+
const scopeMissing = options.scope !== undefined && !(scopeEl instanceof Element);
|
|
174
|
+
const root = scopeEl instanceof Element ? scopeEl : document.body;
|
|
151
175
|
const status = buildStatus(root);
|
|
176
|
+
if (scopeMissing) {
|
|
177
|
+
return { tree: '', status, nodes: 0, truncated: false, scopeMissing: true };
|
|
178
|
+
}
|
|
152
179
|
if (mode === SnapshotMode.STATUS) {
|
|
153
180
|
return { tree: '', status, nodes: 0, truncated: false };
|
|
154
181
|
}
|
package/dist/dom/snapshot.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"snapshot.js","sourceRoot":"","sources":["../../src/dom/snapshot.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC7D,OAAO,EAAE,iBAAiB,EAAE,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACvF,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAE5C,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC;IAC1B,QAAQ;IACR,MAAM;IACN,SAAS;IACT,UAAU;IACV,OAAO;IACP,UAAU;IACV,SAAS;IACT,QAAQ;IACR,YAAY;IACZ,QAAQ;IACR,KAAK;IACL,UAAU;IACV,QAAQ;CACT,CAAC,CAAC;AAEH,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,CAAC,QAAQ,EAAE,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;AAE/F,gFAAgF;AAChF,MAAM,QAAQ,GAAG,EAAE,CAAC;AAEpB;;;;;GAKG;AACH,SAAS,UAAU,CAAC,EAAW;IAC7B,IAAI,GAAG,GAAG,EAAE,CAAC;IACb,KAAK,MAAM,IAAI,IAAI,EAAE,CAAC,UAAU,EAAE,CAAC;QACjC,IAAI,IAAI,CAAC,QAAQ,KAAK,CAAC,CAAC,oBAAoB;YAAE,GAAG,IAAI,IAAI,CAAC,WAAW,IAAI,EAAE,CAAC;IAC9E,CAAC;IACD,MAAM,SAAS,GAAG,GAAG,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;IAClD,OAAO,SAAS,CAAC,MAAM,GAAG,QAAQ,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC;AACtF,CAAC;
|
|
1
|
+
{"version":3,"file":"snapshot.js","sourceRoot":"","sources":["../../src/dom/snapshot.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Where an element is defined in the codebase.
|
|
3
|
+
*
|
|
4
|
+
* This is the single most valuable thing Reticle can hand an agent that has to fix what Reticle just
|
|
5
|
+
* found. Locating the right FILE is what turns a report into an edit; without it the agent pays for a
|
|
6
|
+
* search loop that the instrumentation already knows the answer to.
|
|
7
|
+
*
|
|
8
|
+
* Two lookups, because the callers have very different cost budgets:
|
|
9
|
+
*
|
|
10
|
+
* sourceFromDom — reads the babel-stamped `data-reticle-source` off the nearest ancestor. One
|
|
11
|
+
* native upward walk, bounded by tree depth. Safe to call per element on paths
|
|
12
|
+
* that describe many elements at once (query results, snapshots).
|
|
13
|
+
* sourceFor — prefers a framework adapter's answer (which knows the component that RENDERED
|
|
14
|
+
* the element, not just the nearest stamped host) and falls back to the DOM. The
|
|
15
|
+
* adapter path walks the fiber tree, so this belongs on single-element paths
|
|
16
|
+
* (inspect, act, review) and not in a loop.
|
|
17
|
+
*
|
|
18
|
+
* Both report source independently of how the element is ANCHORED. Anchor answers "how do I find this
|
|
19
|
+
* again", source answers "where is it written" — collapsing the two once meant that adding a
|
|
20
|
+
* data-testid, which Reticle's own docs recommend, silently removed the source pointer.
|
|
21
|
+
*/
|
|
22
|
+
export interface SourceLocation {
|
|
23
|
+
file: string;
|
|
24
|
+
line: number;
|
|
25
|
+
}
|
|
26
|
+
/** Parse a `data-reticle-source="file:line:column"` value into `{ file, line }` (column dropped). */
|
|
27
|
+
export declare function parseSourceAttr(value: string | null): SourceLocation | undefined;
|
|
28
|
+
/** The nearest babel-stamped source at or above this element. Cheap enough to call in bulk. */
|
|
29
|
+
export declare function sourceFromDom(el: Element): SourceLocation | undefined;
|
|
30
|
+
/** Best source for the element: the framework adapter's, else the nearest babel-stamped attribute. */
|
|
31
|
+
export declare function sourceFor(el: Element, adapterSource: SourceLocation | undefined): SourceLocation | undefined;
|
|
32
|
+
/**
|
|
33
|
+
* `file:line` — the form an agent can act on directly.
|
|
34
|
+
*
|
|
35
|
+
* Deliberately a single compact string rather than an object: it costs a couple of dozen bytes on a
|
|
36
|
+
* descriptor that may repeat hundreds of times in one response, and every consumer of it is either
|
|
37
|
+
* opening an editor or printing it.
|
|
38
|
+
*/
|
|
39
|
+
export declare function formatSource(source: SourceLocation | undefined): string | undefined;
|
|
40
|
+
//# sourceMappingURL=source.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"source.d.ts","sourceRoot":"","sources":["../../src/dom/source.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAOH,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAED,qGAAqG;AACrG,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,cAAc,GAAG,SAAS,CAQhF;AAED,+FAA+F;AAC/F,wBAAgB,aAAa,CAAC,EAAE,EAAE,OAAO,GAAG,cAAc,GAAG,SAAS,CAGrE;AAED,sGAAsG;AACtG,wBAAgB,SAAS,CACvB,EAAE,EAAE,OAAO,EACX,aAAa,EAAE,cAAc,GAAG,SAAS,GACxC,cAAc,GAAG,SAAS,CAG5B;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,cAAc,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAEnF"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Where an element is defined in the codebase.
|
|
3
|
+
*
|
|
4
|
+
* This is the single most valuable thing Reticle can hand an agent that has to fix what Reticle just
|
|
5
|
+
* found. Locating the right FILE is what turns a report into an edit; without it the agent pays for a
|
|
6
|
+
* search loop that the instrumentation already knows the answer to.
|
|
7
|
+
*
|
|
8
|
+
* Two lookups, because the callers have very different cost budgets:
|
|
9
|
+
*
|
|
10
|
+
* sourceFromDom — reads the babel-stamped `data-reticle-source` off the nearest ancestor. One
|
|
11
|
+
* native upward walk, bounded by tree depth. Safe to call per element on paths
|
|
12
|
+
* that describe many elements at once (query results, snapshots).
|
|
13
|
+
* sourceFor — prefers a framework adapter's answer (which knows the component that RENDERED
|
|
14
|
+
* the element, not just the nearest stamped host) and falls back to the DOM. The
|
|
15
|
+
* adapter path walks the fiber tree, so this belongs on single-element paths
|
|
16
|
+
* (inspect, act, review) and not in a loop.
|
|
17
|
+
*
|
|
18
|
+
* Both report source independently of how the element is ANCHORED. Anchor answers "how do I find this
|
|
19
|
+
* again", source answers "where is it written" — collapsing the two once meant that adding a
|
|
20
|
+
* data-testid, which Reticle's own docs recommend, silently removed the source pointer.
|
|
21
|
+
*/
|
|
22
|
+
import { DATA_RETICLE_SOURCE_ATTR } from '@reticlehq/core';
|
|
23
|
+
/** Stamped by @reticlehq/babel-plugin / @reticlehq/vite-plugin in dev as `file:line:column`. */
|
|
24
|
+
const SOURCE_ATTR = DATA_RETICLE_SOURCE_ATTR;
|
|
25
|
+
/** Parse a `data-reticle-source="file:line:column"` value into `{ file, line }` (column dropped). */
|
|
26
|
+
export function parseSourceAttr(value) {
|
|
27
|
+
if (value === null)
|
|
28
|
+
return undefined;
|
|
29
|
+
const m = /^(.*):(\d+):(\d+)$/.exec(value);
|
|
30
|
+
if (m === null)
|
|
31
|
+
return undefined;
|
|
32
|
+
const file = m[1];
|
|
33
|
+
const line = Number(m[2]);
|
|
34
|
+
if (file === undefined || file.length === 0 || !Number.isFinite(line))
|
|
35
|
+
return undefined;
|
|
36
|
+
return { file, line };
|
|
37
|
+
}
|
|
38
|
+
/** The nearest babel-stamped source at or above this element. Cheap enough to call in bulk. */
|
|
39
|
+
export function sourceFromDom(el) {
|
|
40
|
+
const host = el.closest(`[${SOURCE_ATTR}]`);
|
|
41
|
+
return host !== null ? parseSourceAttr(host.getAttribute(SOURCE_ATTR)) : undefined;
|
|
42
|
+
}
|
|
43
|
+
/** Best source for the element: the framework adapter's, else the nearest babel-stamped attribute. */
|
|
44
|
+
export function sourceFor(el, adapterSource) {
|
|
45
|
+
if (adapterSource !== undefined)
|
|
46
|
+
return { file: adapterSource.file, line: adapterSource.line };
|
|
47
|
+
return sourceFromDom(el);
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* `file:line` — the form an agent can act on directly.
|
|
51
|
+
*
|
|
52
|
+
* Deliberately a single compact string rather than an object: it costs a couple of dozen bytes on a
|
|
53
|
+
* descriptor that may repeat hundreds of times in one response, and every consumer of it is either
|
|
54
|
+
* opening an editor or printing it.
|
|
55
|
+
*/
|
|
56
|
+
export function formatSource(source) {
|
|
57
|
+
return source === undefined ? undefined : `${source.file}:${String(source.line)}`;
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=source.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"source.js","sourceRoot":"","sources":["../../src/dom/source.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,EAAE,wBAAwB,EAAE,MAAM,iBAAiB,CAAC;AAE3D,gGAAgG;AAChG,MAAM,WAAW,GAAG,wBAAwB,CAAC;AAO7C,qGAAqG;AACrG,MAAM,UAAU,eAAe,CAAC,KAAoB;IAClD,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,SAAS,CAAC;IACrC,MAAM,CAAC,GAAG,oBAAoB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC3C,IAAI,CAAC,KAAK,IAAI;QAAE,OAAO,SAAS,CAAC;IACjC,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IAClB,MAAM,IAAI,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC1B,IAAI,IAAI,KAAK,SAAS,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC;QAAE,OAAO,SAAS,CAAC;IACxF,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;AACxB,CAAC;AAED,+FAA+F;AAC/F,MAAM,UAAU,aAAa,CAAC,EAAW;IACvC,MAAM,IAAI,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,WAAW,GAAG,CAAC,CAAC;IAC5C,OAAO,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,eAAe,CAAC,IAAI,CAAC,YAAY,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;AACrF,CAAC;AAED,sGAAsG;AACtG,MAAM,UAAU,SAAS,CACvB,EAAW,EACX,aAAyC;IAEzC,IAAI,aAAa,KAAK,SAAS;QAAE,OAAO,EAAE,IAAI,EAAE,aAAa,CAAC,IAAI,EAAE,IAAI,EAAE,aAAa,CAAC,IAAI,EAAE,CAAC;IAC/F,OAAO,aAAa,CAAC,EAAE,CAAC,CAAC;AAC3B,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,YAAY,CAAC,MAAkC;IAC7D,OAAO,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,IAAI,IAAI,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;AACpF,CAAC"}
|
package/dist/dom/theme.js
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
* the matched token name is returned when there is one — so the agent can judge, not just trust a flag.
|
|
10
10
|
*/
|
|
11
11
|
let cached = null;
|
|
12
|
-
/** Resolve any CSS color string to canonical computed `rgb
|
|
12
|
+
/** Resolve any CSS color string to canonical computed `rgb...)`/`rgba...)`, or null if not a color. */
|
|
13
13
|
function toRgb(value) {
|
|
14
14
|
if (value.length === 0)
|
|
15
15
|
return null;
|
|
@@ -25,7 +25,7 @@ function toRgb(value) {
|
|
|
25
25
|
probe.remove();
|
|
26
26
|
return rgb;
|
|
27
27
|
}
|
|
28
|
-
/** Collect `--token: value` declarations from every
|
|
28
|
+
/** Collect `--token: value` declarations from every:root/html rule across the app's stylesheets. */
|
|
29
29
|
function collectTokens() {
|
|
30
30
|
const out = {};
|
|
31
31
|
for (const sheet of Array.from(document.styleSheets)) {
|
package/dist/dom/theme.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"theme.js","sourceRoot":"","sources":["../../src/dom/theme.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAOH,IAAI,MAAM,GAAwB,IAAI,CAAC;AAEvC,
|
|
1
|
+
{"version":3,"file":"theme.js","sourceRoot":"","sources":["../../src/dom/theme.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -6,8 +6,10 @@ export { SESSION_AUTO } from '@reticlehq/core';
|
|
|
6
6
|
export { setIgnoreSelectors } from './dom/dom-ignore.js';
|
|
7
7
|
export { registerAdapter, identifyComponent, readComponentState, elementHasHoverHandlers, adapterNames, } from './registry/adapters.js';
|
|
8
8
|
export type { ReticleAdapter, ComponentInfo, ComponentSource } from './registry/adapters.js';
|
|
9
|
-
export { registerStore, unregisterStore, storeNames, readStores } from './registry/stores.js';
|
|
10
|
-
export type { StoreGetter } from './registry/stores.js';
|
|
9
|
+
export { registerStore, unregisterStore, storeNames, readStores, readStoresWithTruncation, } from './registry/stores.js';
|
|
10
|
+
export type { StoreGetter, StoreLike, StoreSubscribe } from './registry/stores.js';
|
|
11
|
+
export { tanstackQueryStore, jotaiStore, xstateStore, valtioStore, mobxStore, pushStore, } from './registry/store-adapters.js';
|
|
12
|
+
export type { QuerySnapshot } from './registry/store-adapters.js';
|
|
11
13
|
export { registerCapabilities, getCapabilities, hasCapabilities } from './registry/capabilities.js';
|
|
12
14
|
export type { Capabilities, CapabilitiesInput, CapabilityFlow } from './registry/capabilities.js';
|
|
13
15
|
export { createReticleEmitter } from './registry/emitter.js';
|
|
@@ -16,6 +18,8 @@ export { commitAndSignal } from './registry/commit-and-signal.js';
|
|
|
16
18
|
export { registerReticleDomain } from './registry/domains.js';
|
|
17
19
|
export type { ReticleDomain } from './registry/domains.js';
|
|
18
20
|
export { buildSnapshot } from './dom/snapshot.js';
|
|
21
|
+
export { inspectChart, canvasChartData } from './dom/chart.js';
|
|
22
|
+
export type { ChartReport, ChartFinding, CanvasChartData } from './dom/chart.js';
|
|
19
23
|
export { matchQuery, runQuery } from './dom/query.js';
|
|
20
24
|
export { executeAction, executeSequence } from './actions/actions.js';
|
|
21
25
|
export { describe, getRole, getAccessibleName, getStates, isVisible } from './dom/a11y.js';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAQvC,eAAO,MAAM,OAAO,EAAE,OAA2D,CAAC;AAElF,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,YAAY,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AAG1D,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAG/C,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAGzD,OAAO,EACL,eAAe,EACf,iBAAiB,EACjB,kBAAkB,EAClB,uBAAuB,EACvB,YAAY,GACb,MAAM,wBAAwB,CAAC;AAChC,YAAY,EAAE,cAAc,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAG7F,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAQvC,eAAO,MAAM,OAAO,EAAE,OAA2D,CAAC;AAElF,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,YAAY,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AAG1D,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAG/C,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAGzD,OAAO,EACL,eAAe,EACf,iBAAiB,EACjB,kBAAkB,EAClB,uBAAuB,EACvB,YAAY,GACb,MAAM,wBAAwB,CAAC;AAChC,YAAY,EAAE,cAAc,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAG7F,OAAO,EACL,aAAa,EACb,eAAe,EACf,UAAU,EACV,UAAU,EACV,wBAAwB,GACzB,MAAM,sBAAsB,CAAC;AAC9B,YAAY,EAAE,WAAW,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAKnF,OAAO,EACL,kBAAkB,EAClB,UAAU,EACV,WAAW,EACX,WAAW,EACX,SAAS,EACT,SAAS,GACV,MAAM,8BAA8B,CAAC;AACtC,YAAY,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAGlE,OAAO,EAAE,oBAAoB,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AACpG,YAAY,EAAE,YAAY,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAGlG,OAAO,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAC7D,YAAY,EACV,cAAc,EACd,aAAa,EACb,2BAA2B,GAC5B,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC;AAClE,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAC9D,YAAY,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAG3D,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAKlD,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAC/D,YAAY,EAAE,WAAW,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACjF,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AACtD,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACtE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,iBAAiB,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAC3F,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,EAAE,SAAS,EAAE,gBAAgB,EAAE,KAAK,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACxF,OAAO,EAAE,iBAAiB,EAAE,KAAK,UAAU,EAAE,MAAM,yBAAyB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -14,7 +14,11 @@ export { setIgnoreSelectors } from './dom/dom-ignore.js';
|
|
|
14
14
|
// Adapter API (used by @reticlehq/react and other framework adapters).
|
|
15
15
|
export { registerAdapter, identifyComponent, readComponentState, elementHasHoverHandlers, adapterNames, } from './registry/adapters.js';
|
|
16
16
|
// Store registry: pull live framework/store state on demand.
|
|
17
|
-
export { registerStore, unregisterStore, storeNames, readStores } from './registry/stores.js';
|
|
17
|
+
export { registerStore, unregisterStore, storeNames, readStores, readStoresWithTruncation, } from './registry/stores.js';
|
|
18
|
+
// Adapters for state libraries that do not natively expose `{getState, subscribe}`. zustand and Redux
|
|
19
|
+
// need none of these; TanStack Query is the one that matters most, because a stale-cache bug fires no
|
|
20
|
+
// request and renders a plausible value, so the cache is the only witness.
|
|
21
|
+
export { tanstackQueryStore, jotaiStore, xstateStore, valtioStore, mobxStore, pushStore, } from './registry/store-adapters.js';
|
|
18
22
|
// Capability registry: the app self-describes its testable surface via reticle.describe.
|
|
19
23
|
export { registerCapabilities, getCapabilities, hasCapabilities } from './registry/capabilities.js';
|
|
20
24
|
// SDK helpers: adopt the recommended integration patterns without boilerplate.
|
|
@@ -23,6 +27,10 @@ export { commitAndSignal } from './registry/commit-and-signal.js';
|
|
|
23
27
|
export { registerReticleDomain } from './registry/domains.js';
|
|
24
28
|
// Lower-level building blocks (useful for tests and advanced embedding).
|
|
25
29
|
export { buildSnapshot } from './dom/snapshot.js';
|
|
30
|
+
// Chart inspection. Surfaced automatically on any element descriptor that contains faulty plot
|
|
31
|
+
// geometry (see ElementDescriptor.chart), and exported for direct use — canvasChartData is the only
|
|
32
|
+
// route to a canvas chart's data, since its pixels are not DOM.
|
|
33
|
+
export { inspectChart, canvasChartData } from './dom/chart.js';
|
|
26
34
|
export { matchQuery, runQuery } from './dom/query.js';
|
|
27
35
|
export { executeAction, executeSequence } from './actions/actions.js';
|
|
28
36
|
export { describe, getRole, getAccessibleName, getStates, isVisible } from './dom/a11y.js';
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAEvC;;;;GAIG;AACH,MAAM,WAAW,GAAG,UAAwD,CAAC;AAC7E,MAAM,CAAC,MAAM,OAAO,GAAY,CAAC,WAAW,CAAC,iBAAiB,KAAK,IAAI,OAAO,EAAE,CAAC,CAAC;AAElF,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAGvC,qGAAqG;AACrG,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAE/C,yDAAyD;AACzD,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAEzD,uEAAuE;AACvE,OAAO,EACL,eAAe,EACf,iBAAiB,EACjB,kBAAkB,EAClB,uBAAuB,EACvB,YAAY,GACb,MAAM,wBAAwB,CAAC;AAGhC,6DAA6D;AAC7D,OAAO,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAEvC;;;;GAIG;AACH,MAAM,WAAW,GAAG,UAAwD,CAAC;AAC7E,MAAM,CAAC,MAAM,OAAO,GAAY,CAAC,WAAW,CAAC,iBAAiB,KAAK,IAAI,OAAO,EAAE,CAAC,CAAC;AAElF,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAGvC,qGAAqG;AACrG,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAE/C,yDAAyD;AACzD,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAEzD,uEAAuE;AACvE,OAAO,EACL,eAAe,EACf,iBAAiB,EACjB,kBAAkB,EAClB,uBAAuB,EACvB,YAAY,GACb,MAAM,wBAAwB,CAAC;AAGhC,6DAA6D;AAC7D,OAAO,EACL,aAAa,EACb,eAAe,EACf,UAAU,EACV,UAAU,EACV,wBAAwB,GACzB,MAAM,sBAAsB,CAAC;AAG9B,sGAAsG;AACtG,sGAAsG;AACtG,2EAA2E;AAC3E,OAAO,EACL,kBAAkB,EAClB,UAAU,EACV,WAAW,EACX,WAAW,EACX,SAAS,EACT,SAAS,GACV,MAAM,8BAA8B,CAAC;AAGtC,yFAAyF;AACzF,OAAO,EAAE,oBAAoB,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAGpG,+EAA+E;AAC/E,OAAO,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAM7D,OAAO,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC;AAClE,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAG9D,yEAAyE;AACzE,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAElD,+FAA+F;AAC/F,oGAAoG;AACpG,gEAAgE;AAChE,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAE/D,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AACtD,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACtE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,iBAAiB,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAC3F,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,EAAE,SAAS,EAAE,gBAAgB,EAAsB,MAAM,uBAAuB,CAAC;AACxF,OAAO,EAAE,iBAAiB,EAAmB,MAAM,yBAAyB,CAAC"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import type { Emit, Teardown } from './types.js';
|
|
2
|
-
/** Observe CSS animations + transitions and emit anim.start / anim.end
|
|
2
|
+
/** Observe CSS animations + transitions and emit anim.start / anim.end. */
|
|
3
3
|
export declare function installAnimation(emit: Emit): Teardown;
|
|
4
4
|
//# sourceMappingURL=animation.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"animation.d.ts","sourceRoot":"","sources":["../../src/observers/animation.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAEjD,
|
|
1
|
+
{"version":3,"file":"animation.d.ts","sourceRoot":"","sources":["../../src/observers/animation.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAEjD,2EAA2E;AAC3E,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,IAAI,GAAG,QAAQ,CAmCrD"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { EventType } from '@reticlehq/core';
|
|
2
2
|
import { refs } from '../dom/refs.js';
|
|
3
3
|
import { isReticleOverlay } from '../dom/dom-ignore.js';
|
|
4
|
-
/** Observe CSS animations + transitions and emit anim.start / anim.end
|
|
4
|
+
/** Observe CSS animations + transitions and emit anim.start / anim.end. */
|
|
5
5
|
export function installAnimation(emit) {
|
|
6
6
|
const onStart = (event) => {
|
|
7
7
|
const target = event.target;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"animation.js","sourceRoot":"","sources":["../../src/observers/animation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAC;AACtC,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAGxD,
|
|
1
|
+
{"version":3,"file":"animation.js","sourceRoot":"","sources":["../../src/observers/animation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAC;AACtC,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAGxD,2EAA2E;AAC3E,MAAM,UAAU,gBAAgB,CAAC,IAAU;IACzC,MAAM,OAAO,GAAG,CAAC,KAAqB,EAAQ,EAAE;QAC9C,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC;QAC5B,6FAA6F;QAC7F,wFAAwF;QACxF,IAAI,MAAM,YAAY,OAAO,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,EAAE,CAAC;YAC3D,IAAI,CAAC,SAAS,CAAC,UAAU,EAAE,EAAE,IAAI,EAAE,KAAK,CAAC,aAAa,EAAE,EAAE,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;QACjF,CAAC;IACH,CAAC,CAAC;IACF,MAAM,KAAK,GAAG,CAAC,KAAqB,EAAQ,EAAE;QAC5C,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC;QAC5B,IAAI,MAAM,YAAY,OAAO,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,EAAE,CAAC;YAC3D,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,EAAE,IAAI,EAAE,KAAK,CAAC,aAAa,EAAE,EAAE,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;QAC/E,CAAC;IACH,CAAC,CAAC;IACF,MAAM,eAAe,GAAG,CAAC,KAAsB,EAAQ,EAAE;QACvD,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC;QAC5B,IAAI,MAAM,YAAY,OAAO,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,EAAE,CAAC;YAC3D,IAAI,CACF,SAAS,CAAC,QAAQ,EAClB,EAAE,IAAI,EAAE,KAAK,CAAC,YAAY,EAAE,IAAI,EAAE,YAAY,EAAE,EAChD,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CACpB,CAAC;QACJ,CAAC;IACH,CAAC,CAAC;IAEF,QAAQ,CAAC,gBAAgB,CAAC,gBAAgB,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC;IAC3D,QAAQ,CAAC,gBAAgB,CAAC,cAAc,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;IACvD,QAAQ,CAAC,gBAAgB,CAAC,eAAe,EAAE,eAAe,EAAE,IAAI,CAAC,CAAC;IAElE,OAAO,GAAG,EAAE;QACV,QAAQ,CAAC,mBAAmB,CAAC,gBAAgB,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC;QAC9D,QAAQ,CAAC,mBAAmB,CAAC,cAAc,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;QAC1D,QAAQ,CAAC,mBAAmB,CAAC,eAAe,EAAE,eAAe,EAAE,IAAI,CAAC,CAAC;IACvE,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { Emit, Teardown } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Blind-spot sensor. The SDK instruments the DOM, but a cross-origin iframe is a wall it cannot
|
|
4
|
+
* see through — its contents, network, and console are invisible. Left unstated, a green verdict would
|
|
5
|
+
* imply the whole page was verified. This detects cross-origin frames and emits a BLIND_SPOT event so the
|
|
6
|
+
* server can mark results `coverage: partial` instead of lying by omission. Closed shadow roots and
|
|
7
|
+
* virtualized-unmounted rows are the other kinds (detected elsewhere / by their tools); this sensor owns
|
|
8
|
+
* the iframe case, the one that is cheaply and reliably detectable from the page.
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* Whether a frame is cross-origin (unobservable). A same-origin frame exposes its `contentDocument`; a
|
|
12
|
+
* cross-origin one returns null (or THROWS a SecurityError on access). A src-less / about:blank frame is
|
|
13
|
+
* same-origin and simply not navigated — not a blind spot.
|
|
14
|
+
*/
|
|
15
|
+
export declare function isCrossOriginFrame(frame: HTMLIFrameElement): boolean;
|
|
16
|
+
/** How many of the given frames are cross-origin (unobservable). */
|
|
17
|
+
export declare function countCrossOriginFrames(frames: readonly HTMLIFrameElement[]): number;
|
|
18
|
+
export declare function installBlindSpots(emit: Emit): Teardown;
|
|
19
|
+
//# sourceMappingURL=blind-spots.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"blind-spots.d.ts","sourceRoot":"","sources":["../../src/observers/blind-spots.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAGjD;;;;;;;GAOG;AAEH;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,iBAAiB,GAAG,OAAO,CAQpE;AAED,oEAAoE;AACpE,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,SAAS,iBAAiB,EAAE,GAAG,MAAM,CAInF;AAmBD,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,IAAI,GAAG,QAAQ,CAoCtD"}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { EventType, BlindSpotKind } from '@reticlehq/core';
|
|
2
|
+
import { nativeClearTimeout, nativeSetTimeout } from '../timers/native-timers.js';
|
|
3
|
+
/**
|
|
4
|
+
* Blind-spot sensor. The SDK instruments the DOM, but a cross-origin iframe is a wall it cannot
|
|
5
|
+
* see through — its contents, network, and console are invisible. Left unstated, a green verdict would
|
|
6
|
+
* imply the whole page was verified. This detects cross-origin frames and emits a BLIND_SPOT event so the
|
|
7
|
+
* server can mark results `coverage: partial` instead of lying by omission. Closed shadow roots and
|
|
8
|
+
* virtualized-unmounted rows are the other kinds (detected elsewhere / by their tools); this sensor owns
|
|
9
|
+
* the iframe case, the one that is cheaply and reliably detectable from the page.
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* Whether a frame is cross-origin (unobservable). A same-origin frame exposes its `contentDocument`; a
|
|
13
|
+
* cross-origin one returns null (or THROWS a SecurityError on access). A src-less / about:blank frame is
|
|
14
|
+
* same-origin and simply not navigated — not a blind spot.
|
|
15
|
+
*/
|
|
16
|
+
export function isCrossOriginFrame(frame) {
|
|
17
|
+
const src = frame.getAttribute('src');
|
|
18
|
+
if (src === null || src.length === 0)
|
|
19
|
+
return false;
|
|
20
|
+
try {
|
|
21
|
+
return frame.contentDocument === null;
|
|
22
|
+
}
|
|
23
|
+
catch {
|
|
24
|
+
return true; // SecurityError on access is itself proof of cross-origin
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
/** How many of the given frames are cross-origin (unobservable). */
|
|
28
|
+
export function countCrossOriginFrames(frames) {
|
|
29
|
+
let count = 0;
|
|
30
|
+
for (const frame of frames)
|
|
31
|
+
if (isCrossOriginFrame(frame))
|
|
32
|
+
count += 1;
|
|
33
|
+
return count;
|
|
34
|
+
}
|
|
35
|
+
function currentCount() {
|
|
36
|
+
return countCrossOriginFrames(Array.from(document.querySelectorAll('iframe')));
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Watch the page for cross-origin iframes and emit BLIND_SPOT whenever the count CHANGES (install +
|
|
40
|
+
* on any added/removed frame). Only the delta is emitted — never a per-mutation flood — so a static
|
|
41
|
+
* embed reports once. Reversible: disconnects the observer on teardown.
|
|
42
|
+
*/
|
|
43
|
+
/**
|
|
44
|
+
* How long added/removed nodes are allowed to pile up before the frame count is re-checked.
|
|
45
|
+
*
|
|
46
|
+
* A blind spot is a coverage caveat on a verdict, not a live signal — noticing an embed a fraction of
|
|
47
|
+
* a second later costs nothing, while checking on every mutation costs a DOM scan per render.
|
|
48
|
+
*/
|
|
49
|
+
const RECHECK_DEBOUNCE_MS = 250;
|
|
50
|
+
export function installBlindSpots(emit) {
|
|
51
|
+
let last = -1;
|
|
52
|
+
const report = () => {
|
|
53
|
+
const count = currentCount();
|
|
54
|
+
if (count === last)
|
|
55
|
+
return;
|
|
56
|
+
last = count;
|
|
57
|
+
if (count > 0) {
|
|
58
|
+
emit(EventType.BLIND_SPOT, { kind: BlindSpotKind.CROSS_ORIGIN_IFRAME, count });
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
report();
|
|
62
|
+
// Coalesce rather than gate.
|
|
63
|
+
//
|
|
64
|
+
// This used to try to skip unrelated churn by testing each added/removed node with
|
|
65
|
+
// `n.querySelector('iframe')` — but that is a full subtree scan per mutated node, so a React commit
|
|
66
|
+
// mounting a 500-node panel paid a 500-node scan to decide whether to do a document scan. The gate
|
|
67
|
+
// cost more than the work, and it scaled with exactly the thing a large app does most.
|
|
68
|
+
//
|
|
69
|
+
// Since report() emits only when the count CHANGES, running it late and rarely is free. One
|
|
70
|
+
// debounced document scan per quarter-second replaces per-node scanning, and it is also more
|
|
71
|
+
// correct: the old gate's `querySelector` missed an iframe added inside a subtree whose own root
|
|
72
|
+
// was a text or comment node.
|
|
73
|
+
let pending;
|
|
74
|
+
const observer = new MutationObserver(() => {
|
|
75
|
+
if (pending !== undefined)
|
|
76
|
+
return;
|
|
77
|
+
pending = nativeSetTimeout(() => {
|
|
78
|
+
pending = undefined;
|
|
79
|
+
report();
|
|
80
|
+
}, RECHECK_DEBOUNCE_MS);
|
|
81
|
+
});
|
|
82
|
+
observer.observe(document.documentElement, { childList: true, subtree: true });
|
|
83
|
+
return () => {
|
|
84
|
+
if (pending !== undefined)
|
|
85
|
+
nativeClearTimeout(pending);
|
|
86
|
+
observer.disconnect();
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
//# sourceMappingURL=blind-spots.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"blind-spots.js","sourceRoot":"","sources":["../../src/observers/blind-spots.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAE3D,OAAO,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAElF;;;;;;;GAOG;AAEH;;;;GAIG;AACH,MAAM,UAAU,kBAAkB,CAAC,KAAwB;IACzD,MAAM,GAAG,GAAG,KAAK,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;IACtC,IAAI,GAAG,KAAK,IAAI,IAAI,GAAG,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IACnD,IAAI,CAAC;QACH,OAAO,KAAK,CAAC,eAAe,KAAK,IAAI,CAAC;IACxC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC,CAAC,0DAA0D;IACzE,CAAC;AACH,CAAC;AAED,oEAAoE;AACpE,MAAM,UAAU,sBAAsB,CAAC,MAAoC;IACzE,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,KAAK,MAAM,KAAK,IAAI,MAAM;QAAE,IAAI,kBAAkB,CAAC,KAAK,CAAC;YAAE,KAAK,IAAI,CAAC,CAAC;IACtE,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,YAAY;IACnB,OAAO,sBAAsB,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;AACjF,CAAC;AAED;;;;GAIG;AACH;;;;;GAKG;AACH,MAAM,mBAAmB,GAAG,GAAG,CAAC;AAEhC,MAAM,UAAU,iBAAiB,CAAC,IAAU;IAC1C,IAAI,IAAI,GAAG,CAAC,CAAC,CAAC;IACd,MAAM,MAAM,GAAG,GAAS,EAAE;QACxB,MAAM,KAAK,GAAG,YAAY,EAAE,CAAC;QAC7B,IAAI,KAAK,KAAK,IAAI;YAAE,OAAO;QAC3B,IAAI,GAAG,KAAK,CAAC;QACb,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;YACd,IAAI,CAAC,SAAS,CAAC,UAAU,EAAE,EAAE,IAAI,EAAE,aAAa,CAAC,mBAAmB,EAAE,KAAK,EAAE,CAAC,CAAC;QACjF,CAAC;IACH,CAAC,CAAC;IACF,MAAM,EAAE,CAAC;IAET,6BAA6B;IAC7B,EAAE;IACF,mFAAmF;IACnF,oGAAoG;IACpG,mGAAmG;IACnG,uFAAuF;IACvF,EAAE;IACF,4FAA4F;IAC5F,6FAA6F;IAC7F,iGAAiG;IACjG,8BAA8B;IAC9B,IAAI,OAAwD,CAAC;IAC7D,MAAM,QAAQ,GAAG,IAAI,gBAAgB,CAAC,GAAG,EAAE;QACzC,IAAI,OAAO,KAAK,SAAS;YAAE,OAAO;QAClC,OAAO,GAAG,gBAAgB,CAAC,GAAG,EAAE;YAC9B,OAAO,GAAG,SAAS,CAAC;YACpB,MAAM,EAAE,CAAC;QACX,CAAC,EAAE,mBAAmB,CAAC,CAAC;IAC1B,CAAC,CAAC,CAAC;IACH,QAAQ,CAAC,OAAO,CAAC,QAAQ,CAAC,eAAe,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;IAC/E,OAAO,GAAG,EAAE;QACV,IAAI,OAAO,KAAK,SAAS;YAAE,kBAAkB,CAAC,OAAO,CAAC,CAAC;QACvD,QAAQ,CAAC,UAAU,EAAE,CAAC;IACxB,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"console.d.ts","sourceRoot":"","sources":["../../src/observers/console.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"console.d.ts","sourceRoot":"","sources":["../../src/observers/console.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAyCjD,0EAA0E;AAC1E,wBAAgB,cAAc,CAAC,IAAI,EAAE,IAAI,GAAG,QAAQ,CAqDnD"}
|
|
@@ -1,10 +1,13 @@
|
|
|
1
|
-
|
|
2
|
-
import { EventType } from '@reticlehq/core';
|
|
1
|
+
import { EventType, TRANSPORT_LIMITS } from '@reticlehq/core';
|
|
3
2
|
import { safeStringify } from '../security/serialization.js';
|
|
4
3
|
const METHOD_EVENT = {
|
|
5
4
|
log: EventType.CONSOLE_LOG,
|
|
6
5
|
warn: EventType.CONSOLE_WARN,
|
|
7
6
|
error: EventType.CONSOLE_ERROR,
|
|
7
|
+
// info/debug are captured for the raw console channel but excluded from summaries/deviation reports
|
|
8
|
+
// (low signal — most apps chatter here). Lean: no stack, like log/warn.
|
|
9
|
+
info: EventType.CONSOLE_INFO,
|
|
10
|
+
debug: EventType.CONSOLE_DEBUG,
|
|
8
11
|
};
|
|
9
12
|
function stringifyArgs(args) {
|
|
10
13
|
return args
|
|
@@ -17,39 +20,69 @@ function stringifyArgs(args) {
|
|
|
17
20
|
})
|
|
18
21
|
.join(' ');
|
|
19
22
|
}
|
|
23
|
+
/** Stacks can be long; cap so a deep async trace never blows the event budget. */
|
|
24
|
+
const MAX_STACK_LEN = TRANSPORT_LIMITS.MAX_STACK_LENGTH;
|
|
25
|
+
function capStack(stack) {
|
|
26
|
+
if (stack === undefined || stack.length === 0)
|
|
27
|
+
return undefined;
|
|
28
|
+
return stack.length > MAX_STACK_LEN ? stack.slice(0, MAX_STACK_LEN) : stack;
|
|
29
|
+
}
|
|
30
|
+
/** The stack of the first Error argument, if any — the single biggest diagnosis upgrade, near-zero cost. */
|
|
31
|
+
function firstErrorStack(args) {
|
|
32
|
+
for (const arg of args) {
|
|
33
|
+
if (arg instanceof Error)
|
|
34
|
+
return capStack(arg.stack);
|
|
35
|
+
}
|
|
36
|
+
return undefined;
|
|
37
|
+
}
|
|
20
38
|
/** Patch console.{log,warn,error} and window error events. Reversible. */
|
|
21
39
|
export function installConsole(emit) {
|
|
22
|
-
const methods = ['log', 'warn', 'error'];
|
|
40
|
+
const methods = ['log', 'warn', 'error', 'info', 'debug'];
|
|
23
41
|
const originals = new Map();
|
|
42
|
+
const patched = new Map();
|
|
24
43
|
for (const method of methods) {
|
|
25
44
|
// Store the true original for teardown identity; call through a bound copy.
|
|
26
45
|
const original = console[method];
|
|
27
46
|
originals.set(method, original);
|
|
28
47
|
const callOriginal = original.bind(console);
|
|
29
|
-
|
|
30
|
-
|
|
48
|
+
const wrapper = (...args) => {
|
|
49
|
+
// Only console.error carries a stack — the diagnosis case; log/warn stay lean.
|
|
50
|
+
const stack = method === 'error' ? firstErrorStack(args) : undefined;
|
|
51
|
+
emit(METHOD_EVENT[method], {
|
|
52
|
+
message: stringifyArgs(args),
|
|
53
|
+
...(stack === undefined ? {} : { stack }),
|
|
54
|
+
});
|
|
31
55
|
callOriginal(...args);
|
|
32
56
|
};
|
|
57
|
+
patched.set(method, wrapper);
|
|
58
|
+
console[method] = wrapper;
|
|
33
59
|
}
|
|
34
60
|
const onError = (event) => {
|
|
61
|
+
const stack = capStack(event.error instanceof Error ? event.error.stack : undefined);
|
|
35
62
|
emit(EventType.ERROR_UNCAUGHT, {
|
|
36
63
|
message: event.message,
|
|
37
64
|
source: event.filename,
|
|
38
65
|
line: event.lineno,
|
|
66
|
+
...(stack === undefined ? {} : { stack }),
|
|
39
67
|
});
|
|
40
68
|
};
|
|
41
69
|
const onRejection = (event) => {
|
|
42
70
|
const reason = event.reason;
|
|
71
|
+
const stack = capStack(reason instanceof Error ? reason.stack : undefined);
|
|
43
72
|
emit(EventType.ERROR_UNCAUGHT, {
|
|
44
73
|
message: reason instanceof Error ? reason.message : String(reason),
|
|
45
74
|
kind: 'unhandledrejection',
|
|
75
|
+
...(stack === undefined ? {} : { stack }),
|
|
46
76
|
});
|
|
47
77
|
};
|
|
48
78
|
window.addEventListener('error', onError);
|
|
49
79
|
window.addEventListener('unhandledrejection', onRejection);
|
|
50
80
|
return () => {
|
|
51
81
|
for (const [method, original] of originals) {
|
|
52
|
-
console[method]
|
|
82
|
+
// Restore only if console[method] still holds our wrapper — a logging SDK (Sentry, LogRocket)
|
|
83
|
+
// that wrapped console AFTER connect() must keep its instrumentation on teardown.
|
|
84
|
+
if (console[method] === patched.get(method))
|
|
85
|
+
console[method] = original;
|
|
53
86
|
}
|
|
54
87
|
window.removeEventListener('error', onError);
|
|
55
88
|
window.removeEventListener('unhandledrejection', onRejection);
|