effect-analyzer 0.1.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/README.md ADDED
@@ -0,0 +1,202 @@
1
+ # effect-analyzer
2
+
3
+ Static analysis for [Effect](https://effect.website/) programs. Visualize service dependencies, error channels, concurrency, and control flow as Mermaid diagrams - without running your code.
4
+
5
+ > **[Documentation](https://jagreehal.github.io/effect-analyzer/)** · **[Getting Started](https://jagreehal.github.io/effect-analyzer/quick-start/)** · **[CLI Reference](https://jagreehal.github.io/effect-analyzer/reference/cli/)** · **[API Reference](https://jagreehal.github.io/effect-analyzer/reference/api/)**
6
+
7
+ ## Why
8
+
9
+ Effect programs are powerful, but their structure - service dependencies, error topology, concurrency patterns - is hard to see in source. effect-analyzer parses your code with [ts-morph](https://ts-morph.com/) and the TypeScript type checker, then produces semantic diagrams and structured analysis. No runtime, no instrumentation.
10
+
11
+ Use it for **code review**, **onboarding**, **architecture docs**, and **CI** to catch regressions in program shape.
12
+
13
+ ## Install
14
+
15
+ ```bash
16
+ npm install -D effect-analyzer
17
+ ```
18
+
19
+ `effect` (>=3.0.0) is a required peer dependency. `ts-morph` is bundled automatically.
20
+
21
+ ## Quick Start
22
+
23
+ ```bash
24
+ # Auto-select the best diagrams for a file
25
+ npx effect-analyze ./src/transfer.ts
26
+
27
+ # Railway diagram (linear happy path with error branches)
28
+ npx effect-analyze ./src/transfer.ts --format mermaid-railway
29
+
30
+ # Plain-English explanation of what a program does
31
+ npx effect-analyze ./src/transfer.ts --format explain
32
+
33
+ # Compare two versions
34
+ npx effect-analyze HEAD:src/transfer.ts src/transfer.ts --diff
35
+
36
+ # Audit an entire project
37
+ npx effect-analyze ./src --coverage-audit
38
+ ```
39
+
40
+ ## What You Get
41
+
42
+ Given an Effect program like this:
43
+
44
+ ```ts
45
+ export const transfer = Effect.gen(function* () {
46
+ const repo = yield* AccountRepo
47
+ const audit = yield* AuditLog
48
+
49
+ const balance = yield* repo.getBalance("from-account")
50
+
51
+ if (balance < 100) {
52
+ yield* Effect.fail(new InsufficientFundsError(balance, 100))
53
+ }
54
+
55
+ yield* repo.debit("from-account", 100)
56
+ yield* repo.credit("to-account", 100)
57
+ yield* audit.record("transfer-complete")
58
+ })
59
+ ```
60
+
61
+ The analyzer produces a railway diagram showing the happy path with error branches:
62
+
63
+ ```mermaid
64
+ flowchart LR
65
+ A["repo <- AccountRepo"] -->|ok| B["audit <- AuditLog"]
66
+ B -->|ok| C["balance <- repo.getBalance"]
67
+ C -->|ok| D{"balance < 100"}
68
+ D -->|ok| E["repo.debit"]
69
+ E -->|ok| F["repo.credit"]
70
+ F -->|ok| G["audit.record"]
71
+ G -->|ok| Done((Success))
72
+ C -.->|err| Err1([AccountNotFound])
73
+ D -.->|err| Err2([InsufficientFunds])
74
+ ```
75
+
76
+ Or a flowchart showing all control flow paths:
77
+
78
+ ```mermaid
79
+ flowchart TB
80
+ start((Start))
81
+ n2["repo <- AccountRepo"]
82
+ n3["audit <- AuditLog"]
83
+ n4["balance <- repo.getBalance"]
84
+ decision{"balance < 100?"}
85
+ n7["Effect.fail(InsufficientFunds)"]
86
+ n8["repo.debit"]
87
+ n9["repo.credit"]
88
+ n10["audit.record"]
89
+ end_node((Done))
90
+
91
+ start --> n2 --> n3 --> n4 --> decision
92
+ decision -->|yes| n7
93
+ decision -->|no| n8
94
+ n7 -.-> end_node
95
+ n8 --> n9 --> n10 --> end_node
96
+ ```
97
+
98
+ ## Features
99
+
100
+ ### 15+ Diagram Types
101
+
102
+ Auto-mode picks the most relevant views for your program, or choose explicitly:
103
+
104
+ | Format | Shows |
105
+ |--------|-------|
106
+ | `mermaid-railway` | Linear happy path with error branches |
107
+ | `mermaid` | Full flowchart with all control flow |
108
+ | `mermaid-services` | Service dependency map |
109
+ | `mermaid-errors` | Error propagation and handling |
110
+ | `mermaid-concurrency` | Parallel and race patterns |
111
+ | `mermaid-layers` | Layer composition graph |
112
+ | `mermaid-retry` | Retry and timeout strategies |
113
+ | `mermaid-timeline` | Step sequence over time |
114
+
115
+ [See all formats →](https://jagreehal.github.io/effect-analyzer/diagrams/all-formats/)
116
+
117
+ ### Complexity Metrics
118
+
119
+ Six metrics calculated for every program: cyclomatic complexity, cognitive complexity, path count, nesting depth, parallel breadth, and decision points.
120
+
121
+ ```bash
122
+ npx effect-analyze ./src/transfer.ts --format stats
123
+ ```
124
+
125
+ [Learn more →](https://jagreehal.github.io/effect-analyzer/analysis/complexity/)
126
+
127
+ ### Semantic Diff
128
+
129
+ Compare two versions of a program at the structural level - not text diffs, but changes in steps, services, and control flow:
130
+
131
+ ```bash
132
+ npx effect-analyze HEAD:src/transfer.ts src/transfer.ts --diff
133
+ ```
134
+
135
+ [Learn more →](https://jagreehal.github.io/effect-analyzer/project/diff/)
136
+
137
+ ### Coverage Audit
138
+
139
+ Scan an entire project to understand Effect usage, identify complex programs, and track analysis quality:
140
+
141
+ ```bash
142
+ npx effect-analyze ./src --coverage-audit
143
+ ```
144
+
145
+ [Learn more →](https://jagreehal.github.io/effect-analyzer/project/coverage-audit/)
146
+
147
+ ### Interactive HTML Viewer
148
+
149
+ Generate a self-contained HTML page with search, filtering, path explorer, complexity heatmap, and 6 color themes:
150
+
151
+ ```ts
152
+ import { renderInteractiveHTML } from "effect-analyzer"
153
+
154
+ const html = renderInteractiveHTML(ir, { theme: "midnight" })
155
+ ```
156
+
157
+ [Learn more →](https://jagreehal.github.io/effect-analyzer/reference/html-viewer/)
158
+
159
+ ### Library API
160
+
161
+ Use the programmatic API to integrate analysis into your own tools:
162
+
163
+ ```ts
164
+ import { analyze } from "effect-analyzer"
165
+ import { Effect } from "effect"
166
+
167
+ const ir = await Effect.runPromise(analyze("./src/transfer.ts").single())
168
+
169
+ console.log(ir.root.programName) // "transfer"
170
+ console.log(ir.root.dependencies) // [{ name: "AccountRepo", ... }, ...]
171
+ console.log(ir.root.errorTypes) // ["InsufficientFundsError", "AccountNotFoundError"]
172
+ ```
173
+
174
+ [Full API reference →](https://jagreehal.github.io/effect-analyzer/reference/api/)
175
+
176
+ ## What It Detects
177
+
178
+ | Area | Patterns |
179
+ |------|----------|
180
+ | **Programs** | `Effect.gen`, pipe chains, `Effect.sync`, `Effect.async`, `Effect.promise` |
181
+ | **Services** | `Context.Tag` via `yield*`, service method calls |
182
+ | **Layers** | `Layer.mergeAll`, `Layer.effect`, `Layer.provide`, `Layer.succeed` |
183
+ | **Errors** | `catchTag`, `catchAll`, `tapError`, `retry`, `timeout` |
184
+ | **Concurrency** | `Effect.all`, `Effect.race`, `Effect.fork`, `Fiber.join` |
185
+ | **Resources** | `acquireRelease`, `ensuring`, `Effect.scoped` |
186
+ | **Streams** | `Stream.fromIterable`, `Stream.mapEffect`, `Stream.runCollect` |
187
+ | **Control flow** | `if/else`, `for..of`, `while`, `try/catch`, `switch` inside generators |
188
+ | **Schedules** | `Schedule.recurs`, `Schedule.exponential` |
189
+ | **Aliases** | `const E = Effect`, destructured imports, renamed imports |
190
+
191
+ ## Requirements
192
+
193
+ - Node.js 22+
194
+ - TypeScript project with `effect` (>=3.0.0)
195
+
196
+ ## Documentation
197
+
198
+ Full documentation is available at **[jagreehal.github.io/effect-analyzer](https://jagreehal.github.io/effect-analyzer/)**.
199
+
200
+ ## License
201
+
202
+ MIT