yield-result 0.1.3 → 0.1.5
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 +16 -4
- package/dist/types.d.ts +5 -1
- package/dist/types.js +7 -1
- package/dist/wrappers.d.ts +8 -0
- package/dist/wrappers.js +12 -0
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -45,6 +45,16 @@ const processOrder = (id: string) => safe.async(async function* () {
|
|
|
45
45
|
});
|
|
46
46
|
```
|
|
47
47
|
|
|
48
|
+
### 🎓 How `yield*` Works Under the Hood (Didactic Guide)
|
|
49
|
+
|
|
50
|
+
Many JavaScript developers assume generators are complex, but in `yield-result`, generator delegation (**`yield*`**) is simply a **native protocol for unwrapping values**:
|
|
51
|
+
|
|
52
|
+
1. **`Ok<T>` Protocol**: Implements `[Symbol.iterator]` to return `value` immediately without yielding anything. Therefore, `const x = yield* ok(10)` assigns `10` directly to `x` in 0 suspension steps.
|
|
53
|
+
2. **`Err<E>` Protocol**: Implements `[Symbol.iterator]` to `yield` the `Err` instance once back to `safe.sync` / `safe.async`.
|
|
54
|
+
3. **Short-Circuiting**: The runner (`safe.sync`) receives the `Err` object, immediately calls `gen.return()` (triggering any `try ... finally` cleanup in your function), and early-returns `err(E)`.
|
|
55
|
+
|
|
56
|
+
No exception throwing, no stack unwinding, 100% native ECMAScript iteration semantics.
|
|
57
|
+
|
|
48
58
|
---
|
|
49
59
|
|
|
50
60
|
## 🚀 Installation
|
|
@@ -277,14 +287,16 @@ safe.sync(function* () {
|
|
|
277
287
|
* **`err(error)`** / **`Result.err(error)`** — Creates an `Err<E>` result.
|
|
278
288
|
* **`isOk(result)`** / **`isErr(result)`** — TypeScript type guards.
|
|
279
289
|
|
|
280
|
-
### Flow Runners (`safe`)
|
|
281
|
-
* **`safe.sync(function* () { ... })`** — Executes a synchronous generator function with early-return short-circuiting on `Err`.
|
|
282
|
-
* **`safe.async(async function* () { ... })`** — Executes an async generator function with early-return short-circuiting on `Err`.
|
|
290
|
+
### Flow Runners (`safe` & `Result.gen`)
|
|
291
|
+
* **`safe.sync(function* () { ... })`** / **`Result.gen(function* () { ... })`** — Executes a synchronous generator function with early-return short-circuiting on `Err`.
|
|
292
|
+
* **`safe.async(async function* () { ... })`** / **`Result.gen.async(async function* () { ... })`** — Executes an async generator function with early-return short-circuiting on `Err`.
|
|
283
293
|
|
|
284
|
-
### Exception Wrappers
|
|
294
|
+
### Exception Wrappers & Function Lifting
|
|
285
295
|
* **`fromThrowable(fn, errorMapper?)`** — Wraps a throwing function into a `Result<T, E>`.
|
|
286
296
|
* **`fromPromise(promise, errorMapper?)`** — Wraps a Promise into `Promise<Result<T, E>>`.
|
|
287
297
|
* **`fromAsyncFn(fn, errorMapper?)`** — Wraps an async function into `Promise<Result<T, E>>`.
|
|
298
|
+
* **`lift(fn, errorMapper?)`** — Lifts a sync throwing function `(...args) => T` into a Result function `(...args) => Result<T, E>`.
|
|
299
|
+
* **`liftAsync(fn, errorMapper?)`** — Lifts an async function `(...args) => Promise<T>` into a Promise<Result> function `(...args) => Promise<Result<T, E>>`.
|
|
288
300
|
|
|
289
301
|
### Combinators & Utilities
|
|
290
302
|
* **`map(result, fn)`** — Transforms the `Ok` value.
|
package/dist/types.d.ts
CHANGED
|
@@ -98,7 +98,7 @@ export interface TaggedError<T extends string> {
|
|
|
98
98
|
*/
|
|
99
99
|
export declare const taggedError: <T extends string, P extends Record<string, unknown> = {}>(tag: T, props?: P) => Readonly<TaggedError<T> & P>;
|
|
100
100
|
/**
|
|
101
|
-
* Namespace object grouping all Result constructors, guards, and
|
|
101
|
+
* Namespace object grouping all Result constructors, guards, combinators, and generator runners.
|
|
102
102
|
*/
|
|
103
103
|
export declare const Result: {
|
|
104
104
|
readonly ok: <T>(value: T) => Ok<T>;
|
|
@@ -123,4 +123,8 @@ export declare const Result: {
|
|
|
123
123
|
errors: E[];
|
|
124
124
|
};
|
|
125
125
|
readonly taggedError: <T extends string, P extends Record<string, unknown> = {}>(tag: T, props?: P) => Readonly<TaggedError<T> & P>;
|
|
126
|
+
readonly gen: (<G extends Generator<Err<unknown>, unknown, unknown>>(fn: () => G) => Result<G extends Generator<unknown, infer R, unknown> ? R : G extends AsyncGenerator<unknown, infer R_1, unknown> ? R_1 : never, G extends Generator<infer Y, unknown, unknown> ? Y extends Err<infer E> ? E : never : G extends AsyncGenerator<infer Y_1, unknown, unknown> ? Y_1 extends Err<infer E_1> ? E_1 : never : never>) & {
|
|
127
|
+
sync: <G extends Generator<Err<unknown>, unknown, unknown>>(fn: () => G) => Result<G extends Generator<unknown, infer R, unknown> ? R : G extends AsyncGenerator<unknown, infer R_1, unknown> ? R_1 : never, G extends Generator<infer Y, unknown, unknown> ? Y extends Err<infer E> ? E : never : G extends AsyncGenerator<infer Y_1, unknown, unknown> ? Y_1 extends Err<infer E_1> ? E_1 : never : never>;
|
|
128
|
+
async: <G extends AsyncGenerator<Err<unknown>, unknown, unknown>>(fn: () => G) => Promise<Result<G extends Generator<unknown, infer R, unknown> ? R : G extends AsyncGenerator<unknown, infer R_1, unknown> ? R_1 : never, G extends Generator<infer Y, unknown, unknown> ? Y extends Err<infer E> ? E : never : G extends AsyncGenerator<infer Y_1, unknown, unknown> ? Y_1 extends Err<infer E_1> ? E_1 : never : never>>;
|
|
129
|
+
};
|
|
126
130
|
};
|
package/dist/types.js
CHANGED
|
@@ -140,8 +140,13 @@ export const taggedError = (tag, props) => Object.freeze({
|
|
|
140
140
|
_tag: tag,
|
|
141
141
|
...(props ?? {}),
|
|
142
142
|
});
|
|
143
|
+
import { safe } from "./flow.js";
|
|
144
|
+
const genRunner = Object.assign((fn) => safe.sync(fn), {
|
|
145
|
+
sync: safe.sync,
|
|
146
|
+
async: safe.async,
|
|
147
|
+
});
|
|
143
148
|
/**
|
|
144
|
-
* Namespace object grouping all Result constructors, guards, and
|
|
149
|
+
* Namespace object grouping all Result constructors, guards, combinators, and generator runners.
|
|
145
150
|
*/
|
|
146
151
|
export const Result = {
|
|
147
152
|
ok,
|
|
@@ -160,4 +165,5 @@ export const Result = {
|
|
|
160
165
|
all,
|
|
161
166
|
partition,
|
|
162
167
|
taggedError,
|
|
168
|
+
gen: genRunner,
|
|
163
169
|
};
|
package/dist/wrappers.d.ts
CHANGED
|
@@ -14,3 +14,11 @@ export declare const fromPromise: <T, E = unknown>(promise: Promise<T>, errorMap
|
|
|
14
14
|
* Catches both synchronous exceptions thrown during execution and async rejections.
|
|
15
15
|
*/
|
|
16
16
|
export declare const fromAsyncFn: <T, E = unknown>(fn: () => Promise<T>, errorMapper?: (e: unknown) => E) => Promise<Result<T, E>>;
|
|
17
|
+
/**
|
|
18
|
+
* Lifts a standard synchronous function that may throw into a Result-returning function.
|
|
19
|
+
*/
|
|
20
|
+
export declare const lift: <A extends any[], T, E = unknown>(fn: (...args: A) => T, errorMapper?: (e: unknown) => E) => ((...args: A) => Result<T, E>);
|
|
21
|
+
/**
|
|
22
|
+
* Lifts an asynchronous function returning a Promise into a Promise<Result<T, E>> function.
|
|
23
|
+
*/
|
|
24
|
+
export declare const liftAsync: <A extends any[], T, E = unknown>(fn: (...args: A) => Promise<T>, errorMapper?: (e: unknown) => E) => ((...args: A) => Promise<Result<T, E>>);
|
package/dist/wrappers.js
CHANGED
|
@@ -37,3 +37,15 @@ export const fromAsyncFn = async (fn, errorMapper) => {
|
|
|
37
37
|
return err(errorMapper ? errorMapper(e) : e);
|
|
38
38
|
}
|
|
39
39
|
};
|
|
40
|
+
/**
|
|
41
|
+
* Lifts a standard synchronous function that may throw into a Result-returning function.
|
|
42
|
+
*/
|
|
43
|
+
export const lift = (fn, errorMapper) => {
|
|
44
|
+
return (...args) => fromThrowable(() => fn(...args), errorMapper);
|
|
45
|
+
};
|
|
46
|
+
/**
|
|
47
|
+
* Lifts an asynchronous function returning a Promise into a Promise<Result<T, E>> function.
|
|
48
|
+
*/
|
|
49
|
+
export const liftAsync = (fn, errorMapper) => {
|
|
50
|
+
return (...args) => fromAsyncFn(() => fn(...args), errorMapper);
|
|
51
|
+
};
|
package/package.json
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "yield-result",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.5",
|
|
4
4
|
"description": "Rust-style ? operator for TypeScript using generators (yield*). Zero dependencies, type-safe error handling.",
|
|
5
5
|
"type": "module",
|
|
6
|
+
"sideEffects": false,
|
|
6
7
|
"main": "./dist/index.js",
|
|
7
8
|
"module": "./dist/index.js",
|
|
8
9
|
"types": "./dist/index.d.ts",
|