resultar 3.3.0 → 3.4.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
@@ -71,21 +71,6 @@ import type { StrictResult } from 'resultar'
71
71
 
72
72
  CommonJS `require('resultar')` is not exported.
73
73
 
74
- ## Mutation Testing
75
-
76
- The core runtime package has a scoped Stryker setup for mutation testing:
77
-
78
- ```sh
79
- pnpm --filter resultar test:mutation
80
- ```
81
-
82
- The setup lives in [`stryker.conf.json`](./stryker.conf.json) and is intentionally separate from
83
- `check:full`. It mutates the central runtime files under `src/`, uses the Vitest runner with
84
- per-test coverage, stores incremental state under `reports/`, and keeps baseline thresholds
85
- report-only while the mutation score is established. The dedicated
86
- [`vitest-stryker.config.ts`](./vitest-stryker.config.ts) maps `vite-plus/test` to `vitest` so
87
- Stryker can run the same tests without the `vp test` bootstrap.
88
-
89
74
  ## Why Teams Use It
90
75
 
91
76
  This signature hides an expected failure:
@@ -174,6 +159,31 @@ const getPosts = (
174
159
  )
175
160
  ```
176
161
 
162
+ The same flow can be written linearly with `safeTry` when the chain gets harder to scan:
163
+
164
+ ```ts
165
+ const getPostsLinear = (
166
+ url: string,
167
+ ): StrictResultAsync<Post[], FetchPostsError | HttpClientError | ParsePostsError> =>
168
+ safeTry(async function* () {
169
+ const response = yield* tryResultAsync(
170
+ fetch(url),
171
+ (cause) => new FetchPostsError({ cause }),
172
+ )
173
+
174
+ if (response.status >= 400) {
175
+ return HttpClientError.err({ status: response.status })
176
+ }
177
+
178
+ const posts = yield* tryResultAsync(
179
+ response.json() as Promise<Post[]>,
180
+ (cause) => new ParsePostsError({ cause }),
181
+ )
182
+
183
+ return ok(posts)
184
+ })
185
+ ```
186
+
177
187
  ## Async Control Without A Runtime
178
188
 
179
189
  The 3.1 async helpers cover common production workflows while keeping plain `Promise` and
@@ -826,6 +836,27 @@ Use `fromPromise` when you already have a promise and need to map rejection into
826
836
  const user = fromPromise(loadUserFromRemote(id), (cause) => new FetchUserError({ cause, id }))
827
837
  ```
828
838
 
839
+ Use `tryResultAsync` when the async boundary is the thing you want to name and document. The object
840
+ form is useful for infrastructure helpers because the task and error mapper stay together:
841
+
842
+ ```ts
843
+ import { createTaggedError, tryResultAsync } from 'resultar'
844
+ import type { StrictResultAsync } from 'resultar'
845
+
846
+ type AsyncTask = () => Promise<void>
847
+
848
+ class TaskError extends createTaggedError({
849
+ name: 'TaskError',
850
+ message: 'Task failed: $label',
851
+ }) {}
852
+
853
+ const tryTask = (label: string, task: AsyncTask): StrictResultAsync<void, TaskError> =>
854
+ tryResultAsync({
855
+ try: task,
856
+ catch: (cause) => new TaskError({ cause, label }),
857
+ })
858
+ ```
859
+
829
860
  After that edge conversion, keep your own domain functions returning `Result` values instead of
830
861
  throwing expected failures.
831
862
 
@@ -952,11 +983,13 @@ Add a check script:
952
983
  ```json
953
984
  {
954
985
  "scripts": {
955
- "check": "resultar-check -p tsconfig.json --noEmit"
986
+ "check": "resultar-check"
956
987
  }
957
988
  }
958
989
  ```
959
990
 
991
+ `resultar-check` defaults to `tsconfig.json` and runs TypeScript with no emit.
992
+
960
993
  These fail in the default `must-use` mode:
961
994
 
962
995
  ```ts
@@ -980,15 +1013,21 @@ Configure Resultar rules in `tsconfig.json`:
980
1013
 
981
1014
  ```json
982
1015
  {
1016
+ "$schema": "./node_modules/resultar-check/schema.json",
983
1017
  "compilerOptions": {
984
1018
  "plugins": [{ "name": "resultar-check", "noDiscard": "error" }]
985
1019
  }
986
1020
  }
987
1021
  ```
988
1022
 
1023
+ The package-local schema provides editor completion and validation for `resultar-check` plugin
1024
+ options.
1025
+
989
1026
  Oxlint is intentionally not part of the Resultar rules path; use it only for general linting if your
990
1027
  project wants it.
991
1028
 
1029
+ For VS Code and Zed setup, use the editor integration section in the `resultar-check` package guide.
1030
+
992
1031
  ## API Decision Guide
993
1032
 
994
1033
  | Need | Use |