legend-doctor 0.1.3 → 0.3.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/EXAMPLES.md +31 -0
- package/README.md +12 -97
- package/REPORT.md +205 -0
- package/dist/src/analysis/analyze-source.js +21 -1
- package/dist/src/analysis/analyze-source.js.map +1 -1
- package/dist/src/analysis/assumptions/async-command-hypothesis.d.ts +4 -0
- package/dist/src/analysis/assumptions/async-command-hypothesis.d.ts.map +1 -0
- package/dist/src/analysis/assumptions/async-command-hypothesis.js +101 -0
- package/dist/src/analysis/assumptions/async-command-hypothesis.js.map +1 -0
- package/dist/src/analysis/assumptions/group-assumptions.d.ts.map +1 -1
- package/dist/src/analysis/assumptions/group-assumptions.js +16 -9
- package/dist/src/analysis/assumptions/group-assumptions.js.map +1 -1
- package/dist/src/analysis/assumptions/hypotheses.d.ts.map +1 -1
- package/dist/src/analysis/assumptions/hypotheses.js +15 -4
- package/dist/src/analysis/assumptions/hypotheses.js.map +1 -1
- package/dist/src/analysis/assumptions/ranked-questions.d.ts.map +1 -1
- package/dist/src/analysis/assumptions/ranked-questions.js +5 -1
- package/dist/src/analysis/assumptions/ranked-questions.js.map +1 -1
- package/dist/src/analysis/assumptions/state-assumptions.d.ts.map +1 -1
- package/dist/src/analysis/assumptions/state-assumptions.js +5 -14
- package/dist/src/analysis/assumptions/state-assumptions.js.map +1 -1
- package/dist/src/analysis/clusters/cowritten-clusters.js +1 -1
- package/dist/src/analysis/clusters/cowritten-clusters.js.map +1 -1
- package/dist/src/analysis/finding-format.d.ts +0 -2
- package/dist/src/analysis/finding-format.d.ts.map +1 -1
- package/dist/src/analysis/finding-format.js +1 -8
- package/dist/src/analysis/finding-format.js.map +1 -1
- package/dist/src/analysis/findings.d.ts.map +1 -1
- package/dist/src/analysis/findings.js +9 -4
- package/dist/src/analysis/findings.js.map +1 -1
- package/dist/src/analysis/review-guidance.d.ts +4 -0
- package/dist/src/analysis/review-guidance.d.ts.map +1 -0
- package/dist/src/analysis/review-guidance.js +69 -0
- package/dist/src/analysis/review-guidance.js.map +1 -0
- package/dist/src/analysis/transition-evidence.d.ts +6 -0
- package/dist/src/analysis/transition-evidence.d.ts.map +1 -0
- package/dist/src/analysis/transition-evidence.js +144 -0
- package/dist/src/analysis/transition-evidence.js.map +1 -0
- package/dist/src/analysis/verdicts/classify-state.d.ts.map +1 -1
- package/dist/src/analysis/verdicts/classify-state.js +10 -0
- package/dist/src/analysis/verdicts/classify-state.js.map +1 -1
- package/dist/src/analysis/verdicts/intrinsic-verdicts.js +1 -1
- package/dist/src/analysis/verdicts/intrinsic-verdicts.js.map +1 -1
- package/dist/src/cli/help.d.ts +1 -1
- package/dist/src/cli/help.d.ts.map +1 -1
- package/dist/src/cli/help.js +12 -4
- package/dist/src/cli/help.js.map +1 -1
- package/dist/src/cli.js +4 -0
- package/dist/src/cli.js.map +1 -1
- package/dist/src/core/imports.d.ts.map +1 -1
- package/dist/src/core/imports.js +29 -1
- package/dist/src/core/imports.js.map +1 -1
- package/dist/src/core/state-transitions.d.ts +28 -0
- package/dist/src/core/state-transitions.d.ts.map +1 -0
- package/dist/src/core/state-transitions.js +2 -0
- package/dist/src/core/state-transitions.js.map +1 -0
- package/dist/src/core/subscriptions.d.ts +93 -0
- package/dist/src/core/subscriptions.d.ts.map +1 -0
- package/dist/src/core/subscriptions.js +2 -0
- package/dist/src/core/subscriptions.js.map +1 -0
- package/dist/src/core/types.d.ts +27 -6
- package/dist/src/core/types.d.ts.map +1 -1
- package/dist/src/core/types.js +1 -1
- package/dist/src/core/types.js.map +1 -1
- package/dist/src/index.d.ts +3 -4
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +0 -1
- package/dist/src/index.js.map +1 -1
- package/dist/src/practices/analyze-legend-practices.d.ts +4 -1
- package/dist/src/practices/analyze-legend-practices.d.ts.map +1 -1
- package/dist/src/practices/analyze-legend-practices.js +3 -1
- package/dist/src/practices/analyze-legend-practices.js.map +1 -1
- package/dist/src/practices/model.d.ts +3 -0
- package/dist/src/practices/model.d.ts.map +1 -1
- package/dist/src/practices/practice-rules.d.ts.map +1 -1
- package/dist/src/practices/practice-rules.js +3 -1
- package/dist/src/practices/practice-rules.js.map +1 -1
- package/dist/src/project/analysis-coverage.d.ts +4 -3
- package/dist/src/project/analysis-coverage.d.ts.map +1 -1
- package/dist/src/project/analysis-coverage.js +5 -5
- package/dist/src/project/analysis-coverage.js.map +1 -1
- package/dist/src/project/analyze-path/analysis-context.d.ts +2 -9
- package/dist/src/project/analyze-path/analysis-context.d.ts.map +1 -1
- package/dist/src/project/analyze-path/analysis-context.js +6 -10
- package/dist/src/project/analyze-path/analysis-context.js.map +1 -1
- package/dist/src/project/analyze-path/analysis-pass.d.ts +2 -0
- package/dist/src/project/analyze-path/analysis-pass.d.ts.map +1 -1
- package/dist/src/project/analyze-path/analysis-pass.js +13 -4
- package/dist/src/project/analyze-path/analysis-pass.js.map +1 -1
- package/dist/src/project/analyze-path/analyze-path.d.ts +3 -3
- package/dist/src/project/analyze-path/analyze-path.d.ts.map +1 -1
- package/dist/src/project/analyze-path/analyze-path.js +6 -29
- package/dist/src/project/analyze-path/analyze-path.js.map +1 -1
- package/dist/src/project/analyze-path/coverage-stages.d.ts +0 -3
- package/dist/src/project/analyze-path/coverage-stages.d.ts.map +1 -1
- package/dist/src/project/analyze-path/coverage-stages.js +2 -16
- package/dist/src/project/analyze-path/coverage-stages.js.map +1 -1
- package/dist/src/project/source-components/module-resolution.d.ts +12 -1
- package/dist/src/project/source-components/module-resolution.d.ts.map +1 -1
- package/dist/src/project/source-components/module-resolution.js +18 -5
- package/dist/src/project/source-components/module-resolution.js.map +1 -1
- package/dist/src/project/source-components/observable-primitive-paths.d.ts +3 -0
- package/dist/src/project/source-components/observable-primitive-paths.d.ts.map +1 -0
- package/dist/src/project/source-components/observable-primitive-paths.js +58 -0
- package/dist/src/project/source-components/observable-primitive-paths.js.map +1 -0
- package/dist/src/project/source-components/source-components.d.ts +3 -1
- package/dist/src/project/source-components/source-components.d.ts.map +1 -1
- package/dist/src/project/source-components/source-components.js +10 -4
- package/dist/src/project/source-components/source-components.js.map +1 -1
- package/dist/src/project/state-flow/control-arms.js +11 -1
- package/dist/src/project/state-flow/control-arms.js.map +1 -1
- package/dist/src/project/state-flow/expression-lowering.d.ts.map +1 -1
- package/dist/src/project/state-flow/expression-lowering.js +29 -2
- package/dist/src/project/state-flow/expression-lowering.js.map +1 -1
- package/dist/src/project/state-flow/model.d.ts +1 -1
- package/dist/src/project/state-flow/model.d.ts.map +1 -1
- package/dist/src/project/state-flow/path-budget.d.ts +4 -0
- package/dist/src/project/state-flow/path-budget.d.ts.map +1 -0
- package/dist/src/project/state-flow/path-budget.js +8 -0
- package/dist/src/project/state-flow/path-budget.js.map +1 -0
- package/dist/src/project/state-flow/state-flow.js +8 -1
- package/dist/src/project/state-flow/state-flow.js.map +1 -1
- package/dist/src/project/state-flow/statement-lowering.d.ts.map +1 -1
- package/dist/src/project/state-flow/statement-lowering.js +86 -7
- package/dist/src/project/state-flow/statement-lowering.js.map +1 -1
- package/dist/src/project/subscription-measurements.d.ts +4 -0
- package/dist/src/project/subscription-measurements.d.ts.map +1 -0
- package/dist/src/project/subscription-measurements.js +67 -0
- package/dist/src/project/subscription-measurements.js.map +1 -0
- package/dist/src/project/workspace/packages.d.ts +9 -0
- package/dist/src/project/workspace/packages.d.ts.map +1 -0
- package/dist/src/project/workspace/packages.js +49 -0
- package/dist/src/project/workspace/packages.js.map +1 -0
- package/dist/src/project/workspace/resolution-host.d.ts +5 -0
- package/dist/src/project/workspace/resolution-host.d.ts.map +1 -0
- package/dist/src/project/workspace/resolution-host.js +25 -0
- package/dist/src/project/workspace/resolution-host.js.map +1 -0
- package/dist/src/project/workspace/source-closure.d.ts +3 -0
- package/dist/src/project/workspace/source-closure.d.ts.map +1 -0
- package/dist/src/project/workspace/source-closure.js +51 -0
- package/dist/src/project/workspace/source-closure.js.map +1 -0
- package/dist/src/report/subscription-measurements.d.ts +3 -0
- package/dist/src/report/subscription-measurements.d.ts.map +1 -0
- package/dist/src/report/subscription-measurements.js +59 -0
- package/dist/src/report/subscription-measurements.js.map +1 -0
- package/dist/src/report/subscription-plans.d.ts +5 -0
- package/dist/src/report/subscription-plans.d.ts.map +1 -0
- package/dist/src/report/subscription-plans.js +123 -0
- package/dist/src/report/subscription-plans.js.map +1 -0
- package/dist/src/rules/child-contract/base-ui-render-events.d.ts +8 -0
- package/dist/src/rules/child-contract/base-ui-render-events.d.ts.map +1 -0
- package/dist/src/rules/child-contract/base-ui-render-events.js +159 -0
- package/dist/src/rules/child-contract/base-ui-render-events.js.map +1 -0
- package/dist/src/rules/child-contract/expression-stages.d.ts.map +1 -1
- package/dist/src/rules/child-contract/expression-stages.js +2 -0
- package/dist/src/rules/child-contract/expression-stages.js.map +1 -1
- package/dist/src/rules/effects/derived-setters.d.ts.map +1 -1
- package/dist/src/rules/effects/derived-setters.js +39 -1
- package/dist/src/rules/effects/derived-setters.js.map +1 -1
- package/dist/src/rules/observable-reads/flow-expressions.d.ts +11 -0
- package/dist/src/rules/observable-reads/flow-expressions.d.ts.map +1 -0
- package/dist/src/rules/observable-reads/flow-expressions.js +159 -0
- package/dist/src/rules/observable-reads/flow-expressions.js.map +1 -0
- package/dist/src/rules/observable-reads/model.d.ts +1 -0
- package/dist/src/rules/observable-reads/model.d.ts.map +1 -1
- package/dist/src/rules/observable-reads/move-down.d.ts.map +1 -1
- package/dist/src/rules/observable-reads/move-down.js +62 -24
- package/dist/src/rules/observable-reads/move-down.js.map +1 -1
- package/dist/src/rules/observable-reads/move-into-child.d.ts.map +1 -1
- package/dist/src/rules/observable-reads/move-into-child.js +16 -2
- package/dist/src/rules/observable-reads/move-into-child.js.map +1 -1
- package/dist/src/rules/observable-reads/observable-reads.d.ts +3 -0
- package/dist/src/rules/observable-reads/observable-reads.d.ts.map +1 -1
- package/dist/src/rules/observable-reads/observable-reads.js +7 -0
- package/dist/src/rules/observable-reads/observable-reads.js.map +1 -1
- package/dist/src/rules/observable-reads/owner-subscription-work.d.ts +5 -0
- package/dist/src/rules/observable-reads/owner-subscription-work.d.ts.map +1 -0
- package/dist/src/rules/observable-reads/owner-subscription-work.js +61 -0
- package/dist/src/rules/observable-reads/owner-subscription-work.js.map +1 -0
- package/dist/src/rules/observable-reads/primitive-paths.d.ts +6 -0
- package/dist/src/rules/observable-reads/primitive-paths.d.ts.map +1 -0
- package/dist/src/rules/observable-reads/primitive-paths.js +126 -0
- package/dist/src/rules/observable-reads/primitive-paths.js.map +1 -0
- package/dist/src/rules/observable-reads/stable-effect-dependencies.d.ts +7 -0
- package/dist/src/rules/observable-reads/stable-effect-dependencies.d.ts.map +1 -0
- package/dist/src/rules/observable-reads/stable-effect-dependencies.js +114 -0
- package/dist/src/rules/observable-reads/stable-effect-dependencies.js.map +1 -0
- package/dist/src/rules/observable-reads/subscription-cut.d.ts +10 -0
- package/dist/src/rules/observable-reads/subscription-cut.d.ts.map +1 -0
- package/dist/src/rules/observable-reads/subscription-cut.js +81 -0
- package/dist/src/rules/observable-reads/subscription-cut.js.map +1 -0
- package/dist/src/rules/observable-reads/subscription-flow.d.ts +22 -0
- package/dist/src/rules/observable-reads/subscription-flow.d.ts.map +1 -0
- package/dist/src/rules/observable-reads/subscription-flow.js +142 -0
- package/dist/src/rules/observable-reads/subscription-flow.js.map +1 -0
- package/dist/src/rules/observable-reads/subscription-inventory.d.ts +5 -0
- package/dist/src/rules/observable-reads/subscription-inventory.d.ts.map +1 -0
- package/dist/src/rules/observable-reads/subscription-inventory.js +64 -0
- package/dist/src/rules/observable-reads/subscription-inventory.js.map +1 -0
- package/dist/src/rules/observable-reads/subscription-leaf-targets.d.ts +15 -0
- package/dist/src/rules/observable-reads/subscription-leaf-targets.d.ts.map +1 -0
- package/dist/src/rules/observable-reads/subscription-leaf-targets.js +84 -0
- package/dist/src/rules/observable-reads/subscription-leaf-targets.js.map +1 -0
- package/dist/src/rules/state-proofs/render-purpose.d.ts +5 -0
- package/dist/src/rules/state-proofs/render-purpose.d.ts.map +1 -0
- package/dist/src/rules/state-proofs/render-purpose.js +60 -0
- package/dist/src/rules/state-proofs/render-purpose.js.map +1 -0
- package/package.json +5 -2
- package/dist/src/project/semantic-context/identity-program.d.ts +0 -7
- package/dist/src/project/semantic-context/identity-program.d.ts.map +0 -1
- package/dist/src/project/semantic-context/identity-program.js +0 -60
- package/dist/src/project/semantic-context/identity-program.js.map +0 -1
- package/dist/src/project/semantic-context/import-provenance.d.ts +0 -8
- package/dist/src/project/semantic-context/import-provenance.d.ts.map +0 -1
- package/dist/src/project/semantic-context/import-provenance.js +0 -104
- package/dist/src/project/semantic-context/import-provenance.js.map +0 -1
- package/dist/src/project/semantic-context/model.d.ts +0 -43
- package/dist/src/project/semantic-context/model.d.ts.map +0 -1
- package/dist/src/project/semantic-context/model.js +0 -2
- package/dist/src/project/semantic-context/model.js.map +0 -1
- package/dist/src/project/semantic-context/semantic-context.d.ts +0 -4
- package/dist/src/project/semantic-context/semantic-context.d.ts.map +0 -1
- package/dist/src/project/semantic-context/semantic-context.js +0 -112
- package/dist/src/project/semantic-context/semantic-context.js.map +0 -1
package/EXAMPLES.md
CHANGED
|
@@ -234,6 +234,37 @@ function Avatar({ url$ }: { url$: Observable<string> }) {
|
|
|
234
234
|
This also shows `move-use-value-down` and `move-use-value-into-child`: the parent passes observable references, not
|
|
235
235
|
rendered values.
|
|
236
236
|
|
|
237
|
+
### Move one subscription into several children
|
|
238
|
+
|
|
239
|
+
When one observable feeds separate small parts of a large owner, `move-use-value-down` can name several
|
|
240
|
+
boundaries in one instruction. Move every named read together so the parent no longer subscribes.
|
|
241
|
+
|
|
242
|
+
```tsx
|
|
243
|
+
function Settings({ enabled$ }: { enabled$: Observable<boolean> }) {
|
|
244
|
+
return (
|
|
245
|
+
<main>
|
|
246
|
+
<UnrelatedSettings />
|
|
247
|
+
<section>
|
|
248
|
+
<EnabledInput enabled$={enabled$} label="Vertical" />
|
|
249
|
+
</section>
|
|
250
|
+
<aside>
|
|
251
|
+
<EnabledInput enabled$={enabled$} label="Horizontal" />
|
|
252
|
+
</aside>
|
|
253
|
+
</main>
|
|
254
|
+
);
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
function EnabledInput({ enabled$, label }: { enabled$: Observable<boolean>; label: string }) {
|
|
258
|
+
const enabled = useValue(enabled$);
|
|
259
|
+
return <input aria-label={label} disabled={!enabled} />;
|
|
260
|
+
}
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
Define the children outside the parent, keep observable ownership unchanged, and pass other inputs as ordinary
|
|
264
|
+
props. Keep the evaluation of those inputs in the parent. If a named boundary contains a conditional, keep the
|
|
265
|
+
whole condition inside its always-mounted child. Prefer one cohesive child when it already isolates the reads;
|
|
266
|
+
separate subscriptions add overhead and are justified only when their combined render work stays small.
|
|
267
|
+
|
|
237
268
|
### Remove selector work and legacy names
|
|
238
269
|
|
|
239
270
|
Use `pass-observable-to-use-value` for a direct value and `replace-legacy-use-value` for old APIs.
|
package/README.md
CHANGED
|
@@ -1,25 +1,8 @@
|
|
|
1
1
|
# Legend Doctor
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
[Legend State](https://legendapp.com/open-source/state/) code and reports:
|
|
7
|
-
|
|
8
|
-
- proven edits that remove a render or an effect
|
|
9
|
-
- edits that need one more fact before they are safe
|
|
10
|
-
- code that is already right and should stay as it is
|
|
11
|
-
|
|
12
|
-
It never edits files. It never guesses. It emits `change` only when the TypeScript structure proves the edit.
|
|
13
|
-
|
|
14
|
-
## Why fewer renders
|
|
15
|
-
|
|
16
|
-
Most React apps re-render whole trees when one value changes. Legend State fixes this by letting each leaf subscribe
|
|
17
|
-
to exactly the value it renders. Jay Meistrich, who built Legend State, explains the idea and the numbers in his
|
|
18
|
-
App.js Conf 2026 talk:
|
|
19
|
-
|
|
20
|
-
[](https://youtu.be/K3flMIHS-cI)
|
|
21
|
-
|
|
22
|
-
Legend Doctor is the tool that finds those cuts in an existing codebase, and holds every one of them to a proof.
|
|
3
|
+
A read-only analyzer for React and Legend State in TypeScript and JavaScript.
|
|
4
|
+
It reports suggested render and effect optimizations, unresolved opportunities, and code to keep.
|
|
5
|
+
Results are JSON; source files are never modified.
|
|
23
6
|
|
|
24
7
|
## Quick start
|
|
25
8
|
|
|
@@ -46,17 +29,12 @@ Copy the skill into your project, then the agent scans before and after every st
|
|
|
46
29
|
cp -r node_modules/legend-doctor/skills/legend-doctor /path/to/app/.claude/skills/
|
|
47
30
|
```
|
|
48
31
|
|
|
49
|
-
|
|
50
|
-
findings, and rescan.
|
|
51
|
-
|
|
52
|
-
To see the effect at runtime, pair it with [genie-react](https://github.com/Genie-sa/genie-react). Genie counts real
|
|
53
|
-
renders in the running app, so the agent can record a render count before the edit and check it dropped after.
|
|
32
|
+
Apply related findings together, validate the changes, and rescan. See [EXAMPLES.md](EXAMPLES.md).
|
|
54
33
|
|
|
55
34
|
## Run in CI
|
|
56
35
|
|
|
57
|
-
The GitHub Action
|
|
58
|
-
|
|
59
|
-
advisory by default. Add `.github/workflows/legend-doctor.yml`:
|
|
36
|
+
The GitHub Action reports findings introduced by a pull request. It is advisory by default.
|
|
37
|
+
Add `.github/workflows/legend-doctor.yml`:
|
|
60
38
|
|
|
61
39
|
```yaml
|
|
62
40
|
name: Legend Doctor
|
|
@@ -80,29 +58,14 @@ jobs:
|
|
|
80
58
|
- uses: actions/checkout@fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09 # v5
|
|
81
59
|
with:
|
|
82
60
|
fetch-depth: 0
|
|
83
|
-
- uses: Genie-sa/legend-doctor@v0.
|
|
61
|
+
- uses: Genie-sa/legend-doctor@v0.3.0
|
|
84
62
|
with:
|
|
85
63
|
directory: src
|
|
86
64
|
```
|
|
87
65
|
|
|
88
66
|
Keep `fetch-depth: 0`. The action diffs the pull request against its base branch and needs the history.
|
|
89
67
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
> Add Legend Doctor to this repository so it reviews every pull request. Create a branch, add the workflow file shown
|
|
93
|
-
> in the "Run in CI" section of https://github.com/Genie-sa/legend-doctor exactly as written, set `directory` to the
|
|
94
|
-
> folder that holds our React components, commit only that file, and open a pull request titled "Add Legend Doctor
|
|
95
|
-
> CI". Do not change application code.
|
|
96
|
-
|
|
97
|
-
| Input | Default | Meaning |
|
|
98
|
-
| ---------------- | --------- | ---------------------------------------------------------------------------------------- |
|
|
99
|
-
| `directory` | `.` | Folder to scan |
|
|
100
|
-
| `scope` | `changed` | `changed` reports what the PR introduced, `files` every finding in changed files, `full` |
|
|
101
|
-
| `blocking` | `none` | Fail the check on `change`, `candidate`, or `style` findings |
|
|
102
|
-
| `materiality` | config | `compact` also reports render cuts in components with 8 to 11 JSX elements |
|
|
103
|
-
| `ignore-actions` | config | Comma-separated actions to hide, added to the config file's list |
|
|
104
|
-
|
|
105
|
-
The action skips pull requests that change no React files. [action.yml](action.yml) lists every input and output.
|
|
68
|
+
See [action.yml](action.yml) for scope, blocking, filtering, and other options.
|
|
106
69
|
|
|
107
70
|
## Configure
|
|
108
71
|
|
|
@@ -141,36 +104,8 @@ Every finding has a disposition:
|
|
|
141
104
|
| `keep` | Correct as is. Leave the React or lifecycle boundary alone. |
|
|
142
105
|
| `style` | Cleaner form. Apply only when the installed Legend State API supports it. |
|
|
143
106
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
`legend-doctor --help` documents every report field. [REPORT.md](REPORT.md) goes further: the `assumption` a
|
|
148
|
-
`review-state` finding carries when one yes/no fact would turn it into a `change`, and how to record the answer.
|
|
149
|
-
|
|
150
|
-
## The loop
|
|
151
|
-
|
|
152
|
-
1. Scan.
|
|
153
|
-
2. Apply one group of `change` findings.
|
|
154
|
-
3. Read the source for each `candidate`. Edit only when the missing fact is proven.
|
|
155
|
-
4. Run your formatter, typecheck, and tests.
|
|
156
|
-
5. Scan again. Stop when every remaining finding is `keep` or an understood `candidate`.
|
|
157
|
-
|
|
158
|
-
Check [EXAMPLES.md](EXAMPLES.md) before applying an action you have not seen before.
|
|
159
|
-
|
|
160
|
-
## What it cuts
|
|
161
|
-
|
|
162
|
-
| Cost | Typical action |
|
|
163
|
-
| -------------------------------------------------- | ------------------------------------------------------ |
|
|
164
|
-
| A parent render caused by one child's local state | `move-state-down`, `use-observable` |
|
|
165
|
-
| A render for a value only commands or cleanup read | `use-ref` |
|
|
166
|
-
| Derived state kept in sync by an effect | `delete-derived-state`, `delete-effect` |
|
|
167
|
-
| An effect that runs after an event it could join | `move-to-event` |
|
|
168
|
-
| A render used only to run an external reaction | `use-observe-effect` |
|
|
169
|
-
| A subscription wider than the value rendered | `narrow-use-value-subscription`, `move-use-value-down` |
|
|
170
|
-
| A render read that never subscribes | `use-value-for-render-read` |
|
|
171
|
-
| A parent clone where one path changed | `narrow-observable-write`, `assign-observable-fields` |
|
|
172
|
-
|
|
173
|
-
[EXAMPLES.md](EXAMPLES.md) has one worked example per action.
|
|
107
|
+
See [REPORT.md](REPORT.md) for review blockers, grouped transitions, subscription plans, and runtime measurements.
|
|
108
|
+
Validate suggested edits with your formatter, typecheck, and tests, then rescan.
|
|
174
109
|
|
|
175
110
|
## Commands
|
|
176
111
|
|
|
@@ -192,28 +127,8 @@ legend-doctor <root> --actionable --staged # staged files
|
|
|
192
127
|
legend-doctor <root> --actionable --since origin/main # this branch
|
|
193
128
|
```
|
|
194
129
|
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
owner — do not depend on the tier. Run `--help` for every flag and exit code.
|
|
198
|
-
|
|
199
|
-
## Safety rules
|
|
200
|
-
|
|
201
|
-
- One owner per value. Do not mirror React state and an observable.
|
|
202
|
-
- `useObservable` for state tied to a component's lifetime.
|
|
203
|
-
- `useValue` at the smallest stable leaf that renders the value.
|
|
204
|
-
- `.peek()` only in a proven non-tracking command.
|
|
205
|
-
- `.assign()` or `batch()` when several writes are one update.
|
|
206
|
-
- Keep small, one-control state in React when an observable removes no render.
|
|
207
|
-
- Keep an effect when its timing, replay, or cleanup is not proven equivalent.
|
|
208
|
-
- Apply grouped findings together.
|
|
209
|
-
- Check the installed `@legendapp/state` version before changing an API.
|
|
210
|
-
|
|
211
|
-
Under `@legendapp/state` 2.x the tracking rule is off, because `enableReactTracking({ auto: true })` can make render
|
|
212
|
-
reads track app-wide. In React Compiler projects, keep clone writes unless the report proves the in-place write safe.
|
|
213
|
-
|
|
214
|
-
These rules follow the [Legend State React API](https://legendapp.com/open-source/state/v3/react/react-api/), the
|
|
215
|
-
[reactivity guide](https://legendapp.com/open-source/state/v3/usage/reactivity/), and the
|
|
216
|
-
[Legend State best-practices skill](https://github.com/LegendApp/legend-skills/tree/main/legend-state-best-practices).
|
|
130
|
+
See `legend-doctor --help` for all flags and exit codes, [ACTIONS.md](ACTIONS.md) for actions, and
|
|
131
|
+
[EXAMPLES.md](EXAMPLES.md) for worked examples.
|
|
217
132
|
|
|
218
133
|
## Develop
|
|
219
134
|
|
package/REPORT.md
ADDED
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
# Report reference
|
|
2
|
+
|
|
3
|
+
Field-level detail for the JSON report. Read [README.md](README.md) first.
|
|
4
|
+
|
|
5
|
+
Version-gate consumers with `schemaVersion`, currently `4`.
|
|
6
|
+
|
|
7
|
+
Grouped state findings may also include additive `transitions` evidence. `writes` lists direct
|
|
8
|
+
setter calls with state names, line/column positions, handler identities, and enclosing control
|
|
9
|
+
contexts. `relations` refers to zero-based write indices in the same handler. `coexecution: proven`
|
|
10
|
+
means a shared synchronous path exists; it does **not** mean all executions are one atomic update.
|
|
11
|
+
`disproven` includes separate suspension phases and mutually exclusive/unreachable paths; `unknown`
|
|
12
|
+
retains an explicit proof gap. No relation is inferred between different handlers.
|
|
13
|
+
|
|
14
|
+
Only `fusion: adjacent-literals` identifies adjacent replacements of distinct fields with literal
|
|
15
|
+
values that can form one `assign`. `preserve-source` means retain evaluation order, branches, and
|
|
16
|
+
exception/suspension boundaries; it does not authorize moving those expressions into an object
|
|
17
|
+
literal. Group reviews name unresolved pairs by exact source location. These are bounded source
|
|
18
|
+
facts, not a complete migration plan or new permission to convert a review finding. Transported
|
|
19
|
+
setters still depend on the existing child-contract proofs and are not listed as direct writes.
|
|
20
|
+
|
|
21
|
+
Schema 4 removes the unused `diagnostics.semantic` field. Coverage schema 2 reports only `parser`, `lowering`,
|
|
22
|
+
and `detector`: no detector consumed the former semantic stage. The experimental `createSemanticContext`,
|
|
23
|
+
`AnalysisContextOptions.configFilePath`, and semantic context types have been removed.
|
|
24
|
+
|
|
25
|
+
Important fields:
|
|
26
|
+
|
|
27
|
+
| Field | Meaning |
|
|
28
|
+
| -------------- | --------------------------------------------------------------------------- |
|
|
29
|
+
| `status` | `ok` or `error` |
|
|
30
|
+
| `root` | Base directory for every finding path |
|
|
31
|
+
| `analyzer` | Tool `version` and compiled `build` |
|
|
32
|
+
| `findings` | React state and effect findings |
|
|
33
|
+
| `practices` | Legend State practice findings |
|
|
34
|
+
| `hidden` | Findings removed by filters |
|
|
35
|
+
| `capabilities` | Legend State version and exports, React Compiler status, and disabled rules |
|
|
36
|
+
| `scope` | Active scope flag and loaded context file count |
|
|
37
|
+
|
|
38
|
+
Compare reports only when `analyzer.build` matches.
|
|
39
|
+
|
|
40
|
+
Every `review-state` and `review-effect` finding has an `abstentionReason`. It names the main fact or safety rule that
|
|
41
|
+
blocked a proven edit.
|
|
42
|
+
|
|
43
|
+
Every review also carries `review: { kind, blockers, next }`. This is additive guidance in schema 4;
|
|
44
|
+
the action and disposition remain authoritative. `blockers` combines the current reason, question facts,
|
|
45
|
+
and any group members' known next blockers. It is not an exhaustive list of every missing proof.
|
|
46
|
+
|
|
47
|
+
| `review.kind` | Next step |
|
|
48
|
+
| ------------------- | ------------------------------------------------------------------------------- |
|
|
49
|
+
| `confirm` | Research and answer the attached open question. |
|
|
50
|
+
| `recheck` | Re-read changed source before renewing a stale answer. |
|
|
51
|
+
| `declined` | Preserve the current behavior; the recorded answer rejected the conversion. |
|
|
52
|
+
| `dependency` | Resolve the question ids in `waitsOn`, then rescan. |
|
|
53
|
+
| `unsupported` | Resolve a binding, callback, or callable-state shape the analyzer cannot model. |
|
|
54
|
+
| `no-proven-benefit` | Establish a render or lifecycle saving before proposing a migration. |
|
|
55
|
+
| `investigate` | Follow `review.next`; no supported yes/no answer currently yields an edit. |
|
|
56
|
+
|
|
57
|
+
`async-command-origin-unresolved` means an async pending interval and leaf boundary are proven, but
|
|
58
|
+
the command's event origin is not. This differs from `callback-timing-unresolved`, which concerns
|
|
59
|
+
captured-value reads. Eligible direct JSX event references and inline adapters receive an event-origin
|
|
60
|
+
question; known direct render calls do not. Confirming it preserves the existing async command and
|
|
61
|
+
changes its pending writes and subscriber boundary. Old answers keyed to the former reason do not
|
|
62
|
+
silently confirm this new question.
|
|
63
|
+
|
|
64
|
+
Use an unfiltered scan to inventory all review kinds. `--actionable` still hides reviews without a
|
|
65
|
+
confirmable question; guidance does not override that filter or make a review actionable.
|
|
66
|
+
|
|
67
|
+
## Answer a review question
|
|
68
|
+
|
|
69
|
+
When one yes/no fact is all that blocks a `review-state` finding, the finding also carries an `assumption`:
|
|
70
|
+
|
|
71
|
+
| Field | Meaning |
|
|
72
|
+
| ------------- | -------------------------------------------------------------------------------------------- |
|
|
73
|
+
| `id` | Stable across line shifts: report file, owner, state name, blocker |
|
|
74
|
+
| `question` | The concrete fact to confirm, naming the states, targets, or read sites involved |
|
|
75
|
+
| `facts` | The blockers a "yes" assumes away; one, or two when a second blocker stands behind the first |
|
|
76
|
+
| `research` | Distinct checks with `file`, first `line`, all `lines`, and the full source-site `total` |
|
|
77
|
+
| `ifConfirmed` | The action a confirmed answer produces; the tool re-ran its proofs with that fact assumed |
|
|
78
|
+
| `fingerprint` | Digest of the owner's source; an answer recorded for a different digest is reported `stale` |
|
|
79
|
+
| `renderCost` | JSX elements the owner renders per update of this state |
|
|
80
|
+
| `updateSites` | Setter call sites; `renderCost × updateSites` is the `priority` used by `report.questions` |
|
|
81
|
+
| `status` | `open`, `confirmed`, `rejected`, or `stale` |
|
|
82
|
+
|
|
83
|
+
A question is asked only when the hypothetical run yields a conversion, so every "yes" has a concrete instruction.
|
|
84
|
+
`report.questions` lists the open ones by `rank`. A group reports the first converting member's action in
|
|
85
|
+
`ifConfirmed` and the number that convert in `convertingCount`; individual outcomes remain in `members`.
|
|
86
|
+
Repeated research instructions list every relevant line and a full site count, including multiple sites on one line. A step without `lines` or `total` describes one site at `line`.
|
|
87
|
+
Record answers in `<root>/.legend-doctor/confirmations.json`, which
|
|
88
|
+
every scan of that root reads, or in any file passed with `--confirm`:
|
|
89
|
+
|
|
90
|
+
```json
|
|
91
|
+
{
|
|
92
|
+
"confirmations": [
|
|
93
|
+
{
|
|
94
|
+
"id": "src/panel.tsx::Panel::open::atomic-transition-unproven",
|
|
95
|
+
"fingerprint": "8444a887430f",
|
|
96
|
+
"answer": "yes",
|
|
97
|
+
"note": "both writes sit in fail(); Drawer renders open directly (drawer.tsx:12)"
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
"id": "src/panel.tsx::Panel::filter::render-cut-unproven",
|
|
101
|
+
"fingerprint": "4f22f4aca655",
|
|
102
|
+
"answer": "no"
|
|
103
|
+
}
|
|
104
|
+
]
|
|
105
|
+
}
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
legend-doctor <root>
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
Or let the tool write the entry, fingerprint included, and report the scan that honours it in one command:
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
legend-doctor <root> --answer "src/panel.tsx::Panel::open::atomic-transition-unproven=yes" --note "both writes sit in fail()"
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
A `review-effect` finding can carry the same block: an empty-dependency setup effect asks whether `useMount`'s once-only
|
|
119
|
+
semantics are intended. An effect whose verdict waits on a React state instead lists that state's open question ids in
|
|
120
|
+
`waitsOn`, so the answer that settles the state settles the effect.
|
|
121
|
+
|
|
122
|
+
When assuming the first blocker away still leaves a review verdict, the tool assumes the next one too and asks both
|
|
123
|
+
facts in one question; the id then joins both reasons with `+`, and `facts` lists them in order. Two facts is the cap.
|
|
124
|
+
|
|
125
|
+
States a handler writes together share one question and one id, `file::Owner::{a,b}::atomic-transition-unproven`.
|
|
126
|
+
Its `members` list says what a "yes" does to each: members whose standalone proof already passes convert together under
|
|
127
|
+
one cluster instruction written with `assign`, and a member another blocker still holds is re-examined without the
|
|
128
|
+
co-write blocker and gets its next question on the same scan.
|
|
129
|
+
|
|
130
|
+
A confirmed individual question turns its finding into `ifConfirmed` with disposition `change`; a group converts only the members whose outcome is actionable. The answer is recorded in each converted finding's evidence. Such a finding also carries `verification`: the conversion rests on an answer rather than a proof, so the
|
|
131
|
+
recipe names the jsdom harness exported as `legend-doctor/runtime` (`mountDom`, `count`), the before/after comparison
|
|
132
|
+
to run, and the render-count and DOM expectations that must hold; a failed comparison means the answer was wrong. A rejected id keeps the review verdict and stops the question from being asked again. When the owner's code
|
|
133
|
+
changes, the fingerprint no longer matches: the answer is reported `stale`, not applied, and the question is asked
|
|
134
|
+
again. The report's `confirmations` block counts applied, rejected, and stale answers, names the file they came from,
|
|
135
|
+
and lists ids no finding produced.
|
|
136
|
+
|
|
137
|
+
Failures are also valid JSON. They include `status: "error"`, a stable `reason`, a useful `message`, and
|
|
138
|
+
sometimes a `next` command.
|
|
139
|
+
|
|
140
|
+
## Compact provenance
|
|
141
|
+
|
|
142
|
+
`materiality: "compact"` means compact mode changed the finding's action or made a new conversion confirmable.
|
|
143
|
+
Kept findings and outcomes already available in broad mode are untagged. This comparison includes consumer-size
|
|
144
|
+
thresholds for hook-owned state. Compact mode evaluates both policies on the same parsed source; it adds analysis
|
|
145
|
+
work but does not reread or reparse files.
|
|
146
|
+
|
|
147
|
+
## Coordinated subscriptions (version 1)
|
|
148
|
+
|
|
149
|
+
`subscriptionAnalysis` is an additive section of schema 4. Its own `version` is `1`.
|
|
150
|
+
|
|
151
|
+
- `inventory` records each recognized imported `useValue` call in eligible scanned files, including aliases.
|
|
152
|
+
Each entry contains its source location, binding, observable, classified reads, derivations, and status:
|
|
153
|
+
`planned`, `other-action`, or `unresolved`. Unresolved entries have explicit reasons; they are not findings.
|
|
154
|
+
- `coverage` counts those three statuses and their total. This is subscription inventory coverage, separate
|
|
155
|
+
from hook coverage and manually labeled corpus recall. It does not count hidden subscriptions inside
|
|
156
|
+
arbitrary custom hooks or unrecognized imports.
|
|
157
|
+
- `plans` groups actionable subscription cuts by owner. Overlapping JSX boundaries merge into one child.
|
|
158
|
+
Each plan lists subscriptions, complete derivation chains, child locations, remaining parent inputs,
|
|
159
|
+
implementation steps, and behavioral verification. Define new children at module scope and retain their
|
|
160
|
+
mount slots. Keep observable creation and atomic writes in their existing owner.
|
|
161
|
+
- `impact.basis: "static-jsx"` ranks by owner JSX elements outside the proposed children. These are source
|
|
162
|
+
counts, not render counts, elapsed time, or a promised speedup. `rank` starts at 1.
|
|
163
|
+
- `impact.basis: "provided-runtime-measurement"` identifies externally supplied before/after render counts.
|
|
164
|
+
Measurements do not bypass detector proofs or create findings.
|
|
165
|
+
- `rejectedMeasurements` reports malformed, stale, duplicate, or unmatched measurement entries.
|
|
166
|
+
|
|
167
|
+
A practice finding with a coordinated cut also has `subscription` metadata. Report filters remove matching
|
|
168
|
+
plans and mark filtered inventory entries `excluded-by-report-filter`, so ignored actions do not reappear
|
|
169
|
+
as implementation instructions. Filtering away any part of a plan also removes its runtime measurement;
|
|
170
|
+
measurements of a complete edit cannot rank a partial edit.
|
|
171
|
+
|
|
172
|
+
To attach runtime evidence, create `<analysis-root>/.legend-doctor/subscription-measurements.json`:
|
|
173
|
+
|
|
174
|
+
```json
|
|
175
|
+
[
|
|
176
|
+
{
|
|
177
|
+
"planId": "copy plans[i].id from the baseline report",
|
|
178
|
+
"fingerprint": "copy plans[i].fingerprint from the baseline report",
|
|
179
|
+
"scenario": "toggle the setting ten times with unrelated UI mounted",
|
|
180
|
+
"samples": 10,
|
|
181
|
+
"before": { "ownerRenders": 10, "siblingRenders": 30 },
|
|
182
|
+
"after": { "ownerRenders": 0, "siblingRenders": 0 },
|
|
183
|
+
"behaviorEquivalent": true
|
|
184
|
+
}
|
|
185
|
+
]
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
Record equal interaction samples before and after in the same runtime configuration, excluding initial
|
|
189
|
+
mounts. Verify visible values, drafts, callback snapshots, identity, effect cleanup, and atomic updates
|
|
190
|
+
before setting `behaviorEquivalent`. The analyzer trusts this supplied assertion; it does not run the app.
|
|
191
|
+
Attach the evidence when scanning the **baseline source**: the fingerprint hashes the owner's source text,
|
|
192
|
+
so a scan of the edited owner rejects it as stale. External modules and runtime settings are not included
|
|
193
|
+
in that fingerprint; repeat measurements when either changes. Programmatic `analyzePath` callers may pass
|
|
194
|
+
`subscriptionMeasurements` instead of creating the file.
|
|
195
|
+
|
|
196
|
+
Measured positive savings rank first, unmeasured static plans next, and measured zero/negative savings last.
|
|
197
|
+
Within measured groups, ranking uses total owner-plus-sibling renders saved per sample. This ordering is a
|
|
198
|
+
triage aid; scenario frequency and render duration still require application profiling.
|
|
199
|
+
|
|
200
|
+
Closed `const` aliases/defaults and supported `useMemo` projections move with their subscriptions. Memo
|
|
201
|
+
identity and dependencies remain intact. Literal primitive effect dependencies and explicitly typed primitive
|
|
202
|
+
props can prove that an independent effect will not rerun on subscription-only updates. Missing/unstable
|
|
203
|
+
or unresolved dependencies, callback snapshots, refs, overlapping parent subscriptions, repeated render
|
|
204
|
+
callbacks, and unsupported expressions remain conservative blockers. General selector relocation is not
|
|
205
|
+
implied by inventory coverage.
|
|
@@ -162,7 +162,7 @@ function ownerBindingIndexes(sourceFile, imports) {
|
|
|
162
162
|
useValueBindingsByOwner: collectUseValueBindings(sourceFile, imports),
|
|
163
163
|
};
|
|
164
164
|
}
|
|
165
|
-
function
|
|
165
|
+
function findingsForPolicy(sourceFile, fileName, options) {
|
|
166
166
|
const analysis = sourceAnalysisBase(sourceFile, fileName, options);
|
|
167
167
|
const callbacks = collectOwnerEventCallbacks(analysis);
|
|
168
168
|
const commands = collectCommandProofs(analysis);
|
|
@@ -181,4 +181,24 @@ function analyzeParsedSource(sourceFile, fileName, options) {
|
|
|
181
181
|
ownership,
|
|
182
182
|
});
|
|
183
183
|
}
|
|
184
|
+
/** Compare final outcomes so consumer thresholds and alternative proofs are accounted for. */
|
|
185
|
+
function analyzeParsedSource(sourceFile, fileName, options) {
|
|
186
|
+
const findings = findingsForPolicy(sourceFile, fileName, options);
|
|
187
|
+
if (options.materiality?.tier !== "compact") {
|
|
188
|
+
return findings;
|
|
189
|
+
}
|
|
190
|
+
const broad = findingsForPolicy(sourceFile, fileName, {
|
|
191
|
+
...options,
|
|
192
|
+
materiality: DEFAULT_MATERIALITY,
|
|
193
|
+
stateFlow: new StateFlowIndex(),
|
|
194
|
+
});
|
|
195
|
+
return findings.map((finding, index) => {
|
|
196
|
+
const baseline = broad[index];
|
|
197
|
+
return finding.disposition !== "keep" &&
|
|
198
|
+
(finding.action !== baseline?.action ||
|
|
199
|
+
finding.assumption?.ifConfirmed !== baseline?.assumption?.ifConfirmed)
|
|
200
|
+
? { ...finding, materiality: "compact" }
|
|
201
|
+
: finding;
|
|
202
|
+
});
|
|
203
|
+
}
|
|
184
204
|
//# sourceMappingURL=analyze-source.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"analyze-source.js","sourceRoot":"","sources":["../../../src/analysis/analyze-source.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAIrE,OAAO,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAC5E,OAAO,EAAE,sBAAsB,EAAE,4BAA4B,EAAE,MAAM,iBAAiB,CAAC;AACvF,OAAO,EACL,0BAA0B,EAC1B,mCAAmC,EACnC,+BAA+B,EAC/B,kCAAkC,EAClC,uBAAuB,GACxB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAClE,OAAO,EAAE,sBAAsB,EAAE,iBAAiB,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AAQlF,OAAO,EAAE,cAAc,EAAE,MAAM,qCAAqC,CAAC;AAErE,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AAClE,OAAO,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AAClE,OAAO,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAChE,OAAO,EAAE,yBAAyB,EAAE,MAAM,kCAAkC,CAAC;AAC7E,OAAO,EAAE,0BAA0B,EAAE,MAAM,6BAA6B,CAAC;AACzE,OAAO,EAAE,sBAAsB,EAAE,MAAM,8BAA8B,CAAC;AACtE,OAAO,EAAE,yBAAyB,EAAE,MAAM,+DAA+D,CAAC;AAC1G,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,sBAAsB,EAAE,MAAM,iDAAiD,CAAC;AACzF,OAAO,EAAE,MAAM,YAAY,CAAC;AAE5B,MAAM,UAAU,aAAa,CAC3B,UAAkB,EAClB,QAAgB,EAChB,mBAAwC,IAAI,GAAG,EAAE;IAEjD,OAAO,iBAAiB,CAAC,UAAU,EAAE,QAAQ,EAAE,EAAE,gBAAgB,EAAE,CAAC,CAAC;AACvE,CAAC;AASD,MAAM,UAAU,iBAAiB,CAC/B,UAAkB,EAClB,QAAgB,EAChB,EACE,aAAa,GAAG,IAAI,EACpB,WAAW,GAAG,IAAI,EAClB,WAAW,GAAG,mBAAmB,EACjC,gBAAgB,GAAG,IAAI,GAAG,EAAE,GACF;IAE5B,MAAM,UAAU,GAAG,EAAE,CAAC,gBAAgB,CACpC,QAAQ,EACR,UAAU,EACV,EAAE,CAAC,YAAY,CAAC,MAAM,EACtB,IAAI,EACJ,iBAAiB,CAAC,QAAQ,CAAC,CAC5B,CAAC;IACF,OAAO,mBAAmB,CAAC,UAAU,EAAE,QAAQ,EAAE;QAC/C,cAAc,EAAE,IAAI;QACpB,aAAa;QACb,qBAAqB,EAAE,IAAI,GAAG,EAAE;QAChC,WAAW;QACX,kBAAkB,EAAE,IAAI,GAAG,EAAE;QAC7B,WAAW;QACX,gBAAgB;QAChB,SAAS,EAAE,IAAI,cAAc,EAAE;KAChC,CAAC,CAAC;AACL,CAAC;AAiBD,MAAM,UAAU,iBAAiB,CAAC,EAChC,YAAY,GAAG,IAAI,EACnB,cAAc,GAAG,IAAI,EACrB,aAAa,GAAG,IAAI,EACpB,qBAAqB,GAAG,IAAI,GAAG,EAAE,EACjC,IAAI,EACJ,WAAW,EACX,WAAW,GAAG,IAAI,EAClB,kBAAkB,GAAG,IAAI,GAAG,EAAE,EAC9B,WAAW,GAAG,mBAAmB,EACjC,cAAc,EACd,gBAAgB,GAAG,IAAI,GAAG,EAAE,EAC5B,SAAS,GAAG,IAAI,cAAc,EAAE,GACV;IACtB,OAAO,mBAAmB,CAAC,IAAI,CAAC,UAAU,EAAE,cAAc,EAAE;QAC1D,YAAY;QACZ,cAAc;QACd,aAAa;QACb,qBAAqB;QACrB,OAAO,EAAE,WAAW,IAAI,kBAAkB,CAAC,IAAI,CAAC,UAAU,CAAC;QAC3D,WAAW;QACX,kBAAkB;QAClB,WAAW;QACX,gBAAgB;QAChB,SAAS;KACV,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,IAAkB;IACnD,MAAM,OAAO,GAAG,kBAAkB,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IACpD,OAAO,uBAAuB,CAAC,IAAI,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC;AAC5E,CAAC;AAED,SAAS,uBAAuB,CAAC,IAAa,EAAE,OAAoB;IAClE,IACE,EAAE,CAAC,gBAAgB,CAAC,IAAI,CAAC;QACzB,CAAC,kBAAkB,CAAC;YAClB,IAAI,EAAE,IAAI;YACV,UAAU,EAAE,OAAO,CAAC,QAAQ;YAC5B,cAAc,EAAE,OAAO,CAAC,eAAe;YACvC,aAAa,EAAE,UAAU;SAC1B,CAAC;YACA,kBAAkB,CAAC;gBACjB,IAAI,EAAE,IAAI;gBACV,UAAU,EAAE,OAAO,CAAC,SAAS;gBAC7B,cAAc,EAAE,OAAO,CAAC,eAAe;gBACvC,aAAa,EAAE,WAAW;aAC3B,CAAC,CAAC,EACL,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,CACL,IAAI,CAAC,YAAY,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,uBAAuB,CAAC,KAAK,EAAE,OAAO,CAAC,IAAI,SAAS,CAAC,KAAK,IAAI,CAC5F,CAAC;AACJ,CAAC;AAED,SAAS,kBAAkB,CACzB,UAAyB,EACzB,QAAgB,EAChB,OAAoC;IAEpC,MAAM,EACJ,YAAY,GAAG,IAAI,EACnB,cAAc,EACd,aAAa,GAAG,IAAI,EACpB,qBAAqB,EACrB,OAAO,GAAG,kBAAkB,CAAC,UAAU,CAAC,EACxC,WAAW,EACX,kBAAkB,EAClB,WAAW,GAAG,mBAAmB,EACjC,gBAAgB,EAChB,SAAS,GACV,GAAG,OAAO,CAAC;IACZ,MAAM,EAAE,OAAO,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,EAAE,mBAAmB,EAAE,YAAY,EAAE,GACxF,aAAa,CAAC,UAAU,EAAE,OAAO,EAAE,WAAW,CAAC,CAAC;IAClD,OAAO;QACL,GAAG,mBAAmB,CAAC,UAAU,EAAE,OAAO,CAAC;QAC3C,GAAG,mBAAmB,CAAC,WAAW,EAAE,OAAO,CAAC;QAC5C,YAAY;QACZ,cAAc;QACd,aAAa;QACb,qBAAqB;QACrB,OAAO;QACP,QAAQ;QACR,OAAO;QACP,eAAe,EAAE,IAAI,GAAG,CAAC,CAAC,GAAG,eAAe,EAAE,GAAG,gBAAgB,CAAC,CAAC;QACnE,WAAW;QACX,kBAAkB;QAClB,eAAe;QACf,WAAW;QACX,oBAAoB,EAAE,sBAAsB,CAAC,QAAQ,CAAC;QACtD,qBAAqB,EAAE,IAAI,GAAG,CAAC;YAC7B,GAAG,4BAA4B,CAAC,UAAU,CAAC;YAC3C,GAAG,CAAC,cAAc,EAAE,sBAAsB,EAAE,IAAI,cAAc,CAAC;SAChE,CAAC;QACF,WAAW;QACX,gBAAgB;QAChB,UAAU;QACV,SAAS;QACT,MAAM;QACN,mBAAmB;QACnB,YAAY;KACb,CAAC;AACJ,CAAC;AAWD,sFAAsF;AACtF,SAAS,aAAa,CACpB,UAAyB,EACzB,OAAoB,EACpB,WAAwC;IAExC,MAAM,WAAW,GAAG,yBAAyB,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;IACnE,MAAM,OAAO,GAAG,WAAW,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,eAAe,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC;IACtF,MAAM,EAAE,MAAM,EAAE,mBAAmB,EAAE,GAAG,sBAAsB,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;IACpF,MAAM,UAAU,GAAG,eAAe,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,CAAC,CAAC;IACnF,OAAO;QACL,OAAO;QACP,eAAe,EAAE,sBAAsB,CAAC,UAAU,EAAE,OAAO,CAAC;QAC5D,WAAW;QACX,MAAM;QACN,mBAAmB;QACnB,YAAY,EAAE,IAAI,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,EAAE,iBAAiB,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC;KAC5F,CAAC;AACJ,CAAC;AASD,SAAS,eAAe,CAAC,EACvB,OAAO,EACP,OAAO,EACP,WAAW,EACX,WAAW,GACM;IACjB,OAAO;QACL,WAAW,EAAE,WAAW,CAAC,gBAAgB;QACzC,OAAO;QACP,gBAAgB,EAAE,sBAAsB,CAAC,OAAO,EAAE,WAAW,CAAC;KAC/D,CAAC;AACJ,CAAC;AASD,SAAS,mBAAmB,CAC1B,WAA+B,EAC/B,OAAmC;IAEnC,OAAO;QACL,qBAAqB,EAAE,WAAW,CAAC,eAAe;QAClD,qBAAqB,EAAE,IAAI,GAAG,CAC5B,OAAO,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CACxE;QACD,iBAAiB,EAAE,IAAI,GAAG,CAAC,WAAW,CAAC,WAAW,CAAC;QACnD,gBAAgB,EAAE,WAAW,CAAC,gBAAgB;KAC/C,CAAC;AACJ,CAAC;AAOD,SAAS,sBAAsB,CAC7B,UAAyB,EACzB,OAAoB;IAEpB,MAAM,MAAM,GAAqB,EAAE,CAAC;IACpC,MAAM,mBAAmB,GAAwB,EAAE,CAAC;IACpD,KAAK,CAAC,UAAU,EAAE,CAAC,IAAI,EAAE,EAAE;QACzB,IACE,CAAC,EAAE,CAAC,gBAAgB,CAAC,IAAI,CAAC;YAC1B,CAAC,kBAAkB,CAAC;gBAClB,IAAI,EAAE,IAAI;gBACV,UAAU,EAAE,OAAO,CAAC,QAAQ;gBAC5B,cAAc,EAAE,OAAO,CAAC,eAAe;gBACvC,aAAa,EAAE,UAAU;aAC1B,CAAC,EACF,CAAC;YACD,OAAO;QACT,CAAC;QACD,MAAM,KAAK,GAAG,cAAc,CAAC,IAAI,CAAC,CAAC;QACnC,IAAI,KAAK,EAAE,CAAC;YACV,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACrB,CAAC;aAAM,CAAC;YACN,mBAAmB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACjC,CAAC;IACH,CAAC,CAAC,CAAC;IACH,OAAO,EAAE,MAAM,EAAE,mBAAmB,EAAE,CAAC;AACzC,CAAC;AAUD,SAAS,mBAAmB,CAAC,UAAyB,EAAE,OAAoB;IAC1E,OAAO;QACL,mBAAmB,EAAE,0BAA0B,CAAC,UAAU,CAAC;QAC3D,8BAA8B,EAAE,mCAAmC,CAAC,UAAU,EAAE,OAAO,CAAC;QACxF,wBAAwB,EAAE,+BAA+B,CAAC,UAAU,CAAC;QACrE,4BAA4B,EAAE,kCAAkC,CAAC,UAAU,EAAE,OAAO,CAAC;QACrF,uBAAuB,EAAE,uBAAuB,CAAC,UAAU,EAAE,OAAO,CAAC;KACtE,CAAC;AACJ,CAAC;AAED,SAAS,
|
|
1
|
+
{"version":3,"file":"analyze-source.js","sourceRoot":"","sources":["../../../src/analysis/analyze-source.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { Hypothesis, HypothesisScope } from "./hypotheses.js";
|
|
2
|
+
/** The async interval and leaf cut have already passed; only command origins may be assumed. */
|
|
3
|
+
export declare function asyncCommandHypothesis(scope: HypothesisScope): Hypothesis | null;
|
|
4
|
+
//# sourceMappingURL=async-command-hypothesis.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"async-command-hypothesis.d.ts","sourceRoot":"","sources":["../../../../src/analysis/assumptions/async-command-hypothesis.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAkGnE,gGAAgG;AAChG,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,eAAe,GAAG,UAAU,GAAG,IAAI,CAiChF"}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { bindingDeclarationCount, isNonValueIdentifier, unwrapTransparentExpression, } from "../../core/analysis-ast.js";
|
|
2
|
+
import { findAncestorUntil, identifiersNamed, nearestNestedFunction } from "../../core/ast.js";
|
|
3
|
+
import { isBindingName } from "../../rules/child-contract/prop-bindings.js";
|
|
4
|
+
import { runtimeFunctionName } from "../ast-helpers.js";
|
|
5
|
+
import ts from "typescript";
|
|
6
|
+
/** Timing confirmation cannot establish execution through arbitrary control flow. */
|
|
7
|
+
function directAdapterCall(expression) {
|
|
8
|
+
const { body } = expression;
|
|
9
|
+
if (!ts.isBlock(body)) {
|
|
10
|
+
return body;
|
|
11
|
+
}
|
|
12
|
+
const [statement] = body.statements;
|
|
13
|
+
if (body.statements.length !== 1 || !statement) {
|
|
14
|
+
return undefined;
|
|
15
|
+
}
|
|
16
|
+
return ts.isExpressionStatement(statement) || ts.isReturnStatement(statement)
|
|
17
|
+
? statement.expression
|
|
18
|
+
: undefined;
|
|
19
|
+
}
|
|
20
|
+
/** A direct JSX event reference or inline event adapter can be researched; an eager call cannot. */
|
|
21
|
+
function eventReference(reference, scope) {
|
|
22
|
+
const attribute = findAncestorUntil(reference, ts.isJsxAttribute, scope.inputs.state.owner);
|
|
23
|
+
const initializer = attribute?.initializer;
|
|
24
|
+
if (!attribute ||
|
|
25
|
+
!/^on[A-Z]/u.test(attribute.name.getText()) ||
|
|
26
|
+
!initializer ||
|
|
27
|
+
!ts.isJsxExpression(initializer) ||
|
|
28
|
+
!initializer.expression) {
|
|
29
|
+
return null;
|
|
30
|
+
}
|
|
31
|
+
const expression = unwrapTransparentExpression(initializer.expression);
|
|
32
|
+
if (expression === reference) {
|
|
33
|
+
return attribute;
|
|
34
|
+
}
|
|
35
|
+
return isDirectAdapter(reference, expression, scope) ? attribute : null;
|
|
36
|
+
}
|
|
37
|
+
function isDirectAdapter(reference, expression, scope) {
|
|
38
|
+
if (!ts.isCallExpression(reference.parent) ||
|
|
39
|
+
reference.parent.expression !== reference ||
|
|
40
|
+
nearestNestedFunction(reference, scope.inputs.state.owner) !== expression ||
|
|
41
|
+
(!ts.isArrowFunction(expression) && !ts.isFunctionExpression(expression)) ||
|
|
42
|
+
expression.asteriskToken) {
|
|
43
|
+
return false;
|
|
44
|
+
}
|
|
45
|
+
const call = directAdapterCall(expression);
|
|
46
|
+
return Boolean(call && unwrapTransparentExpression(call) === reference.parent);
|
|
47
|
+
}
|
|
48
|
+
function commandEventReferences(scope) {
|
|
49
|
+
const { state, usage } = scope.inputs;
|
|
50
|
+
const commands = new Set(usage.setterCallNodes.map((call) => nearestNestedFunction(call, state.owner)));
|
|
51
|
+
const sites = [];
|
|
52
|
+
for (const command of commands) {
|
|
53
|
+
const events = command ? eventsForCommand(runtimeFunctionName(command), scope) : null;
|
|
54
|
+
if (!events) {
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
57
|
+
sites.push(...events);
|
|
58
|
+
}
|
|
59
|
+
return sites.length > 0 ? sites : null;
|
|
60
|
+
}
|
|
61
|
+
function eventsForCommand(name, scope) {
|
|
62
|
+
if (!name || bindingDeclarationCount(scope.inputs.state.owner, name) !== 1) {
|
|
63
|
+
return null;
|
|
64
|
+
}
|
|
65
|
+
const references = identifiersNamed(scope.inputs.state.owner.body, name).filter((reference) => !isBindingName(reference) && !isNonValueIdentifier(reference));
|
|
66
|
+
const events = references.map((reference) => eventReference(reference, scope));
|
|
67
|
+
return events.length === 0 || events.some((event) => event === null)
|
|
68
|
+
? null
|
|
69
|
+
: events.filter((event) => event !== null);
|
|
70
|
+
}
|
|
71
|
+
/** The async interval and leaf cut have already passed; only command origins may be assumed. */
|
|
72
|
+
export function asyncCommandHypothesis(scope) {
|
|
73
|
+
if (!scope.inputs.isUnprovenAsyncStatus) {
|
|
74
|
+
return null;
|
|
75
|
+
}
|
|
76
|
+
const sites = commandEventReferences(scope);
|
|
77
|
+
if (!sites) {
|
|
78
|
+
return null;
|
|
79
|
+
}
|
|
80
|
+
const lines = [
|
|
81
|
+
...new Set(sites.map((site) => scope.inputs.sourceFile.getLineAndCharacterOfPosition(site.getStart()).line + 1)),
|
|
82
|
+
].toSorted((left, right) => left - right);
|
|
83
|
+
const [line] = lines;
|
|
84
|
+
if (line === undefined) {
|
|
85
|
+
return null;
|
|
86
|
+
}
|
|
87
|
+
return {
|
|
88
|
+
inputs: { ...scope.inputs, isAsyncLeafStatus: true, isUnprovenAsyncStatus: false },
|
|
89
|
+
question: `The pending interval and leaf render boundary of \`${scope.inputs.state.valueName}\` are proven. Confirm every listed callback prop invokes its command only from a user event, never during render, memo calculation, effect setup, or subscription registration; keep the command and its async completion boundary unchanged.`,
|
|
90
|
+
research: [
|
|
91
|
+
{
|
|
92
|
+
file: scope.reportFile,
|
|
93
|
+
line,
|
|
94
|
+
lines,
|
|
95
|
+
total: sites.length,
|
|
96
|
+
check: "Open every receiving component and follow this callback prop through wrappers to its event handler; a prop name alone does not prove event timing.",
|
|
97
|
+
},
|
|
98
|
+
],
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
//# sourceMappingURL=async-command-hypothesis.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"async-command-hypothesis.js","sourceRoot":"","sources":["../../../../src/analysis/assumptions/async-command-hypothesis.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"group-assumptions.d.ts","sourceRoot":"","sources":["../../../../src/analysis/assumptions/group-assumptions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,WAAW,EAGX,eAAe,EAChB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAGnE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAC5D,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,uCAAuC,CAAC;AAKvF,4FAA4F;AAC5F,wBAAgB,cAAc,CAC5B,KAAK,EAAE,cAAc,EACrB,QAAQ,EAAE,WAAW,CAAC,cAAc,EAAE,WAAW,CAAC,cAAc,CAAC,CAAC,GACjE,SAAS,cAAc,EAAE,CAY3B;AAED,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,aAAa,EAAE,eAAe,GAAG,IAAI,CAAC;IAC/C,QAAQ,CAAC,MAAM,EAAE,yBAAyB,CAAC;IAC3C,QAAQ,CAAC,OAAO,EAAE,SAAS,cAAc,EAAE,CAAC;IAC5C,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC;CAChC;AAQD,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,UAAU,EAAE,eAAe,CAAC;IACrC,qGAAqG;IACrG,QAAQ,CAAC,SAAS,EAAE,eAAe,GAAG,IAAI,CAAC;IAC3C,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC;CAC1D;AAqDD,wBAAgB,OAAO,CACrB,UAAU,EAAE,MAAM,EAClB,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,SAAS,cAAc,EAAE,GACjC,MAAM,CAGR;
|
|
1
|
+
{"version":3,"file":"group-assumptions.d.ts","sourceRoot":"","sources":["../../../../src/analysis/assumptions/group-assumptions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,WAAW,EAGX,eAAe,EAChB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAGnE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAC5D,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,uCAAuC,CAAC;AAKvF,4FAA4F;AAC5F,wBAAgB,cAAc,CAC5B,KAAK,EAAE,cAAc,EACrB,QAAQ,EAAE,WAAW,CAAC,cAAc,EAAE,WAAW,CAAC,cAAc,CAAC,CAAC,GACjE,SAAS,cAAc,EAAE,CAY3B;AAED,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,aAAa,EAAE,eAAe,GAAG,IAAI,CAAC;IAC/C,QAAQ,CAAC,MAAM,EAAE,yBAAyB,CAAC;IAC3C,QAAQ,CAAC,OAAO,EAAE,SAAS,cAAc,EAAE,CAAC;IAC5C,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC;CAChC;AAQD,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,UAAU,EAAE,eAAe,CAAC;IACrC,qGAAqG;IACrG,QAAQ,CAAC,SAAS,EAAE,eAAe,GAAG,IAAI,CAAC;IAC3C,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC;CAC1D;AAqDD,wBAAgB,OAAO,CACrB,UAAU,EAAE,MAAM,EAClB,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,SAAS,cAAc,EAAE,GACjC,MAAM,CAGR;AAiHD;;;GAGG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,oBAAoB,GAAG,qBAAqB,GAAG,IAAI,CA2BzF"}
|