@effect/language-service 0.77.0 → 0.78.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/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
 
3
- // ../../node_modules/.pnpm/effect@4.0.0-beta.14/node_modules/effect/dist/Pipeable.js
3
+ // ../../node_modules/.pnpm/effect@4.0.0-beta.27/node_modules/effect/dist/Pipeable.js
4
4
  var pipeArguments = (self, args3) => {
5
5
  switch (args3.length) {
6
6
  case 0:
@@ -44,7 +44,7 @@ var Class = /* @__PURE__ */ (function() {
44
44
  return PipeableBase;
45
45
  })();
46
46
 
47
- // ../../node_modules/.pnpm/effect@4.0.0-beta.14/node_modules/effect/dist/Function.js
47
+ // ../../node_modules/.pnpm/effect@4.0.0-beta.27/node_modules/effect/dist/Function.js
48
48
  var dual = function(arity, body) {
49
49
  if (typeof arity === "function") {
50
50
  return function() {
@@ -92,7 +92,7 @@ function pipe(a, ...args3) {
92
92
  return pipeArguments(a, args3);
93
93
  }
94
94
 
95
- // ../../node_modules/.pnpm/effect@4.0.0-beta.14/node_modules/effect/dist/Equivalence.js
95
+ // ../../node_modules/.pnpm/effect@4.0.0-beta.27/node_modules/effect/dist/Equivalence.js
96
96
  var make = (isEquivalent) => (self, that) => self === that || isEquivalent(self, that);
97
97
  function Array2(item) {
98
98
  return make((self, that) => {
@@ -104,7 +104,7 @@ function Array2(item) {
104
104
  });
105
105
  }
106
106
 
107
- // ../../node_modules/.pnpm/effect@4.0.0-beta.14/node_modules/effect/dist/internal/equal.js
107
+ // ../../node_modules/.pnpm/effect@4.0.0-beta.27/node_modules/effect/dist/internal/equal.js
108
108
  var getAllObjectKeys = (obj) => {
109
109
  const keys2 = new Set(Reflect.ownKeys(obj));
110
110
  if (obj.constructor === Object) return keys2;
@@ -127,7 +127,7 @@ var getAllObjectKeys = (obj) => {
127
127
  };
128
128
  var byReferenceInstances = /* @__PURE__ */ new WeakSet();
129
129
 
130
- // ../../node_modules/.pnpm/effect@4.0.0-beta.14/node_modules/effect/dist/Predicate.js
130
+ // ../../node_modules/.pnpm/effect@4.0.0-beta.27/node_modules/effect/dist/Predicate.js
131
131
  function isString(input) {
132
132
  return typeof input === "string";
133
133
  }
@@ -148,7 +148,7 @@ function isObjectKeyword(input) {
148
148
  }
149
149
  var hasProperty = /* @__PURE__ */ dual(2, (self, property) => isObjectKeyword(self) && property in self);
150
150
 
151
- // ../../node_modules/.pnpm/effect@4.0.0-beta.14/node_modules/effect/dist/Hash.js
151
+ // ../../node_modules/.pnpm/effect@4.0.0-beta.27/node_modules/effect/dist/Hash.js
152
152
  var symbol = "~effect/interfaces/Hash";
153
153
  var hash = (self) => {
154
154
  switch (typeof self) {
@@ -267,7 +267,7 @@ function withVisitedTracking(obj, fn2) {
267
267
  return result;
268
268
  }
269
269
 
270
- // ../../node_modules/.pnpm/effect@4.0.0-beta.14/node_modules/effect/dist/Equal.js
270
+ // ../../node_modules/.pnpm/effect@4.0.0-beta.27/node_modules/effect/dist/Equal.js
271
271
  var symbol2 = "~effect/interfaces/Equal";
272
272
  function equals() {
273
273
  if (arguments.length === 1) {
@@ -429,7 +429,7 @@ var compareSets = /* @__PURE__ */ makeCompareSet(compareBoth);
429
429
  var isEqual = (u) => hasProperty(u, symbol2);
430
430
  var asEquivalence = () => equals;
431
431
 
432
- // ../../node_modules/.pnpm/effect@4.0.0-beta.14/node_modules/effect/dist/Redactable.js
432
+ // ../../node_modules/.pnpm/effect@4.0.0-beta.27/node_modules/effect/dist/Redactable.js
433
433
  var symbolRedactable = /* @__PURE__ */ Symbol.for("~effect/Inspectable/redactable");
434
434
  var isRedactable = (u) => hasProperty(u, symbolRedactable);
435
435
  function redact(u) {
@@ -448,7 +448,7 @@ var emptyServiceMap = {
448
448
  }
449
449
  };
450
450
 
451
- // ../../node_modules/.pnpm/effect@4.0.0-beta.14/node_modules/effect/dist/Formatter.js
451
+ // ../../node_modules/.pnpm/effect@4.0.0-beta.27/node_modules/effect/dist/Formatter.js
452
452
  function format(input, options) {
453
453
  const space = options?.space ?? 0;
454
454
  const seen = /* @__PURE__ */ new WeakSet();
@@ -527,7 +527,7 @@ function safeToString(input) {
527
527
  }
528
528
  }
529
529
 
530
- // ../../node_modules/.pnpm/effect@4.0.0-beta.14/node_modules/effect/dist/Inspectable.js
530
+ // ../../node_modules/.pnpm/effect@4.0.0-beta.27/node_modules/effect/dist/Inspectable.js
531
531
  var NodeInspectSymbol = /* @__PURE__ */ Symbol.for("nodejs.util.inspect.custom");
532
532
  var toJson = (input) => {
533
533
  try {
@@ -571,7 +571,7 @@ var Class2 = class {
571
571
  }
572
572
  };
573
573
 
574
- // ../../node_modules/.pnpm/effect@4.0.0-beta.14/node_modules/effect/dist/Utils.js
574
+ // ../../node_modules/.pnpm/effect@4.0.0-beta.27/node_modules/effect/dist/Utils.js
575
575
  var GenKindTypeId = "~effect/Utils/GenKind";
576
576
  var GenKindImpl = class {
577
577
  value;
@@ -639,7 +639,7 @@ var internalCall = isNotOptimizedAway ? standard[InternalTypeId] : forced[Intern
639
639
  var genConstructor = function* () {
640
640
  }.constructor;
641
641
 
642
- // ../../node_modules/.pnpm/effect@4.0.0-beta.14/node_modules/effect/dist/internal/core.js
642
+ // ../../node_modules/.pnpm/effect@4.0.0-beta.27/node_modules/effect/dist/internal/core.js
643
643
  var EffectTypeId = `~effect/Effect`;
644
644
  var ExitTypeId = `~effect/Exit`;
645
645
  var effectVariance = {
@@ -986,7 +986,7 @@ var DoneVoid = {
986
986
  value: void 0
987
987
  };
988
988
 
989
- // ../../node_modules/.pnpm/effect@4.0.0-beta.14/node_modules/effect/dist/internal/option.js
989
+ // ../../node_modules/.pnpm/effect@4.0.0-beta.27/node_modules/effect/dist/internal/option.js
990
990
  var TypeId = "~effect/data/Option";
991
991
  var CommonProto = {
992
992
  [TypeId]: {
@@ -1051,7 +1051,7 @@ var some = (value) => {
1051
1051
  return a;
1052
1052
  };
1053
1053
 
1054
- // ../../node_modules/.pnpm/effect@4.0.0-beta.14/node_modules/effect/dist/internal/result.js
1054
+ // ../../node_modules/.pnpm/effect@4.0.0-beta.27/node_modules/effect/dist/internal/result.js
1055
1055
  var TypeId2 = "~effect/data/Result";
1056
1056
  var CommonProto2 = {
1057
1057
  [TypeId2]: {
@@ -1122,7 +1122,7 @@ var succeed = (success) => {
1122
1122
  return a;
1123
1123
  };
1124
1124
 
1125
- // ../../node_modules/.pnpm/effect@4.0.0-beta.14/node_modules/effect/dist/Result.js
1125
+ // ../../node_modules/.pnpm/effect@4.0.0-beta.27/node_modules/effect/dist/Result.js
1126
1126
  var succeed2 = succeed;
1127
1127
  var fail2 = fail;
1128
1128
  var isFailure2 = isFailure;
@@ -1130,7 +1130,10 @@ var isSuccess2 = isSuccess;
1130
1130
  var map = /* @__PURE__ */ dual(2, (self, f) => isSuccess2(self) ? succeed2(f(self.success)) : fail2(self.failure));
1131
1131
  var getOrElse = /* @__PURE__ */ dual(2, (self, onFailure) => isFailure2(self) ? onFailure(self.failure) : self.success);
1132
1132
 
1133
- // ../../node_modules/.pnpm/effect@4.0.0-beta.14/node_modules/effect/dist/Order.js
1133
+ // ../../node_modules/.pnpm/effect@4.0.0-beta.27/node_modules/effect/dist/internal/array.js
1134
+ var isArrayNonEmpty = (self) => self.length > 0;
1135
+
1136
+ // ../../node_modules/.pnpm/effect@4.0.0-beta.27/node_modules/effect/dist/Order.js
1134
1137
  function make2(compare) {
1135
1138
  return (self, that) => self === that ? 0 : compare(self, that);
1136
1139
  }
@@ -1153,7 +1156,7 @@ var combine2 = /* @__PURE__ */ dual(2, (self, that) => make2((a1, a2) => {
1153
1156
  }));
1154
1157
  var mapInput = /* @__PURE__ */ dual(2, (self, f) => make2((b1, b2) => self(f(b1), f(b2))));
1155
1158
 
1156
- // ../../node_modules/.pnpm/effect@4.0.0-beta.14/node_modules/effect/dist/Option.js
1159
+ // ../../node_modules/.pnpm/effect@4.0.0-beta.27/node_modules/effect/dist/Option.js
1157
1160
  var none2 = () => none;
1158
1161
  var some2 = some;
1159
1162
  var isNone2 = isNone;
@@ -1164,18 +1167,7 @@ var fromNullishOr = (a) => a == null ? none2() : some2(a);
1164
1167
  var getOrUndefined = /* @__PURE__ */ getOrElse2(constUndefined);
1165
1168
  var map2 = /* @__PURE__ */ dual(2, (self, f) => isNone2(self) ? none2() : some2(f(self.value)));
1166
1169
 
1167
- // ../../node_modules/.pnpm/effect@4.0.0-beta.14/node_modules/effect/dist/Filter.js
1168
- var apply = (filter2, input, ...args3) => {
1169
- const result = filter2(input, ...args3);
1170
- if (result === true) return succeed2(input);
1171
- if (result === false) return fail2(input);
1172
- return result;
1173
- };
1174
-
1175
- // ../../node_modules/.pnpm/effect@4.0.0-beta.14/node_modules/effect/dist/internal/array.js
1176
- var isArrayNonEmpty = (self) => self.length > 0;
1177
-
1178
- // ../../node_modules/.pnpm/effect@4.0.0-beta.14/node_modules/effect/dist/Record.js
1170
+ // ../../node_modules/.pnpm/effect@4.0.0-beta.27/node_modules/effect/dist/Record.js
1179
1171
  var map3 = /* @__PURE__ */ dual(2, (self, f) => {
1180
1172
  const out = {
1181
1173
  ...self
@@ -1187,7 +1179,7 @@ var map3 = /* @__PURE__ */ dual(2, (self, f) => {
1187
1179
  });
1188
1180
  var keys = (self) => Object.keys(self);
1189
1181
 
1190
- // ../../node_modules/.pnpm/effect@4.0.0-beta.14/node_modules/effect/dist/Array.js
1182
+ // ../../node_modules/.pnpm/effect@4.0.0-beta.27/node_modules/effect/dist/Array.js
1191
1183
  var Array3 = globalThis.Array;
1192
1184
  var fromIterable = (collection) => Array3.isArray(collection) ? collection : Array3.from(collection);
1193
1185
  var append = /* @__PURE__ */ dual(2, (self, last) => [...self, last]);
@@ -1250,30 +1242,16 @@ var flatMap = /* @__PURE__ */ dual(2, (self, f) => {
1250
1242
  return out;
1251
1243
  });
1252
1244
  var flatten = /* @__PURE__ */ flatMap(identity);
1253
- var filter = /* @__PURE__ */ dual(2, (self, f) => {
1245
+ var filter = /* @__PURE__ */ dual(2, (self, predicate) => {
1254
1246
  const as = fromIterable(self);
1255
1247
  const out = [];
1256
1248
  for (let i = 0; i < as.length; i++) {
1257
- const result = apply(f, as[i], i);
1258
- if (!isFailure2(result)) {
1259
- out.push(result.success);
1249
+ if (predicate(as[i], i)) {
1250
+ out.push(as[i]);
1260
1251
  }
1261
1252
  }
1262
1253
  return out;
1263
1254
  });
1264
- var partition = /* @__PURE__ */ dual(2, (self, f) => {
1265
- const excluded = [];
1266
- const satisfying = [];
1267
- const as = fromIterable(self);
1268
- for (let i = 0; i < as.length; i++) {
1269
- const result = f(as[i], i);
1270
- if (result === true) satisfying.push(as[i]);
1271
- else if (result === false) excluded.push(as[i]);
1272
- else if (isSuccess2(result)) satisfying.push(result.success);
1273
- else excluded.push(result.failure);
1274
- }
1275
- return [excluded, satisfying];
1276
- });
1277
1255
  var every = /* @__PURE__ */ dual(2, (self, refinement) => self.every(refinement));
1278
1256
  var dedupeWith = /* @__PURE__ */ dual(2, (self, isEquivalent) => {
1279
1257
  const input = fromIterable(self);
@@ -1292,7 +1270,7 @@ var dedupeWith = /* @__PURE__ */ dual(2, (self, isEquivalent) => {
1292
1270
  var dedupe = (self) => dedupeWith(self, asEquivalence());
1293
1271
  var join = /* @__PURE__ */ dual(2, (self, sep) => fromIterable(self).join(sep));
1294
1272
 
1295
- // ../../node_modules/.pnpm/effect@4.0.0-beta.14/node_modules/effect/dist/Data.js
1273
+ // ../../node_modules/.pnpm/effect@4.0.0-beta.27/node_modules/effect/dist/Data.js
1296
1274
  var Class3 = class extends Class {
1297
1275
  constructor(props) {
1298
1276
  super();
@@ -1303,7 +1281,7 @@ var Class3 = class extends Class {
1303
1281
  };
1304
1282
  var TaggedError2 = TaggedError;
1305
1283
 
1306
- // ../../node_modules/.pnpm/effect@4.0.0-beta.14/node_modules/effect/dist/Encoding.js
1284
+ // ../../node_modules/.pnpm/effect@4.0.0-beta.27/node_modules/effect/dist/Encoding.js
1307
1285
  var EncodingErrorTypeId = "~effect/encoding/EncodingError";
1308
1286
  var EncodingError = class extends (/* @__PURE__ */ TaggedError2("EncodingError")) {
1309
1287
  /**
@@ -1339,7 +1317,7 @@ var base64EncodeUint8Array = (bytes) => {
1339
1317
  var base64abc = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "+", "/"];
1340
1318
  var base64UrlEncodeUint8Array = (data) => base64EncodeUint8Array(data).replace(/=/g, "").replace(/\+/g, "-").replace(/\//g, "_");
1341
1319
 
1342
- // ../../node_modules/.pnpm/effect@4.0.0-beta.14/node_modules/effect/dist/Graph.js
1320
+ // ../../node_modules/.pnpm/effect@4.0.0-beta.27/node_modules/effect/dist/Graph.js
1343
1321
  var TypeId3 = "~effect/collections/Graph";
1344
1322
  var Edge = class extends Class3 {
1345
1323
  };
@@ -2263,7 +2241,9 @@ function parse(config) {
2263
2241
  keyPatterns: isObject(config) && hasProperty(config, "keyPatterns") && isArray(config.keyPatterns) ? parseKeyPatterns(config.keyPatterns) : defaults.keyPatterns,
2264
2242
  extendedKeyDetection: isObject(config) && hasProperty(config, "extendedKeyDetection") && isBoolean(config.extendedKeyDetection) ? config.extendedKeyDetection : defaults.extendedKeyDetection,
2265
2243
  pipeableMinArgCount: isObject(config) && hasProperty(config, "pipeableMinArgCount") && isNumber(config.pipeableMinArgCount) ? config.pipeableMinArgCount : defaults.pipeableMinArgCount,
2266
- effectFn: isObject(config) && hasProperty(config, "effectFn") && isArray(config.effectFn) && config.effectFn.every(isString) ? config.effectFn.map((_) => _.toLowerCase()) : defaults.effectFn,
2244
+ effectFn: isObject(config) && hasProperty(config, "effectFn") && isArray(config.effectFn) && config.effectFn.every(isString) ? config.effectFn.map(
2245
+ (_) => _.toLowerCase()
2246
+ ) : defaults.effectFn,
2267
2247
  layerGraphFollowDepth: isObject(config) && hasProperty(config, "layerGraphFollowDepth") && isNumber(config.layerGraphFollowDepth) ? config.layerGraphFollowDepth : defaults.layerGraphFollowDepth,
2268
2248
  mermaidProvider: isObject(config) && hasProperty(config, "mermaidProvider") && isString(config.mermaidProvider) ? config.mermaidProvider : defaults.mermaidProvider
2269
2249
  };
@@ -4043,6 +4023,14 @@ function make3(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
4043
4023
  const layerType = cachedBy(
4044
4024
  fn("TypeParser.layerType")(function* (type, atLocation) {
4045
4025
  yield* pipeableType(type, atLocation);
4026
+ if (supportedEffect() === "v4") {
4027
+ const typeIdSymbol = typeChecker.getPropertyOfType(type, "~effect/Layer");
4028
+ if (typeIdSymbol) {
4029
+ const typeIdType = typeChecker.getTypeOfSymbolAtLocation(typeIdSymbol, atLocation);
4030
+ return yield* layerVarianceStruct(typeIdType, atLocation);
4031
+ }
4032
+ return yield* typeParserIssue("Type is not a layer", type, atLocation);
4033
+ }
4046
4034
  const propertiesSymbols = typeChecker.getPropertiesOfType(type).filter(
4047
4035
  (_) => _.flags & ts.SymbolFlags.Property && !(_.flags & ts.SymbolFlags.Optional) && _.valueDeclaration
4048
4036
  );
@@ -4092,6 +4080,34 @@ function make3(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
4092
4080
  "TypeParser.effectSubtype",
4093
4081
  (type) => type
4094
4082
  );
4083
+ const effectYieldableType = cachedBy(
4084
+ fn("TypeParser.effectYieldableType")(function* (type, atLocation) {
4085
+ if (supportedEffect() === "v3") {
4086
+ return yield* effectType(type, atLocation);
4087
+ }
4088
+ return yield* firstSuccessOf([
4089
+ effectType(type, atLocation),
4090
+ gen(function* () {
4091
+ const asEffectSymbol = typeChecker.getPropertyOfType(type, "asEffect");
4092
+ if (!asEffectSymbol) {
4093
+ return yield* typeParserIssue("Type has no 'asEffect' property", type, atLocation);
4094
+ }
4095
+ const asEffectType = typeChecker.getTypeOfSymbolAtLocation(asEffectSymbol, atLocation);
4096
+ const asEffectSignatures = typeChecker.getSignaturesOfType(asEffectType, ts.SignatureKind.Call);
4097
+ if (asEffectSignatures.length === 0) {
4098
+ return yield* typeParserIssue("'asEffect' property is not callable", type, atLocation);
4099
+ }
4100
+ return yield* firstSuccessOf(
4101
+ asEffectSignatures.map(
4102
+ (signature) => effectType(typeChecker.getReturnTypeOfSignature(signature), atLocation)
4103
+ )
4104
+ );
4105
+ })
4106
+ ]);
4107
+ }),
4108
+ "TypeParser.effectYieldableType",
4109
+ (type) => type
4110
+ );
4095
4111
  const isEffectContextSourceFile = cachedBy(
4096
4112
  fn("TypeParser.isEffectContextSourceFile")(function* (sourceFile) {
4097
4113
  const moduleSymbol = typeChecker.getSymbolAtLocation(sourceFile);
@@ -5719,6 +5735,7 @@ function make3(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
5719
5735
  layerType,
5720
5736
  fiberType,
5721
5737
  effectSubtype,
5738
+ effectYieldableType,
5722
5739
  importedEffectModule,
5723
5740
  effectGen,
5724
5741
  effectFnUntracedGen,
@@ -7596,16 +7613,16 @@ var effectFnOpportunity = createDiagnostic({
7596
7613
  if (ts.isFunctionDeclaration(node) && node.name) {
7597
7614
  return node.name;
7598
7615
  }
7599
- if (node.parent && ts.isVariableDeclaration(node.parent) && ts.isIdentifier(node.parent.name)) {
7616
+ if (node.parent && ts.isVariableDeclaration(node.parent) && ts.isIdentifier(node.parent.name) && node.parent.initializer === node) {
7600
7617
  return node.parent.name;
7601
7618
  }
7602
- if (node.parent && ts.isPropertyAssignment(node.parent)) {
7619
+ if (node.parent && ts.isPropertyAssignment(node.parent) && node.parent.initializer === node) {
7603
7620
  const name = node.parent.name;
7604
7621
  if (ts.isIdentifier(name) || ts.isStringLiteral(name)) {
7605
7622
  return name;
7606
7623
  }
7607
7624
  }
7608
- if (node.parent && ts.isPropertyDeclaration(node.parent)) {
7625
+ if (node.parent && ts.isPropertyDeclaration(node.parent) && node.parent.initializer === node) {
7609
7626
  const name = node.parent.name;
7610
7627
  if (ts.isIdentifier(name)) {
7611
7628
  return name;
@@ -7613,6 +7630,190 @@ var effectFnOpportunity = createDiagnostic({
7613
7630
  }
7614
7631
  return void 0;
7615
7632
  };
7633
+ const hasExportModifier = (node) => {
7634
+ if (!ts.canHaveModifiers(node)) return false;
7635
+ const modifiers = ts.getModifiers(node);
7636
+ return modifiers?.some((modifier) => modifier.kind === ts.SyntaxKind.ExportKeyword) ?? false;
7637
+ };
7638
+ const layerServiceNameFromExpression = (expression) => {
7639
+ if (expression.kind === ts.SyntaxKind.ThisKeyword) {
7640
+ const enclosingClass = ts.findAncestor(
7641
+ expression,
7642
+ (node) => ts.isClassDeclaration(node)
7643
+ );
7644
+ if (enclosingClass?.name) {
7645
+ return ts.idText(enclosingClass.name);
7646
+ }
7647
+ }
7648
+ if (ts.isIdentifier(expression)) return ts.idText(expression);
7649
+ return sourceFile.text.slice(expression.pos, expression.end).trim();
7650
+ };
7651
+ const tryGetLayerApiMethod = (node) => pipe(
7652
+ typeParser.isNodeReferenceToEffectLayerModuleApi("effect")(node),
7653
+ map5(() => "effect"),
7654
+ orElse2(
7655
+ () => pipe(
7656
+ typeParser.isNodeReferenceToEffectLayerModuleApi("succeed")(node),
7657
+ map5(() => "succeed"),
7658
+ orElse2(
7659
+ () => pipe(
7660
+ typeParser.isNodeReferenceToEffectLayerModuleApi("sync")(node),
7661
+ map5(() => "sync"),
7662
+ orElse2(() => succeed3(void 0))
7663
+ )
7664
+ )
7665
+ )
7666
+ )
7667
+ );
7668
+ const verifyLayerMethodAtCall = fn("effectFnOpportunity.verifyLayerMethodAtCall")(
7669
+ function* (callExpression, method, implementationExpression) {
7670
+ const directMethod = yield* tryGetLayerApiMethod(callExpression.expression);
7671
+ if (directMethod === method && callExpression.arguments.length >= 2 && callExpression.arguments[1] === implementationExpression) {
7672
+ return layerServiceNameFromExpression(callExpression.arguments[0]);
7673
+ }
7674
+ if (ts.isCallExpression(callExpression.expression)) {
7675
+ const innerCall = callExpression.expression;
7676
+ const innerMethod = yield* tryGetLayerApiMethod(innerCall.expression);
7677
+ if (innerMethod === method && innerCall.arguments.length >= 1 && callExpression.arguments.length >= 1 && callExpression.arguments[0] === implementationExpression) {
7678
+ return layerServiceNameFromExpression(innerCall.arguments[0]);
7679
+ }
7680
+ }
7681
+ return void 0;
7682
+ }
7683
+ );
7684
+ const tryMatchLayerSucceedInference = fn("effectFnOpportunity.tryMatchLayerSucceedInference")(
7685
+ function* (objectLiteral) {
7686
+ const callExpression = objectLiteral.parent;
7687
+ if (!callExpression || !ts.isCallExpression(callExpression)) return void 0;
7688
+ return yield* verifyLayerMethodAtCall(callExpression, "succeed", objectLiteral);
7689
+ }
7690
+ );
7691
+ const tryMatchLayerSyncInference = fn("effectFnOpportunity.tryMatchLayerSyncInference")(
7692
+ function* (objectLiteral) {
7693
+ const returnStatement = objectLiteral.parent;
7694
+ if (!returnStatement || !ts.isReturnStatement(returnStatement)) return void 0;
7695
+ const functionBody = returnStatement.parent;
7696
+ if (!functionBody || !ts.isBlock(functionBody)) return void 0;
7697
+ const lazyFunction = functionBody.parent;
7698
+ if (!lazyFunction || !ts.isArrowFunction(lazyFunction) && !ts.isFunctionExpression(lazyFunction)) {
7699
+ return void 0;
7700
+ }
7701
+ const callExpression = lazyFunction.parent;
7702
+ if (!callExpression || !ts.isCallExpression(callExpression)) return void 0;
7703
+ return yield* verifyLayerMethodAtCall(callExpression, "sync", lazyFunction);
7704
+ }
7705
+ );
7706
+ const tryMatchLayerEffectInference = fn("effectFnOpportunity.tryMatchLayerEffectInference")(
7707
+ function* (objectLiteral) {
7708
+ const returnStatement = objectLiteral.parent;
7709
+ if (!returnStatement || !ts.isReturnStatement(returnStatement)) return void 0;
7710
+ const generatorBody = returnStatement.parent;
7711
+ if (!generatorBody || !ts.isBlock(generatorBody)) return void 0;
7712
+ const generatorFunction = generatorBody.parent;
7713
+ if (!generatorFunction || !ts.isFunctionExpression(generatorFunction) || !generatorFunction.asteriskToken) {
7714
+ return void 0;
7715
+ }
7716
+ const genCall = generatorFunction.parent;
7717
+ if (!genCall || !ts.isCallExpression(genCall)) return void 0;
7718
+ const parsedEffectGen = yield* option(typeParser.effectGen(genCall));
7719
+ if (parsedEffectGen._tag === "None" || parsedEffectGen.value.generatorFunction !== generatorFunction) {
7720
+ return void 0;
7721
+ }
7722
+ const layerCall = genCall.parent;
7723
+ if (!layerCall || !ts.isCallExpression(layerCall)) return void 0;
7724
+ return yield* verifyLayerMethodAtCall(layerCall, "effect", genCall);
7725
+ }
7726
+ );
7727
+ const tryMatchOfInference = fn("effectFnOpportunity.tryMatchOfInference")(
7728
+ function* (objectLiteral) {
7729
+ const callExpression = objectLiteral.parent;
7730
+ if (!callExpression || !ts.isCallExpression(callExpression)) return void 0;
7731
+ if (callExpression.arguments.length < 1 || callExpression.arguments[0] !== objectLiteral) return void 0;
7732
+ if (!ts.isPropertyAccessExpression(callExpression.expression)) return void 0;
7733
+ if (ts.idText(callExpression.expression.name) !== "of") return void 0;
7734
+ const serviceTagExpression = callExpression.expression.expression;
7735
+ const serviceTagType = typeCheckerUtils.getTypeAtLocation(serviceTagExpression);
7736
+ if (!serviceTagType) return void 0;
7737
+ const isTagLike = yield* pipe(
7738
+ typeParser.contextTag(serviceTagType, serviceTagExpression),
7739
+ orElse2(() => typeParser.serviceType(serviceTagType, serviceTagExpression)),
7740
+ option
7741
+ );
7742
+ if (isTagLike._tag === "None") return void 0;
7743
+ return layerServiceNameFromExpression(serviceTagExpression);
7744
+ }
7745
+ );
7746
+ const tryMatchServiceMapMakeInference = fn("effectFnOpportunity.tryMatchServiceMapMakeInference")(
7747
+ function* (objectLiteral) {
7748
+ const returnStatement = objectLiteral.parent;
7749
+ if (!returnStatement || !ts.isReturnStatement(returnStatement)) return void 0;
7750
+ const generatorBody = returnStatement.parent;
7751
+ if (!generatorBody || !ts.isBlock(generatorBody)) return void 0;
7752
+ const generatorFunction = generatorBody.parent;
7753
+ if (!generatorFunction || !ts.isFunctionExpression(generatorFunction) || !generatorFunction.asteriskToken) {
7754
+ return void 0;
7755
+ }
7756
+ const genCall = generatorFunction.parent;
7757
+ if (!genCall || !ts.isCallExpression(genCall)) return void 0;
7758
+ const parsedEffectGen = yield* option(typeParser.effectGen(genCall));
7759
+ if (parsedEffectGen._tag === "None" || parsedEffectGen.value.generatorFunction !== generatorFunction) {
7760
+ return void 0;
7761
+ }
7762
+ const makeProperty = genCall.parent;
7763
+ if (!makeProperty || !ts.isPropertyAssignment(makeProperty)) return void 0;
7764
+ if (makeProperty.initializer !== genCall) return void 0;
7765
+ if (!ts.isIdentifier(makeProperty.name) || ts.idText(makeProperty.name) !== "make") return void 0;
7766
+ let currentNode = makeProperty.parent;
7767
+ let classDeclaration = void 0;
7768
+ while (currentNode) {
7769
+ if (ts.isClassDeclaration(currentNode)) {
7770
+ classDeclaration = currentNode;
7771
+ break;
7772
+ }
7773
+ currentNode = currentNode.parent;
7774
+ }
7775
+ if (!classDeclaration || !classDeclaration.name) return void 0;
7776
+ const parsedServiceMapService = yield* option(typeParser.extendsServiceMapService(classDeclaration));
7777
+ if (parsedServiceMapService._tag === "None") return void 0;
7778
+ return ts.idText(classDeclaration.name);
7779
+ }
7780
+ );
7781
+ const tryGetLayerInferredTraceName = fn("effectFnOpportunity.tryGetLayerInferredTraceName")(
7782
+ function* (node, suggestedTraceName) {
7783
+ if (!suggestedTraceName) return void 0;
7784
+ if (!(node.parent && ts.isPropertyAssignment(node.parent) && node.parent.initializer === node && node.parent.parent && ts.isObjectLiteralExpression(node.parent.parent))) {
7785
+ return void 0;
7786
+ }
7787
+ const objectLiteral = node.parent.parent;
7788
+ const succeedServiceName = yield* tryMatchLayerSucceedInference(objectLiteral);
7789
+ if (succeedServiceName) return `${succeedServiceName}.${suggestedTraceName}`;
7790
+ const syncServiceName = yield* tryMatchLayerSyncInference(objectLiteral);
7791
+ if (syncServiceName) return `${syncServiceName}.${suggestedTraceName}`;
7792
+ const effectServiceName = yield* tryMatchLayerEffectInference(objectLiteral);
7793
+ if (effectServiceName) return `${effectServiceName}.${suggestedTraceName}`;
7794
+ const ofServiceName = yield* tryMatchOfInference(objectLiteral);
7795
+ if (ofServiceName) return `${ofServiceName}.${suggestedTraceName}`;
7796
+ const serviceMapMakeServiceName = yield* tryMatchServiceMapMakeInference(objectLiteral);
7797
+ return serviceMapMakeServiceName ? `${serviceMapMakeServiceName}.${suggestedTraceName}` : void 0;
7798
+ }
7799
+ );
7800
+ const getInferredTraceName = fn("effectFnOpportunity.getInferredTraceName")(
7801
+ function* (node, suggestedTraceName) {
7802
+ const inferredFromLayer = yield* tryGetLayerInferredTraceName(node, suggestedTraceName);
7803
+ if (inferredFromLayer) return inferredFromLayer;
7804
+ if (ts.isFunctionDeclaration(node) && node.name && hasExportModifier(node)) {
7805
+ return ts.idText(node.name);
7806
+ }
7807
+ if (node.parent && ts.isVariableDeclaration(node.parent) && ts.isIdentifier(node.parent.name) && node.parent.initializer === node) {
7808
+ const variableDeclarationList = node.parent.parent;
7809
+ const variableStatement = variableDeclarationList?.parent;
7810
+ if (variableDeclarationList && ts.isVariableDeclarationList(variableDeclarationList) && variableStatement && ts.isVariableStatement(variableStatement) && hasExportModifier(variableStatement) && (variableDeclarationList.flags & ts.NodeFlags.Const) !== 0) {
7811
+ return ts.idText(node.parent.name);
7812
+ }
7813
+ }
7814
+ return void 0;
7815
+ }
7816
+ );
7616
7817
  const areParametersReferencedIn = (fnNode, nodes2) => {
7617
7818
  if (fnNode.parameters.length === 0 || nodes2.length === 0) return false;
7618
7819
  const firstParam = fnNode.parameters[0];
@@ -7697,7 +7898,10 @@ var effectFnOpportunity = createDiagnostic({
7697
7898
  );
7698
7899
  };
7699
7900
  const parseEffectFnOpportunityTargetGen = fn("effectFnOpportunity.parseEffectFnOpportunityTarget")(
7700
- function* (node, returnType, traceName, nameIdentifier) {
7901
+ function* (node, returnType, nameIdentifier) {
7902
+ const suggestedTraceName = nameIdentifier ? ts.isIdentifier(nameIdentifier) ? ts.idText(nameIdentifier) : nameIdentifier.text : void 0;
7903
+ const inferredTraceName = yield* getInferredTraceName(node, suggestedTraceName);
7904
+ const hasStrictLayerInferredName = inferredTraceName !== void 0 && inferredTraceName !== suggestedTraceName;
7701
7905
  if (yield* isInsideEffectFn(node)) {
7702
7906
  return yield* TypeParserIssue.issue;
7703
7907
  }
@@ -7706,11 +7910,11 @@ var effectFnOpportunity = createDiagnostic({
7706
7910
  const opportunity = yield* pipe(
7707
7911
  tryParseGenOpportunity(node),
7708
7912
  orElse2(() => {
7709
- if (ts.isArrowFunction(node) && !ts.isBlock(node.body)) {
7913
+ if (ts.isArrowFunction(node) && !ts.isBlock(node.body) && !hasStrictLayerInferredName) {
7710
7914
  return TypeParserIssue.issue;
7711
7915
  }
7712
7916
  const body = ts.isArrowFunction(node) ? node.body : node.body;
7713
- if (!body || !ts.isBlock(body) || body.statements.length <= 5) {
7917
+ if ((!body || !ts.isBlock(body) || body.statements.length <= 5) && !hasStrictLayerInferredName) {
7714
7918
  return TypeParserIssue.issue;
7715
7919
  }
7716
7920
  return succeed3({
@@ -7725,7 +7929,8 @@ var effectFnOpportunity = createDiagnostic({
7725
7929
  node,
7726
7930
  nameIdentifier,
7727
7931
  effectModuleName: opportunity.effectModuleName,
7728
- inferredTraceName: traceName,
7932
+ inferredTraceName,
7933
+ suggestedTraceName,
7729
7934
  explicitTraceExpression: opportunity.explicitTraceExpression,
7730
7935
  pipeArguments: opportunity.pipeArguments,
7731
7936
  generatorFunction: opportunity.generatorFunction,
@@ -7735,27 +7940,26 @@ var effectFnOpportunity = createDiagnostic({
7735
7940
  );
7736
7941
  const parseEffectFnOpportunityTarget = (node) => {
7737
7942
  if (!ts.isFunctionExpression(node) && !ts.isArrowFunction(node) && !ts.isFunctionDeclaration(node)) {
7738
- return TypeParserIssue.issue;
7943
+ return;
7739
7944
  }
7740
7945
  if ((ts.isFunctionExpression(node) || ts.isFunctionDeclaration(node)) && node.asteriskToken) {
7741
- return TypeParserIssue.issue;
7946
+ return;
7742
7947
  }
7743
7948
  if (ts.isFunctionExpression(node) && node.name) {
7744
- return TypeParserIssue.issue;
7949
+ return;
7745
7950
  }
7746
7951
  if (node.type) {
7747
- return TypeParserIssue.issue;
7952
+ return;
7748
7953
  }
7749
7954
  const functionType = typeChecker.getTypeAtLocation(node);
7750
- if (!functionType) return TypeParserIssue.issue;
7955
+ if (!functionType) return;
7751
7956
  const callSignatures = typeChecker.getSignaturesOfType(functionType, ts.SignatureKind.Call);
7752
- if (callSignatures.length !== 1) return TypeParserIssue.issue;
7957
+ if (callSignatures.length !== 1) return;
7753
7958
  const signature = callSignatures[0];
7754
7959
  const returnType = typeChecker.getReturnTypeOfSignature(signature);
7755
7960
  const nameIdentifier = getNameIdentifier(node);
7756
- const traceName = nameIdentifier ? ts.isIdentifier(nameIdentifier) ? ts.idText(nameIdentifier) : nameIdentifier.text : void 0;
7757
- if (!traceName) return TypeParserIssue.issue;
7758
- return parseEffectFnOpportunityTargetGen(node, returnType, traceName, nameIdentifier);
7961
+ if (!nameIdentifier) return;
7962
+ return parseEffectFnOpportunityTargetGen(node, returnType, nameIdentifier);
7759
7963
  };
7760
7964
  const getFunctionBodyBlock = (node) => {
7761
7965
  if (ts.isArrowFunction(node)) {
@@ -7829,18 +8033,21 @@ var effectFnOpportunity = createDiagnostic({
7829
8033
  while (nodeToVisit.length > 0) {
7830
8034
  const node = nodeToVisit.shift();
7831
8035
  ts.forEachChild(node, appendNodeToVisit);
7832
- const target = yield* pipe(parseEffectFnOpportunityTarget(node), option);
7833
- if (isNone2(target)) continue;
7834
- if (target.value.hasParamsInPipeArgs) continue;
8036
+ const test = parseEffectFnOpportunityTarget(node);
8037
+ if (!test) continue;
8038
+ const target = yield* orUndefined(test);
8039
+ if (!target) continue;
8040
+ if (target.hasParamsInPipeArgs) continue;
7835
8041
  const {
7836
8042
  effectModuleName,
7837
8043
  explicitTraceExpression,
7838
8044
  inferredTraceName,
7839
8045
  nameIdentifier,
7840
8046
  node: targetNode,
7841
- pipeArguments: pipeArguments2
7842
- } = target.value;
7843
- const innerFunction = target.value.generatorFunction ?? targetNode;
8047
+ pipeArguments: pipeArguments2,
8048
+ suggestedTraceName
8049
+ } = target;
8050
+ const innerFunction = target.generatorFunction ?? targetNode;
7844
8051
  const fixes = [];
7845
8052
  if (pluginOptions.effectFn.includes("span") && explicitTraceExpression) {
7846
8053
  fixes.push({
@@ -7860,7 +8067,7 @@ var effectFnOpportunity = createDiagnostic({
7860
8067
  })
7861
8068
  });
7862
8069
  }
7863
- if (pluginOptions.effectFn.includes("untraced") && target.value.generatorFunction) {
8070
+ if (pluginOptions.effectFn.includes("untraced") && target.generatorFunction) {
7864
8071
  fixes.push({
7865
8072
  fixName: "effectFnOpportunity_toEffectFnUntraced",
7866
8073
  description: "Convert to Effect.fnUntraced",
@@ -7882,22 +8089,41 @@ var effectFnOpportunity = createDiagnostic({
7882
8089
  })
7883
8090
  });
7884
8091
  }
7885
- if (pluginOptions.effectFn.includes("inferred-span") && inferredTraceName && !explicitTraceExpression) {
7886
- fixes.push({
7887
- fixName: "effectFnOpportunity_toEffectFnSpanInferred",
7888
- description: `Convert to Effect.fn("${inferredTraceName}")`,
7889
- apply: gen(function* () {
7890
- const changeTracker = yield* service(ChangeTracker);
7891
- const newNode = createEffectFnNode(
7892
- targetNode,
7893
- innerFunction,
7894
- effectModuleName,
7895
- inferredTraceName,
7896
- pipeArguments2
7897
- );
7898
- changeTracker.replaceNode(sourceFile, targetNode, newNode);
7899
- })
7900
- });
8092
+ if (!explicitTraceExpression) {
8093
+ if (pluginOptions.effectFn.includes("inferred-span") && inferredTraceName) {
8094
+ fixes.push({
8095
+ fixName: "effectFnOpportunity_toEffectFnSpanInferred",
8096
+ description: `Convert to Effect.fn("${inferredTraceName}")`,
8097
+ apply: gen(function* () {
8098
+ const changeTracker = yield* service(ChangeTracker);
8099
+ const newNode = createEffectFnNode(
8100
+ targetNode,
8101
+ innerFunction,
8102
+ effectModuleName,
8103
+ inferredTraceName,
8104
+ pipeArguments2
8105
+ );
8106
+ changeTracker.replaceNode(sourceFile, targetNode, newNode);
8107
+ })
8108
+ });
8109
+ }
8110
+ if (pluginOptions.effectFn.includes("suggested-span") && suggestedTraceName && (!pluginOptions.effectFn.includes("inferred-span") || suggestedTraceName !== inferredTraceName)) {
8111
+ fixes.push({
8112
+ fixName: "effectFnOpportunity_toEffectFnSpanSuggested",
8113
+ description: `Convert to Effect.fn("${suggestedTraceName}")`,
8114
+ apply: gen(function* () {
8115
+ const changeTracker = yield* service(ChangeTracker);
8116
+ const newNode = createEffectFnNode(
8117
+ targetNode,
8118
+ innerFunction,
8119
+ effectModuleName,
8120
+ suggestedTraceName,
8121
+ pipeArguments2
8122
+ );
8123
+ changeTracker.replaceNode(sourceFile, targetNode, newNode);
8124
+ })
8125
+ });
8126
+ }
7901
8127
  }
7902
8128
  if (fixes.length === 0) continue;
7903
8129
  const generateExpectedSignature = () => {
@@ -7910,7 +8136,7 @@ var effectFnOpportunity = createDiagnostic({
7910
8136
  }
7911
8137
  return "_";
7912
8138
  }).join(", ");
7913
- const fnSignature = `function*${typeParamNames}(${paramNames}) { ... }`;
8139
+ const fnSignature = ts.isArrowFunction(innerFunction) ? `${typeParamNames}(${paramNames}) => { ... }` : isGeneratorFunction(innerFunction) ? `function*${typeParamNames}(${paramNames}) { ... }` : `function${typeParamNames}(${paramNames}) { ... }`;
7914
8140
  const pipeArgsForWithSpan = pipeArguments2.slice(0, -1);
7915
8141
  const pipeArgsSuffix = (args3) => args3.length > 0 ? ", ...pipeTransformations" : "";
7916
8142
  switch (firstFix.fixName) {
@@ -7924,6 +8150,8 @@ var effectFnOpportunity = createDiagnostic({
7924
8150
  return `${effectModuleName}.fn(${fnSignature}${pipeArgsSuffix(pipeArguments2)})`;
7925
8151
  case "effectFnOpportunity_toEffectFnSpanInferred":
7926
8152
  return `${effectModuleName}.fn("${inferredTraceName}")(${fnSignature}${pipeArgsSuffix(pipeArguments2)})`;
8153
+ case "effectFnOpportunity_toEffectFnSpanSuggested":
8154
+ return `${effectModuleName}.fn("${suggestedTraceName}")(${fnSignature}${pipeArgsSuffix(pipeArguments2)})`;
7927
8155
  default:
7928
8156
  return `${effectModuleName}.fn(${fnSignature})`;
7929
8157
  }
@@ -7976,6 +8204,70 @@ var effectGenUsesAdapter = createDiagnostic({
7976
8204
  })
7977
8205
  });
7978
8206
 
8207
+ // src/diagnostics/effectInFailure.ts
8208
+ var effectInFailure = createDiagnostic({
8209
+ name: "effectInFailure",
8210
+ code: 49,
8211
+ description: "Warns when an Effect is used inside an Effect failure channel",
8212
+ severity: "warning",
8213
+ apply: fn("effectInFailure.apply")(function* (sourceFile, report) {
8214
+ const ts = yield* service(TypeScriptApi);
8215
+ const typeChecker = yield* service(TypeCheckerApi);
8216
+ const typeParser = yield* service(TypeParser);
8217
+ const typeCheckerUtils = yield* service(TypeCheckerUtils);
8218
+ const isStrictEffectType = cachedBy(
8219
+ fn("effectInFailure.isStrictEffectType")(function* (type, atLocation) {
8220
+ yield* typeParser.strictEffectType(type, atLocation);
8221
+ return true;
8222
+ }),
8223
+ "effectInFailure.isStrictEffectType",
8224
+ (type) => type
8225
+ );
8226
+ const visited = /* @__PURE__ */ new WeakSet();
8227
+ const stack = [sourceFile];
8228
+ const shouldSkipBecauseChildMatched = /* @__PURE__ */ new WeakSet();
8229
+ while (stack.length > 0) {
8230
+ const node = stack.pop();
8231
+ if (!visited.has(node)) {
8232
+ visited.add(node);
8233
+ stack.push(node);
8234
+ ts.forEachChild(node, (child) => {
8235
+ stack.push(child);
8236
+ return void 0;
8237
+ });
8238
+ continue;
8239
+ }
8240
+ if (shouldSkipBecauseChildMatched.has(node)) {
8241
+ if (node.parent) shouldSkipBecauseChildMatched.add(node.parent);
8242
+ continue;
8243
+ }
8244
+ const type = typeCheckerUtils.getTypeAtLocation(node);
8245
+ if (!type) continue;
8246
+ const effect = yield* orUndefined(typeParser.strictEffectType(type, node));
8247
+ if (!effect) continue;
8248
+ const failureMembers = typeCheckerUtils.unrollUnionMembers(effect.E);
8249
+ let memberWithEffect = void 0;
8250
+ for (const member of failureMembers) {
8251
+ const isMemberEffect = yield* orUndefined(isStrictEffectType(member, node));
8252
+ if (isMemberEffect) {
8253
+ memberWithEffect = member;
8254
+ break;
8255
+ }
8256
+ }
8257
+ if (!memberWithEffect) continue;
8258
+ const messageText = `The error channel contains an Effect (${typeChecker.typeToString(memberWithEffect)}). Putting Effect computations in the failure channel is not intended; keep only failure types there.`;
8259
+ report({
8260
+ location: node,
8261
+ messageText,
8262
+ fixes: []
8263
+ });
8264
+ if (node.parent) {
8265
+ shouldSkipBecauseChildMatched.add(node.parent);
8266
+ }
8267
+ }
8268
+ })
8269
+ });
8270
+
7979
8271
  // src/diagnostics/effectInVoidSuccess.ts
7980
8272
  var effectInVoidSuccess = createDiagnostic({
7981
8273
  name: "effectInVoidSuccess",
@@ -9344,6 +9636,7 @@ var missingReturnYieldStar = createDiagnostic({
9344
9636
  const ts = yield* service(TypeScriptApi);
9345
9637
  const typeCheckerUtils = yield* service(TypeCheckerUtils);
9346
9638
  const typeParser = yield* service(TypeParser);
9639
+ const tsUtils = yield* service(TypeScriptUtils);
9347
9640
  const nodeToVisit = [];
9348
9641
  const appendNodeToVisit = (node) => {
9349
9642
  nodeToVisit.push(node);
@@ -9353,50 +9646,32 @@ var missingReturnYieldStar = createDiagnostic({
9353
9646
  while (nodeToVisit.length > 0) {
9354
9647
  const node = nodeToVisit.shift();
9355
9648
  ts.forEachChild(node, appendNodeToVisit);
9356
- if (ts.isYieldExpression(node) && node.expression && node.asteriskToken) {
9357
- const type = typeCheckerUtils.getTypeAtLocation(node.expression);
9358
- if (type) {
9359
- const maybeEffect = yield* option(typeParser.effectType(type, node.expression));
9360
- if (isSome2(maybeEffect) && maybeEffect.value.A.flags & ts.TypeFlags.Never) {
9361
- const generatorFunctionOrReturnStatement = ts.findAncestor(
9362
- node,
9363
- (_) => ts.isFunctionExpression(_) || ts.isFunctionDeclaration(_) || ts.isMethodDeclaration(_) || ts.isReturnStatement(_) || ts.isThrowStatement(_)
9364
- );
9365
- if (generatorFunctionOrReturnStatement && !ts.isReturnStatement(generatorFunctionOrReturnStatement) && !ts.isThrowStatement(generatorFunctionOrReturnStatement)) {
9366
- if (generatorFunctionOrReturnStatement && generatorFunctionOrReturnStatement.parent) {
9367
- const effectGenNode = generatorFunctionOrReturnStatement.parent;
9368
- const effectGenLike = yield* pipe(
9369
- typeParser.effectGen(effectGenNode),
9370
- orElse2(() => typeParser.effectFnUntracedGen(effectGenNode)),
9371
- orElse2(() => typeParser.effectFnGen(effectGenNode)),
9372
- option
9373
- );
9374
- if (isSome2(effectGenLike)) {
9375
- const fix = node.expression ? [{
9376
- fixName: "missingReturnYieldStar_fix",
9377
- description: "Add return statement",
9378
- apply: gen(function* () {
9379
- const changeTracker = yield* service(ChangeTracker);
9380
- changeTracker.replaceNode(
9381
- sourceFile,
9382
- node,
9383
- ts.factory.createReturnStatement(
9384
- node
9385
- )
9386
- );
9387
- })
9388
- }] : [];
9389
- report({
9390
- location: node,
9391
- messageText: `It is recommended to use return yield* for Effects that never succeed to signal a definitive exit point for type narrowing and tooling support.`,
9392
- fixes: fix
9393
- });
9394
- }
9395
- }
9396
- }
9397
- }
9398
- }
9399
- }
9649
+ if (!ts.isExpressionStatement(node)) continue;
9650
+ const unwrapped = tsUtils.skipOuterExpressions(node.expression);
9651
+ if (!ts.isYieldExpression(unwrapped) || !unwrapped.expression || !unwrapped.asteriskToken) continue;
9652
+ const type = typeCheckerUtils.getTypeAtLocation(unwrapped.expression);
9653
+ if (!type) continue;
9654
+ const maybeEffect = yield* option(typeParser.effectYieldableType(type, unwrapped.expression));
9655
+ if (!(isSome2(maybeEffect) && maybeEffect.value.A.flags & ts.TypeFlags.Never)) continue;
9656
+ const { effectGen, scopeNode } = yield* typeParser.findEnclosingScopes(node);
9657
+ if (!effectGen || scopeNode && scopeNode !== effectGen.generatorFunction) continue;
9658
+ const fix = [{
9659
+ fixName: "missingReturnYieldStar_fix",
9660
+ description: "Add return statement",
9661
+ apply: gen(function* () {
9662
+ const changeTracker = yield* service(ChangeTracker);
9663
+ changeTracker.replaceNode(
9664
+ sourceFile,
9665
+ node,
9666
+ ts.factory.createReturnStatement(node.expression)
9667
+ );
9668
+ })
9669
+ }];
9670
+ report({
9671
+ location: unwrapped,
9672
+ messageText: `It is recommended to use return yield* for Effects that never succeed to signal a definitive exit point for type narrowing and tooling support.`,
9673
+ fixes: fix
9674
+ });
9400
9675
  }
9401
9676
  })
9402
9677
  });
@@ -9713,9 +9988,7 @@ var effectModuleMigrationDb = {
9713
9988
  "failSync": asUnchanged,
9714
9989
  "fiberId": asUnchanged,
9715
9990
  "filter": asUnchanged,
9716
- "filterMap": asRemoved(
9717
- "Use Effect.filter or Effect.map with Option instead."
9718
- ),
9991
+ "filterMap": asUnchanged,
9719
9992
  "filterOrElse": asUnchanged,
9720
9993
  "filterOrFail": asUnchanged,
9721
9994
  "flatMap": asUnchanged,
@@ -10003,9 +10276,7 @@ var effectModuleMigrationDb = {
10003
10276
  "finalizersMask": asRemoved(
10004
10277
  "Finalizer masking has been removed in Effect v4."
10005
10278
  ),
10006
- "findFirst": asRemoved(
10007
- "Use Effect.forEach with early return instead."
10008
- ),
10279
+ "findFirst": asUnchanged,
10009
10280
  "firstSuccessOf": asRemoved(
10010
10281
  "Use Effect.raceAll instead."
10011
10282
  ),
@@ -11804,6 +12075,7 @@ var diagnostics = [
11804
12075
  missingEffectServiceDependency,
11805
12076
  missingLayerContext,
11806
12077
  floatingEffect,
12078
+ effectInFailure,
11807
12079
  missingStarInYieldEffectGen,
11808
12080
  unnecessaryEffectGen,
11809
12081
  unnecessaryFailYieldableError,
@@ -13300,7 +13572,7 @@ function effectTypeArgs(sourceFile, position, quickInfo2) {
13300
13572
  if (!(data && data.shouldTry)) return quickInfo2;
13301
13573
  const { atLocation, label, node, type } = data;
13302
13574
  const effectTypeArgsDocumentation = yield* pipe(
13303
- typeParser.effectType(
13575
+ typeParser.effectYieldableType(
13304
13576
  type,
13305
13577
  atLocation
13306
13578
  ),
@@ -19060,13 +19332,19 @@ var layerMagic = createRefactor({
19060
19332
  map5((_) => _.ROut),
19061
19333
  option
19062
19334
  );
19063
- const [existingBefore, newlyIntroduced] = pipe(
19335
+ const sorted = pipe(
19064
19336
  fromIterable(layerOutputTypes),
19065
- sort(typeCheckerUtils.deterministicTypeOrder),
19066
- partition(
19067
- (_) => isNone2(previouslyProvided) || typeChecker.isTypeAssignableTo(_, previouslyProvided.value)
19068
- )
19337
+ sort(typeCheckerUtils.deterministicTypeOrder)
19069
19338
  );
19339
+ const existingBefore = [];
19340
+ const newlyIntroduced = [];
19341
+ for (const t of sorted) {
19342
+ if (isNone2(previouslyProvided) || typeChecker.isTypeAssignableTo(t, previouslyProvided.value)) {
19343
+ newlyIntroduced.push(t);
19344
+ } else {
19345
+ existingBefore.push(t);
19346
+ }
19347
+ }
19070
19348
  const typeReferences = pipe(
19071
19349
  newlyIntroduced,
19072
19350
  map4((_) => typeChecker.typeToTypeNode(_, void 0, ts.NodeBuilderFlags.NoTruncation)),