Skip to content

Commit 693e5a5

Browse files
Add Effect v4 support for diagnostics, refactors, and piping (#641)
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
1 parent cfabea6 commit 693e5a5

File tree

177 files changed

+4500
-73
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

177 files changed

+4500
-73
lines changed

.changeset/effect-v4-support.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
---
2+
"@effect/language-service": minor
3+
---
4+
5+
Added Effect v4 support for diagnostics, refactors, and piping features.
6+
7+
**Diagnostics:**
8+
- `multipleEffectProvide`: Warns when multiple `Effect.provide` calls are chained, suggesting consolidation
9+
- `strictEffectProvide`: Warns when using `Effect.provide` with Layer outside of application entry points
10+
- `missingLayerContext`: Detects missing Layer context requirements
11+
- `deterministicKeys`: Extended to support `ServiceMap.Service` patterns
12+
- `leakingRequirements`: Extended to detect leaking requirements in ServiceMap services
13+
- `schemaSyncInEffect`: Updated with v4-specific method mappings (e.g., `decodeSync` -> `decodeEffect`)
14+
15+
**Refactors:**
16+
- `layerMagic`: Automatically compose and build layers based on service dependencies
17+
- `structuralTypeToSchema`: Convert TypeScript interfaces and type aliases to Effect Schema classes
18+
- `makeSchemaOpaque`: Enhanced for v4 with support for `Codec`, `DecodingServices`, and `EncodingServices` types
19+
- `typeToEffectSchema`: Enhanced to support Effect v4 schema patterns
20+
21+
**Piping:**
22+
- Added pipe transformation support for Effect v4 including `Effect.fn`, nested pipes, and function call conversions

SMOL_TODOS.md

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -51,16 +51,16 @@ This file tracks all language service features and their compatibility status wi
5151
- [X] layerMergeAllWithDependencies
5252
- [-] redundantSchemaTagIdentifier
5353
- [X] effectFnOpportunity
54-
- [ ] leakingRequirements
55-
- [ ] multipleEffectProvide
56-
- [ ] outdatedEffectCodegen
57-
- [ ] nonObjectEffectServiceType
58-
- [ ] deterministicKeys
54+
- [X] leakingRequirements
55+
- [X] multipleEffectProvide
56+
- [X] outdatedEffectCodegen
57+
- [-] nonObjectEffectServiceType
58+
- [X] deterministicKeys
5959
- [X] missedPipeableOpportunity
60-
- [ ] strictEffectProvide
61-
- [ ] runEffectInsideEffect
62-
- [ ] missingLayerContext
63-
- [ ] schemaSyncInEffect
60+
- [X] strictEffectProvide
61+
- [-] runEffectInsideEffect
62+
- [X] missingLayerContext
63+
- [X] schemaSyncInEffect
6464

6565
---
6666

@@ -85,17 +85,17 @@ This file tracks all language service features and their compatibility status wi
8585
## Refactors (21 total)
8686

8787
- [X] asyncAwaitToFn
88-
- [ ] asyncAwaitToFnTryPromise
88+
- [X] asyncAwaitToFnTryPromise
8989
- [X] asyncAwaitToGen
90-
- [ ] asyncAwaitToGenTryPromise
90+
- [X] asyncAwaitToGenTryPromise
9191
- [X] effectGenToFn
9292
- [X] functionToArrow
93-
- [ ] layerMagic
94-
- [ ] makeSchemaOpaque
95-
- [ ] makeSchemaOpaqueWithNs
93+
- [X] layerMagic
94+
- [X] makeSchemaOpaque
95+
- [X] makeSchemaOpaqueWithNs
9696
- [X] pipeableToDatafirst
9797
- [X] removeUnnecessaryEffectGen
98-
- [ ] structuralTypeToSchema
98+
- [X] structuralTypeToSchema
9999
- [X] toggleLazyConst
100100
- [X] togglePipeStyle
101101
- [X] toggleReturnTypeAnnotation
@@ -104,4 +104,4 @@ This file tracks all language service features and their compatibility status wi
104104
- [ ] typeToEffectSchemaClass
105105
- [X] wrapWithEffectGen
106106
- [X] wrapWithPipe
107-
- [ ] writeTagClassAccessors
107+
- [-] writeTagClassAccessors
Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
Schema.decodeSync
2-
11:17 - 11:34 | 2 | Using Schema.decodeSync inside an Effect generator is not recommended. Use Schema.decode instead to get properly typed ParseError in the error channel. effect(schemaSyncInEffect)
2+
11:17 - 11:34 | 2 | Using Schema.decodeSync inside an Effect generator is not recommended. Use Schema.decode instead to get properly typed error channel. effect(schemaSyncInEffect)
33

44
Schema.decodeUnknownSync
5-
19:17 - 19:41 | 2 | Using Schema.decodeUnknownSync inside an Effect generator is not recommended. Use Schema.decodeUnknown instead to get properly typed ParseError in the error channel. effect(schemaSyncInEffect)
5+
19:17 - 19:41 | 2 | Using Schema.decodeUnknownSync inside an Effect generator is not recommended. Use Schema.decodeUnknown instead to get properly typed error channel. effect(schemaSyncInEffect)
66

77
Schema.encodeSync
8-
27:18 - 27:35 | 2 | Using Schema.encodeSync inside an Effect generator is not recommended. Use Schema.encode instead to get properly typed ParseError in the error channel. effect(schemaSyncInEffect)
8+
27:18 - 27:35 | 2 | Using Schema.encodeSync inside an Effect generator is not recommended. Use Schema.encode instead to get properly typed error channel. effect(schemaSyncInEffect)
99

1010
Schema.encodeUnknownSync
11-
35:18 - 35:42 | 2 | Using Schema.encodeUnknownSync inside an Effect generator is not recommended. Use Schema.encodeUnknown instead to get properly typed ParseError in the error channel. effect(schemaSyncInEffect)
11+
35:18 - 35:42 | 2 | Using Schema.encodeUnknownSync inside an Effect generator is not recommended. Use Schema.encodeUnknown instead to get properly typed error channel. effect(schemaSyncInEffect)
1212

1313
Schema.decodeSync
14-
58:17 - 58:34 | 2 | Using Schema.decodeSync inside an Effect generator is not recommended. Use Schema.decode instead to get properly typed ParseError in the error channel. effect(schemaSyncInEffect)
14+
58:17 - 58:34 | 2 | Using Schema.decodeSync inside an Effect generator is not recommended. Use Schema.decode instead to get properly typed error channel. effect(schemaSyncInEffect)
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
deterministicKeys_fix from 321 to 348
2+
deterministicKeys_skipNextLine from 321 to 348
3+
deterministicKeys_skipFile from 321 to 348
4+
deterministicKeys_fix from 399 to 407
5+
deterministicKeys_skipNextLine from 399 to 407
6+
deterministicKeys_skipFile from 399 to 407
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// code fix deterministicKeys_fix output for range 317 - 344
2+
// @effect-diagnostics deterministicKeys:error
3+
// @test-config { "keyPatterns": [ { "target": "service", "pattern": "default" }, { "target": "error", "pattern": "default" } ] }
4+
import * as Context from "effect/Context"
5+
import * as Data from "effect/Data"
6+
7+
export class ExpectedServiceIdentifier
8+
extends Context.Tag("@effect/harness-effect-v3/ExpectedServiceIdentifier")<ExpectedServiceIdentifier, {}>()
9+
{}
10+
11+
export class ErrorA extends Data.TaggedError("ErrorA")<{}> {}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// code fix deterministicKeys_fix output for range 321 - 348
2+
// @effect-diagnostics deterministicKeys:error
3+
// @test-config { "keyPatterns": [ { "target": "service", "pattern": "default" }, { "target": "error", "pattern": "default" } ] }
4+
import { ServiceMap, Data } from "effect"
5+
6+
export class ExpectedServiceIdentifier
7+
extends ServiceMap.Service<ExpectedServiceIdentifier, {}>()("@effect/harness-effect-v4/ExpectedServiceIdentifier")
8+
{}
9+
10+
export class ErrorA extends Data.TaggedError("ErrorA")<{}> {}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// code fix deterministicKeys_fix output for range 399 - 407
2+
// @effect-diagnostics deterministicKeys:error
3+
// @test-config { "keyPatterns": [ { "target": "service", "pattern": "default" }, { "target": "error", "pattern": "default" } ] }
4+
import { ServiceMap, Data } from "effect"
5+
6+
export class ExpectedServiceIdentifier
7+
extends ServiceMap.Service<ExpectedServiceIdentifier, {}>()("ExpectedServiceIdentifier")
8+
{}
9+
10+
export class ErrorA extends Data.TaggedError("@effect/harness-effect-v4/ErrorA")<{}> {}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// code fix deterministicKeys_fix output for range 428 - 436
2+
// @effect-diagnostics deterministicKeys:error
3+
// @test-config { "keyPatterns": [ { "target": "service", "pattern": "default" }, { "target": "error", "pattern": "default" } ] }
4+
import * as Context from "effect/Context"
5+
import * as Data from "effect/Data"
6+
7+
export class ExpectedServiceIdentifier
8+
extends Context.Tag("ExpectedServiceIdentifier")<ExpectedServiceIdentifier, {}>()
9+
{}
10+
11+
export class ErrorA extends Data.TaggedError("@effect/harness-effect-v3/ErrorA")<{}> {}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
"ExpectedServiceIdentifier"
2+
6:62 - 6:89 | 1 | Key should be '@effect/harness-effect-v4/ExpectedServiceIdentifier' effect(deterministicKeys)
3+
4+
"ErrorA"
5+
9:45 - 9:53 | 1 | Key should be '@effect/harness-effect-v4/ErrorA' effect(deterministicKeys)
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
deterministicKeys_fix from 427 to 434
2+
deterministicKeys_skipNextLine from 427 to 434
3+
deterministicKeys_skipFile from 427 to 434
4+
deterministicKeys_fix from 554 to 566
5+
deterministicKeys_skipNextLine from 554 to 566
6+
deterministicKeys_skipFile from 554 to 566

0 commit comments

Comments
 (0)