From 60d09688d8022b60421f89f96f7234f6d44e5995 Mon Sep 17 00:00:00 2001 From: Mattia Manzati Date: Fri, 7 Aug 2026 10:06:02 +0200 Subject: [PATCH] Update Effect v4 dependencies to beta.104 --- .changeset/tidy-dragons-smile.md | 5 + package.json | 5 + .../__snapshots__/completions.test.ts.snap | 48 +++++-- ...unnecessaryFailYieldableError.ts.codefixes | 12 +- ...ailYieldableError_fix.from663to704.output} | 4 +- ...ailYieldableError_fix.from707to746.output} | 4 +- ...eTypeAnnotation_schema.ts.ln11col15.output | 2 +- ...eTypeAnnotation_unnamed.ts.ln4col15.output | 2 +- ...ctSchemaSelfInClasses_directImportError.ts | 4 + ...maSelfInClasses_directImportTaggedError.ts | 4 + .../unnecessaryFailYieldableError.ts | 2 +- packages/harness-effect-v4/package.json | 2 +- packages/language-service/package.json | 4 +- .../completions/effectSchemaSelfInClasses.ts | 63 +++------ .../language-service/src/core/LayerGraph.ts | 29 +++- .../src/diagnostics/outdatedApi.db.ts | 8 +- .../src/refactors/toggleTypeAnnotation.ts | 27 +++- pnpm-lock.yaml | 131 ++++++++---------- 18 files changed, 207 insertions(+), 149 deletions(-) create mode 100644 .changeset/tidy-dragons-smile.md rename packages/harness-effect-v4/__snapshots__/diagnostics/{unnecessaryFailYieldableError.ts.unnecessaryFailYieldableError_fix.from668to709.output => unnecessaryFailYieldableError.ts.unnecessaryFailYieldableError_fix.from663to704.output} (90%) rename packages/harness-effect-v4/__snapshots__/diagnostics/{unnecessaryFailYieldableError.ts.unnecessaryFailYieldableError_fix.from712to751.output => unnecessaryFailYieldableError.ts.unnecessaryFailYieldableError_fix.from707to746.output} (90%) create mode 100644 packages/harness-effect-v4/examples/completions/effectSchemaSelfInClasses_directImportError.ts create mode 100644 packages/harness-effect-v4/examples/completions/effectSchemaSelfInClasses_directImportTaggedError.ts diff --git a/.changeset/tidy-dragons-smile.md b/.changeset/tidy-dragons-smile.md new file mode 100644 index 00000000..30d1bfaa --- /dev/null +++ b/.changeset/tidy-dragons-smile.md @@ -0,0 +1,5 @@ +--- +"@effect/language-service": patch +--- + +Update Effect v4 compatibility to 4.0.0-beta.104, including the renamed `Schema.Error` and `Schema.TaggedError` constructors. diff --git a/package.json b/package.json index b4cb7038..5938ef68 100644 --- a/package.json +++ b/package.json @@ -50,5 +50,10 @@ "typescript": "^5.9.3", "vite": "^7.3.1", "vitest": "^4.0.17" + }, + "pnpm": { + "overrides": { + "@effect/platform-node-shared": "4.0.0-beta.104" + } } } diff --git a/packages/harness-effect-v4/__snapshots__/completions.test.ts.snap b/packages/harness-effect-v4/__snapshots__/completions.test.ts.snap index 6d9977c2..dea2388b 100644 --- a/packages/harness-effect-v4/__snapshots__/completions.test.ts.snap +++ b/packages/harness-effect-v4/__snapshots__/completions.test.ts.snap @@ -165,6 +165,38 @@ exports[`Completion effectSchemaSelfInClasses > effectSchemaSelfInClasses_direct ] `; +exports[`Completion effectSchemaSelfInClasses > effectSchemaSelfInClasses_directImportError.ts at 4:35 1`] = ` +[ + { + "insertText": "Error("MyError")({\${0}}){}", + "isSnippet": true, + "kind": "const", + "name": "Error", + "replacementSpan": { + "length": 5, + "start": 143, + }, + "sortText": "11", + }, +] +`; + +exports[`Completion effectSchemaSelfInClasses > effectSchemaSelfInClasses_directImportTaggedError.ts at 4:40 1`] = ` +[ + { + "insertText": "TaggedError()("MyError", {\${0}}){}", + "isSnippet": true, + "kind": "const", + "name": "TaggedError", + "replacementSpan": { + "length": 11, + "start": 149, + }, + "sortText": "11", + }, +] +`; + exports[`Completion effectSchemaSelfInClasses > effectSchemaSelfInClasses_dotToken.ts at 4:22 1`] = ` [ { @@ -179,10 +211,10 @@ exports[`Completion effectSchemaSelfInClasses > effectSchemaSelfInClasses_dotTok "sortText": "11", }, { - "insertText": "S.TaggedErrorClass()("Test", {\${0}}){}", + "insertText": "S.TaggedError()("Test", {\${0}}){}", "isSnippet": true, "kind": "const", - "name": "TaggedErrorClass", + "name": "TaggedError", "replacementSpan": { "length": 2, "start": 130, @@ -201,10 +233,10 @@ exports[`Completion effectSchemaSelfInClasses > effectSchemaSelfInClasses_dotTok "sortText": "11", }, { - "insertText": "S.ErrorClass("Test")({\${0}}){}", + "insertText": "S.Error("Test")({\${0}}){}", "isSnippet": true, "kind": "const", - "name": "ErrorClass", + "name": "Error", "replacementSpan": { "length": 2, "start": 130, @@ -244,10 +276,10 @@ exports[`Completion effectSchemaSelfInClasses > effectSchemaSelfInClasses_tagg.t "sortText": "11", }, { - "insertText": "S.TaggedErrorClass()("Test", {\${0}}){}", + "insertText": "S.TaggedError()("Test", {\${0}}){}", "isSnippet": true, "kind": "const", - "name": "TaggedErrorClass", + "name": "TaggedError", "replacementSpan": { "length": 5, "start": 130, @@ -266,10 +298,10 @@ exports[`Completion effectSchemaSelfInClasses > effectSchemaSelfInClasses_tagg.t "sortText": "11", }, { - "insertText": "S.ErrorClass("Test")({\${0}}){}", + "insertText": "S.Error("Test")({\${0}}){}", "isSnippet": true, "kind": "const", - "name": "ErrorClass", + "name": "Error", "replacementSpan": { "length": 5, "start": 130, diff --git a/packages/harness-effect-v4/__snapshots__/diagnostics/unnecessaryFailYieldableError.ts.codefixes b/packages/harness-effect-v4/__snapshots__/diagnostics/unnecessaryFailYieldableError.ts.codefixes index 6e5859b2..484d4fe1 100644 --- a/packages/harness-effect-v4/__snapshots__/diagnostics/unnecessaryFailYieldableError.ts.codefixes +++ b/packages/harness-effect-v4/__snapshots__/diagnostics/unnecessaryFailYieldableError.ts.codefixes @@ -1,6 +1,6 @@ -unnecessaryFailYieldableError_fix from 668 to 709 -unnecessaryFailYieldableError_skipNextLine from 668 to 709 -unnecessaryFailYieldableError_skipFile from 668 to 709 -unnecessaryFailYieldableError_fix from 712 to 751 -unnecessaryFailYieldableError_skipNextLine from 712 to 751 -unnecessaryFailYieldableError_skipFile from 712 to 751 \ No newline at end of file +unnecessaryFailYieldableError_fix from 663 to 704 +unnecessaryFailYieldableError_skipNextLine from 663 to 704 +unnecessaryFailYieldableError_skipFile from 663 to 704 +unnecessaryFailYieldableError_fix from 707 to 746 +unnecessaryFailYieldableError_skipNextLine from 707 to 746 +unnecessaryFailYieldableError_skipFile from 707 to 746 \ No newline at end of file diff --git a/packages/harness-effect-v4/__snapshots__/diagnostics/unnecessaryFailYieldableError.ts.unnecessaryFailYieldableError_fix.from668to709.output b/packages/harness-effect-v4/__snapshots__/diagnostics/unnecessaryFailYieldableError.ts.unnecessaryFailYieldableError_fix.from663to704.output similarity index 90% rename from packages/harness-effect-v4/__snapshots__/diagnostics/unnecessaryFailYieldableError.ts.unnecessaryFailYieldableError_fix.from668to709.output rename to packages/harness-effect-v4/__snapshots__/diagnostics/unnecessaryFailYieldableError.ts.unnecessaryFailYieldableError_fix.from663to704.output index 988f1692..4b0013a0 100644 --- a/packages/harness-effect-v4/__snapshots__/diagnostics/unnecessaryFailYieldableError.ts.unnecessaryFailYieldableError_fix.from668to709.output +++ b/packages/harness-effect-v4/__snapshots__/diagnostics/unnecessaryFailYieldableError.ts.unnecessaryFailYieldableError_fix.from663to704.output @@ -1,4 +1,4 @@ -// code fix unnecessaryFailYieldableError_fix output for range 668 - 709 +// code fix unnecessaryFailYieldableError_fix output for range 663 - 704 /** @effect-diagnostics missingReturnYieldStar:skip-file */ import * as Data from "effect/Data" import * as Effect from "effect/Effect" @@ -10,7 +10,7 @@ class NonYieldable extends Error { class DataTaggedError extends Data.TaggedError("DataTaggedError")<{}> {} -class SchemaError extends Schema.ErrorClass("SchemaError")({ +class SchemaError extends Schema.Error("SchemaError")({ _tag: Schema.tag("SchemaError") }) {} diff --git a/packages/harness-effect-v4/__snapshots__/diagnostics/unnecessaryFailYieldableError.ts.unnecessaryFailYieldableError_fix.from712to751.output b/packages/harness-effect-v4/__snapshots__/diagnostics/unnecessaryFailYieldableError.ts.unnecessaryFailYieldableError_fix.from707to746.output similarity index 90% rename from packages/harness-effect-v4/__snapshots__/diagnostics/unnecessaryFailYieldableError.ts.unnecessaryFailYieldableError_fix.from712to751.output rename to packages/harness-effect-v4/__snapshots__/diagnostics/unnecessaryFailYieldableError.ts.unnecessaryFailYieldableError_fix.from707to746.output index 9690fc4c..776a9f4a 100644 --- a/packages/harness-effect-v4/__snapshots__/diagnostics/unnecessaryFailYieldableError.ts.unnecessaryFailYieldableError_fix.from712to751.output +++ b/packages/harness-effect-v4/__snapshots__/diagnostics/unnecessaryFailYieldableError.ts.unnecessaryFailYieldableError_fix.from707to746.output @@ -1,4 +1,4 @@ -// code fix unnecessaryFailYieldableError_fix output for range 712 - 751 +// code fix unnecessaryFailYieldableError_fix output for range 707 - 746 /** @effect-diagnostics missingReturnYieldStar:skip-file */ import * as Data from "effect/Data" import * as Effect from "effect/Effect" @@ -10,7 +10,7 @@ class NonYieldable extends Error { class DataTaggedError extends Data.TaggedError("DataTaggedError")<{}> {} -class SchemaError extends Schema.ErrorClass("SchemaError")({ +class SchemaError extends Schema.Error("SchemaError")({ _tag: Schema.tag("SchemaError") }) {} diff --git a/packages/harness-effect-v4/__snapshots__/refactors/toggleTypeAnnotation_schema.ts.ln11col15.output b/packages/harness-effect-v4/__snapshots__/refactors/toggleTypeAnnotation_schema.ts.ln11col15.output index 4a06b3a4..6bc621c1 100644 --- a/packages/harness-effect-v4/__snapshots__/refactors/toggleTypeAnnotation_schema.ts.ln11col15.output +++ b/packages/harness-effect-v4/__snapshots__/refactors/toggleTypeAnnotation_schema.ts.ln11col15.output @@ -8,5 +8,5 @@ class Person extends Schema.Class("Person")({ name: Schema.NonEmptyString, age: Schema.Int }) { - static decode: (input: Schema.Struct.ReadonlySide<{ readonly name: Schema.NonEmptyString; readonly age: Schema.Int }, "Encoded">, options?: ParseOption.ParseOptions) => Effect.Effect = Schema.decodeEffect(Person) + static decode: (input: { readonly name: string; readonly age: number }, options?: ParseOption.ParseOptions) => Effect.Effect = Schema.decodeEffect(Person) } diff --git a/packages/harness-effect-v4/__snapshots__/refactors/toggleTypeAnnotation_unnamed.ts.ln4col15.output b/packages/harness-effect-v4/__snapshots__/refactors/toggleTypeAnnotation_unnamed.ts.ln4col15.output index 8bb726c0..aacce8c8 100644 --- a/packages/harness-effect-v4/__snapshots__/refactors/toggleTypeAnnotation_unnamed.ts.ln4col15.output +++ b/packages/harness-effect-v4/__snapshots__/refactors/toggleTypeAnnotation_unnamed.ts.ln4col15.output @@ -1,6 +1,6 @@ // Result of running refactor toggleTypeAnnotation at position 4:15 import * as Schema from "effect/Schema" -export const debug: (input: Schema.Struct.ReadonlyMakeIn<{ readonly id: Schema.Option }>, options?: Schema.MakeOptions) => Schema.Struct.ReadonlySide<{ readonly id: Schema.Option }, "Type"> = Schema.Struct({ +export const debug: (input: { readonly id: import("effect/Option", { with: { "resolution-mode": "import" } }).Option }, options?: Schema.MakeOptions) => { readonly id: import("effect/Option", { with: { "resolution-mode": "import" } }).Option } = Schema.Struct({ id: Schema.Option(Schema.Number) }).make diff --git a/packages/harness-effect-v4/examples/completions/effectSchemaSelfInClasses_directImportError.ts b/packages/harness-effect-v4/examples/completions/effectSchemaSelfInClasses_directImportError.ts new file mode 100644 index 00000000..8519c2ff --- /dev/null +++ b/packages/harness-effect-v4/examples/completions/effectSchemaSelfInClasses_directImportError.ts @@ -0,0 +1,4 @@ +// 4:35 +import { Error } from "effect/Schema" + +export class MyError extends Error diff --git a/packages/harness-effect-v4/examples/completions/effectSchemaSelfInClasses_directImportTaggedError.ts b/packages/harness-effect-v4/examples/completions/effectSchemaSelfInClasses_directImportTaggedError.ts new file mode 100644 index 00000000..4e6c5c77 --- /dev/null +++ b/packages/harness-effect-v4/examples/completions/effectSchemaSelfInClasses_directImportTaggedError.ts @@ -0,0 +1,4 @@ +// 4:40 +import { TaggedError } from "effect/Schema" + +export class MyError extends TaggedError diff --git a/packages/harness-effect-v4/examples/diagnostics/unnecessaryFailYieldableError.ts b/packages/harness-effect-v4/examples/diagnostics/unnecessaryFailYieldableError.ts index 1e127e1f..1ed787ea 100644 --- a/packages/harness-effect-v4/examples/diagnostics/unnecessaryFailYieldableError.ts +++ b/packages/harness-effect-v4/examples/diagnostics/unnecessaryFailYieldableError.ts @@ -9,7 +9,7 @@ class NonYieldable extends Error { class DataTaggedError extends Data.TaggedError("DataTaggedError")<{}> {} -class SchemaError extends Schema.ErrorClass("SchemaError")({ +class SchemaError extends Schema.Error("SchemaError")({ _tag: Schema.tag("SchemaError") }) {} diff --git a/packages/harness-effect-v4/package.json b/packages/harness-effect-v4/package.json index 36bbe959..3243990a 100644 --- a/packages/harness-effect-v4/package.json +++ b/packages/harness-effect-v4/package.json @@ -6,7 +6,7 @@ }, "dependencies": { "@standard-schema/spec": "^1.1.0", - "effect": "^4.0.0-beta.94" + "effect": "4.0.0-beta.104" }, "devDependencies": { "@types/node": "^25.0.6" diff --git a/packages/language-service/package.json b/packages/language-service/package.json index ae307019..cc514b29 100644 --- a/packages/language-service/package.json +++ b/packages/language-service/package.json @@ -43,10 +43,10 @@ "perf": "tsx test/perf.ts" }, "devDependencies": { - "@effect/platform-node": "^4.0.0-beta.94", + "@effect/platform-node": "4.0.0-beta.104", "@types/pako": "^2.0.4", "@typescript-eslint/project-service": "^8.52.0", - "effect": "^4.0.0-beta.94", + "effect": "4.0.0-beta.104", "pako": "^2.1.0", "ts-patch": "^3.3.0" } diff --git a/packages/language-service/src/completions/effectSchemaSelfInClasses.ts b/packages/language-service/src/completions/effectSchemaSelfInClasses.ts index 8cd50fb2..ab35b53b 100644 --- a/packages/language-service/src/completions/effectSchemaSelfInClasses.ts +++ b/packages/language-service/src/completions/effectSchemaSelfInClasses.ts @@ -56,43 +56,22 @@ export const effectSchemaSelfInClasses = LSP.createCompletion({ } // Check for Schema.TaggedError or direct import TaggedError - if (typeParser.supportedEffect() === "v3") { - const hasTaggedErrorCompletion = isFullyQualified || Option.isSome( - yield* pipe( - typeParser.isNodeReferenceToEffectSchemaModuleApi("TaggedError")(accessedObject), - Nano.option - ) - ) - if (hasTaggedErrorCompletion) { - completions.push({ - name: `TaggedError<${name}>`, - kind: ts.ScriptElementKind.constElement, - insertText: isFullyQualified - ? `${schemaIdentifier}.TaggedError<${name}>()("${errorTagKey}", {${"${0}"}}){}` - : `TaggedError<${name}>()("${errorTagKey}", {${"${0}"}}){}`, - replacementSpan, - isSnippet: true - }) - } - } - if (typeParser.supportedEffect() === "v4") { - const hasTaggedErrorCompletion = isFullyQualified || Option.isSome( - yield* pipe( - typeParser.isNodeReferenceToEffectSchemaModuleApi("TaggedErrorClass")(accessedObject), - Nano.option - ) + const hasTaggedErrorCompletion = isFullyQualified || Option.isSome( + yield* pipe( + typeParser.isNodeReferenceToEffectSchemaModuleApi("TaggedError")(accessedObject), + Nano.option ) - if (hasTaggedErrorCompletion) { - completions.push({ - name: `TaggedErrorClass<${name}>`, - kind: ts.ScriptElementKind.constElement, - insertText: isFullyQualified - ? `${schemaIdentifier}.TaggedErrorClass<${name}>()("${errorTagKey}", {${"${0}"}}){}` - : `TaggedErrorClass<${name}>()("${errorTagKey}", {${"${0}"}}){}`, - replacementSpan, - isSnippet: true - }) - } + ) + if (hasTaggedErrorCompletion) { + completions.push({ + name: `TaggedError<${name}>`, + kind: ts.ScriptElementKind.constElement, + insertText: isFullyQualified + ? `${schemaIdentifier}.TaggedError<${name}>()("${errorTagKey}", {${"${0}"}}){}` + : `TaggedError<${name}>()("${errorTagKey}", {${"${0}"}}){}`, + replacementSpan, + isSnippet: true + }) } // Check for Schema.TaggedClass or direct import TaggedClass @@ -136,19 +115,19 @@ export const effectSchemaSelfInClasses = LSP.createCompletion({ } if (typeParser.supportedEffect() === "v4") { - const hasErrorClassCompletion = isFullyQualified || Option.isSome( + const hasErrorCompletion = isFullyQualified || Option.isSome( yield* pipe( - typeParser.isNodeReferenceToEffectSchemaModuleApi("ErrorClass")(accessedObject), + typeParser.isNodeReferenceToEffectSchemaModuleApi("Error")(accessedObject), Nano.option ) ) - if (hasErrorClassCompletion) { + if (hasErrorCompletion) { completions.push({ - name: `ErrorClass<${name}>`, + name: `Error<${name}>`, kind: ts.ScriptElementKind.constElement, insertText: isFullyQualified - ? `${schemaIdentifier}.ErrorClass<${name}>("${name}")({${"${0}"}}){}` - : `ErrorClass<${name}>()({${"${0}"}}){}`, + ? `${schemaIdentifier}.Error<${name}>("${name}")({${"${0}"}}){}` + : `Error<${name}>("${name}")({${"${0}"}}){}`, replacementSpan, isSnippet: true }) diff --git a/packages/language-service/src/core/LayerGraph.ts b/packages/language-service/src/core/LayerGraph.ts index b0aa1a61..5a68a4aa 100644 --- a/packages/language-service/src/core/LayerGraph.ts +++ b/packages/language-service/src/core/LayerGraph.ts @@ -396,8 +396,8 @@ export const formatNestedLayerGraph = Nano.fn("formatNestedLayerGraph")( // and then the edges for (const edgeInfo of Graph.values(Graph.edges(layerGraph))) { - const sourceData = layerGraph.nodes.get(edgeInfo.source)! - const targetData = layerGraph.nodes.get(edgeInfo.target)! + const sourceData = Option.getOrUndefined(Graph.getNode(layerGraph, edgeInfo.source))! + const targetData = Option.getOrUndefined(Graph.getNode(layerGraph, edgeInfo.target))! let connected: boolean = false for (const kind of ["requires", "provides"] as const) { for (let i = 0; i < sourceData[kind].length; i++) { @@ -540,13 +540,27 @@ export interface LayerMagicResult { missingOutputTypes: Set } +const traversalNeighbors = ( + graph: Graph.Graph | Graph.MutableGraph, + node: Graph.NodeIndex, + direction: Graph.TraversalDirection +) => + direction === "undirected" + ? [...new Set([...Graph.successors(graph, node), ...Graph.predecessors(graph, node)])] + : direction === "outgoing" + ? Graph.successors(graph, node) + : Graph.predecessors(graph, node) + export const dfsPostOrderWithOrder = ( graph: Graph.Graph | Graph.MutableGraph, config: Graph.SearchConfig & { order: Order.Order } ): Graph.NodeWalker => { const start = config.start ?? [] const direction = config.direction ?? "outgoing" - const orderByIndex = Order.mapInput(config.order, (_: Graph.NodeIndex) => graph.nodes.get(_)!) + const orderByIndex = Order.mapInput( + config.order, + (_: Graph.NodeIndex) => Option.getOrUndefined(Graph.getNode(graph, _))! + ) return new Graph.Walker((f) => ({ [Symbol.iterator]: () => { @@ -572,7 +586,7 @@ export const dfsPostOrderWithOrder = ( if (!current.visitedChildren) { current.visitedChildren = true - const neighbors = Graph.neighborsDirected(graph, current.node, direction) + const neighbors = traversalNeighbors(graph, current.node, direction) const sortedNeighbors = Array.sort(neighbors, orderByIndex) for (let i = sortedNeighbors.length - 1; i >= 0; i--) { const neighbor = sortedNeighbors[i] @@ -626,7 +640,10 @@ export const convertOutlineGraphToLayerMagic = Nano.fn("convertOutlineGraphToLay const layerOrder = Order.combine(orderByProvidedCount, orderByRequiredCount) // no need to filter because the outline graph is already deduplicated and only keeping childs - const reversedGraph = Graph.mutate(outlineGraph, Graph.reverse) + const reversedGraph = Graph.mutate(outlineGraph, (mutable) => { + Graph.reverse(mutable) + return undefined + }) const rootIndexes = Array.fromIterable(Graph.indices(Graph.externals(reversedGraph, { direction: "incoming" }))) const allNodes = Array.fromIterable( Graph.values(dfsPostOrderWithOrder(reversedGraph, { start: rootIndexes, order: layerOrder })) @@ -674,7 +691,7 @@ export const walkLeavesMatching = ( if (discovered.has(current)) continue discovered.add(current) - const neighbors = Graph.neighborsDirected(graph, current, direction) + const neighbors = traversalNeighbors(graph, current, direction) const neighborsMatching: Array = [] for (const neighbor of neighbors) { const neighborNode = Graph.getNode(graph, neighbor) diff --git a/packages/language-service/src/diagnostics/outdatedApi.db.ts b/packages/language-service/src/diagnostics/outdatedApi.db.ts index aeac58f8..41e959c9 100644 --- a/packages/language-service/src/diagnostics/outdatedApi.db.ts +++ b/packages/language-service/src/diagnostics/outdatedApi.db.ts @@ -133,6 +133,7 @@ export const effectModuleMigrationDb: ModuleMigrationDb = { "race": asUnchanged, "raceAll": asUnchanged, "raceFirst": asUnchanged, + "reduce": asUnchanged, "repeat": asUnchanged, "repeatOrElse": asUnchanged, "replicate": asUnchanged, @@ -178,7 +179,6 @@ export const effectModuleMigrationDb: ModuleMigrationDb = { "void": asUnchanged, "when": asUnchanged, "whileLoop": asUnchanged, - "withConcurrency": asUnchanged, "withExecutionPlan": asUnchanged, "withLogSpan": asUnchanged, "withParentSpan": asUnchanged, @@ -495,9 +495,6 @@ export const effectModuleMigrationDb: ModuleMigrationDb = { "randomWith": asRemoved( "Random access has been reworked in Effect v4." ), - "reduce": asRemoved( - "Use Effect.forEach with a mutable accumulator or Effect.gen instead." - ), "reduceEffect": asRemoved( "Use Effect.forEach with a mutable accumulator or Effect.gen instead." ), @@ -649,6 +646,9 @@ export const effectModuleMigrationDb: ModuleMigrationDb = { "withConsoleScoped": asRemoved( "Console configuration has been reworked in Effect v4." ), + "withConcurrency": asRemoved( + "Pass concurrency through operation options, such as Effect.all or Effect.forEach." + ), "withEarlyRelease": asRemoved( "Use Effect.scoped with manual resource management instead." ), diff --git a/packages/language-service/src/refactors/toggleTypeAnnotation.ts b/packages/language-service/src/refactors/toggleTypeAnnotation.ts index 8f982dad..5704686a 100644 --- a/packages/language-service/src/refactors/toggleTypeAnnotation.ts +++ b/packages/language-service/src/refactors/toggleTypeAnnotation.ts @@ -1,6 +1,7 @@ import * as Array from "effect/Array" import { pipe } from "effect/Function" import * as Option from "effect/Option" +import type ts from "typescript" import * as LSP from "../core/LSP.js" import * as Nano from "../core/Nano.js" import * as TypeCheckerApi from "../core/TypeCheckerApi.js" @@ -51,14 +52,38 @@ export const toggleTypeAnnotation = LSP.createRefactor({ Option.getOrUndefined ) if (initializerTypeNode) { + // Effect beta.104 exposes Option through its declaration path; emit the public package path. + const transformed = ts.transform(initializerTypeNode, [(context) => { + const visit = (node: ts.Node): ts.VisitResult => { + if ( + ts.isImportTypeNode(node) && ts.isLiteralTypeNode(node.argument) && + ts.isStringLiteral(node.argument.literal) && + node.argument.literal.text === "node_modules/effect/dist/Option" + ) { + return ts.factory.updateImportTypeNode( + node, + ts.factory.createLiteralTypeNode(ts.factory.createStringLiteral( + "effect/Option" + )), + node.attributes, + node.qualifier, + node.typeArguments, + node.isTypeOf + ) + } + return ts.visitEachChild(node, visit, context) + } + return (node) => ts.visitNode(node, visit) as ts.TypeNode + }]) changeTracker.insertNodeAt( sourceFile, node.name.end, - initializerTypeNode, + transformed.transformed[0] as ts.TypeNode, { prefix: ": " } ) + transformed.dispose() } }), Nano.provideService(TypeScriptApi.TypeScriptApi, ts) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 01fb3444..39378645 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -4,6 +4,9 @@ settings: autoInstallPeers: true excludeLinksFromLockfile: false +overrides: + '@effect/platform-node-shared': 4.0.0-beta.104 + importers: .: @@ -124,8 +127,8 @@ importers: specifier: ^1.1.0 version: 1.1.0 effect: - specifier: ^4.0.0-beta.94 - version: 4.0.0-beta.94 + specifier: 4.0.0-beta.104 + version: 4.0.0-beta.104 devDependencies: '@types/node': specifier: ^25.0.6 @@ -134,8 +137,8 @@ importers: packages/language-service: devDependencies: '@effect/platform-node': - specifier: ^4.0.0-beta.94 - version: 4.0.0-beta.94(effect@4.0.0-beta.94)(ioredis@5.10.0) + specifier: 4.0.0-beta.104 + version: 4.0.0-beta.104(effect@4.0.0-beta.104)(ioredis@5.10.0) '@types/pako': specifier: ^2.0.4 version: 2.0.4 @@ -143,8 +146,8 @@ importers: specifier: ^8.52.0 version: 8.52.0(typescript@5.9.3) effect: - specifier: ^4.0.0-beta.94 - version: 4.0.0-beta.94 + specifier: 4.0.0-beta.104 + version: 4.0.0-beta.104 pako: specifier: ^2.1.0 version: 2.1.0 @@ -575,32 +578,32 @@ packages: uuid: 11.1.0 dev: false - /@effect/platform-node-shared@4.0.0-beta.94(effect@4.0.0-beta.94): - resolution: {integrity: sha512-8mCen8dhL4ockkkxevKdFOXqR8sksuZcPwyqkKZv3w30TIdj4TKXG5sQODmpPFI0+/quwm5T78kodqf/QlZwoA==} + /@effect/platform-node-shared@4.0.0-beta.104(effect@4.0.0-beta.104): + resolution: {integrity: sha512-wZQWlreuCfR+Ip6E93h2Wo56lFdBTflzSErFKxvrAW06/ORa7yZMD4oq4Ow5aU5+AlQgomQSEeBKM7uao4ZewQ==} engines: {node: '>=18.0.0'} peerDependencies: - effect: ^4.0.0-beta.94 + effect: ^4.0.0-beta.104 dependencies: '@types/ws': 8.18.1 - effect: 4.0.0-beta.94 - ws: 8.20.0 + effect: 4.0.0-beta.104 + ws: 8.21.2 transitivePeerDependencies: - bufferutil - utf-8-validate dev: true - /@effect/platform-node@4.0.0-beta.94(effect@4.0.0-beta.94)(ioredis@5.10.0): - resolution: {integrity: sha512-3WhV5ZN2pTPcOtEQlM66Ve0/B4EzF88sYBml97NnRV7BA5Kx0FYLSslc/4aWoaXj6XwuWOxmoXeGGeFzw4gbMQ==} + /@effect/platform-node@4.0.0-beta.104(effect@4.0.0-beta.104)(ioredis@5.10.0): + resolution: {integrity: sha512-edqD0sRzL3Qow26TnD+RuHNVolFB7c1M/xWGzW0TRc7PzXpRWQawM1haMXOrB8W1UXpg8T8jF5MU56vFhPGJyw==} engines: {node: '>=18.0.0'} peerDependencies: - effect: ^4.0.0-beta.94 + effect: ^4.0.0-beta.104 ioredis: ^5.7.0 dependencies: - '@effect/platform-node-shared': 4.0.0-beta.94(effect@4.0.0-beta.94) - effect: 4.0.0-beta.94 + '@effect/platform-node-shared': 4.0.0-beta.104(effect@4.0.0-beta.104) + effect: 4.0.0-beta.104 ioredis: 5.10.0 mime: 4.1.0 - undici: 8.2.0 + undici: 8.10.0 transitivePeerDependencies: - bufferutil - utf-8-validate @@ -1165,43 +1168,43 @@ packages: read-yaml-file: 1.1.0 dev: true - /@msgpackr-extract/msgpackr-extract-darwin-arm64@3.0.3: - resolution: {integrity: sha512-QZHtlVgbAdy2zAqNA9Gu1UpIuI8Xvsd1v8ic6B2pZmeFnFcMWiPLfWXh7TVw4eGEZ/C9TH281KwhVoeQUKbyjw==} + /@msgpackr-extract/msgpackr-extract-darwin-arm64@3.0.4: + resolution: {integrity: sha512-LCkGo6JDfaBhgST7UpPWgNgLINpcpabaHfyz5OBx75nUYxBsaEPxjnyNjWpeb/xBup/682QnBfRBy2/LvPutZQ==} cpu: [arm64] os: [darwin] requiresBuild: true optional: true - /@msgpackr-extract/msgpackr-extract-darwin-x64@3.0.3: - resolution: {integrity: sha512-mdzd3AVzYKuUmiWOQ8GNhl64/IoFGol569zNRdkLReh6LRLHOXxU4U8eq0JwaD8iFHdVGqSy4IjFL4reoWCDFw==} + /@msgpackr-extract/msgpackr-extract-darwin-x64@3.0.4: + resolution: {integrity: sha512-zExlW9zUJKZH/tOtVMttwjKa4Xm/3KcNjnE3dPN92uCktwavMxpgCA3MoJK/DOnTWsQgo224OaST27/mPNAf+w==} cpu: [x64] os: [darwin] requiresBuild: true optional: true - /@msgpackr-extract/msgpackr-extract-linux-arm64@3.0.3: - resolution: {integrity: sha512-YxQL+ax0XqBJDZiKimS2XQaf+2wDGVa1enVRGzEvLLVFeqa5kx2bWbtcSXgsxjQB7nRqqIGFIcLteF/sHeVtQg==} + /@msgpackr-extract/msgpackr-extract-linux-arm64@3.0.4: + resolution: {integrity: sha512-dgX0P/9wGPJeHFBG+ZmhgE6bmtMt7NP5CRBGyyktpopdk/mW4POnrpQsSLtKI1dwpc+pPLuXHDh6vvskyQE/sw==} cpu: [arm64] os: [linux] requiresBuild: true optional: true - /@msgpackr-extract/msgpackr-extract-linux-arm@3.0.3: - resolution: {integrity: sha512-fg0uy/dG/nZEXfYilKoRe7yALaNmHoYeIoJuJ7KJ+YyU2bvY8vPv27f7UKhGRpY6euFYqEVhxCFZgAUNQBM3nw==} + /@msgpackr-extract/msgpackr-extract-linux-arm@3.0.4: + resolution: {integrity: sha512-Tg3yX65f5GbtXLkrYEHE5oibZG9epyYWas7FogTTEJeDEF9JlXJzKgXaNhT3UXlTOeA+AfZpYZYZ0uPj7Cfquw==} cpu: [arm] os: [linux] requiresBuild: true optional: true - /@msgpackr-extract/msgpackr-extract-linux-x64@3.0.3: - resolution: {integrity: sha512-cvwNfbP07pKUfq1uH+S6KJ7dT9K8WOE4ZiAcsrSes+UY55E/0jLYc+vq+DO7jlmqRb5zAggExKm0H7O/CBaesg==} + /@msgpackr-extract/msgpackr-extract-linux-x64@3.0.4: + resolution: {integrity: sha512-8TNXMEjJc3QEy7R/x1INhgiU+XakDAFUzBhaz7+Rbrs8NH5UQeHQxxmzsSBJGyV6I1jW79undiQm8tOI+D+8FQ==} cpu: [x64] os: [linux] requiresBuild: true optional: true - /@msgpackr-extract/msgpackr-extract-win32-x64@3.0.3: - resolution: {integrity: sha512-x0fWaQtYp4E6sktbsdAqnehxDgEc/VwM7uLsRCYWaiGu0ykYdZPiS8zCWdnjHwyiumousxfBm4SO31eXqwEZhQ==} + /@msgpackr-extract/msgpackr-extract-win32-x64@3.0.4: + resolution: {integrity: sha512-CmCXPQrkbwExx3j946/PtHWHbYJiCRBRDl4BlkRQcJB/YOwQxJRTpoo7aTsortjgoJ1x7opzTSxn7C+ASSLVjQ==} cpu: [x64] os: [win32] requiresBuild: true @@ -2835,19 +2838,14 @@ packages: fast-check: 3.23.2 dev: false - /effect@4.0.0-beta.94: - resolution: {integrity: sha512-Q8BrCNbp/3Uh+7xQYHphZBkNfm2SJnl1frQ+8yWfd/j3SU3cL13D38cBMLcnULupwza2Nt4DrjZoMzHWL3CoxQ==} + /effect@4.0.0-beta.104: + resolution: {integrity: sha512-YSSaaMc8gBoHnabYXlgHpKVctsj4ezTSoojdd8SA3NWHoZ7LMPiUDhCnP1ZSOfQ7ly6P6XLhAw216NfLEHfg2A==} dependencies: '@standard-schema/spec': 1.1.0 - fast-check: 4.8.0 - find-my-way-ts: 0.1.6 - ini: 7.0.0 + fast-check: 4.9.0 kubernetes-types: 1.30.0 - msgpackr: 2.0.1 - multipasta: 0.2.7 - toml: 4.1.1 - uuid: 14.0.0 - yaml: 2.9.0 + msgpackr: 2.0.5 + uuid: 14.0.1 /electron-to-chromium@1.5.267: resolution: {integrity: sha512-0Drusm6MVRXSOJpGbaSVgcQsuB4hEkMpHXaVstcPmhu5LIedxs1xNK/nIxmQIU/RPC0+1/o0AVZfBTkTNJOdUw==} @@ -3403,8 +3401,8 @@ packages: pure-rand: 6.1.0 dev: false - /fast-check@4.8.0: - resolution: {integrity: sha512-GOJ158CUMnN6cSahsv4+ExARvIDuzzinFjkp0E9WtiBa5zcVeLozVkWaE4IzFcc+Y48Wp1EDlUZsXRyAztQcSg==} + /fast-check@4.9.0: + resolution: {integrity: sha512-7ms6T7SybUev/PQITciI0yLM2pOSFy5zpG8Ty7tQofcVaQUvrMXp6CBwqF6fThLCLOrfBtuHAtwq6Yu4XPCllg==} engines: {node: '>=12.17.0'} dependencies: pure-rand: 8.4.0 @@ -3488,6 +3486,7 @@ packages: /find-my-way-ts@0.1.6: resolution: {integrity: sha512-a85L9ZoXtNAey3Y6Z+eBWW658kO/MwR7zIafkIUPUMf3isZG0NCs2pjW2wtjxAKuJPxMAsHUIP4ZPGv0o5gyTA==} + dev: false /find-up@4.1.0: resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} @@ -3878,10 +3877,6 @@ packages: resolution: {integrity: sha512-X7rqawQBvfdjS10YU1y1YVreA3SsLrW9dX2CewP2EbBJM4ypVNLDkO5y04gejPwKIY9lR+7r9gn3rFPt/kmWFg==} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - /ini@7.0.0: - resolution: {integrity: sha512-ifK0CgjALofS5bkrcTy4RaQ9Vx2Knf/eLeIO+NaswQEpH1UblrtTSCIvN71qQDMq0PeQ/SSPojvEJp9vvvfr+w==} - engines: {node: ^22.22.2 || ^24.15.0 || >=26.0.0} - /internal-slot@1.1.0: resolution: {integrity: sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==} engines: {node: '>= 0.4'} @@ -4607,34 +4602,35 @@ packages: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} dev: true - /msgpackr-extract@3.0.3: - resolution: {integrity: sha512-P0efT1C9jIdVRefqjzOQ9Xml57zpOXnIuS+csaB4MdZbTdmGDLo8XhzBG1N7aO11gKDDkJvBLULeFTo46wwreA==} + /msgpackr-extract@3.0.4: + resolution: {integrity: sha512-4kmO/MdyUIkLIvTPr8VHLil4AtoKIoniWPIEk5+CDy0xnWC84azhSFmuJ7PxZdsYtiP5kEeQsORAVIeMgxT+Hw==} hasBin: true requiresBuild: true dependencies: node-gyp-build-optional-packages: 5.2.2 optionalDependencies: - '@msgpackr-extract/msgpackr-extract-darwin-arm64': 3.0.3 - '@msgpackr-extract/msgpackr-extract-darwin-x64': 3.0.3 - '@msgpackr-extract/msgpackr-extract-linux-arm': 3.0.3 - '@msgpackr-extract/msgpackr-extract-linux-arm64': 3.0.3 - '@msgpackr-extract/msgpackr-extract-linux-x64': 3.0.3 - '@msgpackr-extract/msgpackr-extract-win32-x64': 3.0.3 + '@msgpackr-extract/msgpackr-extract-darwin-arm64': 3.0.4 + '@msgpackr-extract/msgpackr-extract-darwin-x64': 3.0.4 + '@msgpackr-extract/msgpackr-extract-linux-arm': 3.0.4 + '@msgpackr-extract/msgpackr-extract-linux-arm64': 3.0.4 + '@msgpackr-extract/msgpackr-extract-linux-x64': 3.0.4 + '@msgpackr-extract/msgpackr-extract-win32-x64': 3.0.4 optional: true /msgpackr@1.11.8: resolution: {integrity: sha512-bC4UGzHhVvgDNS7kn9tV8fAucIYUBuGojcaLiz7v+P63Lmtm0Xeji8B/8tYKddALXxJLpwIeBmUN3u64C4YkRA==} optionalDependencies: - msgpackr-extract: 3.0.3 + msgpackr-extract: 3.0.4 dev: false - /msgpackr@2.0.1: - resolution: {integrity: sha512-9J+tqTEsbHqY8YohazYgty7LgerFIWxvMLpUjqETSmjHojtJm2WnX2kK/2a1fLI7CO7ERP1YSEUXMucz4j+yBA==} + /msgpackr@2.0.5: + resolution: {integrity: sha512-cef05H/dSYpLpqp3sj/qyZh5vhUYCalnaLO7j1yOmpsR0y/XwLVtK7r5gn+U/F7CTEfMowcGhlUQJDLcLf7jcA==} optionalDependencies: - msgpackr-extract: 3.0.3 + msgpackr-extract: 3.0.4 /multipasta@0.2.7: resolution: {integrity: sha512-KPA58d68KgGil15oDqXjkUBEBYc00XvbPj5/X+dyzeo/lWm9Nc25pQRlf1D+gv4OpK7NM0J1odrbu9JNNGvynA==} + dev: false /mz@2.7.0: resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} @@ -5804,10 +5800,6 @@ packages: resolution: {integrity: sha512-y/mWCZinnvxjTKYhJ+pYxwD0mRLVvOtdS2Awbgxln6iEnt4rk0yBxeSBHkGJcPucRiG0e55mwWp+g/05rsrd6w==} dev: false - /toml@4.1.1: - resolution: {integrity: sha512-EBJnVBr3dTXdA89WVFoAIPUqkBjxPMwRqsfuo1r240tKFHXv3zgca4+NJib/h6TyvGF7vOawz0jGuryJCdNHrw==} - engines: {node: '>=20'} - /tr46@0.0.3: resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} dev: true @@ -6026,8 +6018,8 @@ packages: engines: {node: '>=20.18.1'} dev: true - /undici@8.2.0: - resolution: {integrity: sha512-Z+4Hx9GE26Lh9Upwfnc8C7SsrpBPGaM/Gm6kMFtiG7c+5IvQKlXi/t+9x9DrrCh29cww5TSP9YdVaBcnLDs5fQ==} + /undici@8.10.0: + resolution: {integrity: sha512-HvltHd7avK13QIw/oLe4qoOLyoVSoafqJ2jYOrtMRBkbYT31eiBQ8O0ehRKZiEZCMEyLFQNIADpgCWC5fALvYQ==} engines: {node: '>=22.19.0'} dev: true @@ -6095,8 +6087,8 @@ packages: hasBin: true dev: false - /uuid@14.0.0: - resolution: {integrity: sha512-Qo+uWgilfSmAhXCMav1uYFynlQO7fMFiMVZsQqZRMIXp0O7rR7qjkj+cPvBHLgBqi960QCoo/PH2/6ZtVqKvrg==} + /uuid@14.0.1: + resolution: {integrity: sha512-6ZxzVpzDXDa3bJWaHilVayA+BH/1zmxCJoVgvmqJnid/gPoKHxUrS/aC/T6LGQtNHT+XHG9fXPJB4d+IrU30Ew==} hasBin: true /validate-npm-package-license@3.0.4: @@ -6367,8 +6359,8 @@ packages: resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} dev: true - /ws@8.20.0: - resolution: {integrity: sha512-sAt8BhgNbzCtgGbt2OxmpuryO63ZoDk/sqaB/znQm94T4fCEsy/yV+7CdC1kJhOU9lboAEU7R3kquuycDoibVA==} + /ws@8.21.2: + resolution: {integrity: sha512-54dMVAo4WIe6SKy3vBgN+9bJZqqQ8IMRevAkOLQALhi49qkkQDQfWdAZ8KQlXiEabw88ARXXdUrlvtbKQX+aKw==} engines: {node: '>=10.0.0'} peerDependencies: bufferutil: ^4.0.1 @@ -6390,11 +6382,6 @@ packages: hasBin: true dev: false - /yaml@2.9.0: - resolution: {integrity: sha512-2AvhNX3mb8zd6Zy7INTtSpl1F15HW6Wnqj0srWlkKLcpYl/gMIMJiyuGq2KeI2YFxUPjdlB+3Lc10seMLtL4cA==} - engines: {node: '>= 14.6'} - hasBin: true - /yocto-queue@0.1.0: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'}