nalloc 0.1.0 → 0.2.1
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 +61 -28
- package/build/iter.cjs +6 -8
- package/build/iter.cjs.map +1 -1
- package/build/iter.js +6 -8
- package/build/iter.js.map +1 -1
- package/build/option.cjs +14 -4
- package/build/option.cjs.map +1 -1
- package/build/option.d.ts +11 -0
- package/build/option.js +11 -4
- package/build/option.js.map +1 -1
- package/build/result.cjs +107 -39
- package/build/result.cjs.map +1 -1
- package/build/result.d.ts +95 -12
- package/build/result.js +92 -36
- package/build/result.js.map +1 -1
- package/build/safe.cjs +16 -0
- package/build/safe.cjs.map +1 -1
- package/build/safe.d.ts +22 -1
- package/build/safe.js +8 -1
- package/build/safe.js.map +1 -1
- package/package.json +2 -2
- package/src/__tests__/index.ts +34 -0
- package/src/__tests__/option.ts +23 -1
- package/src/__tests__/option.types.ts +2 -1
- package/src/__tests__/result.ts +194 -1
- package/src/__tests__/result.types.ts +17 -4
- package/src/iter.ts +4 -2
- package/src/option.ts +21 -1
- package/src/result.ts +192 -52
- package/src/safe.ts +49 -1
package/README.md
CHANGED
|
@@ -44,7 +44,7 @@ npm install nalloc
|
|
|
44
44
|
## Quick start
|
|
45
45
|
|
|
46
46
|
```ts
|
|
47
|
-
import { Option, Result, ok, err, none,
|
|
47
|
+
import { Option, Result, ok, err, none, pipe, gen } from 'nalloc';
|
|
48
48
|
|
|
49
49
|
// Option: the value IS the Option
|
|
50
50
|
const port = Option.fromNullable(process.env.PORT);
|
|
@@ -58,12 +58,19 @@ const data = Result.match(
|
|
|
58
58
|
error => ({ fallback: true })
|
|
59
59
|
);
|
|
60
60
|
|
|
61
|
-
//
|
|
62
|
-
const result =
|
|
63
|
-
const a =
|
|
64
|
-
const b =
|
|
61
|
+
// gen: Rust-like ? operator with type-safe errors
|
|
62
|
+
const result = gen(function*($) {
|
|
63
|
+
const a = yield* $(parseNumber('10'));
|
|
64
|
+
const b = yield* $(parseNumber('5'));
|
|
65
65
|
return a + b;
|
|
66
|
-
}); //
|
|
66
|
+
}); // Result<number, ParseError>
|
|
67
|
+
|
|
68
|
+
// pipe: left-to-right composition
|
|
69
|
+
const userId = pipe(
|
|
70
|
+
Result.tryCatch(() => JSON.parse(raw)),
|
|
71
|
+
r => Result.map(r, data => data.userId),
|
|
72
|
+
r => Result.unwrapOr(r, 0),
|
|
73
|
+
);
|
|
67
74
|
```
|
|
68
75
|
|
|
69
76
|
## How it works
|
|
@@ -103,8 +110,8 @@ import * as O from 'fp-ts/Option';
|
|
|
103
110
|
pipe(O.some(42), O.map(x => x * 2));
|
|
104
111
|
|
|
105
112
|
// nalloc - simpler, faster
|
|
106
|
-
import { Option } from 'nalloc';
|
|
107
|
-
Option.map(
|
|
113
|
+
import { Option, pipe } from 'nalloc';
|
|
114
|
+
pipe(42, v => Option.map(v, x => x * 2)); // built-in pipe, value IS the Option
|
|
108
115
|
```
|
|
109
116
|
|
|
110
117
|
### From oxide.ts
|
|
@@ -146,7 +153,7 @@ Option.unwrapOr(42, 0); // value IS the Option
|
|
|
146
153
|
The API mirrors Rust's `Option` and `Result`:
|
|
147
154
|
|
|
148
155
|
```ts
|
|
149
|
-
import { Option, Result, ok, err, none,
|
|
156
|
+
import { Option, Result, ok, err, none, gen } from 'nalloc';
|
|
150
157
|
|
|
151
158
|
// Rust: Some(42).map(|x| x * 2)
|
|
152
159
|
Option.map(42, x => x * 2);
|
|
@@ -157,9 +164,9 @@ Result.andThen(ok(42), x => x > 0 ? ok(x) : err('negative'));
|
|
|
157
164
|
// Rust: result.unwrap_or(0)
|
|
158
165
|
Result.unwrapOr(result, 0);
|
|
159
166
|
|
|
160
|
-
// Rust: let value =
|
|
161
|
-
const value =
|
|
162
|
-
const a =
|
|
167
|
+
// Rust: let value = get_value()?
|
|
168
|
+
const value = gen(function*($) {
|
|
169
|
+
const a = yield* $(getValue());
|
|
163
170
|
return a + 1;
|
|
164
171
|
});
|
|
165
172
|
```
|
|
@@ -205,7 +212,7 @@ const maybeUser = await Option.fromPromise(fetchUserById(id));
|
|
|
205
212
|
A `Result<T, E>` is either `Ok<T>` (the value itself) or `Err<E>` (a wrapper).
|
|
206
213
|
|
|
207
214
|
```ts
|
|
208
|
-
import { Result, ok, err,
|
|
215
|
+
import { Result, ok, err, gen, genAsync, pipe } from 'nalloc';
|
|
209
216
|
|
|
210
217
|
// Wrap throwing functions
|
|
211
218
|
const parsed = Result.tryCatch(
|
|
@@ -213,24 +220,35 @@ const parsed = Result.tryCatch(
|
|
|
213
220
|
e => 'invalid json'
|
|
214
221
|
);
|
|
215
222
|
|
|
216
|
-
//
|
|
217
|
-
const result =
|
|
218
|
-
const config =
|
|
219
|
-
const db =
|
|
223
|
+
// gen: Rust-like ? operator with preserved error types
|
|
224
|
+
const result = gen(function*($) {
|
|
225
|
+
const config = yield* $(parseConfig(raw));
|
|
226
|
+
const db = yield* $(connectDb(config.url));
|
|
220
227
|
return db.query('SELECT 1');
|
|
221
|
-
});
|
|
228
|
+
}); // Result<QueryResult, ConfigError | DbError>
|
|
222
229
|
|
|
223
|
-
// Async
|
|
224
|
-
const data = await
|
|
225
|
-
const res =
|
|
226
|
-
const posts =
|
|
230
|
+
// Async gen
|
|
231
|
+
const data = await genAsync(async function*($) {
|
|
232
|
+
const res = yield* $(await Result.fromPromise(fetchUser(id)));
|
|
233
|
+
const posts = yield* $(await Result.fromPromise(fetchPosts(res.id)));
|
|
227
234
|
return { user: res, posts };
|
|
228
|
-
});
|
|
235
|
+
}); // Promise<Result<{user, posts}, unknown>>
|
|
229
236
|
|
|
230
|
-
//
|
|
231
|
-
const
|
|
232
|
-
|
|
233
|
-
|
|
237
|
+
// wrap / toThrowable: ecosystem boundaries
|
|
238
|
+
const safeParse = Result.wrap(JSON.parse); // throwing -> Result
|
|
239
|
+
safeParse('{"a":1}'); // Ok({a: 1})
|
|
240
|
+
const throwingFind = Result.toThrowable(findUser); // Result -> throwing
|
|
241
|
+
throwingFind('123'); // returns User or throws
|
|
242
|
+
|
|
243
|
+
// Standard Schema validation (Zod, Valibot, ArkType, etc.)
|
|
244
|
+
const validated = Result.fromSchema(userSchema, input);
|
|
245
|
+
// Result<User, readonly SchemaIssue[]>
|
|
246
|
+
|
|
247
|
+
// Transform with pipe
|
|
248
|
+
const userId = pipe(
|
|
249
|
+
parsed,
|
|
250
|
+
r => Result.map(r, data => data.userId),
|
|
251
|
+
r => Result.flatMap(r, id => id > 0 ? ok(id) : err('invalid id')),
|
|
234
252
|
);
|
|
235
253
|
|
|
236
254
|
// Pattern match
|
|
@@ -289,6 +307,7 @@ Iter.tryForEach(items, item => processItem(item));
|
|
|
289
307
|
| `flatMap(opt, fn)` | Chain Option-returning functions |
|
|
290
308
|
| `andThen(opt, fn)` | Alias for flatMap |
|
|
291
309
|
| `tap(opt, fn)` | Side effect on Some, return original |
|
|
310
|
+
| `tapNone(opt, fn)` | Side effect on None, return original |
|
|
292
311
|
| `filter(opt, predicate)` | Keep Some if predicate passes |
|
|
293
312
|
| `match(opt, onSome, onNone)` | Pattern match |
|
|
294
313
|
| `unwrap(opt)` | Extract or throw |
|
|
@@ -327,6 +346,11 @@ Iter.tryForEach(items, item => processItem(item));
|
|
|
327
346
|
| `tryCatch(fn, onError?)` | Wrap throwing function |
|
|
328
347
|
| `tryCatchMaybePromise(fn, onError?)` | Wrap sync-or-async, preserving sync |
|
|
329
348
|
| `of(fn)` | Alias for tryCatch (no error mapper) |
|
|
349
|
+
| `wrap(fn, onError?)` | Wrap throwing function once, reuse |
|
|
350
|
+
| `toThrowable(fn)` | Inverse of wrap: Result-returning to throwing |
|
|
351
|
+
| `fromSchema(schema, value)` | Validate via Standard Schema v1 |
|
|
352
|
+
| `gen(fn)` | Generator do-notation with typed errors |
|
|
353
|
+
| `genAsync(fn)` | Async generator do-notation |
|
|
330
354
|
| `safeTry(fn)` | Imperative error handling with unwrap |
|
|
331
355
|
| `safeTryAsync(fn)` | Async version of safeTry |
|
|
332
356
|
| `unwrap(result)` | Extract Ok or throw error value |
|
|
@@ -382,6 +406,12 @@ Iter.tryForEach(items, item => processItem(item));
|
|
|
382
406
|
| `tryFold(source, init, fn)` | Fold with early exit on Err |
|
|
383
407
|
| `tryForEach(source, fn)` | Iterate with early exit on Err |
|
|
384
408
|
|
|
409
|
+
### Utilities
|
|
410
|
+
|
|
411
|
+
| Function | Description |
|
|
412
|
+
|----------|-------------|
|
|
413
|
+
| `pipe(value, ...fns)` | Thread value through functions left-to-right |
|
|
414
|
+
|
|
385
415
|
## Comparison
|
|
386
416
|
|
|
387
417
|
| Feature | nalloc | neverthrow | fp-ts | oxide.ts | ts-results |
|
|
@@ -393,7 +423,10 @@ Iter.tryForEach(items, item => processItem(item));
|
|
|
393
423
|
| Async support | Yes | Yes | Yes | Limited | No |
|
|
394
424
|
| Tree-shakeable | Yes | Yes | Yes | Yes | Yes |
|
|
395
425
|
| Iterator utilities | Yes | No | Yes | No | No |
|
|
396
|
-
|
|
|
426
|
+
| gen (? operator) | Yes | Yes | No | No | No |
|
|
427
|
+
| pipe | Yes | No | Yes | No | No |
|
|
428
|
+
| Schema validation | Yes | No | No | No | No |
|
|
429
|
+
| Ecosystem interop | Yes | No | No | No | No |
|
|
397
430
|
|
|
398
431
|
## Alternatives
|
|
399
432
|
|
package/build/iter.cjs
CHANGED
|
@@ -26,6 +26,10 @@ _export(exports, {
|
|
|
26
26
|
}
|
|
27
27
|
});
|
|
28
28
|
const _typescjs = require("./types.cjs");
|
|
29
|
+
const ITER_DONE = Object.freeze({
|
|
30
|
+
value: undefined,
|
|
31
|
+
done: true
|
|
32
|
+
});
|
|
29
33
|
function* mapWhile(source, fn) {
|
|
30
34
|
for (const item of source){
|
|
31
35
|
const mapped = fn(item);
|
|
@@ -41,10 +45,7 @@ function safeIter(source) {
|
|
|
41
45
|
return this;
|
|
42
46
|
},
|
|
43
47
|
next () {
|
|
44
|
-
if (done) return
|
|
45
|
-
value: undefined,
|
|
46
|
-
done: true
|
|
47
|
-
};
|
|
48
|
+
if (done) return ITER_DONE;
|
|
48
49
|
try {
|
|
49
50
|
const next = iter.next();
|
|
50
51
|
if (next.done) {
|
|
@@ -70,10 +71,7 @@ function safeIter(source) {
|
|
|
70
71
|
iter.return?.();
|
|
71
72
|
} catch {}
|
|
72
73
|
}
|
|
73
|
-
return
|
|
74
|
-
value: undefined,
|
|
75
|
-
done: true
|
|
76
|
-
};
|
|
74
|
+
return ITER_DONE;
|
|
77
75
|
}
|
|
78
76
|
};
|
|
79
77
|
}
|
package/build/iter.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/iter.ts"],"sourcesContent":["import { isSome, isErr, err as ERR } from './types.js';\nimport type { Option, Result, Ok } from './types.js';\n\n/**\n * Yields mapped values while the mapping function returns Some, stops at the first None.\n * @param source - The iterable to map over\n * @param fn - Mapping function returning Some(value) to continue or None to stop\n * @returns Generator of mapped values\n * @example\n * [...mapWhile([1, 2, 3, 4], n => n < 3 ? some(n * 10) : none)] // [10, 20]\n */\nexport function* mapWhile<T, U>(source: Iterable<T>, fn: (value: T) => Option<U>): Generator<U> {\n for (const item of source) {\n const mapped = fn(item);\n if (!isSome(mapped)) return;\n yield mapped as U;\n }\n}\n\n/**\n * Wraps an iterable so that each yielded value becomes Ok and any throw becomes a single Err.\n * Stops after the first error - the source's internal state is unknown after an exception.\n *\n * Uses a manual iterator instead of a generator to avoid coroutine suspend/resume overhead.\n *\n * Follows the for-of IteratorClose spec:\n * - iter.return() is never called on natural exhaustion or after a caught error\n * - iter.return() is only called on early consumer exit (break/return)\n * - Cleanup errors from iter.return() are suppressed\n *\n * @param source - The iterable to wrap\n * @returns Iterable iterator of Result values\n * @example\n * [...safeIter([1, 2, 3])] // [Ok(1), Ok(2), Ok(3)]\n * [...safeIter(throwingIter())] // [Ok(1), Err(error)]\n */\nexport function safeIter<T>(source: Iterable<T>): IterableIterator<Result<T, unknown>> {\n const iter = source[Symbol.iterator]();\n let done = false;\n return {\n [Symbol.iterator]() {\n return this;\n },\n next(): IteratorResult<Result<T, unknown>> {\n if (done) return
|
|
1
|
+
{"version":3,"sources":["../src/iter.ts"],"sourcesContent":["import { isSome, isErr, err as ERR } from './types.js';\nimport type { Option, Result, Ok } from './types.js';\n\nconst ITER_DONE: IteratorResult<never> = Object.freeze({ value: undefined as never, done: true as const });\n\n/**\n * Yields mapped values while the mapping function returns Some, stops at the first None.\n * @param source - The iterable to map over\n * @param fn - Mapping function returning Some(value) to continue or None to stop\n * @returns Generator of mapped values\n * @example\n * [...mapWhile([1, 2, 3, 4], n => n < 3 ? some(n * 10) : none)] // [10, 20]\n */\nexport function* mapWhile<T, U>(source: Iterable<T>, fn: (value: T) => Option<U>): Generator<U> {\n for (const item of source) {\n const mapped = fn(item);\n if (!isSome(mapped)) return;\n yield mapped as U;\n }\n}\n\n/**\n * Wraps an iterable so that each yielded value becomes Ok and any throw becomes a single Err.\n * Stops after the first error - the source's internal state is unknown after an exception.\n *\n * Uses a manual iterator instead of a generator to avoid coroutine suspend/resume overhead.\n *\n * Follows the for-of IteratorClose spec:\n * - iter.return() is never called on natural exhaustion or after a caught error\n * - iter.return() is only called on early consumer exit (break/return)\n * - Cleanup errors from iter.return() are suppressed\n *\n * @param source - The iterable to wrap\n * @returns Iterable iterator of Result values\n * @example\n * [...safeIter([1, 2, 3])] // [Ok(1), Ok(2), Ok(3)]\n * [...safeIter(throwingIter())] // [Ok(1), Err(error)]\n */\nexport function safeIter<T>(source: Iterable<T>): IterableIterator<Result<T, unknown>> {\n const iter = source[Symbol.iterator]();\n let done = false;\n return {\n [Symbol.iterator]() {\n return this;\n },\n next(): IteratorResult<Result<T, unknown>> {\n if (done) return ITER_DONE;\n try {\n const next = iter.next();\n if (next.done) {\n done = true;\n return next;\n }\n return { value: next.value as Ok<T>, done: false };\n } catch (e) {\n done = true;\n return { value: ERR(e), done: false };\n }\n },\n return(): IteratorResult<Result<T, unknown>> {\n if (!done) {\n done = true;\n try {\n iter.return?.();\n } catch {\n // suppressed\n }\n }\n return ITER_DONE;\n },\n };\n}\n\n// -- Result-oriented terminal operations --\n\n/**\n * Collects an iterable of Results into a single Result containing an array.\n * Short-circuits on the first Err.\n * @param source - Iterable of Result values\n * @returns Ok(values[]) if all Ok, or the first Err encountered\n * @example\n * tryCollect([ok(1), ok(2), ok(3)]) // Ok([1, 2, 3])\n * tryCollect([ok(1), err('x')]) // Err('x')\n */\nexport function tryCollect<T, E>(source: Iterable<Result<T, E>>): Result<T[], E> {\n const collected: T[] = [];\n for (const result of source) {\n if (isErr(result)) return result;\n collected.push(result as T);\n }\n return collected as Ok<T[]>;\n}\n\n/**\n * Folds an iterable with a fallible accumulator function.\n * Short-circuits on the first Err returned by fn.\n * @param source - The iterable to fold over\n * @param init - Initial accumulator value\n * @param fn - Folding function returning Ok(newAcc) or Err\n * @returns Ok(finalAcc) if all steps succeed, or the first Err\n * @example\n * tryFold([1, 2, 3], 0, (acc, n) => ok(acc + n)) // Ok(6)\n * tryFold([1, 2, 3], 0, (acc, n) => n === 2 ? err('stop') : ok(acc + n)) // Err('stop')\n */\nexport function tryFold<T, Acc, E>(source: Iterable<T>, init: Acc, fn: (acc: Acc, item: T) => Result<Acc, E>): Result<Acc, E> {\n let acc = init;\n for (const item of source) {\n const result = fn(acc, item);\n if (isErr(result)) return result;\n acc = result as Acc;\n }\n return acc as Ok<Acc>;\n}\n\n/**\n * Iterates over a source, calling a fallible function for each item.\n * Short-circuits on the first Err returned by fn.\n * @param source - The iterable to iterate over\n * @param fn - Function to call for each item, returning Ok(void) or Err\n * @returns Ok(void) if all calls succeed, or the first Err\n * @example\n * tryForEach([1, 2, 3], n => ok(console.log(n))) // Ok(void), logs 1, 2, 3\n * tryForEach([1, 2, 3], n => n === 2 ? err('stop') : ok(undefined)) // Err('stop')\n */\nexport function tryForEach<T, E>(source: Iterable<T>, fn: (item: T) => Result<void, E>): Result<void, E> {\n for (const item of source) {\n const result = fn(item);\n if (isErr(result)) return result;\n }\n return undefined as Ok<void>;\n}\n"],"names":["mapWhile","safeIter","tryCollect","tryFold","tryForEach","ITER_DONE","Object","freeze","value","undefined","done","source","fn","item","mapped","isSome","iter","Symbol","iterator","next","e","ERR","return","collected","result","isErr","push","init","acc"],"mappings":";;;;;;;;;;;QAaiBA;eAAAA;;QAyBDC;eAAAA;;QA8CAC;eAAAA;;QAoBAC;eAAAA;;QAoBAC;eAAAA;;;0BA5H0B;AAG1C,MAAMC,YAAmCC,OAAOC,MAAM,CAAC;IAAEC,OAAOC;IAAoBC,MAAM;AAAc;AAUjG,UAAUV,SAAeW,MAAmB,EAAEC,EAA2B;IAC9E,KAAK,MAAMC,QAAQF,OAAQ;QACzB,MAAMG,SAASF,GAAGC;QAClB,IAAI,CAACE,IAAAA,gBAAM,EAACD,SAAS;QACrB,MAAMA;IACR;AACF;AAmBO,SAASb,SAAYU,MAAmB;IAC7C,MAAMK,OAAOL,MAAM,CAACM,OAAOC,QAAQ,CAAC;IACpC,IAAIR,OAAO;IACX,OAAO;QACL,CAACO,OAAOC,QAAQ,CAAC;YACf,OAAO,IAAI;QACb;QACAC;YACE,IAAIT,MAAM,OAAOL;YACjB,IAAI;gBACF,MAAMc,OAAOH,KAAKG,IAAI;gBACtB,IAAIA,KAAKT,IAAI,EAAE;oBACbA,OAAO;oBACP,OAAOS;gBACT;gBACA,OAAO;oBAAEX,OAAOW,KAAKX,KAAK;oBAAWE,MAAM;gBAAM;YACnD,EAAE,OAAOU,GAAG;gBACVV,OAAO;gBACP,OAAO;oBAAEF,OAAOa,IAAAA,aAAG,EAACD;oBAAIV,MAAM;gBAAM;YACtC;QACF;QACAY;YACE,IAAI,CAACZ,MAAM;gBACTA,OAAO;gBACP,IAAI;oBACFM,KAAKM,MAAM;gBACb,EAAE,OAAM,CAER;YACF;YACA,OAAOjB;QACT;IACF;AACF;AAaO,SAASH,WAAiBS,MAA8B;IAC7D,MAAMY,YAAiB,EAAE;IACzB,KAAK,MAAMC,UAAUb,OAAQ;QAC3B,IAAIc,IAAAA,eAAK,EAACD,SAAS,OAAOA;QAC1BD,UAAUG,IAAI,CAACF;IACjB;IACA,OAAOD;AACT;AAaO,SAASpB,QAAmBQ,MAAmB,EAAEgB,IAAS,EAAEf,EAAyC;IAC1G,IAAIgB,MAAMD;IACV,KAAK,MAAMd,QAAQF,OAAQ;QACzB,MAAMa,SAASZ,GAAGgB,KAAKf;QACvB,IAAIY,IAAAA,eAAK,EAACD,SAAS,OAAOA;QAC1BI,MAAMJ;IACR;IACA,OAAOI;AACT;AAYO,SAASxB,WAAiBO,MAAmB,EAAEC,EAAgC;IACpF,KAAK,MAAMC,QAAQF,OAAQ;QACzB,MAAMa,SAASZ,GAAGC;QAClB,IAAIY,IAAAA,eAAK,EAACD,SAAS,OAAOA;IAC5B;IACA,OAAOf;AACT"}
|
package/build/iter.js
CHANGED
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
import { isSome, isErr, err as ERR } from "./types.js";
|
|
2
|
+
const ITER_DONE = Object.freeze({
|
|
3
|
+
value: undefined,
|
|
4
|
+
done: true
|
|
5
|
+
});
|
|
2
6
|
export function* mapWhile(source, fn) {
|
|
3
7
|
for (const item of source){
|
|
4
8
|
const mapped = fn(item);
|
|
@@ -14,10 +18,7 @@ export function safeIter(source) {
|
|
|
14
18
|
return this;
|
|
15
19
|
},
|
|
16
20
|
next () {
|
|
17
|
-
if (done) return
|
|
18
|
-
value: undefined,
|
|
19
|
-
done: true
|
|
20
|
-
};
|
|
21
|
+
if (done) return ITER_DONE;
|
|
21
22
|
try {
|
|
22
23
|
const next = iter.next();
|
|
23
24
|
if (next.done) {
|
|
@@ -43,10 +44,7 @@ export function safeIter(source) {
|
|
|
43
44
|
iter.return?.();
|
|
44
45
|
} catch {}
|
|
45
46
|
}
|
|
46
|
-
return
|
|
47
|
-
value: undefined,
|
|
48
|
-
done: true
|
|
49
|
-
};
|
|
47
|
+
return ITER_DONE;
|
|
50
48
|
}
|
|
51
49
|
};
|
|
52
50
|
}
|
package/build/iter.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/iter.ts"],"sourcesContent":["import { isSome, isErr, err as ERR } from './types.js';\nimport type { Option, Result, Ok } from './types.js';\n\n/**\n * Yields mapped values while the mapping function returns Some, stops at the first None.\n * @param source - The iterable to map over\n * @param fn - Mapping function returning Some(value) to continue or None to stop\n * @returns Generator of mapped values\n * @example\n * [...mapWhile([1, 2, 3, 4], n => n < 3 ? some(n * 10) : none)] // [10, 20]\n */\nexport function* mapWhile<T, U>(source: Iterable<T>, fn: (value: T) => Option<U>): Generator<U> {\n for (const item of source) {\n const mapped = fn(item);\n if (!isSome(mapped)) return;\n yield mapped as U;\n }\n}\n\n/**\n * Wraps an iterable so that each yielded value becomes Ok and any throw becomes a single Err.\n * Stops after the first error - the source's internal state is unknown after an exception.\n *\n * Uses a manual iterator instead of a generator to avoid coroutine suspend/resume overhead.\n *\n * Follows the for-of IteratorClose spec:\n * - iter.return() is never called on natural exhaustion or after a caught error\n * - iter.return() is only called on early consumer exit (break/return)\n * - Cleanup errors from iter.return() are suppressed\n *\n * @param source - The iterable to wrap\n * @returns Iterable iterator of Result values\n * @example\n * [...safeIter([1, 2, 3])] // [Ok(1), Ok(2), Ok(3)]\n * [...safeIter(throwingIter())] // [Ok(1), Err(error)]\n */\nexport function safeIter<T>(source: Iterable<T>): IterableIterator<Result<T, unknown>> {\n const iter = source[Symbol.iterator]();\n let done = false;\n return {\n [Symbol.iterator]() {\n return this;\n },\n next(): IteratorResult<Result<T, unknown>> {\n if (done) return
|
|
1
|
+
{"version":3,"sources":["../src/iter.ts"],"sourcesContent":["import { isSome, isErr, err as ERR } from './types.js';\nimport type { Option, Result, Ok } from './types.js';\n\nconst ITER_DONE: IteratorResult<never> = Object.freeze({ value: undefined as never, done: true as const });\n\n/**\n * Yields mapped values while the mapping function returns Some, stops at the first None.\n * @param source - The iterable to map over\n * @param fn - Mapping function returning Some(value) to continue or None to stop\n * @returns Generator of mapped values\n * @example\n * [...mapWhile([1, 2, 3, 4], n => n < 3 ? some(n * 10) : none)] // [10, 20]\n */\nexport function* mapWhile<T, U>(source: Iterable<T>, fn: (value: T) => Option<U>): Generator<U> {\n for (const item of source) {\n const mapped = fn(item);\n if (!isSome(mapped)) return;\n yield mapped as U;\n }\n}\n\n/**\n * Wraps an iterable so that each yielded value becomes Ok and any throw becomes a single Err.\n * Stops after the first error - the source's internal state is unknown after an exception.\n *\n * Uses a manual iterator instead of a generator to avoid coroutine suspend/resume overhead.\n *\n * Follows the for-of IteratorClose spec:\n * - iter.return() is never called on natural exhaustion or after a caught error\n * - iter.return() is only called on early consumer exit (break/return)\n * - Cleanup errors from iter.return() are suppressed\n *\n * @param source - The iterable to wrap\n * @returns Iterable iterator of Result values\n * @example\n * [...safeIter([1, 2, 3])] // [Ok(1), Ok(2), Ok(3)]\n * [...safeIter(throwingIter())] // [Ok(1), Err(error)]\n */\nexport function safeIter<T>(source: Iterable<T>): IterableIterator<Result<T, unknown>> {\n const iter = source[Symbol.iterator]();\n let done = false;\n return {\n [Symbol.iterator]() {\n return this;\n },\n next(): IteratorResult<Result<T, unknown>> {\n if (done) return ITER_DONE;\n try {\n const next = iter.next();\n if (next.done) {\n done = true;\n return next;\n }\n return { value: next.value as Ok<T>, done: false };\n } catch (e) {\n done = true;\n return { value: ERR(e), done: false };\n }\n },\n return(): IteratorResult<Result<T, unknown>> {\n if (!done) {\n done = true;\n try {\n iter.return?.();\n } catch {\n // suppressed\n }\n }\n return ITER_DONE;\n },\n };\n}\n\n// -- Result-oriented terminal operations --\n\n/**\n * Collects an iterable of Results into a single Result containing an array.\n * Short-circuits on the first Err.\n * @param source - Iterable of Result values\n * @returns Ok(values[]) if all Ok, or the first Err encountered\n * @example\n * tryCollect([ok(1), ok(2), ok(3)]) // Ok([1, 2, 3])\n * tryCollect([ok(1), err('x')]) // Err('x')\n */\nexport function tryCollect<T, E>(source: Iterable<Result<T, E>>): Result<T[], E> {\n const collected: T[] = [];\n for (const result of source) {\n if (isErr(result)) return result;\n collected.push(result as T);\n }\n return collected as Ok<T[]>;\n}\n\n/**\n * Folds an iterable with a fallible accumulator function.\n * Short-circuits on the first Err returned by fn.\n * @param source - The iterable to fold over\n * @param init - Initial accumulator value\n * @param fn - Folding function returning Ok(newAcc) or Err\n * @returns Ok(finalAcc) if all steps succeed, or the first Err\n * @example\n * tryFold([1, 2, 3], 0, (acc, n) => ok(acc + n)) // Ok(6)\n * tryFold([1, 2, 3], 0, (acc, n) => n === 2 ? err('stop') : ok(acc + n)) // Err('stop')\n */\nexport function tryFold<T, Acc, E>(source: Iterable<T>, init: Acc, fn: (acc: Acc, item: T) => Result<Acc, E>): Result<Acc, E> {\n let acc = init;\n for (const item of source) {\n const result = fn(acc, item);\n if (isErr(result)) return result;\n acc = result as Acc;\n }\n return acc as Ok<Acc>;\n}\n\n/**\n * Iterates over a source, calling a fallible function for each item.\n * Short-circuits on the first Err returned by fn.\n * @param source - The iterable to iterate over\n * @param fn - Function to call for each item, returning Ok(void) or Err\n * @returns Ok(void) if all calls succeed, or the first Err\n * @example\n * tryForEach([1, 2, 3], n => ok(console.log(n))) // Ok(void), logs 1, 2, 3\n * tryForEach([1, 2, 3], n => n === 2 ? err('stop') : ok(undefined)) // Err('stop')\n */\nexport function tryForEach<T, E>(source: Iterable<T>, fn: (item: T) => Result<void, E>): Result<void, E> {\n for (const item of source) {\n const result = fn(item);\n if (isErr(result)) return result;\n }\n return undefined as Ok<void>;\n}\n"],"names":["isSome","isErr","err","ERR","ITER_DONE","Object","freeze","value","undefined","done","mapWhile","source","fn","item","mapped","safeIter","iter","Symbol","iterator","next","e","return","tryCollect","collected","result","push","tryFold","init","acc","tryForEach"],"mappings":"AAAA,SAASA,MAAM,EAAEC,KAAK,EAAEC,OAAOC,GAAG,QAAQ,aAAa;AAGvD,MAAMC,YAAmCC,OAAOC,MAAM,CAAC;IAAEC,OAAOC;IAAoBC,MAAM;AAAc;AAUxG,OAAO,UAAUC,SAAeC,MAAmB,EAAEC,EAA2B;IAC9E,KAAK,MAAMC,QAAQF,OAAQ;QACzB,MAAMG,SAASF,GAAGC;QAClB,IAAI,CAACb,OAAOc,SAAS;QACrB,MAAMA;IACR;AACF;AAmBA,OAAO,SAASC,SAAYJ,MAAmB;IAC7C,MAAMK,OAAOL,MAAM,CAACM,OAAOC,QAAQ,CAAC;IACpC,IAAIT,OAAO;IACX,OAAO;QACL,CAACQ,OAAOC,QAAQ,CAAC;YACf,OAAO,IAAI;QACb;QACAC;YACE,IAAIV,MAAM,OAAOL;YACjB,IAAI;gBACF,MAAMe,OAAOH,KAAKG,IAAI;gBACtB,IAAIA,KAAKV,IAAI,EAAE;oBACbA,OAAO;oBACP,OAAOU;gBACT;gBACA,OAAO;oBAAEZ,OAAOY,KAAKZ,KAAK;oBAAWE,MAAM;gBAAM;YACnD,EAAE,OAAOW,GAAG;gBACVX,OAAO;gBACP,OAAO;oBAAEF,OAAOJ,IAAIiB;oBAAIX,MAAM;gBAAM;YACtC;QACF;QACAY;YACE,IAAI,CAACZ,MAAM;gBACTA,OAAO;gBACP,IAAI;oBACFO,KAAKK,MAAM;gBACb,EAAE,OAAM,CAER;YACF;YACA,OAAOjB;QACT;IACF;AACF;AAaA,OAAO,SAASkB,WAAiBX,MAA8B;IAC7D,MAAMY,YAAiB,EAAE;IACzB,KAAK,MAAMC,UAAUb,OAAQ;QAC3B,IAAIV,MAAMuB,SAAS,OAAOA;QAC1BD,UAAUE,IAAI,CAACD;IACjB;IACA,OAAOD;AACT;AAaA,OAAO,SAASG,QAAmBf,MAAmB,EAAEgB,IAAS,EAAEf,EAAyC;IAC1G,IAAIgB,MAAMD;IACV,KAAK,MAAMd,QAAQF,OAAQ;QACzB,MAAMa,SAASZ,GAAGgB,KAAKf;QACvB,IAAIZ,MAAMuB,SAAS,OAAOA;QAC1BI,MAAMJ;IACR;IACA,OAAOI;AACT;AAYA,OAAO,SAASC,WAAiBlB,MAAmB,EAAEC,EAAgC;IACpF,KAAK,MAAMC,QAAQF,OAAQ;QACzB,MAAMa,SAASZ,GAAGC;QAClB,IAAIZ,MAAMuB,SAAS,OAAOA;IAC5B;IACA,OAAOhB;AACT"}
|
package/build/option.cjs
CHANGED
|
@@ -96,6 +96,9 @@ _export(exports, {
|
|
|
96
96
|
get tap () {
|
|
97
97
|
return tap;
|
|
98
98
|
},
|
|
99
|
+
get tapNone () {
|
|
100
|
+
return tapNone;
|
|
101
|
+
},
|
|
99
102
|
get toArray () {
|
|
100
103
|
return toArray;
|
|
101
104
|
},
|
|
@@ -128,6 +131,10 @@ _export(exports, {
|
|
|
128
131
|
}
|
|
129
132
|
});
|
|
130
133
|
const _typescjs = require("./types.cjs");
|
|
134
|
+
const NONE_PAIR = Object.freeze([
|
|
135
|
+
_typescjs.NONE,
|
|
136
|
+
_typescjs.NONE
|
|
137
|
+
]);
|
|
131
138
|
function fromNullable(value) {
|
|
132
139
|
return (0, _typescjs.optionOf)(value);
|
|
133
140
|
}
|
|
@@ -181,6 +188,12 @@ function tap(opt, fn) {
|
|
|
181
188
|
}
|
|
182
189
|
return opt;
|
|
183
190
|
}
|
|
191
|
+
function tapNone(opt, fn) {
|
|
192
|
+
if ((0, _typescjs.isNone)(opt)) {
|
|
193
|
+
fn();
|
|
194
|
+
}
|
|
195
|
+
return opt;
|
|
196
|
+
}
|
|
184
197
|
function isNoneOr(opt, predicate) {
|
|
185
198
|
return (0, _typescjs.isNone)(opt) || predicate(opt);
|
|
186
199
|
}
|
|
@@ -227,10 +240,7 @@ function zip(opt, other) {
|
|
|
227
240
|
] : _typescjs.NONE;
|
|
228
241
|
}
|
|
229
242
|
function unzip(opt) {
|
|
230
|
-
if ((0, _typescjs.isNone)(opt)) return
|
|
231
|
-
_typescjs.NONE,
|
|
232
|
-
_typescjs.NONE
|
|
233
|
-
];
|
|
243
|
+
if ((0, _typescjs.isNone)(opt)) return NONE_PAIR;
|
|
234
244
|
const [a, b] = opt;
|
|
235
245
|
return [
|
|
236
246
|
(0, _typescjs.optionOf)(a),
|
package/build/option.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/option.ts"],"sourcesContent":["import { NONE, EMPTY, isSome, isNone, optionOf as of, err, isOk, isErr } from './types.js';\nimport type { Some, None, Option, NoneValueType, ValueType, Result, Ok, Widen } from './types.js';\n\nexport type { Some, None, Option };\nexport { isSome, isNone, of };\n\n/**\n * Creates an Option from a nullable value with widened types.\n * @param value - The value to wrap\n * @returns Some(value) if non-null, None otherwise\n * @example\n * fromNullable(42) // Some(42) with type Option<number>\n * fromNullable(null) // None\n */\nexport function fromNullable(value: null): None;\nexport function fromNullable(value: undefined): None;\nexport function fromNullable<T>(value: T | NoneValueType): Option<Widen<T>>;\nexport function fromNullable<T>(value: T | NoneValueType): Option<Widen<T>> {\n return of(value) as Option<Widen<T>>;\n}\n\n/**\n * Creates an Option from a Promise. Resolves to Some if successful, None on rejection.\n * @param promise - The promise to convert\n * @param onRejected - Optional handler for rejected promises\n * @returns Promise resolving to Some(value) or None\n * @example\n * await fromPromise(Promise.resolve(42)) // Some(42)\n * await fromPromise(Promise.reject('error')) // None\n */\nexport async function fromPromise<T>(promise: Promise<T | NoneValueType>, onRejected?: (error: unknown) => T | NoneValueType): Promise<Option<T>> {\n try {\n const value = await promise;\n return of(value as T);\n } catch (error) {\n if (!onRejected) {\n return NONE;\n }\n return of(onRejected(error));\n }\n}\n\n/**\n * Unwraps an Option or returns a computed value if None.\n * @param opt - The Option to unwrap\n * @param onNone - Function called if opt is None\n * @returns The value if Some, or the result of onNone()\n * @example\n * unwrapOrReturn(some(42), () => 0) // 42\n * unwrapOrReturn(none, () => 0) // 0\n */\nexport function unwrapOrReturn<T, R>(opt: Option<T>, onNone: () => R): Widen<T> | R {\n return isSome(opt) ? (opt as Widen<T>) : onNone();\n}\n\n/**\n * Asserts that an Option is Some, throwing if None.\n * @param opt - The Option to assert\n * @param message - Custom error message\n * @throws Error if opt is None\n * @example\n * assertSome(some(42)) // passes\n * assertSome(none) // throws Error\n */\nexport function assertSome<T>(opt: Option<T>, message?: string): asserts opt is Some<ValueType<T>> {\n if (isNone(opt)) {\n throw new Error(message ?? 'Expected Option to contain a value');\n }\n}\n\n/**\n * Compile-time type assertion helper to satisfy Option type constraints.\n *\n * WARNING: This function performs NO runtime validation. It is a no-op at\n * runtime to preserve zero-allocation semantics. Use assertSome() if you\n * need runtime validation that a value is Some.\n *\n * @param _ - The value to assert as Option (not validated at runtime)\n * @example\n * const value: number | null = getValue();\n * satisfiesOption(value); // Compiles, but no runtime check\n * // value is now typed as Option<number>\n */\nexport function satisfiesOption<T>(_: Option<T> | T): asserts _ is Option<T> {\n // Compile-time only - no runtime validation to preserve zero-allocation semantics.\n}\n\n/**\n * Maps and filters an iterable, collecting only Some values.\n * @param values - The iterable to process\n * @param fn - Function that returns Option for each value\n * @returns Array of unwrapped Some values\n * @example\n * filterMap([1, 2, 3], n => n > 1 ? some(n * 2) : none) // [4, 6]\n */\nexport function filterMap<T, U>(values: Iterable<T>, fn: (value: T) => Option<U>): U[] {\n const collected: U[] = [];\n for (const value of values) {\n const mapped = fn(value);\n if (isSome(mapped)) collected.push(mapped);\n }\n return collected;\n}\n\n/**\n * Finds the first element that maps to Some, returning that value.\n * @param values - Iterable to search\n * @param fn - Function that returns Some for matches\n * @returns The first Some value, or None if no match\n * @example\n * findMap([1, 2, 3], n => n > 1 ? some(n * 2) : none) // Some(4)\n * findMap([1], n => n > 5 ? some(n) : none) // None\n */\nexport function findMap<T, U>(values: Iterable<T>, fn: (value: T) => Option<U>): Option<U> {\n for (const value of values) {\n const mapped = fn(value);\n if (isSome(mapped)) return mapped;\n }\n return NONE;\n}\n\n/**\n * Transforms the value inside a Some, or returns None.\n * @param opt - The Option to map\n * @param fn - Transform function\n * @returns Some(fn(value)) if Some, None otherwise\n * @example\n * map(some(2), x => x * 2) // Some(4)\n * map(none, x => x * 2) // None\n */\nexport function map<T, U>(opt: None, fn: (value: T) => U): None;\nexport function map<T, U>(opt: Option<T>, fn: (value: T) => U | NoneValueType): Option<U>;\nexport function map<T, U>(opt: Option<T>, fn: (value: T) => U | NoneValueType): Option<U> {\n if (isNone(opt)) return NONE;\n const result = fn(opt);\n return result === null || result === undefined ? NONE : (result as Some<ValueType<U>>);\n}\n\n/**\n * Chains Option-returning functions. Returns None if the input is None.\n * @param opt - The Option to chain\n * @param fn - Function returning an Option\n * @returns The result of fn(value) if Some, None otherwise\n * @example\n * flatMap(some(2), x => some(x * 2)) // Some(4)\n * flatMap(some(2), x => none) // None\n * flatMap(none, x => some(x * 2)) // None\n */\nexport function flatMap<T, U>(opt: None, fn: (value: T) => Option<U>): None;\nexport function flatMap<T, U>(opt: Option<T>, fn: (value: T) => Option<U>): Option<U>;\nexport function flatMap<T, U>(opt: Option<T>, fn: (value: T) => Option<U>): Option<U> {\n return isNone(opt) ? NONE : fn(opt);\n}\n\n/**\n * Alias for flatMap. Chains Option-returning functions.\n * @param opt - The Option to chain\n * @param fn - Function returning an Option\n * @returns The result of fn(value) if Some, None otherwise\n */\nexport const andThen: typeof flatMap = flatMap;\n\n/**\n * Executes a side effect if Some, then returns the original Option.\n * @param opt - The Option to tap\n * @param fn - Side effect function\n * @returns The original Option unchanged\n * @example\n * tap(some(42), x => console.log(x)) // logs 42, returns Some(42)\n */\nexport function tap<T>(opt: None, fn: (value: T) => void): None;\nexport function tap<T>(opt: Some<T>, fn: (value: T) => void): Some<T>;\nexport function tap<T>(opt: Option<T>, fn: (value: T) => void): Option<T>;\nexport function tap<T>(opt: Option<T>, fn: (value: T) => void): Option<T> {\n if (isSome(opt)) {\n fn(opt);\n }\n return opt;\n}\n\n/**\n * Returns true if None, or if Some and predicate returns true.\n * @param opt - The Option to check\n * @param predicate - Test function\n * @returns true if None or predicate(value) is true\n * @example\n * isNoneOr(none, x => x > 2) // true\n * isNoneOr(some(4), x => x > 2) // true\n * isNoneOr(some(1), x => x > 2) // false\n */\nexport function isNoneOr<T>(opt: Option<T>, predicate: (value: T) => boolean): boolean {\n return isNone(opt) || predicate(opt);\n}\n\n/**\n * Returns Some if the value passes the predicate, None otherwise.\n * @param opt - The Option to filter\n * @param predicate - Test function\n * @returns Some if predicate returns true, None otherwise\n * @example\n * filter(some(4), x => x > 2) // Some(4)\n * filter(some(1), x => x > 2) // None\n */\nexport function filter<T>(opt: None, predicate: (value: T) => boolean): None;\nexport function filter<T>(opt: Option<T>, predicate: (value: T) => boolean): Option<T>;\nexport function filter<T>(opt: Option<T>, predicate: (value: T) => boolean): Option<T> {\n return isSome(opt) && predicate(opt) ? opt : NONE;\n}\n\n/**\n * Extracts the value from Some, throws if None.\n * @param opt - The Option to unwrap\n * @returns The contained value\n * @throws Error if opt is None\n * @example\n * unwrap(some(42)) // 42\n * unwrap(none) // throws Error\n */\nexport function unwrap<T>(opt: Option<T>): T {\n if (isNone(opt)) {\n throw new Error('Called unwrap on None');\n }\n return opt;\n}\n\n/**\n * Extracts the value from Some, or returns a default value.\n * @param opt - The Option to unwrap\n * @param defaultValue - Value to return if None\n * @returns The contained value or defaultValue\n * @example\n * unwrapOr(some(42), 0) // 42\n * unwrapOr(none, 0) // 0\n */\nexport function unwrapOr<T>(opt: Option<T>, defaultValue: T): T {\n return isSome(opt) ? opt : defaultValue;\n}\n\n/**\n * Extracts the value from Some, or computes a default.\n * @param opt - The Option to unwrap\n * @param fn - Function to compute default value\n * @returns The contained value or fn()\n * @example\n * unwrapOrElse(some(42), () => 0) // 42\n * unwrapOrElse(none, () => 0) // 0\n */\nexport function unwrapOrElse<T>(opt: Option<T>, fn: () => T): T {\n return isSome(opt) ? opt : fn();\n}\n\n/**\n * Extracts the value from Some, throws with custom message if None.\n * @param opt - The Option to unwrap\n * @param message - Error message if None\n * @returns The contained value\n * @throws Error with message if opt is None\n * @example\n * expect(some(42), 'missing value') // 42\n * expect(none, 'missing value') // throws Error('missing value')\n */\nexport function expect<T>(opt: Option<T>, message: string): T {\n if (isNone(opt)) {\n throw new Error(message);\n }\n return opt;\n}\n\n/**\n * Returns the first Some, or the second Option if the first is None.\n * @param opt - First Option\n * @param optb - Fallback Option\n * @returns opt if Some, optb otherwise\n * @example\n * or(some(1), some(2)) // Some(1)\n * or(none, some(2)) // Some(2)\n */\nexport function or<T>(opt: Some<T>, optb: Option<T>): Some<T>;\nexport function or<T>(opt: Option<T>, optb: Option<T>): Option<T>;\nexport function or<T>(opt: Option<T>, optb: Option<T>): Option<T> {\n return isSome(opt) ? opt : optb;\n}\n\n/**\n * Returns opt if Some, otherwise computes a fallback Option.\n * @param opt - First Option\n * @param fn - Function to compute fallback\n * @returns opt if Some, fn() otherwise\n * @example\n * orElse(some(1), () => some(2)) // Some(1)\n * orElse(none, () => some(2)) // Some(2)\n */\nexport function orElse<T>(opt: Some<T>, fn: () => Option<T>): Some<T>;\nexport function orElse<T>(opt: Option<T>, fn: () => Option<T>): Option<T>;\nexport function orElse<T>(opt: Option<T>, fn: () => Option<T>): Option<T> {\n return isSome(opt) ? opt : fn();\n}\n\n/**\n * Returns Some if exactly one of the Options is Some.\n * @param opt - First Option\n * @param optb - Second Option\n * @returns Some if exactly one is Some, None otherwise\n * @example\n * xor(some(1), none) // Some(1)\n * xor(none, some(2)) // Some(2)\n * xor(some(1), some(2)) // None\n * xor(none, none) // None\n */\nexport function xor<T>(opt: Option<T>, optb: Option<T>): Option<T> {\n const a = isSome(opt);\n const b = isSome(optb);\n if (a !== b) return a ? opt : optb;\n return NONE;\n}\n\n/**\n * Returns optb if opt is Some, None otherwise.\n * @param opt - First Option\n * @param optb - Second Option\n * @returns optb if opt is Some, None otherwise\n * @example\n * and(some(1), some(2)) // Some(2)\n * and(none, some(2)) // None\n */\nexport function and<U>(opt: None, optb: Option<U>): None;\nexport function and<T, U>(opt: Option<T>, optb: Option<U>): Option<U>;\nexport function and<T, U>(opt: Option<T>, optb: Option<U>): Option<U> {\n return isSome(opt) ? optb : NONE;\n}\n\n/**\n * Combines two Options into an Option of a tuple.\n * @param opt - First Option\n * @param other - Second Option\n * @returns Some([a, b]) if both are Some, None otherwise\n * @example\n * zip(some(1), some('a')) // Some([1, 'a'])\n * zip(some(1), none) // None\n */\nexport function zip<T, U>(opt: Option<T>, other: Option<U>): Option<[T, U]> {\n return isSome(opt) && isSome(other) ? ([opt, other] as Some<[T, U]>) : NONE;\n}\n\n/**\n * Splits an Option of a tuple into a tuple of Options.\n * @param opt - Option containing a tuple\n * @returns Tuple of Options\n * @example\n * unzip(some([1, 'a'])) // [Some(1), Some('a')]\n * unzip(none) // [None, None]\n */\nexport function unzip<T, U>(opt: Option<[T, U]>): [Option<T>, Option<U>] {\n if (isNone(opt)) return [NONE, NONE];\n const [a, b] = opt;\n return [of(a), of(b)];\n}\n\n/**\n * Maps the value and returns it, or returns a default.\n * @param opt - The Option to map\n * @param defaultValue - Value if None\n * @param fn - Transform function\n * @returns fn(value) if Some, defaultValue otherwise\n * @example\n * mapOr(some(2), 0, x => x * 2) // 4\n * mapOr(none, 0, x => x * 2) // 0\n */\nexport function mapOr<T, U>(opt: Option<T>, defaultValue: U, fn: (value: T) => U): U {\n return isSome(opt) ? fn(opt) : defaultValue;\n}\n\n/**\n * Maps the value and returns it, or computes a default.\n * @param opt - The Option to map\n * @param defaultFn - Function to compute default\n * @param fn - Transform function\n * @returns fn(value) if Some, defaultFn() otherwise\n * @example\n * mapOrElse(some(2), () => 0, x => x * 2) // 4\n * mapOrElse(none, () => 0, x => x * 2) // 0\n */\nexport function mapOrElse<T, U>(opt: Option<T>, defaultFn: () => U, fn: (value: T) => U): U {\n return isSome(opt) ? fn(opt) : defaultFn();\n}\n\n/**\n * Flattens a nested Option.\n * @param opt - Option containing an Option\n * @returns The inner Option\n * @example\n * flatten(some(some(42))) // Some(42)\n * flatten(some(none)) // None\n * flatten(none) // None\n */\nexport function flatten<T>(opt: Option<Option<T>>): Option<T> {\n return isNone(opt) ? NONE : (opt as Option<T>);\n}\n\n/**\n * Checks if the Option contains a specific value (using ===).\n * @param opt - The Option to check\n * @param value - The value to compare\n * @returns true if Some and value matches\n * @example\n * contains(some(42), 42) // true\n * contains(some(42), 0) // false\n * contains(none, 42) // false\n */\nexport function contains<T>(opt: Option<T>, value: T): boolean {\n return isSome(opt) && (opt === value || (opt !== opt && value !== value));\n}\n\n/**\n * Checks if Some and the value satisfies a predicate.\n * @param opt - The Option to check\n * @param predicate - Test function\n * @returns true if Some and predicate returns true\n * @example\n * isSomeAnd(some(4), x => x > 2) // true\n * isSomeAnd(some(1), x => x > 2) // false\n * isSomeAnd(none, x => x > 2) // false\n */\nexport function isSomeAnd<T>(opt: Option<T>, predicate: (value: T) => boolean): boolean {\n return isSome(opt) && predicate(opt);\n}\n\n/**\n * Converts an Option to an array.\n * @param opt - The Option to convert\n * @returns [value] if Some, [] if None\n * @example\n * toArray(some(42)) // [42]\n * toArray(none) // []\n */\nexport function toArray<T>(opt: Option<T>): readonly T[] {\n return isSome(opt) ? [opt] : (EMPTY as readonly T[]);\n}\n\n/**\n * Converts an Option to a nullable value.\n * @param opt - The Option to convert\n * @returns The value if Some, null if None\n * @example\n * toNullable(some(42)) // 42\n * toNullable(none) // null\n */\nexport function toNullable<T>(opt: Option<T>): T | null {\n return isSome(opt) ? opt : null;\n}\n\n/**\n * Converts an Option to an undefined-able value.\n * @param opt - The Option to convert\n * @returns The value if Some, undefined if None\n * @example\n * toUndefined(some(42)) // 42\n * toUndefined(none) // undefined\n */\nexport function toUndefined<T>(opt: Option<T>): T | undefined {\n return isSome(opt) ? opt : undefined;\n}\n\n/**\n * Pattern matches on an Option, handling both Some and None cases.\n * @param opt - The Option to match\n * @param onSome - Handler for Some case\n * @param onNone - Handler for None case\n * @returns Result of the matching handler\n * @example\n * match(some(42), x => x * 2, () => 0) // 84\n * match(none, x => x * 2, () => 0) // 0\n */\nexport function match<T, U>(opt: Option<T>, onSome: (value: T) => U, onNone: () => U): U {\n return isSome(opt) ? onSome(opt) : onNone();\n}\n\n/**\n * Converts an Option to a Result, using a provided error if None.\n * @param opt - The Option to convert\n * @param error - Error value if None\n * @returns Ok(value) if Some, Err(error) if None\n * @example\n * okOr(some(42), 'missing') // Ok(42)\n * okOr(none, 'missing') // Err('missing')\n */\nexport function okOr<T, E>(opt: Option<T>, error: E): Result<T, E> {\n return isSome(opt) ? (opt as unknown as Ok<T>) : err(error);\n}\n\n/**\n * Converts an Option to a Result, computing the error if None.\n * @param opt - The Option to convert\n * @param fn - Function to compute error\n * @returns Ok(value) if Some, Err(fn()) if None\n * @example\n * okOrElse(some(42), () => 'missing') // Ok(42)\n * okOrElse(none, () => 'missing') // Err('missing')\n */\nexport function okOrElse<T, E>(opt: Option<T>, fn: () => E): Result<T, E> {\n return isSome(opt) ? (opt as unknown as Ok<T>) : err(fn());\n}\n\n/**\n * Extracts the Ok value from a Result as an Option.\n * @param result - The Result to convert\n * @returns Some(value) if Ok, None if Err\n * @example\n * ofOk(ok(42)) // Some(42)\n * ofOk(err('failed')) // None\n */\nexport function ofOk<T, E>(result: Result<T, E>): Option<T> {\n if (!isOk(result) || !isSome(result)) {\n return NONE;\n }\n return result as Some<T>;\n}\n\n/**\n * Extracts the Err value from a Result as an Option.\n * @param result - The Result to convert\n * @returns Some(error) if Err, None if Ok\n * @example\n * ofErr(err('failed')) // Some('failed')\n * ofErr(ok(42)) // None\n */\nexport function ofErr<T, E>(result: Result<T, E>): Option<E> {\n if (!isErr(result)) {\n return NONE;\n }\n const error = (result as { error: E }).error;\n if (!isSome(error)) {\n return NONE;\n }\n return error as Some<E>;\n}\n"],"names":["and","andThen","assertSome","contains","expect","filter","filterMap","findMap","flatMap","flatten","fromNullable","fromPromise","isNone","isNoneOr","isSome","isSomeAnd","map","mapOr","mapOrElse","match","of","ofErr","ofOk","okOr","okOrElse","or","orElse","satisfiesOption","tap","toArray","toNullable","toUndefined","unwrap","unwrapOr","unwrapOrElse","unwrapOrReturn","unzip","xor","zip","value","promise","onRejected","error","NONE","opt","onNone","message","Error","_","values","fn","collected","mapped","push","result","undefined","predicate","defaultValue","optb","a","b","other","defaultFn","EMPTY","onSome","err","isOk","isErr"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../src/option.ts"],"sourcesContent":["import { NONE, EMPTY, isSome, isNone, optionOf as of, err, isOk, isErr } from './types.js';\nimport type { Some, None, Option, NoneValueType, ValueType, Result, Ok, Widen } from './types.js';\n\nexport type { Some, None, Option };\nexport { isSome, isNone, of };\n\nconst NONE_PAIR: readonly [None, None] = Object.freeze([NONE, NONE]);\n\n/**\n * Creates an Option from a nullable value with widened types.\n * @param value - The value to wrap\n * @returns Some(value) if non-null, None otherwise\n * @example\n * fromNullable(42) // Some(42) with type Option<number>\n * fromNullable(null) // None\n */\nexport function fromNullable(value: null): None;\nexport function fromNullable(value: undefined): None;\nexport function fromNullable<T>(value: T | NoneValueType): Option<Widen<T>>;\nexport function fromNullable<T>(value: T | NoneValueType): Option<Widen<T>> {\n return of(value) as Option<Widen<T>>;\n}\n\n/**\n * Creates an Option from a Promise. Resolves to Some if successful, None on rejection.\n * @param promise - The promise to convert\n * @param onRejected - Optional handler for rejected promises\n * @returns Promise resolving to Some(value) or None\n * @example\n * await fromPromise(Promise.resolve(42)) // Some(42)\n * await fromPromise(Promise.reject('error')) // None\n */\nexport async function fromPromise<T>(promise: Promise<T | NoneValueType>, onRejected?: (error: unknown) => T | NoneValueType): Promise<Option<T>> {\n try {\n const value = await promise;\n return of(value as T);\n } catch (error) {\n if (!onRejected) {\n return NONE;\n }\n return of(onRejected(error));\n }\n}\n\n/**\n * Unwraps an Option or returns a computed value if None.\n * @param opt - The Option to unwrap\n * @param onNone - Function called if opt is None\n * @returns The value if Some, or the result of onNone()\n * @example\n * unwrapOrReturn(some(42), () => 0) // 42\n * unwrapOrReturn(none, () => 0) // 0\n */\nexport function unwrapOrReturn<T, R>(opt: Option<T>, onNone: () => R): Widen<T> | R {\n return isSome(opt) ? (opt as Widen<T>) : onNone();\n}\n\n/**\n * Asserts that an Option is Some, throwing if None.\n * @param opt - The Option to assert\n * @param message - Custom error message\n * @throws Error if opt is None\n * @example\n * assertSome(some(42)) // passes\n * assertSome(none) // throws Error\n */\nexport function assertSome<T>(opt: Option<T>, message?: string): asserts opt is Some<ValueType<T>> {\n if (isNone(opt)) {\n throw new Error(message ?? 'Expected Option to contain a value');\n }\n}\n\n/**\n * Compile-time type assertion helper to satisfy Option type constraints.\n *\n * WARNING: This function performs NO runtime validation. It is a no-op at\n * runtime to preserve zero-allocation semantics. Use assertSome() if you\n * need runtime validation that a value is Some.\n *\n * @param _ - The value to assert as Option (not validated at runtime)\n * @example\n * const value: number | null = getValue();\n * satisfiesOption(value); // Compiles, but no runtime check\n * // value is now typed as Option<number>\n */\nexport function satisfiesOption<T>(_: Option<T> | T): asserts _ is Option<T> {\n // Compile-time only - no runtime validation to preserve zero-allocation semantics.\n}\n\n/**\n * Maps and filters an iterable, collecting only Some values.\n * @param values - The iterable to process\n * @param fn - Function that returns Option for each value\n * @returns Array of unwrapped Some values\n * @example\n * filterMap([1, 2, 3], n => n > 1 ? some(n * 2) : none) // [4, 6]\n */\nexport function filterMap<T, U>(values: Iterable<T>, fn: (value: T) => Option<U>): U[] {\n const collected: U[] = [];\n for (const value of values) {\n const mapped = fn(value);\n if (isSome(mapped)) collected.push(mapped);\n }\n return collected;\n}\n\n/**\n * Finds the first element that maps to Some, returning that value.\n * @param values - Iterable to search\n * @param fn - Function that returns Some for matches\n * @returns The first Some value, or None if no match\n * @example\n * findMap([1, 2, 3], n => n > 1 ? some(n * 2) : none) // Some(4)\n * findMap([1], n => n > 5 ? some(n) : none) // None\n */\nexport function findMap<T, U>(values: Iterable<T>, fn: (value: T) => Option<U>): Option<U> {\n for (const value of values) {\n const mapped = fn(value);\n if (isSome(mapped)) return mapped;\n }\n return NONE;\n}\n\n/**\n * Transforms the value inside a Some, or returns None.\n * @param opt - The Option to map\n * @param fn - Transform function\n * @returns Some(fn(value)) if Some, None otherwise\n * @example\n * map(some(2), x => x * 2) // Some(4)\n * map(none, x => x * 2) // None\n */\nexport function map<T, U>(opt: None, fn: (value: T) => U): None;\nexport function map<T, U>(opt: Option<T>, fn: (value: T) => U | NoneValueType): Option<U>;\nexport function map<T, U>(opt: Option<T>, fn: (value: T) => U | NoneValueType): Option<U> {\n if (isNone(opt)) return NONE;\n const result = fn(opt);\n return result === null || result === undefined ? NONE : (result as Some<ValueType<U>>);\n}\n\n/**\n * Chains Option-returning functions. Returns None if the input is None.\n * @param opt - The Option to chain\n * @param fn - Function returning an Option\n * @returns The result of fn(value) if Some, None otherwise\n * @example\n * flatMap(some(2), x => some(x * 2)) // Some(4)\n * flatMap(some(2), x => none) // None\n * flatMap(none, x => some(x * 2)) // None\n */\nexport function flatMap<T, U>(opt: None, fn: (value: T) => Option<U>): None;\nexport function flatMap<T, U>(opt: Option<T>, fn: (value: T) => Option<U>): Option<U>;\nexport function flatMap<T, U>(opt: Option<T>, fn: (value: T) => Option<U>): Option<U> {\n return isNone(opt) ? NONE : fn(opt);\n}\n\n/**\n * Alias for flatMap. Chains Option-returning functions.\n * @param opt - The Option to chain\n * @param fn - Function returning an Option\n * @returns The result of fn(value) if Some, None otherwise\n */\nexport const andThen: typeof flatMap = flatMap;\n\n/**\n * Executes a side effect if Some, then returns the original Option.\n * @param opt - The Option to tap\n * @param fn - Side effect function\n * @returns The original Option unchanged\n * @example\n * tap(some(42), x => console.log(x)) // logs 42, returns Some(42)\n */\nexport function tap<T>(opt: None, fn: (value: T) => void): None;\nexport function tap<T>(opt: Some<T>, fn: (value: T) => void): Some<T>;\nexport function tap<T>(opt: Option<T>, fn: (value: T) => void): Option<T>;\nexport function tap<T>(opt: Option<T>, fn: (value: T) => void): Option<T> {\n if (isSome(opt)) {\n fn(opt);\n }\n return opt;\n}\n\n/**\n * Executes a side effect if None, then returns the original Option.\n * @param opt - The Option to tap\n * @param fn - Side effect function\n * @returns The original Option unchanged\n * @example\n * tapNone(none, () => console.log('missing')) // logs 'missing', returns None\n */\nexport function tapNone<T>(opt: Some<T>, fn: () => void): Some<T>;\nexport function tapNone(opt: None, fn: () => void): None;\nexport function tapNone<T>(opt: Option<T>, fn: () => void): Option<T>;\nexport function tapNone<T>(opt: Option<T>, fn: () => void): Option<T> {\n if (isNone(opt)) {\n fn();\n }\n return opt;\n}\n\n/**\n * Returns true if None, or if Some and predicate returns true.\n * @param opt - The Option to check\n * @param predicate - Test function\n * @returns true if None or predicate(value) is true\n * @example\n * isNoneOr(none, x => x > 2) // true\n * isNoneOr(some(4), x => x > 2) // true\n * isNoneOr(some(1), x => x > 2) // false\n */\nexport function isNoneOr<T>(opt: Option<T>, predicate: (value: T) => boolean): boolean {\n return isNone(opt) || predicate(opt);\n}\n\n/**\n * Returns Some if the value passes the predicate, None otherwise.\n * @param opt - The Option to filter\n * @param predicate - Test function\n * @returns Some if predicate returns true, None otherwise\n * @example\n * filter(some(4), x => x > 2) // Some(4)\n * filter(some(1), x => x > 2) // None\n */\nexport function filter<T>(opt: None, predicate: (value: T) => boolean): None;\nexport function filter<T>(opt: Option<T>, predicate: (value: T) => boolean): Option<T>;\nexport function filter<T>(opt: Option<T>, predicate: (value: T) => boolean): Option<T> {\n return isSome(opt) && predicate(opt) ? opt : NONE;\n}\n\n/**\n * Extracts the value from Some, throws if None.\n * @param opt - The Option to unwrap\n * @returns The contained value\n * @throws Error if opt is None\n * @example\n * unwrap(some(42)) // 42\n * unwrap(none) // throws Error\n */\nexport function unwrap<T>(opt: Option<T>): T {\n if (isNone(opt)) {\n throw new Error('Called unwrap on None');\n }\n return opt;\n}\n\n/**\n * Extracts the value from Some, or returns a default value.\n * @param opt - The Option to unwrap\n * @param defaultValue - Value to return if None\n * @returns The contained value or defaultValue\n * @example\n * unwrapOr(some(42), 0) // 42\n * unwrapOr(none, 0) // 0\n */\nexport function unwrapOr<T>(opt: Option<T>, defaultValue: T): T {\n return isSome(opt) ? opt : defaultValue;\n}\n\n/**\n * Extracts the value from Some, or computes a default.\n * @param opt - The Option to unwrap\n * @param fn - Function to compute default value\n * @returns The contained value or fn()\n * @example\n * unwrapOrElse(some(42), () => 0) // 42\n * unwrapOrElse(none, () => 0) // 0\n */\nexport function unwrapOrElse<T>(opt: Option<T>, fn: () => T): T {\n return isSome(opt) ? opt : fn();\n}\n\n/**\n * Extracts the value from Some, throws with custom message if None.\n * @param opt - The Option to unwrap\n * @param message - Error message if None\n * @returns The contained value\n * @throws Error with message if opt is None\n * @example\n * expect(some(42), 'missing value') // 42\n * expect(none, 'missing value') // throws Error('missing value')\n */\nexport function expect<T>(opt: Option<T>, message: string): T {\n if (isNone(opt)) {\n throw new Error(message);\n }\n return opt;\n}\n\n/**\n * Returns the first Some, or the second Option if the first is None.\n * @param opt - First Option\n * @param optb - Fallback Option\n * @returns opt if Some, optb otherwise\n * @example\n * or(some(1), some(2)) // Some(1)\n * or(none, some(2)) // Some(2)\n */\nexport function or<T>(opt: Some<T>, optb: Option<T>): Some<T>;\nexport function or<T>(opt: Option<T>, optb: Option<T>): Option<T>;\nexport function or<T>(opt: Option<T>, optb: Option<T>): Option<T> {\n return isSome(opt) ? opt : optb;\n}\n\n/**\n * Returns opt if Some, otherwise computes a fallback Option.\n * @param opt - First Option\n * @param fn - Function to compute fallback\n * @returns opt if Some, fn() otherwise\n * @example\n * orElse(some(1), () => some(2)) // Some(1)\n * orElse(none, () => some(2)) // Some(2)\n */\nexport function orElse<T>(opt: Some<T>, fn: () => Option<T>): Some<T>;\nexport function orElse<T>(opt: Option<T>, fn: () => Option<T>): Option<T>;\nexport function orElse<T>(opt: Option<T>, fn: () => Option<T>): Option<T> {\n return isSome(opt) ? opt : fn();\n}\n\n/**\n * Returns Some if exactly one of the Options is Some.\n * @param opt - First Option\n * @param optb - Second Option\n * @returns Some if exactly one is Some, None otherwise\n * @example\n * xor(some(1), none) // Some(1)\n * xor(none, some(2)) // Some(2)\n * xor(some(1), some(2)) // None\n * xor(none, none) // None\n */\nexport function xor<T>(opt: Option<T>, optb: Option<T>): Option<T> {\n const a = isSome(opt);\n const b = isSome(optb);\n if (a !== b) return a ? opt : optb;\n return NONE;\n}\n\n/**\n * Returns optb if opt is Some, None otherwise.\n * @param opt - First Option\n * @param optb - Second Option\n * @returns optb if opt is Some, None otherwise\n * @example\n * and(some(1), some(2)) // Some(2)\n * and(none, some(2)) // None\n */\nexport function and<U>(opt: None, optb: Option<U>): None;\nexport function and<T, U>(opt: Option<T>, optb: Option<U>): Option<U>;\nexport function and<T, U>(opt: Option<T>, optb: Option<U>): Option<U> {\n return isSome(opt) ? optb : NONE;\n}\n\n/**\n * Combines two Options into an Option of a tuple.\n * @param opt - First Option\n * @param other - Second Option\n * @returns Some([a, b]) if both are Some, None otherwise\n * @example\n * zip(some(1), some('a')) // Some([1, 'a'])\n * zip(some(1), none) // None\n */\nexport function zip<T, U>(opt: Option<T>, other: Option<U>): Option<[T, U]> {\n return isSome(opt) && isSome(other) ? ([opt, other] as Some<[T, U]>) : NONE;\n}\n\n/**\n * Splits an Option of a tuple into a tuple of Options.\n * @param opt - Option containing a tuple\n * @returns Tuple of Options\n * @example\n * unzip(some([1, 'a'])) // [Some(1), Some('a')]\n * unzip(none) // [None, None]\n */\nexport function unzip<T, U>(opt: Option<[T, U]>): [Option<T>, Option<U>] {\n if (isNone(opt)) return NONE_PAIR as [Option<T>, Option<U>];\n const [a, b] = opt;\n return [of(a), of(b)];\n}\n\n/**\n * Maps the value and returns it, or returns a default.\n * @param opt - The Option to map\n * @param defaultValue - Value if None\n * @param fn - Transform function\n * @returns fn(value) if Some, defaultValue otherwise\n * @example\n * mapOr(some(2), 0, x => x * 2) // 4\n * mapOr(none, 0, x => x * 2) // 0\n */\nexport function mapOr<T, U>(opt: Option<T>, defaultValue: U, fn: (value: T) => U): U {\n return isSome(opt) ? fn(opt) : defaultValue;\n}\n\n/**\n * Maps the value and returns it, or computes a default.\n * @param opt - The Option to map\n * @param defaultFn - Function to compute default\n * @param fn - Transform function\n * @returns fn(value) if Some, defaultFn() otherwise\n * @example\n * mapOrElse(some(2), () => 0, x => x * 2) // 4\n * mapOrElse(none, () => 0, x => x * 2) // 0\n */\nexport function mapOrElse<T, U>(opt: Option<T>, defaultFn: () => U, fn: (value: T) => U): U {\n return isSome(opt) ? fn(opt) : defaultFn();\n}\n\n/**\n * Flattens a nested Option.\n * @param opt - Option containing an Option\n * @returns The inner Option\n * @example\n * flatten(some(some(42))) // Some(42)\n * flatten(some(none)) // None\n * flatten(none) // None\n */\nexport function flatten<T>(opt: Option<Option<T>>): Option<T> {\n return isNone(opt) ? NONE : (opt as Option<T>);\n}\n\n/**\n * Checks if the Option contains a specific value (using ===).\n * @param opt - The Option to check\n * @param value - The value to compare\n * @returns true if Some and value matches\n * @example\n * contains(some(42), 42) // true\n * contains(some(42), 0) // false\n * contains(none, 42) // false\n */\nexport function contains<T>(opt: Option<T>, value: T): boolean {\n return isSome(opt) && (opt === value || (opt !== opt && value !== value));\n}\n\n/**\n * Checks if Some and the value satisfies a predicate.\n * @param opt - The Option to check\n * @param predicate - Test function\n * @returns true if Some and predicate returns true\n * @example\n * isSomeAnd(some(4), x => x > 2) // true\n * isSomeAnd(some(1), x => x > 2) // false\n * isSomeAnd(none, x => x > 2) // false\n */\nexport function isSomeAnd<T>(opt: Option<T>, predicate: (value: T) => boolean): boolean {\n return isSome(opt) && predicate(opt);\n}\n\n/**\n * Converts an Option to an array.\n * @param opt - The Option to convert\n * @returns [value] if Some, [] if None\n * @example\n * toArray(some(42)) // [42]\n * toArray(none) // []\n */\nexport function toArray<T>(opt: Option<T>): readonly T[] {\n return isSome(opt) ? [opt] : (EMPTY as readonly T[]);\n}\n\n/**\n * Converts an Option to a nullable value.\n * @param opt - The Option to convert\n * @returns The value if Some, null if None\n * @example\n * toNullable(some(42)) // 42\n * toNullable(none) // null\n */\nexport function toNullable<T>(opt: Option<T>): T | null {\n return isSome(opt) ? opt : null;\n}\n\n/**\n * Converts an Option to an undefined-able value.\n * @param opt - The Option to convert\n * @returns The value if Some, undefined if None\n * @example\n * toUndefined(some(42)) // 42\n * toUndefined(none) // undefined\n */\nexport function toUndefined<T>(opt: Option<T>): T | undefined {\n return isSome(opt) ? opt : undefined;\n}\n\n/**\n * Pattern matches on an Option, handling both Some and None cases.\n * @param opt - The Option to match\n * @param onSome - Handler for Some case\n * @param onNone - Handler for None case\n * @returns Result of the matching handler\n * @example\n * match(some(42), x => x * 2, () => 0) // 84\n * match(none, x => x * 2, () => 0) // 0\n */\nexport function match<T, U>(opt: Option<T>, onSome: (value: T) => U, onNone: () => U): U {\n return isSome(opt) ? onSome(opt) : onNone();\n}\n\n/**\n * Converts an Option to a Result, using a provided error if None.\n * @param opt - The Option to convert\n * @param error - Error value if None\n * @returns Ok(value) if Some, Err(error) if None\n * @example\n * okOr(some(42), 'missing') // Ok(42)\n * okOr(none, 'missing') // Err('missing')\n */\nexport function okOr<T, E>(opt: Option<T>, error: E): Result<T, E> {\n return isSome(opt) ? (opt as unknown as Ok<T>) : err(error);\n}\n\n/**\n * Converts an Option to a Result, computing the error if None.\n * @param opt - The Option to convert\n * @param fn - Function to compute error\n * @returns Ok(value) if Some, Err(fn()) if None\n * @example\n * okOrElse(some(42), () => 'missing') // Ok(42)\n * okOrElse(none, () => 'missing') // Err('missing')\n */\nexport function okOrElse<T, E>(opt: Option<T>, fn: () => E): Result<T, E> {\n return isSome(opt) ? (opt as unknown as Ok<T>) : err(fn());\n}\n\n/**\n * Extracts the Ok value from a Result as an Option.\n * @param result - The Result to convert\n * @returns Some(value) if Ok, None if Err\n * @example\n * ofOk(ok(42)) // Some(42)\n * ofOk(err('failed')) // None\n */\nexport function ofOk<T, E>(result: Result<T, E>): Option<T> {\n if (!isOk(result) || !isSome(result)) {\n return NONE;\n }\n return result as Some<T>;\n}\n\n/**\n * Extracts the Err value from a Result as an Option.\n * @param result - The Result to convert\n * @returns Some(error) if Err, None if Ok\n * @example\n * ofErr(err('failed')) // Some('failed')\n * ofErr(ok(42)) // None\n */\nexport function ofErr<T, E>(result: Result<T, E>): Option<E> {\n if (!isErr(result)) {\n return NONE;\n }\n const error = (result as { error: E }).error;\n if (!isSome(error)) {\n return NONE;\n }\n return error as Some<E>;\n}\n"],"names":["and","andThen","assertSome","contains","expect","filter","filterMap","findMap","flatMap","flatten","fromNullable","fromPromise","isNone","isNoneOr","isSome","isSomeAnd","map","mapOr","mapOrElse","match","of","ofErr","ofOk","okOr","okOrElse","or","orElse","satisfiesOption","tap","tapNone","toArray","toNullable","toUndefined","unwrap","unwrapOr","unwrapOrElse","unwrapOrReturn","unzip","xor","zip","NONE_PAIR","Object","freeze","NONE","value","promise","onRejected","error","opt","onNone","message","Error","_","values","fn","collected","mapped","push","result","undefined","predicate","defaultValue","optb","a","b","other","defaultFn","EMPTY","onSome","err","isOk","isErr"],"mappings":"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"}
|
package/build/option.d.ts
CHANGED
|
@@ -117,6 +117,17 @@ export declare const andThen: typeof flatMap;
|
|
|
117
117
|
export declare function tap<T>(opt: None, fn: (value: T) => void): None;
|
|
118
118
|
export declare function tap<T>(opt: Some<T>, fn: (value: T) => void): Some<T>;
|
|
119
119
|
export declare function tap<T>(opt: Option<T>, fn: (value: T) => void): Option<T>;
|
|
120
|
+
/**
|
|
121
|
+
* Executes a side effect if None, then returns the original Option.
|
|
122
|
+
* @param opt - The Option to tap
|
|
123
|
+
* @param fn - Side effect function
|
|
124
|
+
* @returns The original Option unchanged
|
|
125
|
+
* @example
|
|
126
|
+
* tapNone(none, () => console.log('missing')) // logs 'missing', returns None
|
|
127
|
+
*/
|
|
128
|
+
export declare function tapNone<T>(opt: Some<T>, fn: () => void): Some<T>;
|
|
129
|
+
export declare function tapNone(opt: None, fn: () => void): None;
|
|
130
|
+
export declare function tapNone<T>(opt: Option<T>, fn: () => void): Option<T>;
|
|
120
131
|
/**
|
|
121
132
|
* Returns true if None, or if Some and predicate returns true.
|
|
122
133
|
* @param opt - The Option to check
|
package/build/option.js
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import { NONE, EMPTY, isSome, isNone, optionOf as of, err, isOk, isErr } from "./types.js";
|
|
2
2
|
export { isSome, isNone, of };
|
|
3
|
+
const NONE_PAIR = Object.freeze([
|
|
4
|
+
NONE,
|
|
5
|
+
NONE
|
|
6
|
+
]);
|
|
3
7
|
export function fromNullable(value) {
|
|
4
8
|
return of(value);
|
|
5
9
|
}
|
|
@@ -53,6 +57,12 @@ export function tap(opt, fn) {
|
|
|
53
57
|
}
|
|
54
58
|
return opt;
|
|
55
59
|
}
|
|
60
|
+
export function tapNone(opt, fn) {
|
|
61
|
+
if (isNone(opt)) {
|
|
62
|
+
fn();
|
|
63
|
+
}
|
|
64
|
+
return opt;
|
|
65
|
+
}
|
|
56
66
|
export function isNoneOr(opt, predicate) {
|
|
57
67
|
return isNone(opt) || predicate(opt);
|
|
58
68
|
}
|
|
@@ -99,10 +109,7 @@ export function zip(opt, other) {
|
|
|
99
109
|
] : NONE;
|
|
100
110
|
}
|
|
101
111
|
export function unzip(opt) {
|
|
102
|
-
if (isNone(opt)) return
|
|
103
|
-
NONE,
|
|
104
|
-
NONE
|
|
105
|
-
];
|
|
112
|
+
if (isNone(opt)) return NONE_PAIR;
|
|
106
113
|
const [a, b] = opt;
|
|
107
114
|
return [
|
|
108
115
|
of(a),
|