@llui/lint-idiomatic 0.0.1 → 0.0.2
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 +52 -3
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,13 +1,62 @@
|
|
|
1
1
|
# @llui/lint-idiomatic
|
|
2
2
|
|
|
3
|
-
AST linter for idiomatic [LLui](https://github.com/fponticelli/llui) patterns.
|
|
4
|
-
|
|
5
|
-
6 rules covering common anti-patterns: mutation in update, missing keys in each, state-derived map in view, and more.
|
|
3
|
+
AST linter for idiomatic [LLui](https://github.com/fponticelli/llui) patterns. Catches common anti-patterns at the source level.
|
|
6
4
|
|
|
7
5
|
```bash
|
|
8
6
|
pnpm add -D @llui/lint-idiomatic
|
|
9
7
|
```
|
|
10
8
|
|
|
9
|
+
## Usage
|
|
10
|
+
|
|
11
|
+
```ts
|
|
12
|
+
import { lintIdiomatic } from '@llui/lint-idiomatic'
|
|
13
|
+
|
|
14
|
+
const source = `
|
|
15
|
+
function update(state: State, msg: Msg): [State, Effect[]] {
|
|
16
|
+
switch (msg.type) {
|
|
17
|
+
case 'increment':
|
|
18
|
+
state.count++ // mutation!
|
|
19
|
+
return [state, []]
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
`
|
|
23
|
+
|
|
24
|
+
const { violations, score } = lintIdiomatic(source, 'counter.ts')
|
|
25
|
+
|
|
26
|
+
console.log(score) // 5 (out of 6)
|
|
27
|
+
console.log(violations) // [{ rule: 'state-mutation', line: 5, message: '...' }]
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## API
|
|
31
|
+
|
|
32
|
+
```ts
|
|
33
|
+
lintIdiomatic(source: string, filename?: string) => { violations: Violation[], score: number }
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
| Field | Type | Description |
|
|
37
|
+
| ------------ | ------------- | ------------------------------------------ |
|
|
38
|
+
| `violations` | `Violation[]` | List of rule violations found |
|
|
39
|
+
| `score` | `number` | Idiomatic score 0-6 (6 = fully idiomatic) |
|
|
40
|
+
|
|
41
|
+
### Violation
|
|
42
|
+
|
|
43
|
+
| Field | Type | Description |
|
|
44
|
+
| --------- | -------- | ------------------------------ |
|
|
45
|
+
| `rule` | `string` | Rule identifier |
|
|
46
|
+
| `line` | `number` | Source line number |
|
|
47
|
+
| `message` | `string` | Human-readable explanation |
|
|
48
|
+
|
|
49
|
+
## Rules
|
|
50
|
+
|
|
51
|
+
| Rule | Description |
|
|
52
|
+
| ------------------------- | -------------------------------------------------------------- |
|
|
53
|
+
| `state-mutation` | Direct mutation of state in `update()` instead of returning a new object |
|
|
54
|
+
| `missing-memo` | Expensive derived computation in `view()` without `memo()` |
|
|
55
|
+
| `each-closure-violation` | Capturing mutable outer variable inside `each()` render callback |
|
|
56
|
+
| `map-on-state-array` | Calling `.map()` on a state array in `view()` (use `each()` instead) |
|
|
57
|
+
| `unnecessary-child` | Using `child()` boundary when a view function would suffice |
|
|
58
|
+
| `form-boilerplate` | Repetitive form field pattern that could use a view function |
|
|
59
|
+
|
|
11
60
|
## License
|
|
12
61
|
|
|
13
62
|
MIT
|