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 +202 -0
- package/dist/analyze-a8PswlPG.d.cts +1152 -0
- package/dist/analyze-a8PswlPG.d.ts +1152 -0
- package/dist/cli.js +198 -0
- package/dist/effect-workflow.cjs +5 -0
- package/dist/effect-workflow.cjs.map +1 -0
- package/dist/effect-workflow.d.cts +31 -0
- package/dist/effect-workflow.d.ts +31 -0
- package/dist/effect-workflow.js +5 -0
- package/dist/effect-workflow.js.map +1 -0
- package/dist/index.cjs +548 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +1895 -0
- package/dist/index.d.ts +1895 -0
- package/dist/index.js +548 -0
- package/dist/index.js.map +1 -0
- package/dist/lsp/server.js +8827 -0
- package/package.json +76 -0
- package/scripts/analyze-public-repos.ts +130 -0
- package/scripts/audit-ci.ts +213 -0
- package/scripts/audit-public-effect-modules.ts +111 -0
- package/scripts/baselines/effect-audit-baseline.json +14 -0
- package/scripts/benchmark.ts +107 -0
- package/scripts/diff-effect-scans.ts +87 -0
- package/scripts/effect-scan-utils.ts +275 -0
- package/scripts/eslint-rules/no-inline-type-import.js +39 -0
- package/scripts/fetch-effect-repo.ts +52 -0
- package/scripts/openapi-runtime-runner.mjs +66 -0
- package/scripts/scan-effect-internals.ts +53 -0
- package/scripts/scan-effect-top-level.ts +52 -0
- package/scripts/summarize-scan.ts +47 -0
- package/scripts/triage-effect-scan.ts +85 -0
|
@@ -0,0 +1,1152 @@
|
|
|
1
|
+
import { Option, Effect } from 'effect';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Static Effect Analysis - Type Definitions
|
|
5
|
+
*
|
|
6
|
+
* These types represent Effect code structure extracted through static analysis
|
|
7
|
+
* (AST walking) rather than runtime execution.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Source code location for tracing back to original code.
|
|
12
|
+
*/
|
|
13
|
+
interface SourceLocation {
|
|
14
|
+
/** Absolute file path */
|
|
15
|
+
readonly filePath: string;
|
|
16
|
+
/** Line number (1-indexed) */
|
|
17
|
+
readonly line: number;
|
|
18
|
+
/** Column number (0-indexed) */
|
|
19
|
+
readonly column: number;
|
|
20
|
+
/** End line number */
|
|
21
|
+
readonly endLine?: number | undefined;
|
|
22
|
+
/** End column number */
|
|
23
|
+
readonly endColumn?: number | undefined;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Semantic role classification for display and styling.
|
|
27
|
+
*/
|
|
28
|
+
type SemanticRole = 'constructor' | 'service-call' | 'environment' | 'side-effect' | 'transform' | 'error-handler' | 'concurrency' | 'resource' | 'control-flow' | 'scheduling' | 'stream' | 'layer' | 'fiber' | 'unknown';
|
|
29
|
+
/**
|
|
30
|
+
* Structured JSDoc tag data extracted from comments.
|
|
31
|
+
*/
|
|
32
|
+
interface JSDocTags {
|
|
33
|
+
readonly params: readonly {
|
|
34
|
+
readonly name: string;
|
|
35
|
+
readonly description?: string;
|
|
36
|
+
}[];
|
|
37
|
+
readonly returns?: string | undefined;
|
|
38
|
+
readonly throws: readonly string[];
|
|
39
|
+
readonly example?: string | undefined;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Detail level for Mermaid diagram labels.
|
|
43
|
+
*/
|
|
44
|
+
type MermaidDetailLevel = 'compact' | 'standard' | 'verbose';
|
|
45
|
+
/**
|
|
46
|
+
* Base properties shared by all static analysis nodes.
|
|
47
|
+
*/
|
|
48
|
+
interface StaticBaseNode {
|
|
49
|
+
/** Unique identifier for this node */
|
|
50
|
+
readonly id: string;
|
|
51
|
+
/** Human-readable name */
|
|
52
|
+
readonly name?: string | undefined;
|
|
53
|
+
/** Source location */
|
|
54
|
+
readonly location?: SourceLocation | undefined;
|
|
55
|
+
/** Pre-computed human-readable display label (e.g. "user <- UserRepo.getById") */
|
|
56
|
+
readonly displayName?: string | undefined;
|
|
57
|
+
/** Semantic role classification for styling and filtering */
|
|
58
|
+
readonly semanticRole?: SemanticRole | undefined;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* A single Effect operation (yield* or direct call).
|
|
62
|
+
*/
|
|
63
|
+
interface StaticEffectNode extends StaticBaseNode {
|
|
64
|
+
readonly type: 'effect';
|
|
65
|
+
/** The Effect being created (e.g., "Effect.succeed", "Effect.sync") */
|
|
66
|
+
readonly callee: string;
|
|
67
|
+
/** Description of what this effect does */
|
|
68
|
+
readonly description?: string | undefined;
|
|
69
|
+
/** JSDoc description extracted from comments above the effect */
|
|
70
|
+
readonly jsdocDescription?: string | undefined;
|
|
71
|
+
/** Structured JSDoc tags extracted from comments */
|
|
72
|
+
readonly jsdocTags?: JSDocTags | undefined;
|
|
73
|
+
/** Error type if statically determinable */
|
|
74
|
+
readonly errorType?: string | undefined;
|
|
75
|
+
/** Full type signature (A, E, R) - requires type extraction */
|
|
76
|
+
readonly typeSignature?: EffectTypeSignature | undefined;
|
|
77
|
+
/** Services required by this specific effect */
|
|
78
|
+
readonly requiredServices?: ServiceRequirement[] | undefined;
|
|
79
|
+
/** If this effect is a method call on a typed service object */
|
|
80
|
+
readonly serviceCall?: {
|
|
81
|
+
/** Resolved type name of the service object (e.g. 'UserRepo') */
|
|
82
|
+
readonly serviceType: string;
|
|
83
|
+
/** Method name being called (e.g. 'getById') */
|
|
84
|
+
readonly methodName: string;
|
|
85
|
+
/** Variable/expression name used at call site (e.g. 'repo') */
|
|
86
|
+
readonly objectName: string;
|
|
87
|
+
} | undefined;
|
|
88
|
+
/** Resolved service method when call is e.g. yield* db.query() and db is bound to a service tag */
|
|
89
|
+
readonly serviceMethod?: {
|
|
90
|
+
readonly serviceId: string;
|
|
91
|
+
readonly methodName: string;
|
|
92
|
+
} | undefined;
|
|
93
|
+
/** Inner effects from Effect.sync/promise/async callback body (one level only) */
|
|
94
|
+
readonly callbackBody?: readonly StaticFlowNode[] | undefined;
|
|
95
|
+
/** Effect.async/asyncEffect only: resume/canceller callback patterns (GAP async callback interop). */
|
|
96
|
+
readonly asyncCallback?: {
|
|
97
|
+
readonly resumeParamName: string;
|
|
98
|
+
readonly resumeCallCount: number;
|
|
99
|
+
readonly returnsCanceller: boolean;
|
|
100
|
+
} | undefined;
|
|
101
|
+
/** Effect.provide only: whether context is provided via Layer, Context, or Runtime. */
|
|
102
|
+
readonly provideKind?: 'layer' | 'context' | 'runtime' | undefined;
|
|
103
|
+
/** Constructor subtype classification */
|
|
104
|
+
readonly constructorKind?: 'sync' | 'promise' | 'async' | 'never' | 'void' | 'fromNullable' | 'fn' | 'fnUntraced' | undefined;
|
|
105
|
+
/** FiberRef built-in name (e.g. currentLogLevel, currentConcurrency) */
|
|
106
|
+
readonly fiberRefName?: string | undefined;
|
|
107
|
+
/** Effect.fn traced name */
|
|
108
|
+
readonly tracedName?: string | undefined;
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Generator-based effect block (Effect.gen).
|
|
112
|
+
*/
|
|
113
|
+
interface StaticGeneratorNode extends StaticBaseNode {
|
|
114
|
+
readonly type: 'generator';
|
|
115
|
+
/** Variables yielded in the generator */
|
|
116
|
+
readonly yields: {
|
|
117
|
+
readonly variableName?: string | undefined;
|
|
118
|
+
readonly effect: StaticFlowNode;
|
|
119
|
+
}[];
|
|
120
|
+
/** Final return value */
|
|
121
|
+
readonly returnNode?: StaticFlowNode | undefined;
|
|
122
|
+
/** JSDoc description extracted from comments above the generator function */
|
|
123
|
+
readonly jsdocDescription?: string | undefined;
|
|
124
|
+
/** Structured JSDoc tags extracted from comments */
|
|
125
|
+
readonly jsdocTags?: JSDocTags | undefined;
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Pipe composition chain (effect.pipe(...)).
|
|
129
|
+
*/
|
|
130
|
+
interface StaticPipeNode extends StaticBaseNode {
|
|
131
|
+
readonly type: 'pipe';
|
|
132
|
+
/** The initial effect */
|
|
133
|
+
readonly initial: StaticFlowNode;
|
|
134
|
+
/** Pipe transformations in order */
|
|
135
|
+
readonly transformations: readonly StaticFlowNode[];
|
|
136
|
+
/** Type flow through the pipe chain (A, E, R at each step) */
|
|
137
|
+
readonly typeFlow?: readonly EffectTypeSignature[] | undefined;
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Concurrency mode for Effect.all / Effect.allWith.
|
|
141
|
+
*/
|
|
142
|
+
type ConcurrencyMode = 'sequential' | 'bounded' | 'unbounded' | number;
|
|
143
|
+
/**
|
|
144
|
+
* Parallel execution (Effect.all, Effect.allPar).
|
|
145
|
+
*/
|
|
146
|
+
interface StaticParallelNode extends StaticBaseNode {
|
|
147
|
+
readonly type: 'parallel';
|
|
148
|
+
/** Child effects running in parallel */
|
|
149
|
+
readonly children: readonly StaticFlowNode[];
|
|
150
|
+
/** Mode: sequential (all) or parallel (allPar) */
|
|
151
|
+
readonly mode: 'sequential' | 'parallel';
|
|
152
|
+
/** The callee (e.g., "Effect.all", "Effect.allPar") */
|
|
153
|
+
readonly callee: string;
|
|
154
|
+
/** Resolved concurrency: from options or inferred from mode (GAP 18) */
|
|
155
|
+
readonly concurrency?: ConcurrencyMode | undefined;
|
|
156
|
+
/** Request batching enabled (Effect.all with { batching: true }) */
|
|
157
|
+
readonly batching?: boolean | undefined;
|
|
158
|
+
/** Results discarded (Effect.all with { discard: true }) */
|
|
159
|
+
readonly discard?: boolean | undefined;
|
|
160
|
+
/** Labels for each parallel branch (from child displayNames) */
|
|
161
|
+
readonly branchLabels?: readonly string[] | undefined;
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Race execution (Effect.race, Effect.raceAll).
|
|
165
|
+
*/
|
|
166
|
+
interface StaticRaceNode extends StaticBaseNode {
|
|
167
|
+
readonly type: 'race';
|
|
168
|
+
/** Child effects racing */
|
|
169
|
+
readonly children: readonly StaticFlowNode[];
|
|
170
|
+
/** The callee */
|
|
171
|
+
readonly callee: string;
|
|
172
|
+
/** Labels for each race competitor */
|
|
173
|
+
readonly raceLabels?: readonly string[] | undefined;
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Error handling (catchAll, catchTag, orElse, etc.).
|
|
177
|
+
*/
|
|
178
|
+
interface StaticErrorHandlerNode extends StaticBaseNode {
|
|
179
|
+
readonly type: 'error-handler';
|
|
180
|
+
/** Type of handler: catchAll, catchTag, orElse, etc. */
|
|
181
|
+
readonly handlerType: 'catchAll' | 'catchTag' | 'catchAllCause' | 'catchIf' | 'catchSome' | 'catchSomeCause' | 'catchSomeDefect' | 'catchAllDefect' | 'catchTags' | 'orElse' | 'orElseFail' | 'orElseSucceed' | 'orDie' | 'orDieWith' | 'flip' | 'mapError' | 'mapErrorCause' | 'mapBoth' | 'sandbox' | 'unsandbox' | 'parallelErrors' | 'filterOrDie' | 'filterOrDieMessage' | 'filterOrElse' | 'filterOrFail' | 'match' | 'matchCause' | 'matchEffect' | 'matchCauseEffect' | 'firstSuccessOf' | 'ignore' | 'ignoreLogged' | 'eventually';
|
|
182
|
+
/** The effect being handled */
|
|
183
|
+
readonly source: StaticFlowNode;
|
|
184
|
+
/** The handler (recovery) effect */
|
|
185
|
+
readonly handler?: StaticFlowNode | undefined;
|
|
186
|
+
/** For catchTag, the error tag being caught */
|
|
187
|
+
readonly errorTag?: string | undefined;
|
|
188
|
+
/** For catchTags (object form), the error tags being caught */
|
|
189
|
+
readonly errorTags?: readonly string[] | undefined;
|
|
190
|
+
/** Edge label for the error path (e.g. "on DatabaseError") */
|
|
191
|
+
readonly errorEdgeLabel?: string | undefined;
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Schedule composition info (GAP 8).
|
|
195
|
+
*/
|
|
196
|
+
interface ScheduleInfo {
|
|
197
|
+
readonly baseStrategy: 'fixed' | 'exponential' | 'fibonacci' | 'spaced' | 'linear' | 'cron' | 'windowed' | 'duration' | 'elapsed' | 'delays' | 'once' | 'stop' | 'count' | 'custom';
|
|
198
|
+
readonly maxRetries?: number | 'unlimited' | undefined;
|
|
199
|
+
readonly initialDelay?: string | undefined;
|
|
200
|
+
readonly maxDelay?: string | undefined;
|
|
201
|
+
readonly jittered: boolean;
|
|
202
|
+
readonly conditions: readonly string[];
|
|
203
|
+
readonly estimatedMaxDuration?: string | undefined;
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Retry/Schedule operation.
|
|
207
|
+
*/
|
|
208
|
+
interface StaticRetryNode extends StaticBaseNode {
|
|
209
|
+
readonly type: 'retry';
|
|
210
|
+
/** The effect being retried */
|
|
211
|
+
readonly source: StaticFlowNode;
|
|
212
|
+
/** Schedule policy if statically determinable (expression text) */
|
|
213
|
+
readonly schedule?: string | undefined;
|
|
214
|
+
/** Parsed schedule when present (GAP 8 dedicated Schedule IR) */
|
|
215
|
+
readonly scheduleNode?: StaticFlowNode | undefined;
|
|
216
|
+
/** Whether it's a retryOrElse */
|
|
217
|
+
readonly hasFallback: boolean;
|
|
218
|
+
/** Decomposed schedule (GAP 8) */
|
|
219
|
+
readonly scheduleInfo?: ScheduleInfo | undefined;
|
|
220
|
+
/** Edge label for the retry path (e.g. "retry: exponential(100ms)") */
|
|
221
|
+
readonly retryEdgeLabel?: string | undefined;
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Timeout operation.
|
|
225
|
+
*/
|
|
226
|
+
interface StaticTimeoutNode extends StaticBaseNode {
|
|
227
|
+
readonly type: 'timeout';
|
|
228
|
+
/** The effect being timed out */
|
|
229
|
+
readonly source: StaticFlowNode;
|
|
230
|
+
/** Timeout duration if statically determinable */
|
|
231
|
+
readonly duration?: string | undefined;
|
|
232
|
+
/** Whether there's a fallback */
|
|
233
|
+
readonly hasFallback: boolean;
|
|
234
|
+
}
|
|
235
|
+
/**
|
|
236
|
+
* Resource acquisition (acquireRelease).
|
|
237
|
+
*/
|
|
238
|
+
interface StaticResourceNode extends StaticBaseNode {
|
|
239
|
+
readonly type: 'resource';
|
|
240
|
+
/** Acquisition effect */
|
|
241
|
+
readonly acquire: StaticFlowNode;
|
|
242
|
+
/** Release effect */
|
|
243
|
+
readonly release: StaticFlowNode;
|
|
244
|
+
/** Use effect */
|
|
245
|
+
readonly use?: StaticFlowNode | undefined;
|
|
246
|
+
}
|
|
247
|
+
/**
|
|
248
|
+
* Conditional execution (Effect.if, when, unless).
|
|
249
|
+
*/
|
|
250
|
+
interface StaticConditionalNode extends StaticBaseNode {
|
|
251
|
+
readonly type: 'conditional';
|
|
252
|
+
/** The condition as source string */
|
|
253
|
+
readonly condition: string;
|
|
254
|
+
/** Type of conditional */
|
|
255
|
+
readonly conditionalType: 'if' | 'when' | 'unless' | 'whenEffect' | 'whenFiberRef' | 'whenRef' | 'unlessEffect' | 'option' | 'either' | 'exit' | 'liftPredicate';
|
|
256
|
+
/** Branch when condition is true */
|
|
257
|
+
readonly onTrue: StaticFlowNode;
|
|
258
|
+
/** Branch when condition is false (if present) */
|
|
259
|
+
readonly onFalse?: StaticFlowNode | undefined;
|
|
260
|
+
/** Semantic label for the condition (e.g. "isAdmin") */
|
|
261
|
+
readonly conditionLabel?: string | undefined;
|
|
262
|
+
/** Label for the true branch edge */
|
|
263
|
+
readonly trueEdgeLabel?: string | undefined;
|
|
264
|
+
/** Label for the false branch edge */
|
|
265
|
+
readonly falseEdgeLabel?: string | undefined;
|
|
266
|
+
}
|
|
267
|
+
/**
|
|
268
|
+
* Decision node for raw `if`, ternaries, short-circuits, and `Step.decide`.
|
|
269
|
+
*/
|
|
270
|
+
interface StaticDecisionNode extends StaticBaseNode {
|
|
271
|
+
readonly type: 'decision';
|
|
272
|
+
/** Unique decision identifier */
|
|
273
|
+
readonly decisionId: string;
|
|
274
|
+
/** Human-readable label for the decision */
|
|
275
|
+
readonly label: string;
|
|
276
|
+
/** Condition expression source text */
|
|
277
|
+
readonly condition: string;
|
|
278
|
+
/** Origin of the decision construct */
|
|
279
|
+
readonly source: 'effect-flow' | 'raw-if' | 'raw-ternary' | 'raw-short-circuit';
|
|
280
|
+
/** Branch when condition is true */
|
|
281
|
+
readonly onTrue: readonly StaticFlowNode[];
|
|
282
|
+
/** Branch when condition is false (if present) */
|
|
283
|
+
readonly onFalse?: readonly StaticFlowNode[] | undefined;
|
|
284
|
+
}
|
|
285
|
+
/**
|
|
286
|
+
* A single case arm in a switch node.
|
|
287
|
+
*/
|
|
288
|
+
interface StaticSwitchCase {
|
|
289
|
+
/** Labels for this case (e.g. string/number literals) */
|
|
290
|
+
readonly labels: readonly string[];
|
|
291
|
+
/** Whether this is the default case */
|
|
292
|
+
readonly isDefault: boolean;
|
|
293
|
+
/** Body nodes for this case */
|
|
294
|
+
readonly body: readonly StaticFlowNode[];
|
|
295
|
+
}
|
|
296
|
+
/**
|
|
297
|
+
* Switch node for raw `switch` statements and `Step.branch`.
|
|
298
|
+
*/
|
|
299
|
+
interface StaticSwitchNode extends StaticBaseNode {
|
|
300
|
+
readonly type: 'switch';
|
|
301
|
+
/** Optional switch identifier */
|
|
302
|
+
readonly switchId?: string | undefined;
|
|
303
|
+
/** Expression being switched on */
|
|
304
|
+
readonly expression: string;
|
|
305
|
+
/** Case arms */
|
|
306
|
+
readonly cases: readonly StaticSwitchCase[];
|
|
307
|
+
/** Origin of the switch construct */
|
|
308
|
+
readonly source: 'effect-flow' | 'raw-js';
|
|
309
|
+
/** Whether a default case is present */
|
|
310
|
+
readonly hasDefault: boolean;
|
|
311
|
+
/** Whether any case falls through to the next */
|
|
312
|
+
readonly hasFallthrough: boolean;
|
|
313
|
+
}
|
|
314
|
+
/**
|
|
315
|
+
* Try/catch/finally node for raw exception handling.
|
|
316
|
+
*/
|
|
317
|
+
interface StaticTryCatchNode extends StaticBaseNode {
|
|
318
|
+
readonly type: 'try-catch';
|
|
319
|
+
/** Body of the try block */
|
|
320
|
+
readonly tryBody: readonly StaticFlowNode[];
|
|
321
|
+
/** Catch clause variable name */
|
|
322
|
+
readonly catchVariable?: string | undefined;
|
|
323
|
+
/** Body of the catch block */
|
|
324
|
+
readonly catchBody?: readonly StaticFlowNode[] | undefined;
|
|
325
|
+
/** Body of the finally block */
|
|
326
|
+
readonly finallyBody?: readonly StaticFlowNode[] | undefined;
|
|
327
|
+
/** Whether the try body contains a terminal statement (return/throw) */
|
|
328
|
+
readonly hasTerminalInTry: boolean;
|
|
329
|
+
}
|
|
330
|
+
/**
|
|
331
|
+
* Terminal node for `return`, `throw`, `break`, and `continue` statements.
|
|
332
|
+
*/
|
|
333
|
+
interface StaticTerminalNode extends StaticBaseNode {
|
|
334
|
+
readonly type: 'terminal';
|
|
335
|
+
/** Kind of terminal statement */
|
|
336
|
+
readonly terminalKind: 'return' | 'throw' | 'break' | 'continue';
|
|
337
|
+
/** Label for labeled break/continue */
|
|
338
|
+
readonly label?: string | undefined;
|
|
339
|
+
/** Value expression (e.g. the returned/thrown value) */
|
|
340
|
+
readonly value?: readonly StaticFlowNode[] | undefined;
|
|
341
|
+
}
|
|
342
|
+
/**
|
|
343
|
+
* Opaque node for unsupported or unanalyzable constructs.
|
|
344
|
+
*/
|
|
345
|
+
interface StaticOpaqueNode extends StaticBaseNode {
|
|
346
|
+
readonly type: 'opaque';
|
|
347
|
+
/** Reason why this construct could not be analyzed */
|
|
348
|
+
readonly reason: string;
|
|
349
|
+
/** Original source text of the construct */
|
|
350
|
+
readonly sourceText: string;
|
|
351
|
+
}
|
|
352
|
+
/**
|
|
353
|
+
* Cause module operation — construction or inspection of Effect Cause values.
|
|
354
|
+
*/
|
|
355
|
+
interface StaticCauseNode extends StaticBaseNode {
|
|
356
|
+
readonly type: 'cause';
|
|
357
|
+
/** The specific Cause operation */
|
|
358
|
+
readonly causeOp: 'fail' | 'die' | 'interrupt' | 'parallel' | 'sequential' | 'empty' | 'failures' | 'defects' | 'interruptors' | 'squash' | 'squashWith' | 'pretty' | 'flatten' | 'isDie' | 'isFailure' | 'isInterrupted' | 'isEmpty' | 'map' | 'filter' | 'other';
|
|
359
|
+
/** Whether this is a constructor (fail/die/interrupt/parallel/sequential/empty) */
|
|
360
|
+
readonly isConstructor: boolean;
|
|
361
|
+
/** For parallel/sequential: child cause nodes (GAP Cause structural traversal). */
|
|
362
|
+
readonly children?: readonly StaticFlowNode[] | undefined;
|
|
363
|
+
/** Cause kind classification */
|
|
364
|
+
readonly causeKind?: 'fail' | 'die' | 'interrupt' | 'mixed' | undefined;
|
|
365
|
+
}
|
|
366
|
+
/**
|
|
367
|
+
* Exit module operation — construction or inspection of Effect Exit values.
|
|
368
|
+
*/
|
|
369
|
+
interface StaticExitNode extends StaticBaseNode {
|
|
370
|
+
readonly type: 'exit';
|
|
371
|
+
/** The specific Exit operation */
|
|
372
|
+
readonly exitOp: 'succeed' | 'fail' | 'die' | 'interrupt' | 'void' | 'unit' | 'match' | 'isSuccess' | 'isFailure' | 'isInterrupted' | 'when' | 'whenEffect' | 'exists' | 'contains' | 'flatten' | 'map' | 'mapBoth' | 'mapError' | 'flatMap' | 'zipWith' | 'tap' | 'tapBoth' | 'tapError' | 'other';
|
|
373
|
+
/** Whether this is a constructor (succeed/fail/die/interrupt/void/unit) */
|
|
374
|
+
readonly isConstructor: boolean;
|
|
375
|
+
}
|
|
376
|
+
/**
|
|
377
|
+
* Schedule module operation — construction or composition of Schedule values (GAP 8 dedicated IR).
|
|
378
|
+
*/
|
|
379
|
+
interface StaticScheduleNode extends StaticBaseNode {
|
|
380
|
+
readonly type: 'schedule';
|
|
381
|
+
/** The specific Schedule operation */
|
|
382
|
+
readonly scheduleOp: 'exponential' | 'fibonacci' | 'spaced' | 'fixed' | 'linear' | 'cron' | 'windowed' | 'duration' | 'elapsed' | 'delays' | 'once' | 'stop' | 'count' | 'forever' | 'jittered' | 'andThen' | 'intersect' | 'union' | 'compose' | 'zipWith' | 'addDelay' | 'modifyDelay' | 'check' | 'resetAfter' | 'resetWhen' | 'ensure' | 'driver' | 'mapInput' | 'other';
|
|
383
|
+
/** Decomposed schedule (when parseable from expression text) */
|
|
384
|
+
readonly scheduleInfo?: ScheduleInfo | undefined;
|
|
385
|
+
}
|
|
386
|
+
/**
|
|
387
|
+
* Match module operation (Match.type / Match.when / Match.exhaustive etc.).
|
|
388
|
+
*/
|
|
389
|
+
interface StaticMatchNode extends StaticBaseNode {
|
|
390
|
+
readonly type: 'match';
|
|
391
|
+
/** The specific Match operation */
|
|
392
|
+
readonly matchOp: 'type' | 'tag' | 'value' | 'when' | 'whenOr' | 'whenAnd' | 'not' | 'is' | 'exhaustive' | 'orElse' | 'option' | 'either' | 'discriminator' | 'discriminatorsExhaustive' | 'tags' | 'tagsExhaustive' | 'withReturnType' | 'run' | 'other';
|
|
393
|
+
/** Tag names matched (for Match.tag, Match.when with tag literals, Match.tags) */
|
|
394
|
+
readonly matchedTags?: readonly string[] | undefined;
|
|
395
|
+
/** Whether this match arm makes the overall match exhaustive */
|
|
396
|
+
readonly isExhaustive: boolean;
|
|
397
|
+
}
|
|
398
|
+
/**
|
|
399
|
+
* Transformation step in a pipe chain (map, flatMap, andThen, tap, zip, as, etc.).
|
|
400
|
+
* These preserve the Effect channel but transform A, E, or R.
|
|
401
|
+
*/
|
|
402
|
+
interface StaticTransformNode extends StaticBaseNode {
|
|
403
|
+
readonly type: 'transform';
|
|
404
|
+
/** Specific transformation operation */
|
|
405
|
+
readonly transformType: 'map' | 'flatMap' | 'andThen' | 'tap' | 'tapBoth' | 'tapError' | 'tapErrorTag' | 'tapErrorCause' | 'tapDefect' | 'zipLeft' | 'zipRight' | 'zipWith' | 'zip' | 'as' | 'asVoid' | 'asSome' | 'asSomeError' | 'flatten' | 'ap' | 'negate' | 'merge' | 'other';
|
|
406
|
+
/**
|
|
407
|
+
* Whether this is an effectful transformation
|
|
408
|
+
* (e.g. flatMap/andThen produce a new Effect, map does not).
|
|
409
|
+
*/
|
|
410
|
+
readonly isEffectful: boolean;
|
|
411
|
+
/** The source/input effect (if extractable from args, undefined for curried forms). */
|
|
412
|
+
readonly source?: StaticFlowNode | undefined;
|
|
413
|
+
/** The transformation function text (if simple enough to extract). */
|
|
414
|
+
readonly fn?: string | undefined;
|
|
415
|
+
/** Input type signature (before transform) */
|
|
416
|
+
readonly inputType?: EffectTypeSignature | undefined;
|
|
417
|
+
/** Output type signature (after transform) */
|
|
418
|
+
readonly outputType?: EffectTypeSignature | undefined;
|
|
419
|
+
}
|
|
420
|
+
/**
|
|
421
|
+
* Loop structure (forEach, loop).
|
|
422
|
+
*/
|
|
423
|
+
interface StaticLoopNode extends StaticBaseNode {
|
|
424
|
+
readonly type: 'loop';
|
|
425
|
+
/** Type of loop / collection operation */
|
|
426
|
+
readonly loopType: 'forEach' | 'filter' | 'filterMap' | 'partition' | 'reduce' | 'validate' | 'replicate' | 'dropUntil' | 'dropWhile' | 'takeUntil' | 'takeWhile' | 'every' | 'exists' | 'findFirst' | 'head' | 'mergeAll' | 'loop' | 'for' | 'forOf' | 'forIn' | 'while' | 'doWhile';
|
|
427
|
+
/** The iteration source */
|
|
428
|
+
readonly iterSource?: string | undefined;
|
|
429
|
+
/** Body of the loop */
|
|
430
|
+
readonly body: StaticFlowNode;
|
|
431
|
+
/** Whether the loop contains an early exit (break/return) */
|
|
432
|
+
readonly hasEarlyExit?: boolean | undefined;
|
|
433
|
+
/** Yield expressions in the loop header (e.g. for-of with yield* in initializer) */
|
|
434
|
+
readonly headerYields?: readonly StaticFlowNode[] | undefined;
|
|
435
|
+
/** Iteration variable name (for for-of/for-in loops) */
|
|
436
|
+
readonly iterVariable?: string | undefined;
|
|
437
|
+
}
|
|
438
|
+
/**
|
|
439
|
+
* Layer lifecycle (GAP 2).
|
|
440
|
+
*/
|
|
441
|
+
type LayerLifecycle = 'default' | 'fresh' | 'scoped' | 'memoized';
|
|
442
|
+
/**
|
|
443
|
+
* Layer/service provision.
|
|
444
|
+
*/
|
|
445
|
+
interface StaticLayerNode extends StaticBaseNode {
|
|
446
|
+
readonly type: 'layer';
|
|
447
|
+
/** Layer operations */
|
|
448
|
+
readonly operations: readonly StaticFlowNode[];
|
|
449
|
+
/** Whether this is a merged layer */
|
|
450
|
+
readonly isMerged: boolean;
|
|
451
|
+
/** Service tags this layer provides (GAP 2) */
|
|
452
|
+
readonly provides?: readonly string[] | undefined;
|
|
453
|
+
/** Service tags this layer requires (GAP 2) */
|
|
454
|
+
readonly requires?: readonly string[] | undefined;
|
|
455
|
+
/** Lifecycle (GAP 2) */
|
|
456
|
+
readonly lifecycle?: LayerLifecycle | undefined;
|
|
457
|
+
/** True when this layer is or contains Layer.MemoMap (GAP dedicated memo-map analysis). */
|
|
458
|
+
readonly isMemoMap?: boolean | undefined;
|
|
459
|
+
}
|
|
460
|
+
/**
|
|
461
|
+
* Stream operator in a pipeline (GAP 5).
|
|
462
|
+
*/
|
|
463
|
+
interface StreamOperatorInfo {
|
|
464
|
+
readonly operation: string;
|
|
465
|
+
readonly isEffectful: boolean;
|
|
466
|
+
readonly estimatedCardinality?: 'same' | 'fewer' | 'more' | 'unknown' | undefined;
|
|
467
|
+
readonly category?: 'constructor' | 'transform' | 'filter' | 'windowing' | 'merge' | 'broadcasting' | 'halting' | 'text' | 'backpressure' | 'error' | 'resource' | 'context' | 'sink' | 'conversion' | 'channel' | 'other' | undefined;
|
|
468
|
+
/** Windowing: size for grouped/groupedWithin/sliding (GAP 2 windowing detail). */
|
|
469
|
+
readonly windowSize?: number | undefined;
|
|
470
|
+
/** Windowing: stride/step for sliding (GAP 2 windowing detail). */
|
|
471
|
+
readonly stride?: number | undefined;
|
|
472
|
+
}
|
|
473
|
+
/**
|
|
474
|
+
* Stream pipeline (GAP 5).
|
|
475
|
+
*/
|
|
476
|
+
interface StaticStreamNode extends StaticBaseNode {
|
|
477
|
+
readonly type: 'stream';
|
|
478
|
+
readonly source: StaticFlowNode;
|
|
479
|
+
readonly pipeline: readonly StreamOperatorInfo[];
|
|
480
|
+
readonly sink?: string | undefined;
|
|
481
|
+
readonly backpressureStrategy?: 'buffer' | 'drop' | 'sliding' | undefined;
|
|
482
|
+
/** Classified constructor type when this is a Stream.from* / Stream.make / etc. */
|
|
483
|
+
readonly constructorType?: 'fromIterable' | 'fromArray' | 'fromQueue' | 'fromPubSub' | 'fromEffect' | 'fromAsyncIterable' | 'fromReadableStream' | 'fromEventListener' | 'fromSchedule' | 'range' | 'tick' | 'iterate' | 'unfold' | 'make' | 'empty' | 'never' | 'succeed' | 'fail' | 'fromMailbox' | 'fromSubscriptionRef' | 'other' | undefined;
|
|
484
|
+
}
|
|
485
|
+
/**
|
|
486
|
+
* Concurrency primitive (Queue, PubSub, Deferred, Semaphore, Mailbox, Latch, FiberSet, FiberMap, FiberHandle, RateLimiter, SubscriptionRef) - GAP 6.
|
|
487
|
+
*/
|
|
488
|
+
interface StaticConcurrencyPrimitiveNode extends StaticBaseNode {
|
|
489
|
+
readonly type: 'concurrency-primitive';
|
|
490
|
+
readonly primitive: 'queue' | 'pubsub' | 'deferred' | 'semaphore' | 'mailbox' | 'latch' | 'fiberHandle' | 'fiberSet' | 'fiberMap' | 'rateLimiter' | 'cache' | 'scopedCache' | 'rcRef' | 'rcMap' | 'reloadable' | 'subscriptionRef';
|
|
491
|
+
readonly operation: 'create' | 'offer' | 'take' | 'takeAll' | 'publish' | 'subscribe' | 'await' | 'succeed' | 'fail' | 'withPermit' | 'run' | 'open' | 'close' | 'release' | 'available' | 'get' | 'set' | 'invalidate' | 'contains' | 'update' | 'reload' | 'end' | 'toStream' | 'changes';
|
|
492
|
+
readonly strategy?: 'bounded' | 'unbounded' | 'sliding' | 'dropping' | undefined;
|
|
493
|
+
readonly capacity?: number | undefined;
|
|
494
|
+
/** For Semaphore take(n) / release(n): permit count when first arg is numeric literal (GAP 13). */
|
|
495
|
+
readonly permitCount?: number | undefined;
|
|
496
|
+
readonly source?: StaticFlowNode | undefined;
|
|
497
|
+
/** Lifecycle options (e.g. FiberHandle.run { onlyIfMissing: true }) */
|
|
498
|
+
readonly lifecycleOptions?: Record<string, unknown> | undefined;
|
|
499
|
+
}
|
|
500
|
+
/**
|
|
501
|
+
* Fiber operation (fork, join, interrupt) - GAP 1.
|
|
502
|
+
*/
|
|
503
|
+
interface StaticFiberNode extends StaticBaseNode {
|
|
504
|
+
readonly type: 'fiber';
|
|
505
|
+
readonly operation: 'fork' | 'forkScoped' | 'forkDaemon' | 'forkAll' | 'forkIn' | 'forkWithErrorHandler' | 'join' | 'await' | 'interrupt' | 'interruptFork' | 'poll' | 'status' | 'all' | 'awaitAll' | 'children' | 'dump' | 'scoped' | 'inheritAll' | 'map' | 'mapEffect' | 'mapFiber' | 'roots' | 'getCurrentFiber';
|
|
506
|
+
readonly fiberSource?: StaticFlowNode | undefined;
|
|
507
|
+
readonly joinPoint?: string | undefined;
|
|
508
|
+
readonly isScoped: boolean;
|
|
509
|
+
readonly isDaemon: boolean;
|
|
510
|
+
/** Scope context: 'safe' when fiber is inside Effect.scoped or after Scope.make */
|
|
511
|
+
readonly scopeContext?: string | undefined;
|
|
512
|
+
}
|
|
513
|
+
/**
|
|
514
|
+
* Interruption region (interruptible/uninterruptible/mask/onInterrupt).
|
|
515
|
+
*/
|
|
516
|
+
interface StaticInterruptionNode extends StaticBaseNode {
|
|
517
|
+
readonly type: 'interruption';
|
|
518
|
+
/** The interruption operation */
|
|
519
|
+
readonly interruptionType: 'interrupt' | 'interruptWith' | 'interruptible' | 'uninterruptible' | 'interruptibleMask' | 'uninterruptibleMask' | 'onInterrupt' | 'disconnect' | 'allowInterrupt';
|
|
520
|
+
/** The wrapped effect (for interruptible/uninterruptible/mask) */
|
|
521
|
+
readonly source?: StaticFlowNode | undefined;
|
|
522
|
+
/** The interrupt handler (for onInterrupt) */
|
|
523
|
+
readonly handler?: StaticFlowNode | undefined;
|
|
524
|
+
}
|
|
525
|
+
/**
|
|
526
|
+
* Unknown or unanalyzable code block.
|
|
527
|
+
*/
|
|
528
|
+
interface StaticUnknownNode extends StaticBaseNode {
|
|
529
|
+
readonly type: 'unknown';
|
|
530
|
+
/** Reason why this couldn't be analyzed */
|
|
531
|
+
readonly reason: string;
|
|
532
|
+
/** The source code that couldn't be analyzed */
|
|
533
|
+
readonly sourceCode?: string | undefined;
|
|
534
|
+
}
|
|
535
|
+
/** Channel operator or constructor (improve.md §8). */
|
|
536
|
+
interface ChannelOperatorInfo {
|
|
537
|
+
readonly operation: string;
|
|
538
|
+
readonly category?: 'constructor' | 'transform' | 'pipe' | 'other' | undefined;
|
|
539
|
+
}
|
|
540
|
+
/**
|
|
541
|
+
* Channel pipeline node (improve.md §8 dedicated Channel analysis).
|
|
542
|
+
*/
|
|
543
|
+
interface StaticChannelNode extends StaticBaseNode {
|
|
544
|
+
readonly type: 'channel';
|
|
545
|
+
readonly source?: StaticFlowNode | undefined;
|
|
546
|
+
readonly pipeline: readonly ChannelOperatorInfo[];
|
|
547
|
+
}
|
|
548
|
+
/** Sink operator (improve.md §8). */
|
|
549
|
+
interface SinkOperatorInfo {
|
|
550
|
+
readonly operation: string;
|
|
551
|
+
readonly category?: 'constructor' | 'transform' | 'other' | undefined;
|
|
552
|
+
}
|
|
553
|
+
/**
|
|
554
|
+
* Sink pipeline node (improve.md §8 dedicated Sink analysis).
|
|
555
|
+
*/
|
|
556
|
+
interface StaticSinkNode extends StaticBaseNode {
|
|
557
|
+
readonly type: 'sink';
|
|
558
|
+
readonly source?: StaticFlowNode | undefined;
|
|
559
|
+
readonly pipeline: readonly SinkOperatorInfo[];
|
|
560
|
+
}
|
|
561
|
+
/**
|
|
562
|
+
* Union of all static flow node types.
|
|
563
|
+
*/
|
|
564
|
+
type StaticFlowNode = StaticEffectNode | StaticGeneratorNode | StaticPipeNode | StaticParallelNode | StaticRaceNode | StaticErrorHandlerNode | StaticRetryNode | StaticTimeoutNode | StaticResourceNode | StaticConditionalNode | StaticLoopNode | StaticCauseNode | StaticExitNode | StaticScheduleNode | StaticMatchNode | StaticTransformNode | StaticLayerNode | StaticStreamNode | StaticChannelNode | StaticSinkNode | StaticConcurrencyPrimitiveNode | StaticFiberNode | StaticInterruptionNode | StaticDecisionNode | StaticSwitchNode | StaticTryCatchNode | StaticTerminalNode | StaticOpaqueNode | StaticUnknownNode;
|
|
565
|
+
/**
|
|
566
|
+
* Root node representing the analyzed effect program.
|
|
567
|
+
*/
|
|
568
|
+
interface StaticEffectProgram extends StaticBaseNode {
|
|
569
|
+
readonly type: 'program';
|
|
570
|
+
/** Name of the program (from file name or variable) */
|
|
571
|
+
readonly programName: string;
|
|
572
|
+
/** Entry point: gen, direct, pipe, run, workflow-execute, or class */
|
|
573
|
+
readonly source: 'generator' | 'direct' | 'pipe' | 'run' | 'workflow-execute' | 'class' | 'classProperty' | 'classMethod';
|
|
574
|
+
/** Discovery confidence based on alias/path resolution vs heuristics */
|
|
575
|
+
readonly discoveryConfidence?: 'high' | 'medium' | 'low';
|
|
576
|
+
/** Best-effort reason used to classify this as an Effect program */
|
|
577
|
+
readonly discoveryReason?: string | undefined;
|
|
578
|
+
/** The root effect nodes */
|
|
579
|
+
readonly children: readonly StaticFlowNode[];
|
|
580
|
+
/** Dependencies (services required) */
|
|
581
|
+
readonly dependencies: readonly DependencyInfo[];
|
|
582
|
+
/** Error types */
|
|
583
|
+
readonly errorTypes: readonly string[];
|
|
584
|
+
/** Full type signature of the program (A, E, R) */
|
|
585
|
+
readonly typeSignature?: EffectTypeSignature | undefined;
|
|
586
|
+
/** All service requirements across the program */
|
|
587
|
+
readonly requiredServices?: ServiceRequirement[] | undefined;
|
|
588
|
+
/** Description */
|
|
589
|
+
readonly description?: string | undefined;
|
|
590
|
+
/** JSDoc description extracted from comments above the program */
|
|
591
|
+
readonly jsdocDescription?: string | undefined;
|
|
592
|
+
/** Structured JSDoc tags extracted from comments */
|
|
593
|
+
readonly jsdocTags?: JSDocTags | undefined;
|
|
594
|
+
}
|
|
595
|
+
/**
|
|
596
|
+
* Information about a dependency/service.
|
|
597
|
+
*/
|
|
598
|
+
interface DependencyInfo {
|
|
599
|
+
readonly name: string;
|
|
600
|
+
readonly typeSignature?: string | undefined;
|
|
601
|
+
readonly isLayer: boolean;
|
|
602
|
+
}
|
|
603
|
+
/**
|
|
604
|
+
* Effect Type Signature - A, E, R parameters
|
|
605
|
+
*/
|
|
606
|
+
interface EffectTypeSignature {
|
|
607
|
+
/** Success type (A) */
|
|
608
|
+
readonly successType: string;
|
|
609
|
+
/** Error type (E) */
|
|
610
|
+
readonly errorType: string;
|
|
611
|
+
/** Requirements/Context type (R) */
|
|
612
|
+
readonly requirementsType: string;
|
|
613
|
+
/** Whether the type was successfully extracted */
|
|
614
|
+
readonly isInferred: boolean;
|
|
615
|
+
/** Confidence level of the type extraction */
|
|
616
|
+
readonly typeConfidence: 'declared' | 'inferred' | 'unknown';
|
|
617
|
+
/** Raw type string from TypeScript */
|
|
618
|
+
readonly rawTypeString?: string;
|
|
619
|
+
}
|
|
620
|
+
/** Stream type args — Stream<A, E, R> (21.3 type extraction) */
|
|
621
|
+
interface StreamTypeSignature {
|
|
622
|
+
readonly successType: string;
|
|
623
|
+
readonly errorType: string;
|
|
624
|
+
readonly requirementsType: string;
|
|
625
|
+
readonly rawTypeString?: string;
|
|
626
|
+
}
|
|
627
|
+
/** Layer type args — Layer<ROut, E, RIn> (provides, error, requires) (21.3 type extraction) */
|
|
628
|
+
interface LayerTypeSignature {
|
|
629
|
+
readonly providedType: string;
|
|
630
|
+
readonly errorType: string;
|
|
631
|
+
readonly requiredType: string;
|
|
632
|
+
readonly rawTypeString?: string;
|
|
633
|
+
}
|
|
634
|
+
/** Schedule type args — Schedule<Out, In, R> (21.3 type extraction) */
|
|
635
|
+
interface ScheduleTypeSignature {
|
|
636
|
+
readonly outputType: string;
|
|
637
|
+
readonly inputType: string;
|
|
638
|
+
readonly requirementsType: string;
|
|
639
|
+
readonly rawTypeString?: string;
|
|
640
|
+
}
|
|
641
|
+
/** Cause type args — Cause<E> (21.3 type extraction) */
|
|
642
|
+
interface CauseTypeSignature {
|
|
643
|
+
readonly errorType: string;
|
|
644
|
+
readonly rawTypeString?: string;
|
|
645
|
+
}
|
|
646
|
+
/**
|
|
647
|
+
* Service requirement extracted from Context type
|
|
648
|
+
*/
|
|
649
|
+
interface ServiceRequirement {
|
|
650
|
+
/** Service identifier (tag key) */
|
|
651
|
+
readonly serviceId: string;
|
|
652
|
+
/** Service type name */
|
|
653
|
+
readonly serviceType: string;
|
|
654
|
+
/** Where this requirement originates */
|
|
655
|
+
readonly requiredAt: SourceLocation;
|
|
656
|
+
}
|
|
657
|
+
/**
|
|
658
|
+
* Complete static Effect IR.
|
|
659
|
+
*/
|
|
660
|
+
interface StaticEffectIR {
|
|
661
|
+
readonly root: StaticEffectProgram;
|
|
662
|
+
readonly metadata: StaticAnalysisMetadata;
|
|
663
|
+
readonly references: ReadonlyMap<string, StaticEffectIR>;
|
|
664
|
+
}
|
|
665
|
+
/**
|
|
666
|
+
* Service interface shape extracted from Context.Tag / Effect.Service class (GAP service interface tracking).
|
|
667
|
+
*/
|
|
668
|
+
interface ServiceDefinition {
|
|
669
|
+
/** Tag/service identifier (class name or tag string). */
|
|
670
|
+
readonly tagId: string;
|
|
671
|
+
/** Method names from the service interface type. */
|
|
672
|
+
readonly methods: readonly string[];
|
|
673
|
+
/** Property names (non-callable members) from the service interface type. */
|
|
674
|
+
readonly properties: readonly string[];
|
|
675
|
+
/** Whether class implements [Equal.symbol] */
|
|
676
|
+
readonly hasCustomEquality?: boolean | undefined;
|
|
677
|
+
/** Whether class implements [Hash.symbol] */
|
|
678
|
+
readonly hasCustomHash?: boolean | undefined;
|
|
679
|
+
}
|
|
680
|
+
/**
|
|
681
|
+
* Metadata about the static analysis.
|
|
682
|
+
*/
|
|
683
|
+
interface StaticAnalysisMetadata {
|
|
684
|
+
readonly analyzedAt: number;
|
|
685
|
+
readonly filePath: string;
|
|
686
|
+
readonly tsVersion?: string | undefined;
|
|
687
|
+
readonly warnings: readonly AnalysisWarning[];
|
|
688
|
+
readonly stats: AnalysisStats;
|
|
689
|
+
/** Service interface shapes (methods/properties) from Context.Tag/Effect.Service in this file. */
|
|
690
|
+
readonly serviceDefinitions?: readonly ServiceDefinition[] | undefined;
|
|
691
|
+
}
|
|
692
|
+
/**
|
|
693
|
+
* Warning generated during analysis.
|
|
694
|
+
*/
|
|
695
|
+
interface AnalysisWarning {
|
|
696
|
+
readonly code: string;
|
|
697
|
+
readonly message: string;
|
|
698
|
+
readonly location?: SourceLocation | undefined;
|
|
699
|
+
}
|
|
700
|
+
/**
|
|
701
|
+
* Statistics about the analysis.
|
|
702
|
+
*/
|
|
703
|
+
interface AnalysisStats {
|
|
704
|
+
totalEffects: number;
|
|
705
|
+
parallelCount: number;
|
|
706
|
+
raceCount: number;
|
|
707
|
+
errorHandlerCount: number;
|
|
708
|
+
retryCount: number;
|
|
709
|
+
timeoutCount: number;
|
|
710
|
+
resourceCount: number;
|
|
711
|
+
loopCount: number;
|
|
712
|
+
conditionalCount: number;
|
|
713
|
+
layerCount: number;
|
|
714
|
+
interruptionCount: number;
|
|
715
|
+
unknownCount: number;
|
|
716
|
+
decisionCount: number;
|
|
717
|
+
switchCount: number;
|
|
718
|
+
tryCatchCount: number;
|
|
719
|
+
terminalCount: number;
|
|
720
|
+
opaqueCount: number;
|
|
721
|
+
}
|
|
722
|
+
type DiagramReadabilityBand = 'good' | 'ok' | 'noisy';
|
|
723
|
+
interface DiagramQualityMetrics {
|
|
724
|
+
readonly stepCountDetailed: number;
|
|
725
|
+
readonly stepCountSummary: number;
|
|
726
|
+
readonly collapsedGroupsSummary: number;
|
|
727
|
+
readonly logRatio: number;
|
|
728
|
+
readonly sideEffectRatio: number;
|
|
729
|
+
readonly anonymousNodeCount: number;
|
|
730
|
+
readonly anonymousRatio: number;
|
|
731
|
+
readonly unknownNodeCount: number;
|
|
732
|
+
readonly serviceCallCount: number;
|
|
733
|
+
readonly namedServiceCallRatio: number;
|
|
734
|
+
readonly pipeChainCount: number;
|
|
735
|
+
readonly maxPipeChainLength: number;
|
|
736
|
+
}
|
|
737
|
+
interface DiagramQuality {
|
|
738
|
+
readonly score: number;
|
|
739
|
+
readonly band: DiagramReadabilityBand;
|
|
740
|
+
readonly metrics: DiagramQualityMetrics;
|
|
741
|
+
readonly reasons: readonly string[];
|
|
742
|
+
readonly tips: readonly string[];
|
|
743
|
+
}
|
|
744
|
+
interface DiagramTopOffenderEntry {
|
|
745
|
+
readonly filePath: string;
|
|
746
|
+
readonly metricValue: number;
|
|
747
|
+
readonly tip: string;
|
|
748
|
+
}
|
|
749
|
+
interface DiagramTopOffendersReport {
|
|
750
|
+
readonly largestPrograms: readonly DiagramTopOffenderEntry[];
|
|
751
|
+
readonly mostAnonymousNodes: readonly DiagramTopOffenderEntry[];
|
|
752
|
+
readonly mostUnknownNodes: readonly DiagramTopOffenderEntry[];
|
|
753
|
+
readonly highestLogRatio: readonly DiagramTopOffenderEntry[];
|
|
754
|
+
}
|
|
755
|
+
interface DiagramQualityWithFile {
|
|
756
|
+
readonly filePath: string;
|
|
757
|
+
readonly quality: DiagramQuality;
|
|
758
|
+
}
|
|
759
|
+
/**
|
|
760
|
+
* Options for the static analyzer.
|
|
761
|
+
*/
|
|
762
|
+
interface AnalyzerOptions {
|
|
763
|
+
readonly tsConfigPath?: string | undefined;
|
|
764
|
+
readonly resolveReferences?: boolean | undefined;
|
|
765
|
+
readonly maxReferenceDepth?: number | undefined;
|
|
766
|
+
readonly includeLocations?: boolean | undefined;
|
|
767
|
+
readonly assumeImported?: boolean | undefined;
|
|
768
|
+
/** Enable effect-workflow patterns (Workflow.make / Workflow.run). Use the "effect-workflow" entrypoint for this. */
|
|
769
|
+
readonly enableEffectWorkflow?: boolean | undefined;
|
|
770
|
+
/** Optional path to known Effect internals root; local/relative imports under this path are treated as Effect-like (improve.md §1). */
|
|
771
|
+
readonly knownEffectInternalsRoot?: string | undefined;
|
|
772
|
+
/** Optional minimum confidence threshold for discovered programs. */
|
|
773
|
+
readonly minDiscoveryConfidence?: 'low' | 'medium' | 'high' | undefined;
|
|
774
|
+
/** When true, only keep discovered programs whose roots are exported (or top-level run statements). */
|
|
775
|
+
readonly onlyExportedPrograms?: boolean | undefined;
|
|
776
|
+
/** Enable effect-flow analysis for raw control-flow constructs (if/switch/try-catch/loops). */
|
|
777
|
+
readonly enableEffectFlow?: boolean | undefined;
|
|
778
|
+
}
|
|
779
|
+
/**
|
|
780
|
+
* Errors that can occur during analysis.
|
|
781
|
+
*/
|
|
782
|
+
declare class AnalysisError extends Error {
|
|
783
|
+
readonly code: string;
|
|
784
|
+
readonly location?: SourceLocation | undefined;
|
|
785
|
+
constructor(code: string, message: string, location?: SourceLocation);
|
|
786
|
+
}
|
|
787
|
+
/**
|
|
788
|
+
* A single execution path through the effect program.
|
|
789
|
+
*/
|
|
790
|
+
interface EffectPath {
|
|
791
|
+
readonly id: string;
|
|
792
|
+
readonly description: string;
|
|
793
|
+
readonly steps: readonly PathStepRef[];
|
|
794
|
+
readonly conditions: readonly PathCondition[];
|
|
795
|
+
readonly hasLoops: boolean;
|
|
796
|
+
readonly hasUnresolvedRefs: boolean;
|
|
797
|
+
}
|
|
798
|
+
/**
|
|
799
|
+
* Reference to a step in a path.
|
|
800
|
+
*/
|
|
801
|
+
interface PathStepRef {
|
|
802
|
+
readonly nodeId: string;
|
|
803
|
+
readonly name?: string | undefined;
|
|
804
|
+
readonly repeated: boolean;
|
|
805
|
+
}
|
|
806
|
+
/**
|
|
807
|
+
* A condition for a path.
|
|
808
|
+
*/
|
|
809
|
+
interface PathCondition {
|
|
810
|
+
readonly expression: string;
|
|
811
|
+
readonly mustBe: boolean;
|
|
812
|
+
readonly location?: SourceLocation | undefined;
|
|
813
|
+
}
|
|
814
|
+
/**
|
|
815
|
+
* Complexity metrics for an effect program.
|
|
816
|
+
*/
|
|
817
|
+
interface ComplexityMetrics {
|
|
818
|
+
readonly cyclomaticComplexity: number;
|
|
819
|
+
readonly pathCount: number | 'unbounded';
|
|
820
|
+
readonly maxDepth: number;
|
|
821
|
+
readonly maxParallelBreadth: number;
|
|
822
|
+
readonly decisionPoints: number;
|
|
823
|
+
readonly cognitiveComplexity: number;
|
|
824
|
+
}
|
|
825
|
+
/**
|
|
826
|
+
* Complexity thresholds.
|
|
827
|
+
*/
|
|
828
|
+
interface ComplexityThresholds {
|
|
829
|
+
readonly cyclomaticWarning: number;
|
|
830
|
+
readonly cyclomaticError: number;
|
|
831
|
+
readonly pathCountWarning: number;
|
|
832
|
+
readonly maxDepthWarning: number;
|
|
833
|
+
}
|
|
834
|
+
/**
|
|
835
|
+
* Test coverage matrix.
|
|
836
|
+
*/
|
|
837
|
+
interface TestMatrix {
|
|
838
|
+
readonly paths: readonly TestPath[];
|
|
839
|
+
readonly conditions: readonly TestCondition[];
|
|
840
|
+
readonly summary: TestMatrixSummary;
|
|
841
|
+
}
|
|
842
|
+
/**
|
|
843
|
+
* A path in the test matrix.
|
|
844
|
+
*/
|
|
845
|
+
interface TestPath {
|
|
846
|
+
readonly id: string;
|
|
847
|
+
readonly suggestedTestName: string;
|
|
848
|
+
readonly description: string;
|
|
849
|
+
readonly setupConditions: readonly string[];
|
|
850
|
+
readonly expectedSteps: readonly string[];
|
|
851
|
+
readonly priority: 'high' | 'medium' | 'low';
|
|
852
|
+
}
|
|
853
|
+
/**
|
|
854
|
+
* A condition affecting tests.
|
|
855
|
+
*/
|
|
856
|
+
interface TestCondition {
|
|
857
|
+
readonly expression: string;
|
|
858
|
+
readonly affectedPathsWhenTrue: readonly string[];
|
|
859
|
+
readonly affectedPathsWhenFalse: readonly string[];
|
|
860
|
+
}
|
|
861
|
+
/**
|
|
862
|
+
* Test matrix summary.
|
|
863
|
+
*/
|
|
864
|
+
interface TestMatrixSummary {
|
|
865
|
+
readonly totalPaths: number;
|
|
866
|
+
readonly highPriorityPaths: number;
|
|
867
|
+
readonly totalConditions: number;
|
|
868
|
+
readonly minTestsForCoverage: number;
|
|
869
|
+
}
|
|
870
|
+
declare const isStaticEffectNode: (node: StaticFlowNode) => node is StaticEffectNode;
|
|
871
|
+
declare const isStaticGeneratorNode: (node: StaticFlowNode) => node is StaticGeneratorNode;
|
|
872
|
+
declare const isStaticPipeNode: (node: StaticFlowNode) => node is StaticPipeNode;
|
|
873
|
+
declare const isStaticParallelNode: (node: StaticFlowNode) => node is StaticParallelNode;
|
|
874
|
+
declare const isStaticRaceNode: (node: StaticFlowNode) => node is StaticRaceNode;
|
|
875
|
+
declare const isStaticErrorHandlerNode: (node: StaticFlowNode) => node is StaticErrorHandlerNode;
|
|
876
|
+
declare const isStaticRetryNode: (node: StaticFlowNode) => node is StaticRetryNode;
|
|
877
|
+
declare const isStaticTimeoutNode: (node: StaticFlowNode) => node is StaticTimeoutNode;
|
|
878
|
+
declare const isStaticResourceNode: (node: StaticFlowNode) => node is StaticResourceNode;
|
|
879
|
+
declare const isStaticConditionalNode: (node: StaticFlowNode) => node is StaticConditionalNode;
|
|
880
|
+
declare const isStaticLoopNode: (node: StaticFlowNode) => node is StaticLoopNode;
|
|
881
|
+
declare const isStaticLayerNode: (node: StaticFlowNode) => node is StaticLayerNode;
|
|
882
|
+
declare const isStaticCauseNode: (node: StaticFlowNode) => node is StaticCauseNode;
|
|
883
|
+
declare const isStaticExitNode: (node: StaticFlowNode) => node is StaticExitNode;
|
|
884
|
+
declare const isStaticScheduleNode: (node: StaticFlowNode) => node is StaticScheduleNode;
|
|
885
|
+
declare const isStaticMatchNode: (node: StaticFlowNode) => node is StaticMatchNode;
|
|
886
|
+
declare const isStaticTransformNode: (node: StaticFlowNode) => node is StaticTransformNode;
|
|
887
|
+
declare const isStaticStreamNode: (node: StaticFlowNode) => node is StaticStreamNode;
|
|
888
|
+
declare const isStaticConcurrencyPrimitiveNode: (node: StaticFlowNode) => node is StaticConcurrencyPrimitiveNode;
|
|
889
|
+
declare const isStaticFiberNode: (node: StaticFlowNode) => node is StaticFiberNode;
|
|
890
|
+
declare const isStaticUnknownNode: (node: StaticFlowNode) => node is StaticUnknownNode;
|
|
891
|
+
/**
|
|
892
|
+
* Options for JSON output rendering.
|
|
893
|
+
*/
|
|
894
|
+
interface JSONRenderOptions {
|
|
895
|
+
readonly pretty: boolean;
|
|
896
|
+
readonly includeMetadata: boolean;
|
|
897
|
+
readonly compact: boolean;
|
|
898
|
+
}
|
|
899
|
+
/**
|
|
900
|
+
* Style definitions for Mermaid diagram output.
|
|
901
|
+
*/
|
|
902
|
+
interface MermaidStyles {
|
|
903
|
+
readonly effect: string;
|
|
904
|
+
readonly generator: string;
|
|
905
|
+
readonly pipe: string;
|
|
906
|
+
readonly parallel: string;
|
|
907
|
+
readonly race: string;
|
|
908
|
+
readonly errorHandler: string;
|
|
909
|
+
readonly retry: string;
|
|
910
|
+
readonly timeout: string;
|
|
911
|
+
readonly resource: string;
|
|
912
|
+
readonly conditional: string;
|
|
913
|
+
readonly loop: string;
|
|
914
|
+
readonly layer: string;
|
|
915
|
+
readonly stream?: string | undefined;
|
|
916
|
+
readonly concurrencyPrimitive?: string | undefined;
|
|
917
|
+
readonly fiber?: string | undefined;
|
|
918
|
+
readonly unknown: string;
|
|
919
|
+
/** Start node style */
|
|
920
|
+
readonly start?: string | undefined;
|
|
921
|
+
/** End node style */
|
|
922
|
+
readonly end?: string | undefined;
|
|
923
|
+
/** Decision node style */
|
|
924
|
+
readonly decision?: string | undefined;
|
|
925
|
+
/** Switch node style */
|
|
926
|
+
readonly switch?: string | undefined;
|
|
927
|
+
/** Try/catch node style */
|
|
928
|
+
readonly tryCatch?: string | undefined;
|
|
929
|
+
/** Terminal node style */
|
|
930
|
+
readonly terminal?: string | undefined;
|
|
931
|
+
/** Opaque node style */
|
|
932
|
+
readonly opaque?: string | undefined;
|
|
933
|
+
/** Cause node style */
|
|
934
|
+
readonly cause?: string | undefined;
|
|
935
|
+
/** Exit node style */
|
|
936
|
+
readonly exit?: string | undefined;
|
|
937
|
+
/** Schedule node style */
|
|
938
|
+
readonly schedule?: string | undefined;
|
|
939
|
+
/** Match node style */
|
|
940
|
+
readonly match?: string | undefined;
|
|
941
|
+
/** Transform node style */
|
|
942
|
+
readonly transform?: string | undefined;
|
|
943
|
+
/** Channel node style */
|
|
944
|
+
readonly channel?: string | undefined;
|
|
945
|
+
/** Sink node style */
|
|
946
|
+
readonly sink?: string | undefined;
|
|
947
|
+
/** Interruption node style */
|
|
948
|
+
readonly interruption?: string | undefined;
|
|
949
|
+
}
|
|
950
|
+
/**
|
|
951
|
+
* Options for Mermaid diagram output.
|
|
952
|
+
*/
|
|
953
|
+
interface MermaidOptions {
|
|
954
|
+
readonly direction: 'TB' | 'LR' | 'BT' | 'RL';
|
|
955
|
+
readonly includeIds: boolean;
|
|
956
|
+
readonly includeDescriptions: boolean;
|
|
957
|
+
readonly styles: MermaidStyles;
|
|
958
|
+
readonly compact: boolean;
|
|
959
|
+
readonly title?: string | undefined;
|
|
960
|
+
/** Include type signatures (A, E, R) on effect nodes */
|
|
961
|
+
readonly includeTypeSignatures?: boolean | undefined;
|
|
962
|
+
/** Wrap parallel/race blocks in subgraphs */
|
|
963
|
+
readonly useSubgraphs?: boolean | undefined;
|
|
964
|
+
/** Show condition labels on edges (e.g. true/false for conditionals) */
|
|
965
|
+
readonly showConditions?: boolean | undefined;
|
|
966
|
+
/** Level of detail in node labels: compact (callee only), standard (+ variable names), verbose (+ types + roles) */
|
|
967
|
+
readonly detail?: MermaidDetailLevel | undefined;
|
|
968
|
+
/** Overlay data-flow variable annotations on edges and warning classes on nodes */
|
|
969
|
+
readonly dataFlowOverlay?: boolean | undefined;
|
|
970
|
+
/** Overlay error-flow annotations (error types, unhandled errors) on nodes */
|
|
971
|
+
readonly errorFlowOverlay?: boolean | undefined;
|
|
972
|
+
}
|
|
973
|
+
/**
|
|
974
|
+
* Get children of a node as an Option.
|
|
975
|
+
* Accepts StaticFlowNode or StaticEffectProgram (root) so that walking from ir.root works.
|
|
976
|
+
*/
|
|
977
|
+
declare const getStaticChildren: (node: StaticFlowNode | StaticEffectProgram) => Option.Option<readonly StaticFlowNode[]>;
|
|
978
|
+
/**
|
|
979
|
+
* A layer implementation that provides a service.
|
|
980
|
+
*/
|
|
981
|
+
interface LayerImplementation {
|
|
982
|
+
/** Name of the layer variable (e.g. 'UserRepoLive') */
|
|
983
|
+
readonly name: string;
|
|
984
|
+
/** File where the layer is defined */
|
|
985
|
+
readonly filePath: string;
|
|
986
|
+
/** Source location of the layer definition */
|
|
987
|
+
readonly location: SourceLocation;
|
|
988
|
+
/** Layer kind */
|
|
989
|
+
readonly kind: 'effect' | 'succeed' | 'sync' | 'scoped' | 'other';
|
|
990
|
+
/** Services required by this layer implementation */
|
|
991
|
+
readonly requires: readonly string[];
|
|
992
|
+
/** IR of the layer's implementation body (if analyzable) */
|
|
993
|
+
readonly bodyIR?: StaticEffectIR | undefined;
|
|
994
|
+
}
|
|
995
|
+
/**
|
|
996
|
+
* A reference to a program that consumes a service.
|
|
997
|
+
*/
|
|
998
|
+
interface ServiceConsumerRef {
|
|
999
|
+
/** Program name that uses this service */
|
|
1000
|
+
readonly programName: string;
|
|
1001
|
+
/** File containing the program */
|
|
1002
|
+
readonly filePath: string;
|
|
1003
|
+
/** Location of the yield* call */
|
|
1004
|
+
readonly location?: SourceLocation | undefined;
|
|
1005
|
+
}
|
|
1006
|
+
/**
|
|
1007
|
+
* First-class artifact for an Effect service, deduplicated at the project level.
|
|
1008
|
+
*/
|
|
1009
|
+
interface ServiceArtifact {
|
|
1010
|
+
/** Unique service identifier (tag string, e.g. 'UserRepo') */
|
|
1011
|
+
readonly serviceId: string;
|
|
1012
|
+
/** Class name (may differ from serviceId if tag string differs) */
|
|
1013
|
+
readonly className: string;
|
|
1014
|
+
/** File where the service tag class is defined */
|
|
1015
|
+
readonly definitionFilePath: string;
|
|
1016
|
+
/** Source location of the class declaration */
|
|
1017
|
+
readonly definitionLocation: SourceLocation;
|
|
1018
|
+
/** Interface shape (methods, properties) */
|
|
1019
|
+
readonly definition: ServiceDefinition;
|
|
1020
|
+
/** Full type text of the service interface */
|
|
1021
|
+
readonly interfaceTypeText?: string | undefined;
|
|
1022
|
+
/** Layer implementations that provide this service */
|
|
1023
|
+
readonly layerImplementations: readonly LayerImplementation[];
|
|
1024
|
+
/** Programs that consume (yield*) this service */
|
|
1025
|
+
readonly consumers: readonly ServiceConsumerRef[];
|
|
1026
|
+
/** Services this service's layers depend on (transitive requirements) */
|
|
1027
|
+
readonly dependencies: readonly string[];
|
|
1028
|
+
}
|
|
1029
|
+
/**
|
|
1030
|
+
* Project-level deduplicated service map.
|
|
1031
|
+
*/
|
|
1032
|
+
interface ProjectServiceMap {
|
|
1033
|
+
/** Map from serviceId to its artifact */
|
|
1034
|
+
readonly services: ReadonlyMap<string, ServiceArtifact>;
|
|
1035
|
+
/** Services referenced but with no tag definition found */
|
|
1036
|
+
readonly unresolvedServices: readonly string[];
|
|
1037
|
+
/** Topological order of services (leaves first) */
|
|
1038
|
+
readonly topologicalOrder: readonly string[];
|
|
1039
|
+
}
|
|
1040
|
+
interface ShowcaseStepDetail {
|
|
1041
|
+
readonly stepId: string;
|
|
1042
|
+
readonly name: string;
|
|
1043
|
+
readonly callee: string;
|
|
1044
|
+
readonly outputType: string;
|
|
1045
|
+
readonly outputTypeKind: 'declared' | 'inferred' | 'unknown';
|
|
1046
|
+
readonly outputTypeDisplay: string;
|
|
1047
|
+
readonly outputTypeText: string;
|
|
1048
|
+
readonly errorTypeDisplay: string;
|
|
1049
|
+
readonly errors: readonly string[];
|
|
1050
|
+
readonly depSource?: string | undefined;
|
|
1051
|
+
readonly stepKind?: string | undefined;
|
|
1052
|
+
readonly retry?: {
|
|
1053
|
+
readonly attempts: number | 'unlimited';
|
|
1054
|
+
readonly backoff: string;
|
|
1055
|
+
} | undefined;
|
|
1056
|
+
readonly timeout?: {
|
|
1057
|
+
readonly ms: string;
|
|
1058
|
+
} | undefined;
|
|
1059
|
+
readonly kind?: 'resource' | undefined;
|
|
1060
|
+
readonly acquire?: string | undefined;
|
|
1061
|
+
readonly use?: string | undefined;
|
|
1062
|
+
readonly release?: string | undefined;
|
|
1063
|
+
readonly repeats?: 'loop' | undefined;
|
|
1064
|
+
readonly loopType?: string | undefined;
|
|
1065
|
+
readonly iterationSource?: string | undefined;
|
|
1066
|
+
}
|
|
1067
|
+
interface ShowcaseEntry {
|
|
1068
|
+
readonly title: string;
|
|
1069
|
+
readonly code: string;
|
|
1070
|
+
readonly mermaid: string;
|
|
1071
|
+
readonly stepDetails: readonly ShowcaseStepDetail[];
|
|
1072
|
+
}
|
|
1073
|
+
|
|
1074
|
+
/**
|
|
1075
|
+
* Fluent Builder API for Static Effect Analysis
|
|
1076
|
+
*
|
|
1077
|
+
* Provides an ergonomic API for analyzing Effect files with explicit intent.
|
|
1078
|
+
* Built entirely with Effect for composability.
|
|
1079
|
+
*
|
|
1080
|
+
* @example
|
|
1081
|
+
* ```typescript
|
|
1082
|
+
* import { Effect } from "effect";
|
|
1083
|
+
* import { analyze } from "effect-analyzer";
|
|
1084
|
+
*
|
|
1085
|
+
* // Single program file
|
|
1086
|
+
* const ir = await Effect.runPromise(analyze("./program.ts").single());
|
|
1087
|
+
*
|
|
1088
|
+
* // Multi-program file
|
|
1089
|
+
* const programs = await Effect.runPromise(analyze("./programs.ts").all());
|
|
1090
|
+
*
|
|
1091
|
+
* // Get specific program by name
|
|
1092
|
+
* const program = await Effect.runPromise(analyze("./programs.ts").named("myProgram"));
|
|
1093
|
+
*
|
|
1094
|
+
* // From source string
|
|
1095
|
+
* const ir = await Effect.runPromise(analyze.source(code).single());
|
|
1096
|
+
* ```
|
|
1097
|
+
*/
|
|
1098
|
+
|
|
1099
|
+
/**
|
|
1100
|
+
* Result object from analyze() with fluent methods to retrieve programs.
|
|
1101
|
+
*/
|
|
1102
|
+
interface AnalyzeResult {
|
|
1103
|
+
/**
|
|
1104
|
+
* Get single program. Fails if file has 0 or >1 programs.
|
|
1105
|
+
*/
|
|
1106
|
+
readonly single: () => Effect.Effect<StaticEffectIR, AnalysisError>;
|
|
1107
|
+
/**
|
|
1108
|
+
* Get single program or None if not exactly one.
|
|
1109
|
+
*/
|
|
1110
|
+
readonly singleOption: () => Effect.Effect<Option.Option<StaticEffectIR>>;
|
|
1111
|
+
/**
|
|
1112
|
+
* Get all programs as array.
|
|
1113
|
+
*/
|
|
1114
|
+
readonly all: () => Effect.Effect<readonly StaticEffectIR[], AnalysisError>;
|
|
1115
|
+
/**
|
|
1116
|
+
* Get program by name. Fails if not found.
|
|
1117
|
+
*/
|
|
1118
|
+
readonly named: (name: string) => Effect.Effect<StaticEffectIR, AnalysisError>;
|
|
1119
|
+
/**
|
|
1120
|
+
* Get first program. Fails if empty.
|
|
1121
|
+
*/
|
|
1122
|
+
readonly first: () => Effect.Effect<StaticEffectIR, AnalysisError>;
|
|
1123
|
+
/**
|
|
1124
|
+
* Get first program or None if empty.
|
|
1125
|
+
*/
|
|
1126
|
+
readonly firstOption: () => Effect.Effect<Option.Option<StaticEffectIR>>;
|
|
1127
|
+
}
|
|
1128
|
+
/**
|
|
1129
|
+
* Analyze an Effect file and return a fluent result object.
|
|
1130
|
+
*
|
|
1131
|
+
* @param filePath - Path to the TypeScript file containing the Effect program(s)
|
|
1132
|
+
* @param options - Analysis options
|
|
1133
|
+
* @returns Fluent result object with methods to retrieve programs
|
|
1134
|
+
*
|
|
1135
|
+
* @example
|
|
1136
|
+
* ```typescript
|
|
1137
|
+
* // Single program file
|
|
1138
|
+
* const ir = await Effect.runPromise(analyze("./program.ts").single());
|
|
1139
|
+
*
|
|
1140
|
+
* // Multiple programs - get all as array
|
|
1141
|
+
* const programs = await Effect.runPromise(analyze("./programs.ts").all());
|
|
1142
|
+
*
|
|
1143
|
+
* // Get specific program by name
|
|
1144
|
+
* const program = await Effect.runPromise(analyze("./programs.ts").named("myProgram"));
|
|
1145
|
+
* ```
|
|
1146
|
+
*/
|
|
1147
|
+
declare const analyze: {
|
|
1148
|
+
(filePath: string, options?: AnalyzerOptions): AnalyzeResult;
|
|
1149
|
+
source(code: string, options?: AnalyzerOptions): AnalyzeResult;
|
|
1150
|
+
};
|
|
1151
|
+
|
|
1152
|
+
export { type StaticLoopNode as $, type AnalyzerOptions as A, type ScheduleInfo as B, type ComplexityThresholds as C, type DiagramQualityWithFile as D, type EffectPath as E, type SemanticRole as F, type ServiceArtifact as G, type ServiceConsumerRef as H, type ServiceDefinition as I, type JSONRenderOptions as J, type ShowcaseStepDetail as K, type LayerTypeSignature as L, type MermaidOptions as M, type StaticAnalysisMetadata as N, type StaticBaseNode as O, type ProjectServiceMap as P, type StaticCauseNode as Q, type StaticConcurrencyPrimitiveNode as R, type StaticEffectIR as S, type TestMatrix as T, type StaticConditionalNode as U, type StaticEffectProgram as V, type StaticErrorHandlerNode as W, type StaticExitNode as X, type StaticFlowNode as Y, type StaticGeneratorNode as Z, type StaticLayerNode as _, AnalysisError as a, type StaticMatchNode as a0, type StaticParallelNode as a1, type StaticPipeNode as a2, type StaticRaceNode as a3, type StaticResourceNode as a4, type StaticRetryNode as a5, type StaticScheduleNode as a6, type StaticStreamNode as a7, type StaticTimeoutNode as a8, type StaticTransformNode as a9, isStaticTransformNode as aA, isStaticUnknownNode as aB, type StaticUnknownNode as aa, type StreamOperatorInfo as ab, type TestCondition as ac, type TestMatrixSummary as ad, type TestPath as ae, analyze as af, getStaticChildren as ag, isStaticCauseNode as ah, isStaticConcurrencyPrimitiveNode as ai, isStaticConditionalNode as aj, isStaticEffectNode as ak, isStaticErrorHandlerNode as al, isStaticExitNode as am, isStaticFiberNode as an, isStaticGeneratorNode as ao, isStaticLayerNode as ap, isStaticLoopNode as aq, isStaticMatchNode as ar, isStaticParallelNode as as, isStaticPipeNode as at, isStaticRaceNode as au, isStaticResourceNode as av, isStaticRetryNode as aw, isStaticScheduleNode as ax, isStaticStreamNode as ay, isStaticTimeoutNode as az, type DiagramTopOffendersReport as b, type DiagramQuality as c, type ShowcaseEntry as d, type ServiceRequirement as e, type SourceLocation as f, type StaticEffectNode as g, type ComplexityMetrics as h, type StaticFiberNode as i, type CauseTypeSignature as j, type EffectTypeSignature as k, type ScheduleTypeSignature as l, type StreamTypeSignature as m, type AnalysisStats as n, type AnalysisWarning as o, type AnalyzeResult as p, type DependencyInfo as q, type DiagramQualityMetrics as r, type DiagramReadabilityBand as s, type DiagramTopOffenderEntry as t, type JSDocTags as u, type LayerImplementation as v, type MermaidDetailLevel as w, type MermaidStyles as x, type PathCondition as y, type PathStepRef as z };
|