@thomaflette/eslint-plugin-solid-2 0.2.0 → 0.2.1
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/README.md
CHANGED
|
@@ -63,7 +63,9 @@ The `flat/recommended` and `flat/recommended-type-checked` names are aliases for
|
|
|
63
63
|
| `prefer-show` | Uses `<Show>` for idiomatic reactive JSX conditionals. |
|
|
64
64
|
| `self-closing-comp` | Keeps empty JSX elements consistently self-closing. |
|
|
65
65
|
|
|
66
|
-
Every rule has focused documentation in [docs](./docs).
|
|
66
|
+
Every rule has focused documentation in [docs](./docs). The
|
|
67
|
+
[dev-diagnostic coverage matrix](./docs/dev-diagnostic-coverage.md) records which Solid runtime
|
|
68
|
+
diagnostics are covered statically and which remain intentionally runtime-only.
|
|
67
69
|
|
|
68
70
|
## Design principles
|
|
69
71
|
|
|
@@ -58,3 +58,8 @@ props are valid code that static analysis cannot prove safe or unsafe.
|
|
|
58
58
|
proven from bindings or nominal Solid accessor types, and recognizes JSX, nested closures,
|
|
59
59
|
reactive callbacks, and `untrack` as safe execution contexts. It does not restore the deleted
|
|
60
60
|
heuristic's guesses about arbitrary helper calls.
|
|
61
|
+
- Runtime-state mirrors for `PENDING_ASYNC_FORBIDDEN_SCOPE`, `SETTLED_CLEANUP_UNOWNED`, and the
|
|
62
|
+
`NO_OWNER_*` diagnostics were prototyped and rejected. Whether they fire depends on the source's
|
|
63
|
+
pending state or the active owner at execution; an owner-backed scheduler and an already-settled
|
|
64
|
+
async memo are valid counterexamples to static callback/source heuristics. Solid's exact runtime
|
|
65
|
+
diagnostics own these cases.
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# Solid 2 dev-diagnostic coverage
|
|
2
|
+
|
|
3
|
+
The plugin complements Solid's
|
|
4
|
+
[dev-mode diagnostics](https://github.com/solidjs/solid/blob/next/documentation/solid-2.0/08-dev-diagnostics.md).
|
|
5
|
+
It reports a diagnostic statically only when the source proves the invalid runtime context. Dynamic
|
|
6
|
+
ownership, pending state, disposal state, and scheduler behavior remain with the runtime.
|
|
7
|
+
|
|
8
|
+
| Solid diagnostic | Static coverage | Rule or owner |
|
|
9
|
+
| -------------------------------- | ------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------- |
|
|
10
|
+
| `REACTIVE_WRITE_IN_OWNED_SCOPE` | Strong, sound subset | `no-owned-scope-writes` |
|
|
11
|
+
| `PENDING_ASYNC_UNTRACKED_READ` | Partial; catches provable untracked reads, regardless of pending state | `no-stale-props-alias`, `no-destructure`, `no-untracked-read-in-effect-apply` |
|
|
12
|
+
| `ASYNC_OUTSIDE_LOADING_BOUNDARY` | Runtime only; loading ancestry and render timing are dynamic | Solid runtime |
|
|
13
|
+
| `CLEANUP_IN_FORBIDDEN_SCOPE` | Strong | `no-leaf-owner-operations` |
|
|
14
|
+
| `SETTLED_CLEANUP_UNOWNED` | Runtime only; ownership at execution determines whether cleanup is honored | Solid runtime |
|
|
15
|
+
| `PRIMITIVE_IN_FORBIDDEN_SCOPE` | Strong for owner-creating primitives; plain value signals/stores follow current runtime behavior | `no-leaf-owner-operations` |
|
|
16
|
+
| Invalid cleanup return | Type-level cases are intentionally delegated | TypeScript and Solid runtime |
|
|
17
|
+
| `flush()` in forbidden scope | Strong | `no-leaf-owner-operations` |
|
|
18
|
+
| Potential infinite loop | Runtime only; depends on executed graph behavior | Solid runtime |
|
|
19
|
+
| `STRICT_READ_UNTRACKED` | Strong, sound subset of binding-proven reads | `no-stale-props-alias`, `no-destructure`, `no-untracked-read-in-effect-apply` |
|
|
20
|
+
| `PENDING_ASYNC_FORBIDDEN_SCOPE` | Runtime only; the source must actually be pending when read | Solid runtime |
|
|
21
|
+
| `NO_OWNER_EFFECT` | Runtime only; the active owner is execution-context state | Solid runtime |
|
|
22
|
+
| `NO_OWNER_CLEANUP` | Runtime only; the active owner is execution-context state | Solid runtime |
|
|
23
|
+
| `NO_OWNER_BOUNDARY` | Runtime only; the active owner is execution-context state | Solid runtime |
|
|
24
|
+
| `RUN_WITH_DISPOSED_OWNER` | Runtime only; disposal is dynamic | Solid runtime |
|
|
25
|
+
|
|
26
|
+
Some plugin rules have no corresponding runtime diagnostic. For example,
|
|
27
|
+
`no-reactive-read-after-await` catches dependency loss that native async continuation semantics make
|
|
28
|
+
indistinguishable from an intentional untracked read at runtime. The control-flow and JSX rules
|
|
29
|
+
likewise protect static structure or style rather than mirroring a dev diagnostic.
|
|
@@ -34,11 +34,15 @@ onSettled(() => {
|
|
|
34
34
|
|
|
35
35
|
## Good
|
|
36
36
|
|
|
37
|
-
```
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
37
|
+
```tsx
|
|
38
|
+
function Ticker() {
|
|
39
|
+
onSettled(() => {
|
|
40
|
+
const id = setInterval(tick, 1000);
|
|
41
|
+
return () => clearInterval(id);
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
return <output>{time()}</output>;
|
|
45
|
+
}
|
|
42
46
|
```
|
|
43
47
|
|
|
44
48
|
```ts
|
|
@@ -49,17 +53,21 @@ createTrackedEffect(() => {
|
|
|
49
53
|
```
|
|
50
54
|
|
|
51
55
|
```ts
|
|
52
|
-
|
|
53
|
-
() =>
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
);
|
|
56
|
+
onSettled(() => {
|
|
57
|
+
queueMicrotask(() => {
|
|
58
|
+
setOpen(true);
|
|
59
|
+
flush(); // Commit the update before reading the resulting DOM.
|
|
60
|
+
dialog.focus();
|
|
61
|
+
});
|
|
62
|
+
});
|
|
58
63
|
```
|
|
59
64
|
|
|
60
65
|
## Notes
|
|
61
66
|
|
|
62
67
|
- Only **direct** calls inside the forbidden callback body are checked; nested helper function definitions are allowed.
|
|
68
|
+
- `flush()` is normally unnecessary because Solid flushes updates automatically. Use it only at an
|
|
69
|
+
imperative boundary that must observe the updated DOM synchronously; a microtask scheduled from a
|
|
70
|
+
leaf-owner callback is outside that callback's non-reentrant flush cycle.
|
|
63
71
|
- Calls are matched by binding (a direct, aliased, or namespace `solid-js` import, or an unresolved
|
|
64
72
|
global) — a same-named function from another package is not flagged. Type-aware mode also follows
|
|
65
73
|
re-export chains.
|
|
@@ -3,9 +3,9 @@
|
|
|
3
3
|
Disallow writing to signals/stores or calling actions inside component bodies and reactive compute
|
|
4
4
|
scopes.
|
|
5
5
|
|
|
6
|
-
This matches Solid 2's `
|
|
7
|
-
|
|
8
|
-
boundaries such as event handlers.
|
|
6
|
+
This matches Solid 2's `REACTIVE_WRITE_IN_OWNED_SCOPE` behavior. In these places, derive values
|
|
7
|
+
instead of writing state back into the graph. It also matches the runtime's
|
|
8
|
+
`ACTION_CALLED_IN_OWNED_SCOPE` error: actions belong at imperative boundaries such as event handlers.
|
|
9
9
|
|
|
10
10
|
## Bad
|
|
11
11
|
|