@descryy/runtime-identity-grounding 0.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/dist/element-identity.d.ts +146 -0
- package/dist/element-identity.d.ts.map +1 -0
- package/dist/element-identity.js +99 -0
- package/dist/element-identity.js.map +1 -0
- package/dist/fiber-probe.d.ts +112 -0
- package/dist/fiber-probe.d.ts.map +1 -0
- package/dist/fiber-probe.js +269 -0
- package/dist/fiber-probe.js.map +1 -0
- package/dist/graph-join.d.ts +61 -0
- package/dist/graph-join.d.ts.map +1 -0
- package/dist/graph-join.js +59 -0
- package/dist/graph-join.js.map +1 -0
- package/dist/identity-grounder.d.ts +60 -0
- package/dist/identity-grounder.d.ts.map +1 -0
- package/dist/identity-grounder.js +64 -0
- package/dist/identity-grounder.js.map +1 -0
- package/dist/identity-grounding.d.ts +54 -0
- package/dist/identity-grounding.d.ts.map +1 -0
- package/dist/identity-grounding.js +238 -0
- package/dist/identity-grounding.js.map +1 -0
- package/dist/index.d.ts +22 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +16 -0
- package/dist/index.js.map +1 -0
- package/dist/owner-stack.d.ts +90 -0
- package/dist/owner-stack.d.ts.map +1 -0
- package/dist/owner-stack.js +125 -0
- package/dist/owner-stack.js.map +1 -0
- package/package.json +36 -0
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The join to `descry-core`'s graph — as a **hand-off**, not a second
|
|
3
|
+
* resolver.
|
|
4
|
+
*
|
|
5
|
+
* `@descryy/runtime-graph-correlator`'s `resolveSymbolNode` already does the
|
|
6
|
+
* whole job of turning `{ file, symbolName, line }` into a `FUNCTION`/
|
|
7
|
+
* `CLASS` node, and everything hard about that job is in the parts this
|
|
8
|
+
* function must not duplicate: refusing ambiguity instead of ranking
|
|
9
|
+
* candidates, checking the claimed line against the node's own range and
|
|
10
|
+
* reporting `line-mismatch` distinctly, translating between the absolute /
|
|
11
|
+
* repo-relative / relative-to-launch-cwd path languages, and requiring
|
|
12
|
+
* `repo` because `FUNCTION` is repo-scoped and there is no honest default.
|
|
13
|
+
* A copy of any of that here would be a copy that drifts.
|
|
14
|
+
*
|
|
15
|
+
* So this function's entire contract is: hand `resolveSymbolNode` exactly
|
|
16
|
+
* the input it asks for, or hand it nothing.
|
|
17
|
+
*
|
|
18
|
+
* ## No new node type, no new edge type
|
|
19
|
+
*
|
|
20
|
+
* The component resolves to a `FUNCTION` or `CLASS` node that an adapter
|
|
21
|
+
* already produced — `descry-core`'s frozen 15 node types and 15 edge types
|
|
22
|
+
* are untouched. There is no `COMPONENT_INSTANCE`, no `RENDERS` edge, and
|
|
23
|
+
* nothing here asks for one. (`COMPONENT` is already one of the 15, and a
|
|
24
|
+
* React component that an adapter emitted as one is found by the same
|
|
25
|
+
* name+file lookup.)
|
|
26
|
+
*
|
|
27
|
+
* ## Why a compiled location is withheld rather than passed through
|
|
28
|
+
*
|
|
29
|
+
* `resolveSymbolNode` would take a bundle path quite happily and report
|
|
30
|
+
* `not-found` for it, which reads to a consumer as *"that component is not
|
|
31
|
+
* in the graph"* — the exact misleading refusal `symbol.ts`'s own header
|
|
32
|
+
* describes and fixed for absolute paths. A React 19 answer with
|
|
33
|
+
* `authoredSource: false` names `dist/dev.js`, a file no adapter ever
|
|
34
|
+
* indexed and never will. Withholding it keeps the honest statement —
|
|
35
|
+
* *"we know the component, we could not reach authored source"* — inside
|
|
36
|
+
* `ElementIdentity`, where the capability status explains it, instead of
|
|
37
|
+
* laundering it into a graph miss.
|
|
38
|
+
*/
|
|
39
|
+
import type { ElementIdentity } from "./element-identity.ts";
|
|
40
|
+
/**
|
|
41
|
+
* Structurally `resolveSymbolNode`'s own `location` parameter. Deliberately
|
|
42
|
+
* declared with `line` optional rather than nullable, because that is the
|
|
43
|
+
* shape that function accepts; `graph-join.test.ts` asserts the
|
|
44
|
+
* compatibility against the real signature at compile time, so a change on
|
|
45
|
+
* either side breaks the build rather than being discovered at runtime.
|
|
46
|
+
*/
|
|
47
|
+
export interface GraphSymbolLocation {
|
|
48
|
+
readonly file: string;
|
|
49
|
+
readonly symbolName: string;
|
|
50
|
+
readonly line?: number;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* The graph lookup this identity supports, or `null` when it supports none.
|
|
54
|
+
*
|
|
55
|
+
* `null` for every outcome except a `grounded` one that reached authored
|
|
56
|
+
* source with a real file — including `component-only`, which knows the
|
|
57
|
+
* component's name and nothing about where it lives, and including a
|
|
58
|
+
* `grounded` answer whose location is compiled output.
|
|
59
|
+
*/
|
|
60
|
+
export declare function symbolLocationForGraph(identity: ElementIdentity): GraphSymbolLocation | null;
|
|
61
|
+
//# sourceMappingURL=graph-join.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"graph-join.d.ts","sourceRoot":"","sources":["../src/graph-join.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAE7D;;;;;;GAMG;AACH,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;CACxB;AAED;;;;;;;GAOG;AACH,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,eAAe,GAAG,mBAAmB,GAAG,IAAI,CAU5F"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The join to `descry-core`'s graph — as a **hand-off**, not a second
|
|
3
|
+
* resolver.
|
|
4
|
+
*
|
|
5
|
+
* `@descryy/runtime-graph-correlator`'s `resolveSymbolNode` already does the
|
|
6
|
+
* whole job of turning `{ file, symbolName, line }` into a `FUNCTION`/
|
|
7
|
+
* `CLASS` node, and everything hard about that job is in the parts this
|
|
8
|
+
* function must not duplicate: refusing ambiguity instead of ranking
|
|
9
|
+
* candidates, checking the claimed line against the node's own range and
|
|
10
|
+
* reporting `line-mismatch` distinctly, translating between the absolute /
|
|
11
|
+
* repo-relative / relative-to-launch-cwd path languages, and requiring
|
|
12
|
+
* `repo` because `FUNCTION` is repo-scoped and there is no honest default.
|
|
13
|
+
* A copy of any of that here would be a copy that drifts.
|
|
14
|
+
*
|
|
15
|
+
* So this function's entire contract is: hand `resolveSymbolNode` exactly
|
|
16
|
+
* the input it asks for, or hand it nothing.
|
|
17
|
+
*
|
|
18
|
+
* ## No new node type, no new edge type
|
|
19
|
+
*
|
|
20
|
+
* The component resolves to a `FUNCTION` or `CLASS` node that an adapter
|
|
21
|
+
* already produced — `descry-core`'s frozen 15 node types and 15 edge types
|
|
22
|
+
* are untouched. There is no `COMPONENT_INSTANCE`, no `RENDERS` edge, and
|
|
23
|
+
* nothing here asks for one. (`COMPONENT` is already one of the 15, and a
|
|
24
|
+
* React component that an adapter emitted as one is found by the same
|
|
25
|
+
* name+file lookup.)
|
|
26
|
+
*
|
|
27
|
+
* ## Why a compiled location is withheld rather than passed through
|
|
28
|
+
*
|
|
29
|
+
* `resolveSymbolNode` would take a bundle path quite happily and report
|
|
30
|
+
* `not-found` for it, which reads to a consumer as *"that component is not
|
|
31
|
+
* in the graph"* — the exact misleading refusal `symbol.ts`'s own header
|
|
32
|
+
* describes and fixed for absolute paths. A React 19 answer with
|
|
33
|
+
* `authoredSource: false` names `dist/dev.js`, a file no adapter ever
|
|
34
|
+
* indexed and never will. Withholding it keeps the honest statement —
|
|
35
|
+
* *"we know the component, we could not reach authored source"* — inside
|
|
36
|
+
* `ElementIdentity`, where the capability status explains it, instead of
|
|
37
|
+
* laundering it into a graph miss.
|
|
38
|
+
*/
|
|
39
|
+
/**
|
|
40
|
+
* The graph lookup this identity supports, or `null` when it supports none.
|
|
41
|
+
*
|
|
42
|
+
* `null` for every outcome except a `grounded` one that reached authored
|
|
43
|
+
* source with a real file — including `component-only`, which knows the
|
|
44
|
+
* component's name and nothing about where it lives, and including a
|
|
45
|
+
* `grounded` answer whose location is compiled output.
|
|
46
|
+
*/
|
|
47
|
+
export function symbolLocationForGraph(identity) {
|
|
48
|
+
if (identity.outcome !== "grounded")
|
|
49
|
+
return null;
|
|
50
|
+
if (!identity.authoredSource)
|
|
51
|
+
return null;
|
|
52
|
+
const { file, line } = identity.sourceLocation;
|
|
53
|
+
if (file === null)
|
|
54
|
+
return null;
|
|
55
|
+
return line === null
|
|
56
|
+
? { file, symbolName: identity.component.name }
|
|
57
|
+
: { file, symbolName: identity.component.name, line };
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=graph-join.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"graph-join.js","sourceRoot":"","sources":["../src/graph-join.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AAiBH;;;;;;;GAOG;AACH,MAAM,UAAU,sBAAsB,CAAC,QAAyB;IAC9D,IAAI,QAAQ,CAAC,OAAO,KAAK,UAAU;QAAE,OAAO,IAAI,CAAC;IACjD,IAAI,CAAC,QAAQ,CAAC,cAAc;QAAE,OAAO,IAAI,CAAC;IAE1C,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,QAAQ,CAAC,cAAc,CAAC;IAC/C,IAAI,IAAI,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IAE/B,OAAO,IAAI,KAAK,IAAI;QAClB,CAAC,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,QAAQ,CAAC,SAAS,CAAC,IAAI,EAAE;QAC/C,CAAC,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,QAAQ,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC;AAC1D,CAAC"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The composed, page-driving surface — install once, then ask about a
|
|
3
|
+
* selector.
|
|
4
|
+
*
|
|
5
|
+
* Everything hard here is a composition of parts this repo already owns,
|
|
6
|
+
* deliberately:
|
|
7
|
+
*
|
|
8
|
+
* | step | owner |
|
|
9
|
+
* | --- | --- |
|
|
10
|
+
* | inject into the page | `page.addInitScript`, the seam `frontend-initiator-capture.ts` established |
|
|
11
|
+
* | read the fiber | `fiber-probe.ts` (this package) |
|
|
12
|
+
* | browser URL to on-disk path | `rewriteScriptUrls` (`@descryy/runtime-browser`) |
|
|
13
|
+
* | parse a V8 stack | `createV8StackTraceParser` (`@descryy/runtime-adapter-typescript`) |
|
|
14
|
+
* | source map, staleness, `reliability` | `createNodeSourceLocationResolver` (same) |
|
|
15
|
+
* | decide what may be claimed | `identity-grounding.ts` (this package) |
|
|
16
|
+
*
|
|
17
|
+
* The only genuinely new machinery in this package is the fiber read and
|
|
18
|
+
* the decision table. A second source-map resolver, a second stack parser
|
|
19
|
+
* or a second URL-rewriting rule here would each be a copy that holds in
|
|
20
|
+
* one place — this repo has measured that drift and says so in
|
|
21
|
+
* `graph-correlator/src/symbol.ts` and `fixture-apps/roots.ts` alike.
|
|
22
|
+
*
|
|
23
|
+
* ## `resolveSourceRoot` is what makes the React 19 path work at all
|
|
24
|
+
*
|
|
25
|
+
* A React 19 owner stack names the bundle by its **browser URL**
|
|
26
|
+
* (`http://127.0.0.1:41369/dev.js:21714:62`). `createNodeSourceLocation-
|
|
27
|
+
* Resolver` resolves source maps from **disk**. `resolveSourceRoot` is the
|
|
28
|
+
* existing bridge between those two coordinate systems
|
|
29
|
+
* (`CollectorContext.resolveSourceRoot`, RT-023/RT-029), and without one
|
|
30
|
+
* the React 19 path degrades honestly: the stack still parses, the frame
|
|
31
|
+
* still names a position, and the answer comes back with
|
|
32
|
+
* `authoredSource: false` and a `degraded` capability rather than a
|
|
33
|
+
* fabricated authored file. React 18 needs none of this — its location is
|
|
34
|
+
* already authored, on the fiber.
|
|
35
|
+
*/
|
|
36
|
+
import type { SourceRootResolver } from "@descryy/runtime-contracts";
|
|
37
|
+
import type { Page } from "playwright-core";
|
|
38
|
+
import type { ElementIdentity } from "./element-identity.ts";
|
|
39
|
+
export interface IdentityGrounderOptions {
|
|
40
|
+
/**
|
|
41
|
+
* Joins a browser origin to the on-disk directory it is served from, so a
|
|
42
|
+
* React 19 owner stack's compiled frames can be mapped back to authored
|
|
43
|
+
* source. Absent is a supported configuration, not a misconfiguration —
|
|
44
|
+
* see this module's header.
|
|
45
|
+
*/
|
|
46
|
+
readonly resolveSourceRoot?: SourceRootResolver;
|
|
47
|
+
}
|
|
48
|
+
export interface IdentityGrounder {
|
|
49
|
+
/**
|
|
50
|
+
* Installs the page-side reader into every document this page loads from
|
|
51
|
+
* this point forward. **Call before navigating** — `page.addInitScript`
|
|
52
|
+
* does not reach a document that is already loaded, and a page navigated
|
|
53
|
+
* first reports `probe-not-installed` by name.
|
|
54
|
+
*/
|
|
55
|
+
install(page: Page): Promise<void>;
|
|
56
|
+
/** Resolves one on-screen element to the component that produced it, and to that component's file and line where those can be established. Never throws for a routine unavailability; refuses by name instead. */
|
|
57
|
+
ground(page: Page, selector: string): Promise<ElementIdentity>;
|
|
58
|
+
}
|
|
59
|
+
export declare function createIdentityGrounder(options?: IdentityGrounderOptions): IdentityGrounder;
|
|
60
|
+
//# sourceMappingURL=identity-grounder.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"identity-grounder.d.ts","sourceRoot":"","sources":["../src/identity-grounder.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAc,MAAM,4BAA4B,CAAC;AAGjF,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAE5C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAI7D,MAAM,WAAW,uBAAuB;IACtC;;;;;OAKG;IACH,QAAQ,CAAC,iBAAiB,CAAC,EAAE,kBAAkB,CAAC;CACjD;AAED,MAAM,WAAW,gBAAgB;IAC/B;;;;;OAKG;IACH,OAAO,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACnC,kNAAkN;IAClN,MAAM,CAAC,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;CAChE;AAED,wBAAgB,sBAAsB,CAAC,OAAO,GAAE,uBAA4B,GAAG,gBAAgB,CAyB9F"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The composed, page-driving surface — install once, then ask about a
|
|
3
|
+
* selector.
|
|
4
|
+
*
|
|
5
|
+
* Everything hard here is a composition of parts this repo already owns,
|
|
6
|
+
* deliberately:
|
|
7
|
+
*
|
|
8
|
+
* | step | owner |
|
|
9
|
+
* | --- | --- |
|
|
10
|
+
* | inject into the page | `page.addInitScript`, the seam `frontend-initiator-capture.ts` established |
|
|
11
|
+
* | read the fiber | `fiber-probe.ts` (this package) |
|
|
12
|
+
* | browser URL to on-disk path | `rewriteScriptUrls` (`@descryy/runtime-browser`) |
|
|
13
|
+
* | parse a V8 stack | `createV8StackTraceParser` (`@descryy/runtime-adapter-typescript`) |
|
|
14
|
+
* | source map, staleness, `reliability` | `createNodeSourceLocationResolver` (same) |
|
|
15
|
+
* | decide what may be claimed | `identity-grounding.ts` (this package) |
|
|
16
|
+
*
|
|
17
|
+
* The only genuinely new machinery in this package is the fiber read and
|
|
18
|
+
* the decision table. A second source-map resolver, a second stack parser
|
|
19
|
+
* or a second URL-rewriting rule here would each be a copy that holds in
|
|
20
|
+
* one place — this repo has measured that drift and says so in
|
|
21
|
+
* `graph-correlator/src/symbol.ts` and `fixture-apps/roots.ts` alike.
|
|
22
|
+
*
|
|
23
|
+
* ## `resolveSourceRoot` is what makes the React 19 path work at all
|
|
24
|
+
*
|
|
25
|
+
* A React 19 owner stack names the bundle by its **browser URL**
|
|
26
|
+
* (`http://127.0.0.1:41369/dev.js:21714:62`). `createNodeSourceLocation-
|
|
27
|
+
* Resolver` resolves source maps from **disk**. `resolveSourceRoot` is the
|
|
28
|
+
* existing bridge between those two coordinate systems
|
|
29
|
+
* (`CollectorContext.resolveSourceRoot`, RT-023/RT-029), and without one
|
|
30
|
+
* the React 19 path degrades honestly: the stack still parses, the frame
|
|
31
|
+
* still names a position, and the answer comes back with
|
|
32
|
+
* `authoredSource: false` and a `degraded` capability rather than a
|
|
33
|
+
* fabricated authored file. React 18 needs none of this — its location is
|
|
34
|
+
* already authored, on the fiber.
|
|
35
|
+
*/
|
|
36
|
+
import { rewriteScriptUrls } from "@descryy/runtime-browser";
|
|
37
|
+
import { createNodeSourceLocationResolver, createV8StackTraceParser } from "@descryy/runtime-adapter-typescript";
|
|
38
|
+
import { createIdentityGroundingProbe } from "./fiber-probe.js";
|
|
39
|
+
import { groundFromProbe } from "./identity-grounding.js";
|
|
40
|
+
export function createIdentityGrounder(options = {}) {
|
|
41
|
+
const probe = createIdentityGroundingProbe();
|
|
42
|
+
const parser = createV8StackTraceParser(createNodeSourceLocationResolver());
|
|
43
|
+
const resolveOwnerStack = (rawStackText) => {
|
|
44
|
+
// Rewritten before parsing, not after -- `script-url-mapping.ts`'s own
|
|
45
|
+
// reasoning, reused rather than re-argued: the parser and its resolver
|
|
46
|
+
// already know how to turn `at f (/abs/path.js:12:5)` into a resolved
|
|
47
|
+
// location, and rewriting the text first lets all of that apply
|
|
48
|
+
// unchanged. An unmapped URL is left exactly as the browser reported
|
|
49
|
+
// it, which then resolves as a compiled location rather than a
|
|
50
|
+
// fabricated file.
|
|
51
|
+
const rewritten = rewriteScriptUrls(rawStackText, options.resolveSourceRoot);
|
|
52
|
+
return parser.parse(rewritten.text);
|
|
53
|
+
};
|
|
54
|
+
return {
|
|
55
|
+
install(page) {
|
|
56
|
+
return probe.install(page);
|
|
57
|
+
},
|
|
58
|
+
async ground(page, selector) {
|
|
59
|
+
const raw = await probe.probe(page, selector);
|
|
60
|
+
return groundFromProbe(raw, selector, resolveOwnerStack);
|
|
61
|
+
},
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=identity-grounder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"identity-grounder.js","sourceRoot":"","sources":["../src/identity-grounder.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AAGH,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,EAAE,gCAAgC,EAAE,wBAAwB,EAAE,MAAM,qCAAqC,CAAC;AAIjH,OAAO,EAAE,4BAA4B,EAAE,MAAM,kBAAkB,CAAC;AAChE,OAAO,EAAE,eAAe,EAA2B,MAAM,yBAAyB,CAAC;AAwBnF,MAAM,UAAU,sBAAsB,CAAC,UAAmC,EAAE;IAC1E,MAAM,KAAK,GAAG,4BAA4B,EAAE,CAAC;IAC7C,MAAM,MAAM,GAAG,wBAAwB,CAAC,gCAAgC,EAAE,CAAC,CAAC;IAE5E,MAAM,iBAAiB,GAAuB,CAAC,YAAoB,EAA8B,EAAE;QACjG,uEAAuE;QACvE,uEAAuE;QACvE,sEAAsE;QACtE,gEAAgE;QAChE,qEAAqE;QACrE,+DAA+D;QAC/D,mBAAmB;QACnB,MAAM,SAAS,GAAG,iBAAiB,CAAC,YAAY,EAAE,OAAO,CAAC,iBAAiB,CAAC,CAAC;QAC7E,OAAO,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;IACtC,CAAC,CAAC;IAEF,OAAO;QACL,OAAO,CAAC,IAAU;YAChB,OAAO,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAC7B,CAAC;QACD,KAAK,CAAC,MAAM,CAAC,IAAU,EAAE,QAAgB;YACvC,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,KAAK,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;YAC9C,OAAO,eAAe,CAAC,GAAG,EAAE,QAAQ,EAAE,iBAAiB,CAAC,CAAC;QAC3D,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The decision layer: raw fiber facts in, one `ElementIdentity` out.
|
|
3
|
+
*
|
|
4
|
+
* Pure with respect to the browser — it never touches a `Page`. Everything
|
|
5
|
+
* it needs from the page arrives as a `RawFiberProbe`, and the one piece of
|
|
6
|
+
* machinery it cannot own (turning a React 19 owner stack into a resolved
|
|
7
|
+
* `StackTrace`, which needs source-map resolution and filesystem access) is
|
|
8
|
+
* injected as `OwnerStackResolver`. That split is what lets every refusal
|
|
9
|
+
* branch below be exercised as a plain unit test, with no Chromium and no
|
|
10
|
+
* fixture app, while the fixture apps prove the two mechanisms end to end.
|
|
11
|
+
*
|
|
12
|
+
* ## What this cannot do, stated once, in the place that decides it
|
|
13
|
+
*
|
|
14
|
+
* - **A production React build.** No `_debug*` field survives, and the
|
|
15
|
+
* component name on the fiber is minified. Refused by name
|
|
16
|
+
* (`react-debug-fields-absent`); see that value's own documentation.
|
|
17
|
+
* - **Anything that is not React.** No fiber key, no answer. There is no
|
|
18
|
+
* Vue/Svelte/Angular/Solid path here — not a gap in this module, a scope
|
|
19
|
+
* boundary, and the refusal says "not React" rather than "unknown".
|
|
20
|
+
* - **A React 19 bundle with no source map.** The owner stack still names a
|
|
21
|
+
* real position, in compiled output. Reported with
|
|
22
|
+
* `authoredSource: false` and a `degraded` capability, never dressed up
|
|
23
|
+
* as the file a developer wrote.
|
|
24
|
+
* - **An anonymous component.** Refused: there is no symbol for
|
|
25
|
+
* `resolveSymbolNode` to look up and no name for a reader to act on.
|
|
26
|
+
*
|
|
27
|
+
* ## Owner versus renderer
|
|
28
|
+
*
|
|
29
|
+
* `component` is read from `_debugOwner` — the component whose render
|
|
30
|
+
* *created* this element — because that is the component the source
|
|
31
|
+
* location belongs to. `renderedBy` is the nearest component in the fiber
|
|
32
|
+
* `return` chain, which is where the element ended up. They differ whenever
|
|
33
|
+
* an element is created in one component and passed to another as
|
|
34
|
+
* `children`; the fixture app renders that case deliberately. Both are
|
|
35
|
+
* reported and neither is reconciled into the other.
|
|
36
|
+
*/
|
|
37
|
+
import { type StackTrace } from "@descryy/runtime-contracts";
|
|
38
|
+
import { type ElementIdentity } from "./element-identity.ts";
|
|
39
|
+
import type { RawFiberProbe } from "./fiber-probe.ts";
|
|
40
|
+
/**
|
|
41
|
+
* Turns React 19's raw `_debugStack` text into a resolved `StackTrace`, or
|
|
42
|
+
* `null` when the text is not a V8 stack at all.
|
|
43
|
+
*
|
|
44
|
+
* Injected rather than constructed here because the real implementation is
|
|
45
|
+
* a composition of three things this repo already owns and this package
|
|
46
|
+
* must not re-own: `@descryy/runtime-browser`'s `rewriteScriptUrls` (browser
|
|
47
|
+
* URL to on-disk path), and `@descryy/runtime-adapter-typescript`'s
|
|
48
|
+
* `createV8StackTraceParser` plus `createNodeSourceLocationResolver`
|
|
49
|
+
* (parsing, source-map resolution and the `reliability` classification —
|
|
50
|
+
* including staleness detection). `identity-grounder.ts` wires them.
|
|
51
|
+
*/
|
|
52
|
+
export type OwnerStackResolver = (rawStackText: string) => Promise<StackTrace | null>;
|
|
53
|
+
export declare function groundFromProbe(probe: RawFiberProbe, selector: string, resolveOwnerStack: OwnerStackResolver | null): Promise<ElementIdentity>;
|
|
54
|
+
//# sourceMappingURL=identity-grounding.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"identity-grounding.d.ts","sourceRoot":"","sources":["../src/identity-grounding.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AAEH,OAAO,EAA6C,KAAK,UAAU,EAAE,MAAM,4BAA4B,CAAC;AAExG,OAAO,EAEL,KAAK,eAAe,EAGrB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,KAAK,EAA0B,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAG9E;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,kBAAkB,GAAG,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC;AAOtF,wBAAsB,eAAe,CACnC,KAAK,EAAE,aAAa,EACpB,QAAQ,EAAE,MAAM,EAChB,iBAAiB,EAAE,kBAAkB,GAAG,IAAI,GAC3C,OAAO,CAAC,eAAe,CAAC,CA4N1B"}
|
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The decision layer: raw fiber facts in, one `ElementIdentity` out.
|
|
3
|
+
*
|
|
4
|
+
* Pure with respect to the browser — it never touches a `Page`. Everything
|
|
5
|
+
* it needs from the page arrives as a `RawFiberProbe`, and the one piece of
|
|
6
|
+
* machinery it cannot own (turning a React 19 owner stack into a resolved
|
|
7
|
+
* `StackTrace`, which needs source-map resolution and filesystem access) is
|
|
8
|
+
* injected as `OwnerStackResolver`. That split is what lets every refusal
|
|
9
|
+
* branch below be exercised as a plain unit test, with no Chromium and no
|
|
10
|
+
* fixture app, while the fixture apps prove the two mechanisms end to end.
|
|
11
|
+
*
|
|
12
|
+
* ## What this cannot do, stated once, in the place that decides it
|
|
13
|
+
*
|
|
14
|
+
* - **A production React build.** No `_debug*` field survives, and the
|
|
15
|
+
* component name on the fiber is minified. Refused by name
|
|
16
|
+
* (`react-debug-fields-absent`); see that value's own documentation.
|
|
17
|
+
* - **Anything that is not React.** No fiber key, no answer. There is no
|
|
18
|
+
* Vue/Svelte/Angular/Solid path here — not a gap in this module, a scope
|
|
19
|
+
* boundary, and the refusal says "not React" rather than "unknown".
|
|
20
|
+
* - **A React 19 bundle with no source map.** The owner stack still names a
|
|
21
|
+
* real position, in compiled output. Reported with
|
|
22
|
+
* `authoredSource: false` and a `degraded` capability, never dressed up
|
|
23
|
+
* as the file a developer wrote.
|
|
24
|
+
* - **An anonymous component.** Refused: there is no symbol for
|
|
25
|
+
* `resolveSymbolNode` to look up and no name for a reader to act on.
|
|
26
|
+
*
|
|
27
|
+
* ## Owner versus renderer
|
|
28
|
+
*
|
|
29
|
+
* `component` is read from `_debugOwner` — the component whose render
|
|
30
|
+
* *created* this element — because that is the component the source
|
|
31
|
+
* location belongs to. `renderedBy` is the nearest component in the fiber
|
|
32
|
+
* `return` chain, which is where the element ended up. They differ whenever
|
|
33
|
+
* an element is created in one component and passed to another as
|
|
34
|
+
* `children`; the fixture app renders that case deliberately. Both are
|
|
35
|
+
* reported and neither is reconciled into the other.
|
|
36
|
+
*/
|
|
37
|
+
import { locationNamesNothing } from "@descryy/runtime-contracts";
|
|
38
|
+
import { capabilityFor, } from "./element-identity.js";
|
|
39
|
+
import { selectOwnerFrame } from "./owner-stack.js";
|
|
40
|
+
function resolvedComponent(raw) {
|
|
41
|
+
if (raw === null || raw.name === null || raw.nameSource === null)
|
|
42
|
+
return null;
|
|
43
|
+
return { name: raw.name, nameSource: raw.nameSource, kind: raw.kind };
|
|
44
|
+
}
|
|
45
|
+
export async function groundFromProbe(probe, selector, resolveOwnerStack) {
|
|
46
|
+
if (probe.status === "probe-not-installed") {
|
|
47
|
+
return {
|
|
48
|
+
outcome: "refused",
|
|
49
|
+
selector,
|
|
50
|
+
fiberDistance: 0,
|
|
51
|
+
refusal: "probe-not-installed",
|
|
52
|
+
observedTypeName: null,
|
|
53
|
+
reason: "the identity-grounding reader is not present in this document. `page.addInitScript` only affects " +
|
|
54
|
+
"documents loaded after it is registered, so `install()` must be called before navigating — exactly as " +
|
|
55
|
+
"every collector in @descryy/runtime-browser already requires. Reported as its own refusal rather than " +
|
|
56
|
+
"as \"not React\", which is what a caller would otherwise conclude about a perfectly ordinary React page.",
|
|
57
|
+
capability: capabilityFor("unavailable", "the page-side reader was never installed in this document; nothing was inspected."),
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
if (probe.status === "element-not-found") {
|
|
61
|
+
return {
|
|
62
|
+
outcome: "refused",
|
|
63
|
+
selector,
|
|
64
|
+
fiberDistance: 0,
|
|
65
|
+
refusal: "element-not-found",
|
|
66
|
+
observedTypeName: null,
|
|
67
|
+
reason: `no element matched "${selector}" in the page's current document.`,
|
|
68
|
+
capability: capabilityFor("unavailable", "the selector matched no element; there was nothing to ground."),
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
if (probe.status === "no-fiber") {
|
|
72
|
+
return {
|
|
73
|
+
outcome: "refused",
|
|
74
|
+
selector,
|
|
75
|
+
fiberDistance: 0,
|
|
76
|
+
refusal: "not-react",
|
|
77
|
+
observedTypeName: null,
|
|
78
|
+
reason: `neither the element matched by "${selector}" nor any of its ancestors carries a React fiber key ` +
|
|
79
|
+
`(${probe.ownKeys.length === 0 ? "the element has no own enumerable keys at all" : `own keys: ${probe.ownKeys.join(", ")}`}). ` +
|
|
80
|
+
"This page's DOM was not produced by React, or not by a React that tags host nodes. Identity grounding is " +
|
|
81
|
+
"React-only; there is no Vue, Svelte, Angular or Solid equivalent in this package, which is a scope " +
|
|
82
|
+
"boundary and not a temporary gap.",
|
|
83
|
+
capability: capabilityFor("unavailable", "no React fiber on the element or any ancestor — not a React tree."),
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
const { fiberDistance } = probe;
|
|
87
|
+
if (probe.debugFields.length === 0) {
|
|
88
|
+
// The queried node is usually a *host* fiber whose `type` is the tag
|
|
89
|
+
// name string ("button"), so the minified identifier a reader wants to
|
|
90
|
+
// see lives on the nearest component above it, not here. Both are
|
|
91
|
+
// consulted, in that order, and the result is still not a component
|
|
92
|
+
// name -- see `ElementIdentityRefused.observedTypeName`.
|
|
93
|
+
const observedTypeName = probe.observedTypeName ?? probe.returnChainComponent?.name ?? probe.owner?.name ?? null;
|
|
94
|
+
return {
|
|
95
|
+
outcome: "refused",
|
|
96
|
+
selector,
|
|
97
|
+
fiberDistance,
|
|
98
|
+
refusal: "react-debug-fields-absent",
|
|
99
|
+
observedTypeName,
|
|
100
|
+
reason: "a React fiber was found and it carries no `_debug*` field of any kind. React strips `_debugSource`, " +
|
|
101
|
+
"`_debugOwner` and `_debugStack` from fibers outside a development build, so this is a production React " +
|
|
102
|
+
"build (overwhelmingly the common reading) or a React version that no longer exposes them in development " +
|
|
103
|
+
"either. Two things are lost, not one: there is no source location to recover, AND a production bundle is " +
|
|
104
|
+
"minified, so the fiber's own `type.name` " +
|
|
105
|
+
(observedTypeName === null ? "(absent here)" : `("${observedTypeName}")`) +
|
|
106
|
+
" is whatever the minifier left behind rather than the authored component name. Reporting that name as " +
|
|
107
|
+
"the component would be a confident wrong answer; refused instead.",
|
|
108
|
+
capability: capabilityFor("unavailable", "React development-build debug fields are absent (production build): no source location exists to " +
|
|
109
|
+
"recover, and the component name on the fiber is minified rather than authored."),
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
const owner = resolvedComponent(probe.owner);
|
|
113
|
+
const returnChain = resolvedComponent(probe.returnChainComponent);
|
|
114
|
+
const component = owner ?? returnChain;
|
|
115
|
+
const componentSource = owner !== null ? "debug-owner" : "return-chain";
|
|
116
|
+
if (component === null) {
|
|
117
|
+
const sawSomething = probe.owner !== null || probe.returnChainComponent !== null;
|
|
118
|
+
return {
|
|
119
|
+
outcome: "refused",
|
|
120
|
+
selector,
|
|
121
|
+
fiberDistance,
|
|
122
|
+
refusal: sawSomething ? "anonymous-component" : "no-component-fiber",
|
|
123
|
+
observedTypeName: probe.observedTypeName,
|
|
124
|
+
reason: sawSomething
|
|
125
|
+
? "a component fiber was found and it has no resolvable name — an anonymous function or arrow with no " +
|
|
126
|
+
"`displayName`. Refused rather than reported as a nameless component: there is no symbol for " +
|
|
127
|
+
"`resolveSymbolNode` to look up and no name a reader could act on."
|
|
128
|
+
: "the fiber has no `_debugOwner` and no nameable component anywhere in its `return` chain, so no " +
|
|
129
|
+
"component produced this element in a way this can name — an element rendered directly by the root, or " +
|
|
130
|
+
"one whose whole ancestry is host elements, fragments and context providers.",
|
|
131
|
+
capability: capabilityFor("unavailable", sawSomething ? "the owning component is anonymous." : "no component fiber above this element."),
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
const renderedBy = returnChain;
|
|
135
|
+
// ---- React 18 and earlier: the authored location is on the fiber. ----
|
|
136
|
+
const debugSource = probe.debugSource;
|
|
137
|
+
if (debugSource !== null && debugSource.fileName !== null) {
|
|
138
|
+
const sourceLocation = {
|
|
139
|
+
file: debugSource.fileName,
|
|
140
|
+
line: debugSource.lineNumber,
|
|
141
|
+
column: debugSource.columnNumber,
|
|
142
|
+
functionName: component.name,
|
|
143
|
+
// The application's own recorded creation site, not a translation
|
|
144
|
+
// through a side artifact -- the same class `node-source-location-
|
|
145
|
+
// resolver.ts` gives a frame with no `sourceMappingURL`: nothing was
|
|
146
|
+
// lost, this IS the accurate answer.
|
|
147
|
+
reliability: "self-contained",
|
|
148
|
+
resolvedVia: null,
|
|
149
|
+
};
|
|
150
|
+
return {
|
|
151
|
+
outcome: "grounded",
|
|
152
|
+
selector,
|
|
153
|
+
fiberDistance,
|
|
154
|
+
component,
|
|
155
|
+
componentSource,
|
|
156
|
+
renderedBy,
|
|
157
|
+
sourceLocation,
|
|
158
|
+
authoredSource: true,
|
|
159
|
+
mechanism: "react-debug-source",
|
|
160
|
+
capability: debugSource.lineNumber === null
|
|
161
|
+
? capabilityFor("degraded", "`_debugSource` named the authored file but carried no line number, so the answer is file-level " +
|
|
162
|
+
"rather than line-level.")
|
|
163
|
+
: capabilityFor("available"),
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
// ---- React 19: an owner stack in compiled coordinates. ----
|
|
167
|
+
const stackText = probe.debugStackText;
|
|
168
|
+
if (stackText !== null) {
|
|
169
|
+
if (resolveOwnerStack === null) {
|
|
170
|
+
return componentOnly(selector, fiberDistance, component, componentSource, renderedBy, "this fiber carries a React 19 owner stack (`_debugStack`) and no owner-stack resolver is configured, so " +
|
|
171
|
+
"its compiled frames cannot be mapped back to authored source. The component is named; its file and " +
|
|
172
|
+
"line are not.");
|
|
173
|
+
}
|
|
174
|
+
const stack = await resolveOwnerStack(stackText);
|
|
175
|
+
if (stack === null) {
|
|
176
|
+
return componentOnly(selector, fiberDistance, component, componentSource, renderedBy, "this fiber carries a React 19 owner stack, and the stack parser did not recognise its text as a V8 " +
|
|
177
|
+
"stack at all. Refused rather than parsed best-effort, per the parser's own contract.");
|
|
178
|
+
}
|
|
179
|
+
const selection = selectOwnerFrame(stack);
|
|
180
|
+
if (!selection.ok) {
|
|
181
|
+
return componentOnly(selector, fiberDistance, component, componentSource, renderedBy, selection.reason);
|
|
182
|
+
}
|
|
183
|
+
const frameLocation = stack.frames[selection.index]?.location ?? null;
|
|
184
|
+
if (frameLocation === null || locationNamesNothing(frameLocation)) {
|
|
185
|
+
return componentOnly(selector, fiberDistance, component, componentSource, renderedBy, "the owner stack's application call site resolved to a location that names no file, line or function — " +
|
|
186
|
+
"so there is a frame, and nothing in it to report as a source location.");
|
|
187
|
+
}
|
|
188
|
+
const reliability = frameLocation.reliability;
|
|
189
|
+
const authoredSource = reliability === "side-artifact-resolved" || reliability === "side-artifact-stale";
|
|
190
|
+
return {
|
|
191
|
+
outcome: "grounded",
|
|
192
|
+
selector,
|
|
193
|
+
fiberDistance,
|
|
194
|
+
component,
|
|
195
|
+
componentSource,
|
|
196
|
+
renderedBy,
|
|
197
|
+
sourceLocation: frameLocation,
|
|
198
|
+
authoredSource,
|
|
199
|
+
mechanism: "react-owner-stack",
|
|
200
|
+
capability: ownerStackCapability(frameLocation),
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
return componentOnly(selector, fiberDistance, component, componentSource, renderedBy, "this fiber carries React development-build debug fields " +
|
|
204
|
+
`(${probe.debugFields.join(", ")}) but neither \`_debugSource\` nor \`_debugStack\` — the application was ` +
|
|
205
|
+
"built without the JSX transform's source annotation (React 18 and earlier), so React itself never recorded " +
|
|
206
|
+
"where this element was written. The component is named; its file and line are not.");
|
|
207
|
+
}
|
|
208
|
+
function ownerStackCapability(location) {
|
|
209
|
+
if (location.reliability === "side-artifact-stale") {
|
|
210
|
+
return capabilityFor("degraded", `the owner stack mapped through "${location.resolvedVia ?? "a source map"}", and that map's embedded ` +
|
|
211
|
+
"`sourcesContent` does not match the file now on disk — the file and line are the map's, and the map is " +
|
|
212
|
+
"older than the source.");
|
|
213
|
+
}
|
|
214
|
+
if (location.reliability !== "side-artifact-resolved") {
|
|
215
|
+
return capabilityFor("degraded", "the owner stack named a real position in the compiled bundle and nothing mapped it back to authored " +
|
|
216
|
+
`source (reliability "${location.reliability}"). The location is the bundle's, not the file a developer ` +
|
|
217
|
+
"wrote. React 19 removed `_debugSource`, so a bundle shipped without a source map beside it has no " +
|
|
218
|
+
"authored line to recover from the running page at all.");
|
|
219
|
+
}
|
|
220
|
+
if (location.line === null) {
|
|
221
|
+
return capabilityFor("degraded", "the owner stack mapped to an authored file with no line, so the answer is file-level rather than " +
|
|
222
|
+
"line-level.");
|
|
223
|
+
}
|
|
224
|
+
return capabilityFor("available");
|
|
225
|
+
}
|
|
226
|
+
function componentOnly(selector, fiberDistance, component, componentSource, renderedBy, reason) {
|
|
227
|
+
return {
|
|
228
|
+
outcome: "component-only",
|
|
229
|
+
selector,
|
|
230
|
+
fiberDistance,
|
|
231
|
+
component,
|
|
232
|
+
componentSource,
|
|
233
|
+
renderedBy,
|
|
234
|
+
reason,
|
|
235
|
+
capability: capabilityFor("degraded", reason),
|
|
236
|
+
};
|
|
237
|
+
}
|
|
238
|
+
//# sourceMappingURL=identity-grounding.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"identity-grounding.js","sourceRoot":"","sources":["../src/identity-grounding.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Identity grounding: an on-screen DOM element to the React component that
|
|
3
|
+
* produced it, and to that component's authored file and line.
|
|
4
|
+
*
|
|
5
|
+
* Start at `createIdentityGrounder` (`identity-grounder.ts`). Read
|
|
6
|
+
* `element-identity.ts` for what an answer is allowed to say, and
|
|
7
|
+
* `owner-stack.ts` for the measured difference between React 18's and React
|
|
8
|
+
* 19's fiber internals — they are not two implementations of one mechanism.
|
|
9
|
+
*/
|
|
10
|
+
export type { IdentityRefusal, GroundingMechanism, ComponentKind, ComponentNameSource, ComponentSource, ResolvedComponent, ElementIdentity, ElementIdentityGrounded, ElementIdentityComponentOnly, ElementIdentityRefused, } from "./element-identity.ts";
|
|
11
|
+
export { IDENTITY_REFUSALS, GROUNDING_MECHANISMS, COMPONENT_KINDS, COMPONENT_NAME_SOURCES, COMPONENT_SOURCES, capabilityFor, } from "./element-identity.ts";
|
|
12
|
+
export type { RawFiberProbe, RawComponentDescriptor, RawDebugSource, FiberKeyPrefix, IdentityGroundingProbe } from "./fiber-probe.ts";
|
|
13
|
+
export { createIdentityGroundingProbe, IDENTITY_GROUNDING_BINDING, FIBER_KEY_PREFIXES } from "./fiber-probe.ts";
|
|
14
|
+
export type { OwnerFrameSelection } from "./owner-stack.ts";
|
|
15
|
+
export { selectOwnerFrame, REACT_ELEMENT_CREATION_FRAMES } from "./owner-stack.ts";
|
|
16
|
+
export type { OwnerStackResolver } from "./identity-grounding.ts";
|
|
17
|
+
export { groundFromProbe } from "./identity-grounding.ts";
|
|
18
|
+
export type { IdentityGrounder, IdentityGrounderOptions } from "./identity-grounder.ts";
|
|
19
|
+
export { createIdentityGrounder } from "./identity-grounder.ts";
|
|
20
|
+
export type { GraphSymbolLocation } from "./graph-join.ts";
|
|
21
|
+
export { symbolLocationForGraph } from "./graph-join.ts";
|
|
22
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,YAAY,EACV,eAAe,EACf,kBAAkB,EAClB,aAAa,EACb,mBAAmB,EACnB,eAAe,EACf,iBAAiB,EACjB,eAAe,EACf,uBAAuB,EACvB,4BAA4B,EAC5B,sBAAsB,GACvB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,iBAAiB,EACjB,oBAAoB,EACpB,eAAe,EACf,sBAAsB,EACtB,iBAAiB,EACjB,aAAa,GACd,MAAM,uBAAuB,CAAC;AAE/B,YAAY,EAAE,aAAa,EAAE,sBAAsB,EAAE,cAAc,EAAE,cAAc,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAC;AACtI,OAAO,EAAE,4BAA4B,EAAE,0BAA0B,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAEhH,YAAY,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAC5D,OAAO,EAAE,gBAAgB,EAAE,6BAA6B,EAAE,MAAM,kBAAkB,CAAC;AAEnF,YAAY,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAClE,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAE1D,YAAY,EAAE,gBAAgB,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AACxF,OAAO,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AAEhE,YAAY,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAC3D,OAAO,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Identity grounding: an on-screen DOM element to the React component that
|
|
3
|
+
* produced it, and to that component's authored file and line.
|
|
4
|
+
*
|
|
5
|
+
* Start at `createIdentityGrounder` (`identity-grounder.ts`). Read
|
|
6
|
+
* `element-identity.ts` for what an answer is allowed to say, and
|
|
7
|
+
* `owner-stack.ts` for the measured difference between React 18's and React
|
|
8
|
+
* 19's fiber internals — they are not two implementations of one mechanism.
|
|
9
|
+
*/
|
|
10
|
+
export { IDENTITY_REFUSALS, GROUNDING_MECHANISMS, COMPONENT_KINDS, COMPONENT_NAME_SOURCES, COMPONENT_SOURCES, capabilityFor, } from "./element-identity.js";
|
|
11
|
+
export { createIdentityGroundingProbe, IDENTITY_GROUNDING_BINDING, FIBER_KEY_PREFIXES } from "./fiber-probe.js";
|
|
12
|
+
export { selectOwnerFrame, REACT_ELEMENT_CREATION_FRAMES } from "./owner-stack.js";
|
|
13
|
+
export { groundFromProbe } from "./identity-grounding.js";
|
|
14
|
+
export { createIdentityGrounder } from "./identity-grounder.js";
|
|
15
|
+
export { symbolLocationForGraph } from "./graph-join.js";
|
|
16
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAcH,OAAO,EACL,iBAAiB,EACjB,oBAAoB,EACpB,eAAe,EACf,sBAAsB,EACtB,iBAAiB,EACjB,aAAa,GACd,MAAM,uBAAuB,CAAC;AAG/B,OAAO,EAAE,4BAA4B,EAAE,0BAA0B,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAGhH,OAAO,EAAE,gBAAgB,EAAE,6BAA6B,EAAE,MAAM,kBAAkB,CAAC;AAGnF,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAG1D,OAAO,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AAGhE,OAAO,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAC"}
|