@effect/tsgo 0.1.0 → 0.2.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 CHANGED
@@ -191,8 +191,6 @@ Each release of `effect-tsgo` is built against a specific upstream `tsgo` commit
191
191
  "refactors": true,
192
192
  // Controls Effect diagnostics. (default: true)
193
193
  "diagnostics": true,
194
- // Maps rule names to severity levels. Use {} to enable diagnostics with rule defaults. (default: {})
195
- "diagnosticSeverity": {},
196
194
  // When false, suggestion-level Effect diagnostics are omitted from tsc CLI output. (default: true)
197
195
  "includeSuggestionsInTsc": true,
198
196
  // Controls Effect quickinfo. (default: true)
@@ -211,6 +209,22 @@ Each release of `effect-tsgo` is built against a specific upstream `tsgo` commit
211
209
  "ignoreEffectErrorsInTscExitCode": false,
212
210
  // When true, disabled diagnostics are still processed so directives can re-enable them. (default: false)
213
211
  "skipDisabledOptimization": false,
212
+ // Mermaid rendering service for layer graph links. Accepts mermaid.live, mermaid.com, or a custom URL. (default: "mermaid.live")
213
+ "mermaidProvider": "mermaid.live",
214
+ // When true, suppresses external Mermaid links in hover output. (default: false)
215
+ "noExternal": false,
216
+ // How many levels deep the layer graph extraction follows symbol references. (default: 0)
217
+ "layerGraphFollowDepth": 0,
218
+ // When true, suppresses redundant return-type inlay hints on supported Effect generator functions. (default: false)
219
+ "inlays": false,
220
+ // Package names that should prefer namespace imports. (default: [])
221
+ "namespaceImportPackages": [],
222
+ // Package names that should prefer barrel named imports. (default: [])
223
+ "barrelImportPackages": [],
224
+ // Package-level import aliases keyed by package name. (default: {})
225
+ "importAliases": {},
226
+ // Controls whether named reexports are followed at package top-level. (default: "ignore")
227
+ "topLevelNamedReexports": "ignore",
214
228
  // Configures key pattern formulas for the deterministicKeys rule. (default: [{"target":"service","pattern":"default","skipLeadingPath":["src/"]},{"target":"custom","pattern":"default","skipLeadingPath":["src/"]}])
215
229
  "keyPatterns": [
216
230
  {
@@ -232,28 +246,27 @@ Each release of `effect-tsgo` is built against a specific upstream `tsgo` commit
232
246
  "extendedKeyDetection": false,
233
247
  // Minimum number of contiguous pipeable transformations to trigger missedPipeableOpportunity. (default: 2)
234
248
  "pipeableMinArgCount": 2,
235
- // Mermaid rendering service for layer graph links. Accepts mermaid.live, mermaid.com, or a custom URL. (default: "mermaid.live")
236
- "mermaidProvider": "mermaid.live",
237
- // When true, suppresses external Mermaid links in hover output. (default: false)
238
- "noExternal": false,
239
- // How many levels deep the layer graph extraction follows symbol references. (default: 0)
240
- "layerGraphFollowDepth": 0,
249
+ // Package names allowed to have multiple versions without triggering duplicatePackage. (default: [])
250
+ "allowedDuplicatedPackages": [],
241
251
  // Controls which effectFnOpportunity quickfix variants are offered. (default: ["span"])
242
252
  "effectFn": [
243
253
  "span"
244
254
  ],
245
- // When true, suppresses redundant return-type inlay hints on supported Effect generator functions. (default: false)
246
- "inlays": false,
247
- // Package names allowed to have multiple versions without triggering duplicatePackage. (default: [])
248
- "allowedDuplicatedPackages": [],
249
- // Package names that should prefer namespace imports. (default: [])
250
- "namespaceImportPackages": [],
251
- // Package names that should prefer barrel named imports. (default: [])
252
- "barrelImportPackages": [],
253
- // Package-level import aliases keyed by package name. (default: {})
254
- "importAliases": {},
255
- // Controls whether named reexports are followed at package top-level. (default: "ignore")
256
- "topLevelNamedReexports": "ignore"
255
+ // Maps rule names to severity levels. Use {} to enable diagnostics with rule defaults. (default: {})
256
+ "diagnosticSeverity": {},
257
+ // Ordered per-file diagnostic option overrides. (default: [{"include":["src/**/*.ts"],"options":{"diagnosticSeverity":{"floatingEffect":"error"}}}])
258
+ "overrides": [
259
+ {
260
+ "include": [
261
+ "src/**/*.ts"
262
+ ],
263
+ "options": {
264
+ "diagnosticSeverity": {
265
+ "floatingEffect": "error"
266
+ }
267
+ }
268
+ }
269
+ ]
257
270
  }
258
271
  ]
259
272
  }
@@ -3910,6 +3910,39 @@ const getFailure$1 = getFailure$2;
3910
3910
  */
3911
3911
  const getOrElse$1 = /* @__PURE__ */ dual(2, (self, onNone) => isNone(self) ? onNone() : self.value);
3912
3912
  /**
3913
+ * Returns the fallback `Option` if `self` is `None`; otherwise returns `self`.
3914
+ *
3915
+ * **When to use**
3916
+ *
3917
+ * - Chaining fallback `Option` computations
3918
+ * - Building priority chains of optional values
3919
+ *
3920
+ * **Behavior**
3921
+ *
3922
+ * - `Some` → returns `self` unchanged
3923
+ * - `None` → evaluates and returns `that()`
3924
+ * - `that` is lazily evaluated
3925
+ *
3926
+ * **Example** (Providing a fallback Option)
3927
+ *
3928
+ * ```ts
3929
+ * import { Option } from "effect"
3930
+ *
3931
+ * console.log(Option.none().pipe(Option.orElse(() => Option.some("b"))))
3932
+ * // Output: { _id: 'Option', _tag: 'Some', value: 'b' }
3933
+ *
3934
+ * console.log(Option.some("a").pipe(Option.orElse(() => Option.some("b"))))
3935
+ * // Output: { _id: 'Option', _tag: 'Some', value: 'a' }
3936
+ * ```
3937
+ *
3938
+ * @see {@link orElseSome} to wrap the fallback value in `Some` automatically
3939
+ * @see {@link firstSomeOf} to pick the first `Some` from a collection
3940
+ *
3941
+ * @category Error handling
3942
+ * @since 2.0.0
3943
+ */
3944
+ const orElse = /* @__PURE__ */ dual(2, (self, that) => isNone(self) ? that() : self);
3945
+ /**
3913
3946
  * Converts a nullable value (`null` or `undefined`) into an `Option`.
3914
3947
  *
3915
3948
  * **When to use**
@@ -197344,14 +197377,16 @@ var FileReadError = class extends TaggedError("FileReadError") {
197344
197377
  //#endregion
197345
197378
  //#region package.json
197346
197379
  var name = "@effect/tsgo";
197347
- var version = "0.1.0";
197380
+ var version = "0.2.0";
197348
197381
 
197349
197382
  //#endregion
197350
197383
  //#region src/setup/consts.ts
197351
197384
  const LSP_PACKAGE_NAME = name;
197352
197385
  const LSP_PLUGIN_NAME = "@effect/language-service";
197386
+ const NATIVE_PREVIEW_PACKAGE_NAME = "@typescript/native-preview";
197353
197387
  const PATCH_COMMAND = "effect-tsgo patch";
197354
197388
  const DEFAULT_LSP_VERSION = version;
197389
+ const DEFAULT_NATIVE_PREVIEW_VERSION = "latest";
197355
197390
  const TSCONFIG_SCHEMA_URL = "https://raw.githubusercontent.com/Effect-TS/tsgo/refs/heads/main/schema.json";
197356
197391
 
197357
197392
  //#endregion
@@ -197396,15 +197431,19 @@ const createAssessmentInput = (currentDir, tsconfigInput) => gen(function* () {
197396
197431
  const assessPackageJson = (input) => {
197397
197432
  const sourceFile = import_typescript.parseJsonText(input.fileName, input.text);
197398
197433
  const parsed = import_typescript.convertToObject(sourceFile, []);
197399
- let lspVersion = none$3();
197400
- if (LSP_PACKAGE_NAME in (parsed.devDependencies ?? {})) lspVersion = some({
197401
- dependencyType: "devDependencies",
197402
- version: parsed.devDependencies[LSP_PACKAGE_NAME]
197403
- });
197404
- else if (LSP_PACKAGE_NAME in (parsed.dependencies ?? {})) lspVersion = some({
197405
- dependencyType: "dependencies",
197406
- version: parsed.dependencies[LSP_PACKAGE_NAME]
197407
- });
197434
+ const assessDependency = (packageName) => {
197435
+ if (packageName in (parsed.devDependencies ?? {})) return some({
197436
+ dependencyType: "devDependencies",
197437
+ version: parsed.devDependencies[packageName]
197438
+ });
197439
+ if (packageName in (parsed.dependencies ?? {})) return some({
197440
+ dependencyType: "dependencies",
197441
+ version: parsed.dependencies[packageName]
197442
+ });
197443
+ return none$3();
197444
+ };
197445
+ const lspVersion = assessDependency(LSP_PACKAGE_NAME);
197446
+ const nativePreviewVersion = assessDependency(NATIVE_PREVIEW_PACKAGE_NAME);
197408
197447
  const prepareScript = "prepare" in (parsed.scripts ?? {}) ? some({
197409
197448
  script: parsed.scripts.prepare,
197410
197449
  hasPatch: parsed.scripts.prepare.toLowerCase().includes(PATCH_COMMAND)
@@ -197415,6 +197454,7 @@ const assessPackageJson = (input) => {
197415
197454
  parsed,
197416
197455
  text: input.text,
197417
197456
  lspVersion,
197457
+ nativePreviewVersion,
197418
197458
  prepareScript
197419
197459
  };
197420
197460
  };
@@ -197685,6 +197725,25 @@ function insertNodeAtEndOfList(tracker, sourceFile, nodeArray, newNode) {
197685
197725
  tracker.insertNodeAt(sourceFile, lastElement.end, newNode, { prefix: ",\n" });
197686
197726
  }
197687
197727
  }
197728
+ function findDependencyCollectionProperty(rootObj, dependencyType) {
197729
+ return findPropertyInObject(rootObj, dependencyType);
197730
+ }
197731
+ function upsertDependency(tracker, sourceFile, rootObj, dependencyName, dependency) {
197732
+ const depsProperty = findDependencyCollectionProperty(rootObj, dependency.dependencyType);
197733
+ if (!depsProperty) {
197734
+ const newDepsProp = import_typescript.factory.createPropertyAssignment(import_typescript.factory.createStringLiteral(dependency.dependencyType), import_typescript.factory.createObjectLiteralExpression([import_typescript.factory.createPropertyAssignment(import_typescript.factory.createStringLiteral(dependencyName), import_typescript.factory.createStringLiteral(dependency.version))], false));
197735
+ insertNodeAtEndOfList(tracker, sourceFile, rootObj.properties, newDepsProp);
197736
+ return;
197737
+ }
197738
+ if (!import_typescript.isObjectLiteralExpression(depsProperty.initializer)) return;
197739
+ const existingProperty = findPropertyInObject(depsProperty.initializer, dependencyName);
197740
+ if (!existingProperty) {
197741
+ const newDepProp = import_typescript.factory.createPropertyAssignment(import_typescript.factory.createStringLiteral(dependencyName), import_typescript.factory.createStringLiteral(dependency.version));
197742
+ insertNodeAtEndOfList(tracker, sourceFile, depsProperty.initializer.properties, newDepProp);
197743
+ return;
197744
+ }
197745
+ if (import_typescript.isStringLiteral(existingProperty.initializer) && existingProperty.initializer.text !== dependency.version) tracker.replaceNode(sourceFile, existingProperty.initializer, import_typescript.factory.createStringLiteral(dependency.version));
197746
+ }
197688
197747
  function createDiagnosticSeverityObject(severities) {
197689
197748
  const entries = Object.entries(severities).sort(([a], [b]) => a.localeCompare(b));
197690
197749
  return import_typescript.factory.createObjectLiteralExpression(entries.map(([name, severity]) => import_typescript.factory.createPropertyAssignment(import_typescript.factory.createStringLiteral(name), import_typescript.factory.createStringLiteral(severity))), true);
@@ -197734,6 +197793,14 @@ const computePackageJsonChanges = (current, target) => {
197734
197793
  if (!rootObj) return emptyFileChangesResult();
197735
197794
  const ctx = createTrackerContext();
197736
197795
  const fileChange = tsInternal.textChanges.ChangeTracker.with(ctx, (tracker) => {
197796
+ const shouldAddNativePreviewWithDependencyType = (dependencyType) => isSome(target.nativePreviewVersion) && isNone(current.nativePreviewVersion) && target.nativePreviewVersion.value.dependencyType === dependencyType;
197797
+ const ensureNativePreviewDependency = () => {
197798
+ if (isNone(target.nativePreviewVersion) || isSome(current.nativePreviewVersion)) return;
197799
+ const targetNativePreview = target.nativePreviewVersion.value;
197800
+ if (!findDependencyCollectionProperty(rootObj, targetNativePreview.dependencyType) && isSome(target.lspVersion) && target.lspVersion.value.dependencyType === targetNativePreview.dependencyType) return;
197801
+ descriptions.push(`Add ${NATIVE_PREVIEW_PACKAGE_NAME}@${targetNativePreview.version} to ${targetNativePreview.dependencyType}`);
197802
+ upsertDependency(tracker, current.sourceFile, rootObj, NATIVE_PREVIEW_PACKAGE_NAME, targetNativePreview);
197803
+ };
197737
197804
  if (isSome(target.lspVersion)) {
197738
197805
  const targetDepType = target.lspVersion.value.dependencyType;
197739
197806
  const targetVersion = target.lspVersion.value.version;
@@ -197747,12 +197814,16 @@ const computePackageJsonChanges = (current, target) => {
197747
197814
  const lspProperty = findPropertyInObject(oldDepsProperty.initializer, LSP_PACKAGE_NAME);
197748
197815
  if (lspProperty) deleteNodeFromList(tracker, current.sourceFile, oldDepsProperty.initializer.properties, lspProperty);
197749
197816
  }
197750
- const newDepsProperty = findPropertyInObject(rootObj, targetDepType);
197751
- const newLspProp = import_typescript.factory.createPropertyAssignment(import_typescript.factory.createStringLiteral(LSP_PACKAGE_NAME), import_typescript.factory.createStringLiteral(targetVersion));
197817
+ const newDepsProperty = findDependencyCollectionProperty(rootObj, targetDepType);
197752
197818
  if (!newDepsProperty) {
197753
- const newDepsProp = import_typescript.factory.createPropertyAssignment(import_typescript.factory.createStringLiteral(targetDepType), import_typescript.factory.createObjectLiteralExpression([newLspProp], false));
197819
+ const dependencyProperties = [import_typescript.factory.createPropertyAssignment(import_typescript.factory.createStringLiteral(LSP_PACKAGE_NAME), import_typescript.factory.createStringLiteral(targetVersion))];
197820
+ if (shouldAddNativePreviewWithDependencyType(targetDepType)) {
197821
+ const targetNativePreview = target.nativePreviewVersion.pipe(getOrUndefined);
197822
+ if (targetNativePreview) dependencyProperties.push(import_typescript.factory.createPropertyAssignment(import_typescript.factory.createStringLiteral(NATIVE_PREVIEW_PACKAGE_NAME), import_typescript.factory.createStringLiteral(targetNativePreview.version)));
197823
+ }
197824
+ const newDepsProp = import_typescript.factory.createPropertyAssignment(import_typescript.factory.createStringLiteral(targetDepType), import_typescript.factory.createObjectLiteralExpression(dependencyProperties, false));
197754
197825
  insertNodeAtEndOfList(tracker, current.sourceFile, rootObj.properties, newDepsProp);
197755
- } else if (import_typescript.isObjectLiteralExpression(newDepsProperty.initializer)) insertNodeAtEndOfList(tracker, current.sourceFile, newDepsProperty.initializer.properties, newLspProp);
197826
+ } else if (import_typescript.isObjectLiteralExpression(newDepsProperty.initializer)) insertNodeAtEndOfList(tracker, current.sourceFile, newDepsProperty.initializer.properties, import_typescript.factory.createPropertyAssignment(import_typescript.factory.createStringLiteral(LSP_PACKAGE_NAME), import_typescript.factory.createStringLiteral(targetVersion)));
197756
197827
  } else if (currentVersion !== targetVersion) {
197757
197828
  descriptions.push(`Update ${LSP_PACKAGE_NAME} from ${currentVersion} to ${targetVersion}`);
197758
197829
  const depsProperty = findPropertyInObject(rootObj, targetDepType);
@@ -197763,15 +197834,18 @@ const computePackageJsonChanges = (current, target) => {
197763
197834
  }
197764
197835
  } else {
197765
197836
  descriptions.push(`Add ${LSP_PACKAGE_NAME}@${targetVersion} to ${targetDepType}`);
197766
- const depsProperty = findPropertyInObject(rootObj, targetDepType);
197837
+ const depsProperty = findDependencyCollectionProperty(rootObj, targetDepType);
197767
197838
  if (!depsProperty) {
197768
- const newDepsProp = import_typescript.factory.createPropertyAssignment(import_typescript.factory.createStringLiteral(targetDepType), import_typescript.factory.createObjectLiteralExpression([import_typescript.factory.createPropertyAssignment(import_typescript.factory.createStringLiteral(LSP_PACKAGE_NAME), import_typescript.factory.createStringLiteral(targetVersion))], false));
197839
+ const dependencyProperties = [import_typescript.factory.createPropertyAssignment(import_typescript.factory.createStringLiteral(LSP_PACKAGE_NAME), import_typescript.factory.createStringLiteral(targetVersion))];
197840
+ if (shouldAddNativePreviewWithDependencyType(targetDepType)) {
197841
+ const targetNativePreview = target.nativePreviewVersion.pipe(getOrUndefined);
197842
+ if (targetNativePreview) dependencyProperties.push(import_typescript.factory.createPropertyAssignment(import_typescript.factory.createStringLiteral(NATIVE_PREVIEW_PACKAGE_NAME), import_typescript.factory.createStringLiteral(targetNativePreview.version)));
197843
+ }
197844
+ const newDepsProp = import_typescript.factory.createPropertyAssignment(import_typescript.factory.createStringLiteral(targetDepType), import_typescript.factory.createObjectLiteralExpression(dependencyProperties, false));
197769
197845
  insertNodeAtEndOfList(tracker, current.sourceFile, rootObj.properties, newDepsProp);
197770
- } else if (import_typescript.isObjectLiteralExpression(depsProperty.initializer)) {
197771
- const newLspProp = import_typescript.factory.createPropertyAssignment(import_typescript.factory.createStringLiteral(LSP_PACKAGE_NAME), import_typescript.factory.createStringLiteral(targetVersion));
197772
- insertNodeAtEndOfList(tracker, current.sourceFile, depsProperty.initializer.properties, newLspProp);
197773
- }
197846
+ } else if (import_typescript.isObjectLiteralExpression(depsProperty.initializer)) insertNodeAtEndOfList(tracker, current.sourceFile, depsProperty.initializer.properties, import_typescript.factory.createPropertyAssignment(import_typescript.factory.createStringLiteral(LSP_PACKAGE_NAME), import_typescript.factory.createStringLiteral(targetVersion)));
197774
197847
  }
197848
+ ensureNativePreviewDependency();
197775
197849
  } else if (isSome(current.lspVersion)) {
197776
197850
  descriptions.push(`Remove ${LSP_PACKAGE_NAME} from dependencies`);
197777
197851
  const currentDepType = current.lspVersion.value.dependencyType;
@@ -198192,7 +198266,7 @@ var rules = [
198192
198266
  "diagnostics": [{
198193
198267
  "start": 154,
198194
198268
  "end": 169,
198195
- "text": "Self type parameter should be 'InvalidContextTag'. effect(classSelfMismatch)"
198269
+ "text": "The `Self` type parameter for this class should be `InvalidContextTag`. effect(classSelfMismatch)"
198196
198270
  }]
198197
198271
  }
198198
198272
  },
@@ -198222,7 +198296,7 @@ var rules = [
198222
198296
  "diagnostics": [{
198223
198297
  "start": 78,
198224
198298
  "end": 83,
198225
- "text": "Parameter 'input' implicitly has an 'any' type in Effect.fn/Effect.fnUntraced/Effect.fnUntracedEager. Add an explicit type annotation or provide a contextual function type. effect(effectFnImplicitAny)"
198299
+ "text": "Parameter `input` implicitly has type `any` in `Effect.fn`, `Effect.fnUntraced`, or `Effect.fnUntracedEager`. No parameter type is available from an explicit annotation or contextual function type. effect(effectFnImplicitAny)"
198226
198300
  }]
198227
198301
  }
198228
198302
  },
@@ -198239,7 +198313,7 @@ var rules = [
198239
198313
  "diagnostics": [{
198240
198314
  "start": 41,
198241
198315
  "end": 64,
198242
- "text": "Effect must be yielded or assigned to a variable. effect(floatingEffect)"
198316
+ "text": "This Effect value is neither yielded nor used in an assignment. effect(floatingEffect)"
198243
198317
  }]
198244
198318
  }
198245
198319
  },
@@ -198273,7 +198347,7 @@ var rules = [
198273
198347
  "diagnostics": [{
198274
198348
  "start": 160,
198275
198349
  "end": 167,
198276
- "text": "Missing context Db in the expected Effect type. effect(missingEffectContext)"
198350
+ "text": "This Effect requires a service that is missing from the expected Effect context: `Db`. effect(missingEffectContext)"
198277
198351
  }]
198278
198352
  }
198279
198353
  },
@@ -198324,7 +198398,7 @@ var rules = [
198324
198398
  "diagnostics": [{
198325
198399
  "start": 121,
198326
198400
  "end": 126,
198327
- "text": "It is recommended to use return yield* for Effects that never succeed to signal a definitive exit point for type narrowing and tooling support. effect(missingReturnYieldStar)"
198401
+ "text": "This Effect never succeeds; using `return yield*` preserves a definitive generator exit point for type narrowing and tooling support. effect(missingReturnYieldStar)"
198328
198402
  }]
198329
198403
  }
198330
198404
  },
@@ -198341,7 +198415,7 @@ var rules = [
198341
198415
  "diagnostics": [{
198342
198416
  "start": 105,
198343
198417
  "end": 110,
198344
- "text": "When yielding Effects inside Effect.gen, you should use yield* instead of yield. effect(missingStarInYieldEffectGen)"
198418
+ "text": "This uses `yield` for an `Effect` value. `yield*` is the Effect-aware form in this context. effect(missingStarInYieldEffectGen)"
198345
198419
  }]
198346
198420
  }
198347
198421
  },
@@ -198358,7 +198432,7 @@ var rules = [
198358
198432
  "diagnostics": [{
198359
198433
  "start": 142,
198360
198434
  "end": 149,
198361
- "text": "Effect.Service requires the service type to be an object {} and not a primitive type. Consider wrapping the value in an object, or manually using Context.Tag or Effect.Tag if you want to use a primitive instead. effect(nonObjectEffectServiceType)"
198435
+ "text": "`Effect.Service` is declared with a primitive service type. `Effect.Service` models object-shaped services; primitive values use `Context.Tag` or `Effect.Tag` directly. effect(nonObjectEffectServiceType)"
198362
198436
  }]
198363
198437
  }
198364
198438
  },
@@ -198375,11 +198449,11 @@ var rules = [
198375
198449
  "diagnostics": [{
198376
198450
  "start": 0,
198377
198451
  "end": 0,
198378
- "text": "This project targets Effect v4, but is using Effect v3 APIs. To find the correct API to use, consult the Effect v4 documentation for the corresponding v4 replacement. effect(outdatedApi)"
198452
+ "text": "This project targets Effect v4, but this code uses Effect v3 APIs. The referenced API belongs to the v3 surface rather than the configured v4 surface. effect(outdatedApi)"
198379
198453
  }, {
198380
198454
  "start": 126,
198381
198455
  "end": 133,
198382
- "text": "runtime is an Effect v3 API, but the project is using Effect v4. Runtime has been removed in Effect v4. Use Effect.services to grab services and then run using Effect.runPromiseWith. effect(outdatedApi)"
198456
+ "text": "This project targets Effect v4, but this code uses the Effect v3 API `runtime`. The referenced API belongs to the v3 surface rather than the configured v4 surface. Runtime has been removed in Effect v4. Use Effect.services to grab services and then run using Effect.runPromiseWith. effect(outdatedApi)"
198383
198457
  }]
198384
198458
  }
198385
198459
  },
@@ -198396,7 +198470,7 @@ var rules = [
198396
198470
  "diagnostics": [{
198397
198471
  "start": 123,
198398
198472
  "end": 134,
198399
- "text": "Classes extending Schema must not override the constructor; this is because it silently breaks the schema decoding behaviour. If that's needed, we recommend instead to use a static 'new' method that constructs the instance. effect(overriddenSchemaConstructor)"
198473
+ "text": "This Schema subclass defines its own constructor. For Schema classes, constructor overrides break decoding behavior for the class shape. Custom construction can be expressed through a static `new` method instead. effect(overriddenSchemaConstructor)"
198400
198474
  }]
198401
198475
  }
198402
198476
  },
@@ -198413,7 +198487,7 @@ var rules = [
198413
198487
  "diagnostics": [{
198414
198488
  "start": 82,
198415
198489
  "end": 94,
198416
- "text": "Looks like the previous effect never fails, so probably this error handling will never be triggered. effect(catchUnfailableEffect)"
198490
+ "text": "The previous Effect does not fail, so this error-handling branch will never run. effect(catchUnfailableEffect)"
198417
198491
  }]
198418
198492
  }
198419
198493
  },
@@ -198430,7 +198504,7 @@ var rules = [
198430
198504
  "diagnostics": [{
198431
198505
  "start": 64,
198432
198506
  "end": 137,
198433
- "text": "Effect.fn returns a reusable function that can take arguments, but here it's called immediately. Use Effect.gen instead with Effect.withSpan(\"preview\") piped in the end to maintain tracing spans. effect(effectFnIife)"
198507
+ "text": "`Effect.fn` returns a reusable function that can take arguments, but it is invoked immediately here. `Effect.gen` represents the immediate-use form for this pattern with Effect.withSpan(\"preview\") piped in the end to maintain tracing spans. effect(effectFnIife)"
198434
198508
  }]
198435
198509
  }
198436
198510
  },
@@ -198502,7 +198576,7 @@ var rules = [
198502
198576
  "diagnostics": [{
198503
198577
  "start": 56,
198504
198578
  "end": 73,
198505
- "text": "The 'catch' callback in Effect.tryPromise returns global 'Error', which loses type safety as untagged errors merge together. Consider using a tagged error and optionally wrapping the original in a 'cause' property. effect(globalErrorInEffectCatch)"
198579
+ "text": "The `catch` callback in `Effect.tryPromise` returns the global `Error` type. Untagged errors merge together in the Effect error channel and lose type-level distinction; a tagged error preserves that distinction and can wrap the original error in a `cause` property. effect(globalErrorInEffectCatch)"
198506
198580
  }]
198507
198581
  }
198508
198582
  },
@@ -198553,7 +198627,7 @@ var rules = [
198553
198627
  "diagnostics": [{
198554
198628
  "start": 212,
198555
198629
  "end": 217,
198556
- "text": "Methods of this Service require 'FileSystem' from every caller. This leaks implementation details resolve these dependencies at Layer creation time. effect(leakingRequirements)"
198630
+ "text": "Methods of this Service require `FileSystem` from every caller.\n\nThe requirement becomes part of the public service surface instead of remaining internal to Layer implementation.\n\nResolve these dependencies at Layer creation and provide them to each method, so the service's type reflects its purpose, not its implementation.\n\nTo suppress this diagnostic for specific dependency types that are intentionally passed through (e.g., HttpServerRequest), add `@effect-leakable-service` JSDoc to their interface declarations, or to this service by adding a `@effect-expect-leaking FileSystem` JSDoc.\n\nMore info and examples at https://effect.website/docs/requirements-management/layers/#avoiding-requirement-leakage effect(leakingRequirements)"
198557
198631
  }]
198558
198632
  }
198559
198633
  },
@@ -198570,7 +198644,7 @@ var rules = [
198570
198644
  "diagnostics": [{
198571
198645
  "start": 348,
198572
198646
  "end": 373,
198573
- "text": "Avoid chaining Effect.provide calls, as this can lead to service lifecycle issues. Instead, merge layers and provide them in a single call. effect(multipleEffectProvide)"
198647
+ "text": "This expression chains multiple `Effect.provide` calls. Providing Layers in multiple calls in a chain can break service lifecycle behavior compared with a single combined provide with merged layers. effect(multipleEffectProvide)"
198574
198648
  }]
198575
198649
  }
198576
198650
  },
@@ -198587,7 +198661,7 @@ var rules = [
198587
198661
  "diagnostics": [{
198588
198662
  "start": 91,
198589
198663
  "end": 97,
198590
- "text": "You are returning an Effect-able type inside a generator function, and will result in nested Effect<Effect<...>>.\nMaybe you wanted to return yield* instead?\nNested Effect-able types may be intended if you plan to later manually flatten or unwrap this Effect, if so you can safely disable this diagnostic for this line through quickfixes. effect(returnEffectInGen)"
198664
+ "text": "This generator returns an Effect-able value directly, which produces a nested `Effect<Effect<...>>`. If the intended result is the inner Effect value, `return yield*` represents that form. effect(returnEffectInGen)"
198591
198665
  }]
198592
198666
  }
198593
198667
  },
@@ -198608,7 +198682,7 @@ var rules = [
198608
198682
  "diagnostics": [{
198609
198683
  "start": 101,
198610
198684
  "end": 115,
198611
- "text": "Using Effect.runSync inside an Effect is not recommended. The same services should generally be used instead to run child effects.\nConsider extracting the current services by using for example Effect.services and then use Effect.runSyncWith with the extracted services instead. effect(runEffectInsideEffect)"
198685
+ "text": "`Effect.runSync` is called inside an Effect with a separate services invocation. In this context, child Effects run with the surrounding services, which can be accessed through `Effect.services` and `Effect.runSyncWith`. effect(runEffectInsideEffect)"
198612
198686
  }]
198613
198687
  }
198614
198688
  },
@@ -198625,7 +198699,7 @@ var rules = [
198625
198699
  "diagnostics": [{
198626
198700
  "start": 276,
198627
198701
  "end": 293,
198628
- "text": "Using Schema.decodeSync inside an Effect generator is not recommended. Use Schema.decode instead to get properly typed error channel. effect(schemaSyncInEffect)"
198702
+ "text": "`Schema.decodeSync` is used inside an Effect generator. `Schema.decode` preserves the typed Effect error channel for this operation without throwing. effect(schemaSyncInEffect)"
198629
198703
  }]
198630
198704
  }
198631
198705
  },
@@ -198642,7 +198716,7 @@ var rules = [
198642
198716
  "diagnostics": [{
198643
198717
  "start": 211,
198644
198718
  "end": 338,
198645
- "text": "Seems like you are constructing a layer with a scope in the requirements.\nConsider using \"scoped\" instead to get rid of the scope in the requirements. effect(scopeInLayerEffect)"
198719
+ "text": "This layer construction leaves `Scope` in the requirement set. The scoped API removes `Scope` from the resulting requirements. effect(scopeInLayerEffect)"
198646
198720
  }]
198647
198721
  }
198648
198722
  },
@@ -198676,7 +198750,7 @@ var rules = [
198676
198750
  "diagnostics": [{
198677
198751
  "start": 91,
198678
198752
  "end": 151,
198679
- "text": "Avoid using try/catch inside Effect generators. Use Effect's error handling mechanisms instead (e.g. Effect.try, Effect.tryPromise, Effect.catch, Effect.catchTag). effect(tryCatchInEffectGen)"
198753
+ "text": "This Effect generator contains `try/catch`; in this context, error handling is expressed with Effect APIs such as Effect.try, Effect.tryPromise, Effect.catch, Effect.catchTag). effect(tryCatchInEffectGen)"
198680
198754
  }]
198681
198755
  }
198682
198756
  },
@@ -198693,7 +198767,7 @@ var rules = [
198693
198767
  "diagnostics": [{
198694
198768
  "start": 56,
198695
198769
  "end": 73,
198696
- "text": "The 'catch' callback in Effect.tryPromise returns 'unknown'. The catch callback should be used to provide typed errors.\nConsider wrapping unknown errors into Effect's Data.TaggedError for example, or narrow down the type to the specific error raised. effect(unknownInEffectCatch)"
198770
+ "text": "The `catch` callback in `Effect.tryPromise` returns `unknown`, so the Effect error type stays untyped. A specific typed error preserves error-channel information, for example by narrowing the value or wrapping it in `Data.TaggedError`. effect(unknownInEffectCatch)"
198697
198771
  }]
198698
198772
  }
198699
198773
  },
@@ -198710,7 +198784,7 @@ var rules = [
198710
198784
  "diagnostics": [{
198711
198785
  "start": 14,
198712
198786
  "end": 26,
198713
- "text": "Avoid extending the native 'Error' class directly. Consider using a tagged error (e.g. Data.TaggedError) to maintain type safety in the Effect failure channel. effect(extendsNativeError)"
198787
+ "text": "This class extends the native `Error` type directly. Untagged native errors lose distinction in the Effect failure channel. effect(extendsNativeError)"
198714
198788
  }]
198715
198789
  }
198716
198790
  },
@@ -198727,7 +198801,7 @@ var rules = [
198727
198801
  "diagnostics": [{
198728
198802
  "start": 1,
198729
198803
  "end": 23,
198730
- "text": "Prefer using Effect.log or Logger instead of console.log. effect(globalConsole)"
198804
+ "text": "This code uses `console.log`, the corresponding Effect logging API is `Effect.log or Logger`. effect(globalConsole)"
198731
198805
  }]
198732
198806
  }
198733
198807
  },
@@ -198744,7 +198818,7 @@ var rules = [
198744
198818
  "diagnostics": [{
198745
198819
  "start": 83,
198746
198820
  "end": 103,
198747
- "text": "Prefer using Effect.log or Logger instead of console.log inside Effect generators. effect(globalConsoleInEffect)"
198821
+ "text": "This Effect code uses `console.log`, logging in Effect code is represented through `Effect.log or Logger`. effect(globalConsoleInEffect)"
198748
198822
  }]
198749
198823
  }
198750
198824
  },
@@ -198761,7 +198835,7 @@ var rules = [
198761
198835
  "diagnostics": [{
198762
198836
  "start": 24,
198763
198837
  "end": 34,
198764
- "text": "Prefer using Clock or DateTime from Effect instead of Date.now(). effect(globalDate)"
198838
+ "text": "This code uses `Date.now()`, time access is represented through `Clock` from Effect. effect(globalDate)"
198765
198839
  }]
198766
198840
  }
198767
198841
  },
@@ -198778,7 +198852,7 @@ var rules = [
198778
198852
  "diagnostics": [{
198779
198853
  "start": 95,
198780
198854
  "end": 105,
198781
- "text": "Prefer using Clock or DateTime from Effect instead of Date.now() inside Effect generators. effect(globalDateInEffect)"
198855
+ "text": "This Effect code uses `Date.now()`, time access in Effect code is represented through `Clock` from Effect. effect(globalDateInEffect)"
198782
198856
  }]
198783
198857
  }
198784
198858
  },
@@ -198795,7 +198869,7 @@ var rules = [
198795
198869
  "diagnostics": [{
198796
198870
  "start": 24,
198797
198871
  "end": 29,
198798
- "text": "Prefer using HttpClient from @effect/platform instead of the global 'fetch' function. effect(globalFetch)"
198872
+ "text": "This code uses the global `fetch` function, HTTP requests are represented through `HttpClient` from `@effect/platform`. effect(globalFetch)"
198799
198873
  }]
198800
198874
  }
198801
198875
  },
@@ -198825,7 +198899,7 @@ var rules = [
198825
198899
  "diagnostics": [{
198826
198900
  "start": 24,
198827
198901
  "end": 37,
198828
- "text": "Prefer using the Random service from Effect instead of Math.random(). effect(globalRandom)"
198902
+ "text": "This code uses `Math.random()`, randomness is represented through the Effect `Random` service. effect(globalRandom)"
198829
198903
  }]
198830
198904
  }
198831
198905
  },
@@ -198842,7 +198916,7 @@ var rules = [
198842
198916
  "diagnostics": [{
198843
198917
  "start": 93,
198844
198918
  "end": 106,
198845
- "text": "Prefer using the Random service from Effect instead of Math.random() inside Effect generators. effect(globalRandomInEffect)"
198919
+ "text": "This Effect code uses `Math.random()`, randomness is represented through the Effect `Random` service. effect(globalRandomInEffect)"
198846
198920
  }]
198847
198921
  }
198848
198922
  },
@@ -198859,7 +198933,7 @@ var rules = [
198859
198933
  "diagnostics": [{
198860
198934
  "start": 1,
198861
198935
  "end": 26,
198862
- "text": "Prefer using Effect.sleep or Schedule from Effect instead of setTimeout. effect(globalTimers)"
198936
+ "text": "This code uses `setTimeout`, the corresponding Effect timer API is `Effect.sleep or Schedule` from Effect. effect(globalTimers)"
198863
198937
  }]
198864
198938
  }
198865
198939
  },
@@ -198876,7 +198950,7 @@ var rules = [
198876
198950
  "diagnostics": [{
198877
198951
  "start": 83,
198878
198952
  "end": 108,
198879
- "text": "Prefer using Effect.sleep or Schedule from Effect instead of setTimeout inside Effect generators. effect(globalTimersInEffect)"
198953
+ "text": "This Effect code uses `setTimeout`, the corresponding timer API in this context is `Effect.sleep or Schedule` from Effect. effect(globalTimersInEffect)"
198880
198954
  }]
198881
198955
  }
198882
198956
  },
@@ -198893,7 +198967,7 @@ var rules = [
198893
198967
  "diagnostics": [{
198894
198968
  "start": 159,
198895
198969
  "end": 180,
198896
- "text": "Consider using Schema.is instead of instanceof for Effect Schema types. effect(instanceOfSchema)"
198970
+ "text": "This code uses `instanceof` with an Effect Schema type. `Schema.is` is the schema-aware runtime check for this case. effect(instanceOfSchema)"
198897
198971
  }]
198898
198972
  }
198899
198973
  },
@@ -198910,7 +198984,7 @@ var rules = [
198910
198984
  "diagnostics": [{
198911
198985
  "start": 15,
198912
198986
  "end": 24,
198913
- "text": "Prefer using FileSystem from @effect/platform instead of the Node.js 'fs' module. effect(nodeBuiltinImport)"
198987
+ "text": "This module reference uses the `fs` module, the corresponding Effect API is `FileSystem` from `@effect/platform`. effect(nodeBuiltinImport)"
198914
198988
  }]
198915
198989
  }
198916
198990
  },
@@ -198927,7 +199001,7 @@ var rules = [
198927
199001
  "diagnostics": [{
198928
199002
  "start": 142,
198929
199003
  "end": 158,
198930
- "text": "Consider using Effect Schema for JSON operations instead of JSON.parse/JSON.stringify. effect(preferSchemaOverJson)"
199004
+ "text": "This code uses `JSON.parse` or `JSON.stringify`. Effect Schema provides Effect-aware APIs for JSON parsing and stringifying. effect(preferSchemaOverJson)"
198931
199005
  }]
198932
199006
  }
198933
199007
  },
@@ -198944,7 +199018,7 @@ var rules = [
198944
199018
  "diagnostics": [{
198945
199019
  "start": 150,
198946
199020
  "end": 162,
198947
- "text": "You can use Effect.mapError instead of Effect.catch + Effect.fail to transform the error type. effect(catchAllToMapError)"
199021
+ "text": "`Effect.mapError` expresses the same error-type transformation more directly than `Effect.catch` followed by `Effect.fail`. effect(catchAllToMapError)"
198948
199022
  }]
198949
199023
  }
198950
199024
  },
@@ -198961,7 +199035,7 @@ var rules = [
198961
199035
  "diagnostics": [{
198962
199036
  "start": 116,
198963
199037
  "end": 134,
198964
- "text": "Key should be 'effect-v4-tests/preview/RenamedService'. effect(deterministicKeys)"
199038
+ "text": "This key does not match the deterministic key for this declaration. The expected key is `effect-v4-tests/preview/RenamedService`. effect(deterministicKeys)"
198965
199039
  }]
198966
199040
  }
198967
199041
  },
@@ -198978,7 +199052,7 @@ var rules = [
198978
199052
  "diagnostics": [{
198979
199053
  "start": 54,
198980
199054
  "end": 61,
198981
- "text": "Can be rewritten as a reusable function: Effect.fn(function*() { ... }). effect(effectFnOpportunity)"
199055
+ "text": "This expression can be rewritten in the reusable function form `Effect.fn(function*() { ... })`. effect(effectFnOpportunity)"
198982
199056
  }]
198983
199057
  }
198984
199058
  },
@@ -198995,7 +199069,7 @@ var rules = [
198995
199069
  "diagnostics": [{
198996
199070
  "start": 82,
198997
199071
  "end": 92,
198998
- "text": "Effect.asVoid can be used instead to discard the success value. effect(effectMapVoid)"
199072
+ "text": "This expression discards the success value through mapping. `Effect.asVoid` represents that form directly. effect(effectMapVoid)"
198999
199073
  }]
199000
199074
  }
199001
199075
  },
@@ -199012,7 +199086,7 @@ var rules = [
199012
199086
  "diagnostics": [{
199013
199087
  "start": 56,
199014
199088
  "end": 81,
199015
- "text": "Effect.void can be used instead of Effect.succeed(undefined) or Effect.succeed(void 0). effect(effectSucceedWithVoid)"
199089
+ "text": "`Effect.void` represents the same outcome as `Effect.succeed(undefined)` or `Effect.succeed(void 0)`. effect(effectSucceedWithVoid)"
199016
199090
  }]
199017
199091
  }
199018
199092
  },
@@ -199029,7 +199103,7 @@ var rules = [
199029
199103
  "diagnostics": [{
199030
199104
  "start": 116,
199031
199105
  "end": 172,
199032
- "text": "Nested function calls can be converted to pipeable style for better readability; consider using Schema.decodeEffect(User)({ id: 1 }).pipe(...) instead. effect(missedPipeableOpportunity)"
199106
+ "text": "This nested call structure has a pipeable form. `Schema.decodeEffect(User)({ id: 1 }).pipe(...)` represents the same call sequence in pipe style and may be easier to read. effect(missedPipeableOpportunity)"
199033
199107
  }]
199034
199108
  }
199035
199109
  },
@@ -199080,7 +199154,7 @@ var rules = [
199080
199154
  "diagnostics": [{
199081
199155
  "start": 64,
199082
199156
  "end": 136,
199083
- "text": "Schema.Struct with a _tag field can be simplified to Schema.TaggedStruct to make the tag optional in the constructor. effect(schemaStructWithTag)"
199157
+ "text": "This `Schema.Struct` includes a `_tag` field. `Schema.TaggedStruct` is the tagged-struct form for this pattern and makes the tag optional in the constructor. effect(schemaStructWithTag)"
199084
199158
  }]
199085
199159
  }
199086
199160
  },
@@ -199097,7 +199171,7 @@ var rules = [
199097
199171
  "diagnostics": [{
199098
199172
  "start": 64,
199099
199173
  "end": 118,
199100
- "text": "A Schema.Union of multiple Schema.Literal calls can be simplified to a single Schema.Literal call. effect(schemaUnionOfLiterals)"
199174
+ "text": "This `Schema.Union` contains multiple `Schema.Literal` members and can be simplified to a single `Schema.Literal` call. effect(schemaUnionOfLiterals)"
199101
199175
  }]
199102
199176
  }
199103
199177
  },
@@ -199114,7 +199188,7 @@ var rules = [
199114
199188
  "diagnostics": [{
199115
199189
  "start": 60,
199116
199190
  "end": 107,
199117
- "text": "ServiceMap.Service should be used in a class declaration instead of as a variable. Use: class Preview extends ServiceMap.Service<Preview, { port: number }>()(\"Preview\") {} effect(serviceNotAsClass)"
199191
+ "text": "`ServiceMap.Service` is assigned to a variable here, but this API is intended for a class declaration shape such as `class Preview extends ServiceMap.Service<Preview, { port: number }>()(\"Preview\") {}`. effect(serviceNotAsClass)"
199118
199192
  }]
199119
199193
  }
199120
199194
  },
@@ -199169,7 +199243,7 @@ var rules = [
199169
199243
  "diagnostics": [{
199170
199244
  "start": 178,
199171
199245
  "end": 183,
199172
- "text": "This Effect.fail call uses a yieldable error type as argument. You can yield* the error directly instead. effect(unnecessaryFailYieldableError)"
199246
+ "text": "This `yield* Effect.fail(...)` passes a yieldable error value. `yield*` represents that value directly without wrapping it in `Effect.fail`. effect(unnecessaryFailYieldableError)"
199173
199247
  }]
199174
199248
  }
199175
199249
  },
@@ -199203,7 +199277,7 @@ var rules = [
199203
199277
  "diagnostics": [{
199204
199278
  "start": 64,
199205
199279
  "end": 125,
199206
- "text": "Chained pipe calls can be simplified to a single pipe call. effect(unnecessaryPipeChain)"
199280
+ "text": "This expression contains chained `pipe` calls that can be simplified to a single `pipe` call. effect(unnecessaryPipeChain)"
199207
199281
  }]
199208
199282
  }
199209
199283
  }
@@ -199612,6 +199686,7 @@ function createRulePrompt(rules, initialSeverities) {
199612
199686
  const fromAssessment = (inputState) => ({
199613
199687
  packageJson: {
199614
199688
  lspVersion: inputState.packageJson.lspVersion,
199689
+ nativePreviewVersion: inputState.packageJson.nativePreviewVersion,
199615
199690
  prepareScript: map$9(inputState.packageJson.prepareScript, (_) => _.hasPatch).pipe(getOrElse$1(() => false))
199616
199691
  },
199617
199692
  tsconfig: { diagnosticSeverities: inputState.tsconfig.currentDiagnosticSeverities },
@@ -199783,6 +199858,7 @@ const gatherTargetState = (assessment, context) => gen(function* () {
199783
199858
  if (lspDependencyType === "no") return {
199784
199859
  packageJson: {
199785
199860
  lspVersion: none$3(),
199861
+ nativePreviewVersion: assessment.packageJson.nativePreviewVersion,
199786
199862
  prepareScript: false
199787
199863
  },
199788
199864
  tsconfig: { diagnosticSeverities: none$3() },
@@ -199840,6 +199916,10 @@ const gatherTargetState = (assessment, context) => gen(function* () {
199840
199916
  dependencyType: lspDependencyType,
199841
199917
  version: context.defaultLspVersion
199842
199918
  }),
199919
+ nativePreviewVersion: orElse(assessment.packageJson.nativePreviewVersion, () => some({
199920
+ dependencyType: lspDependencyType,
199921
+ version: DEFAULT_NATIVE_PREVIEW_VERSION
199922
+ })),
199843
199923
  prepareScript: true
199844
199924
  },
199845
199925
  tsconfig: { diagnosticSeverities },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@effect/tsgo",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "Effect Language Service for TypeScript-Go — Effect-specific diagnostics and hover features.",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -22,13 +22,13 @@
22
22
  "README.md"
23
23
  ],
24
24
  "optionalDependencies": {
25
- "@effect/tsgo-win32-x64": "0.1.0",
26
- "@effect/tsgo-win32-arm64": "0.1.0",
27
- "@effect/tsgo-linux-x64": "0.1.0",
28
- "@effect/tsgo-linux-arm64": "0.1.0",
29
- "@effect/tsgo-linux-arm": "0.1.0",
30
- "@effect/tsgo-darwin-x64": "0.1.0",
31
- "@effect/tsgo-darwin-arm64": "0.1.0"
25
+ "@effect/tsgo-win32-x64": "0.2.0",
26
+ "@effect/tsgo-win32-arm64": "0.2.0",
27
+ "@effect/tsgo-linux-x64": "0.2.0",
28
+ "@effect/tsgo-linux-arm64": "0.2.0",
29
+ "@effect/tsgo-linux-arm": "0.2.0",
30
+ "@effect/tsgo-darwin-x64": "0.2.0",
31
+ "@effect/tsgo-darwin-arm64": "0.2.0"
32
32
  },
33
33
  "devDependencies": {
34
34
  "@effect/platform-node": "^4.0.0-beta.40",