resultar 3.3.1 → 3.5.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
@@ -45,7 +45,7 @@ Use it when expected failures should be impossible to miss:
45
45
  - Ignored `Result` values can be reported by a type-aware no-discard check.
46
46
 
47
47
  Resultar began as an initial fork of `neverthrow`. The v3 line keeps the explicit wrapper model,
48
- then leans into Resultar-specific tagged errors, strict service-boundary types, TypeScript 7-first
48
+ then leans into Resultar-specific tagged errors, strict service-boundary types, TypeScript >=7
49
49
  diagnostics, and ESM-only packaging.
50
50
 
51
51
  ## Install
@@ -61,7 +61,7 @@ npm install resultar
61
61
  ## Requirements
62
62
 
63
63
  - Node.js 24+
64
- - TypeScript 7 for the canonical Resultar diagnostics workflow
64
+ - TypeScript >=7 for the canonical Resultar diagnostics workflow
65
65
  - ESM only
66
66
 
67
67
  ```ts
@@ -738,6 +738,21 @@ const lines = ResultAsync.withResource({
738
738
  })
739
739
  ```
740
740
 
741
+ Adapt callback and subscription APIs with `ResultAsync.fromCallback`. The callback source can
742
+ resolve or reject once, receives the cooperative signal, and returns a synchronous unsubscribe
743
+ function that runs after success, failure, or cancellation.
744
+
745
+ ```ts
746
+ const nextValue = ResultAsync.fromCallback<number, SubscriptionError>({
747
+ catch: (cause) => new SubscriptionError({ cause }),
748
+ signal,
749
+ subscribe: ({ reject, resolve }) => {
750
+ const subscription = source.subscribe({ error: reject, next: resolve })
751
+ return () => subscription.unsubscribe()
752
+ },
753
+ })
754
+ ```
755
+
741
756
  For pull-based streams, keep the runtime native: expose an `AsyncIterable<Result<T, E>>` and close
742
757
  resources in `finally`. See
743
758
  [DOCUMENTATION.md](../../DOCUMENTATION.md#resourceful-async-iterables) for the full recipe.
@@ -756,6 +771,7 @@ where the failure appears.
756
771
  | Catch thrown sync code now | `tryResult(fn, toError?)` |
757
772
  | Wrap a throwing sync function for later | `fromThrowable(fn, toError?)` |
758
773
  | Catch an existing rejecting promise | `fromPromise(promise, toError)` |
774
+ | Adapt a callback or subscription | `ResultAsync.fromCallback({ subscribe, catch, signal? })` |
759
775
  | Catch a promise or async factory | `tryResultAsync(promiseOrFactory, toError?)` |
760
776
  | Wrap an async function for later | `fromThrowableAsync(fn, toError?)` |
761
777
  | Turn one error into another | `mapErr(fn)` |
@@ -836,6 +852,27 @@ Use `fromPromise` when you already have a promise and need to map rejection into
836
852
  const user = fromPromise(loadUserFromRemote(id), (cause) => new FetchUserError({ cause, id }))
837
853
  ```
838
854
 
855
+ Use `tryResultAsync` when the async boundary is the thing you want to name and document. The object
856
+ form is useful for infrastructure helpers because the task and error mapper stay together:
857
+
858
+ ```ts
859
+ import { createTaggedError, tryResultAsync } from 'resultar'
860
+ import type { StrictResultAsync } from 'resultar'
861
+
862
+ type AsyncTask = () => Promise<void>
863
+
864
+ class TaskError extends createTaggedError({
865
+ name: 'TaskError',
866
+ message: 'Task failed: $label',
867
+ }) {}
868
+
869
+ const tryTask = (label: string, task: AsyncTask): StrictResultAsync<void, TaskError> =>
870
+ tryResultAsync({
871
+ try: task,
872
+ catch: (cause) => new TaskError({ cause, label }),
873
+ })
874
+ ```
875
+
839
876
  After that edge conversion, keep your own domain functions returning `Result` values instead of
840
877
  throwing expected failures.
841
878
 
@@ -950,11 +987,11 @@ const config = safeTry({
950
987
 
951
988
  ## No-Discard Validation
952
989
 
953
- Resultar values should not be ignored. Use `resultar-check` to run TypeScript 7 and Resultar
990
+ Resultar values should not be ignored. Use `resultar-check` to run TypeScript >=7 and Resultar
954
991
  diagnostics through one command.
955
992
 
956
993
  ```sh
957
- pnpm add -D resultar-check typescript-7@npm:typescript@rc
994
+ pnpm add -D resultar-check "typescript@>=7"
958
995
  ```
959
996
 
960
997
  Add a check script:
@@ -962,11 +999,13 @@ Add a check script:
962
999
  ```json
963
1000
  {
964
1001
  "scripts": {
965
- "check": "resultar-check -p tsconfig.json --noEmit"
1002
+ "check": "resultar-check"
966
1003
  }
967
1004
  }
968
1005
  ```
969
1006
 
1007
+ `resultar-check` defaults to `tsconfig.json` and runs TypeScript with no emit.
1008
+
970
1009
  These fail in the default `must-use` mode:
971
1010
 
972
1011
  ```ts
@@ -990,14 +1029,22 @@ Configure Resultar rules in `tsconfig.json`:
990
1029
 
991
1030
  ```json
992
1031
  {
1032
+ "$schema": "./node_modules/resultar-check/schema.json",
993
1033
  "compilerOptions": {
994
1034
  "plugins": [{ "name": "resultar-check", "noDiscard": "error" }]
995
1035
  }
996
1036
  }
997
1037
  ```
998
1038
 
999
- Oxlint is intentionally not part of the Resultar rules path; use it only for general linting if your
1000
- project wants it.
1039
+ The package-local schema provides editor completion and validation for `resultar-check` plugin
1040
+ options.
1041
+
1042
+ For fast AST-only Oxlint, ESLint, or Deno Lint feedback, use the adapter exports documented in the
1043
+ `resultar-check` package guide. Use the `resultar-check` CLI for the full TypeScript-backed rule set.
1044
+ The `examples/lint` package shows how to compare Oxlint, ESLint, and CLI counts by running the CLI
1045
+ with the same AST-only rule subset.
1046
+
1047
+ For VS Code and Zed setup, use the editor integration section in the `resultar-check` package guide.
1001
1048
 
1002
1049
  ## API Decision Guide
1003
1050
 
@@ -1010,6 +1057,7 @@ project wants it.
1010
1057
  | Create an `Ok(undefined)` | `unit()` or `unitAsync()` |
1011
1058
  | Convert throwing sync code | `tryResult` or `fromThrowable` |
1012
1059
  | Convert rejecting async code | `tryResultAsync`, `fromPromise`, or `fromThrowableAsync` |
1060
+ | Convert a callback subscription | `ResultAsync.fromCallback` or `fromCallback` |
1013
1061
  | Treat an `Err` as unrecoverable at an edge | `unwrapOrThrow()` |
1014
1062
  | Transform success | `map` or `asyncMap` |
1015
1063
  | Replace success with a known value | `as(value)` |
@@ -1076,19 +1124,17 @@ More focused material:
1076
1124
  - [Full guide](https://github.com/inaiat/resultar/blob/main/DOCUMENTATION.md)
1077
1125
  - [Type-safe error handling article, English](https://github.com/inaiat/resultar/blob/main/articles/en/type-safe.md)
1078
1126
  - [Artigo sobre tratamento de erros type-safe, Portuguese](https://github.com/inaiat/resultar/blob/main/articles/pt/type-safe.md)
1079
- - [resultar-check package guide](https://github.com/inaiat/resultar/blob/main/packages/resultar-check/README.md)
1127
+ - [resultar-check package guide](https://github.com/inaiat/resultar/blob/main/packages/check/README.md)
1080
1128
 
1081
1129
  ## Repository
1082
1130
 
1083
1131
  This repository is a pnpm workspace:
1084
1132
 
1085
1133
  - `packages/resultar`: Resultar runtime package.
1086
- - `packages/resultar-check`: TypeScript 7 plus Resultar validation.
1087
- - `packages/resultar-lint`: deprecated compatibility wrapper.
1088
- - `packages/resultar-tsgo`: deprecated compatibility wrapper for older installs.
1134
+ - `packages/check`: TypeScript >=7 plus Resultar validation and AST-only lint adapters.
1089
1135
  - `benchmarks`: benchmark package.
1090
1136
  - `examples/resultar`: runnable core Resultar cookbook.
1091
- - `examples/lint`: TypeScript 7 `resultar-check` smoke example.
1137
+ - `examples/lint`: adapter parity smoke for AST-only Resultar rules across Oxlint, ESLint, and `resultar-check` CLI.
1092
1138
 
1093
1139
  Common commands:
1094
1140