@shirudo/result 1.1.1 → 1.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.
Files changed (66) hide show
  1. package/README.md +6 -2
  2. package/dist/collections.cjs +181 -9
  3. package/dist/collections.cjs.map +1 -0
  4. package/dist/collections.d.cts +101 -3
  5. package/dist/collections.d.cts.map +1 -0
  6. package/dist/collections.d.mts +101 -3
  7. package/dist/collections.d.mts.map +1 -0
  8. package/dist/collections.mjs +175 -3
  9. package/dist/collections.mjs.map +1 -0
  10. package/dist/errors-CVgC7NII.cjs +278 -0
  11. package/dist/errors-CVgC7NII.cjs.map +1 -0
  12. package/dist/errors-MuakEcnM.mjs +146 -0
  13. package/dist/errors-MuakEcnM.mjs.map +1 -0
  14. package/dist/errors.cjs +22 -130
  15. package/dist/errors.d.cts +9 -9
  16. package/dist/errors.d.cts.map +1 -1
  17. package/dist/errors.d.mts +9 -9
  18. package/dist/errors.d.mts.map +1 -1
  19. package/dist/errors.mjs +2 -109
  20. package/dist/index.cjs +99 -69
  21. package/dist/index.cjs.map +1 -1
  22. package/dist/index.d.cts +87 -74
  23. package/dist/index.d.cts.map +1 -1
  24. package/dist/index.d.mts +87 -74
  25. package/dist/index.d.mts.map +1 -1
  26. package/dist/index.mjs +64 -34
  27. package/dist/index.mjs.map +1 -1
  28. package/dist/operators.cjs +412 -31
  29. package/dist/operators.cjs.map +1 -0
  30. package/dist/operators.d.cts +211 -3
  31. package/dist/operators.d.cts.map +1 -0
  32. package/dist/operators.d.mts +211 -3
  33. package/dist/operators.d.mts.map +1 -0
  34. package/dist/operators.mjs +384 -3
  35. package/dist/operators.mjs.map +1 -0
  36. package/dist/{result-q9Na2bGa.mjs → result-DQCpkuOJ.mjs} +36 -17
  37. package/dist/result-DQCpkuOJ.mjs.map +1 -0
  38. package/dist/{result-BBOGxvSH.cjs → result-DoqQufvR.cjs} +36 -17
  39. package/dist/result-DoqQufvR.cjs.map +1 -0
  40. package/dist/{sequence-DDwePRLd.d.cts → sequence-CmugKPbu.d.cts} +105 -84
  41. package/dist/sequence-CmugKPbu.d.cts.map +1 -0
  42. package/dist/{sequence-DDwePRLd.d.mts → sequence-CmugKPbu.d.mts} +105 -84
  43. package/dist/sequence-CmugKPbu.d.mts.map +1 -0
  44. package/package.json +20 -12
  45. package/dist/errors.cjs.map +0 -1
  46. package/dist/errors.mjs.map +0 -1
  47. package/dist/flatten-B_XIkaOK.cjs +0 -208
  48. package/dist/flatten-B_XIkaOK.cjs.map +0 -1
  49. package/dist/flatten-C7D6Kttf.d.mts +0 -81
  50. package/dist/flatten-C7D6Kttf.d.mts.map +0 -1
  51. package/dist/flatten-ChTL5BfA.mjs +0 -167
  52. package/dist/flatten-ChTL5BfA.mjs.map +0 -1
  53. package/dist/flatten-D0K8UcQH.d.cts +0 -81
  54. package/dist/flatten-D0K8UcQH.d.cts.map +0 -1
  55. package/dist/result-BBOGxvSH.cjs.map +0 -1
  56. package/dist/result-q9Na2bGa.mjs.map +0 -1
  57. package/dist/sequence-DDwePRLd.d.cts.map +0 -1
  58. package/dist/sequence-DDwePRLd.d.mts.map +0 -1
  59. package/dist/swap-BnyMBdD_.cjs +0 -552
  60. package/dist/swap-BnyMBdD_.cjs.map +0 -1
  61. package/dist/swap-CFD2g1cB.mjs +0 -385
  62. package/dist/swap-CFD2g1cB.mjs.map +0 -1
  63. package/dist/swap-CrHQZIax.d.cts +0 -212
  64. package/dist/swap-CrHQZIax.d.cts.map +0 -1
  65. package/dist/swap-DT4LdRFV.d.mts +0 -212
  66. package/dist/swap-DT4LdRFV.d.mts.map +0 -1
package/README.md CHANGED
@@ -75,9 +75,9 @@ A `Result<User, UserError>` puts the failure into the signature. The compiler fo
75
75
  There are several Result implementations for TypeScript. This one is built around a few hard guarantees:
76
76
 
77
77
  - **Error types that cannot lie.** Declaring an explicit error type requires an error mapper: `fromPromise<User, ApiError>(promise)` without one is a compile error, so `E` never silently holds an unmapped `unknown`. And bugs inside the mapper itself are rethrown instead of being disguised as `Err` values.
78
- - **Exhaustive matching, checked at compile time.** `matchError().when(NotFoundError, ...).run()` only compiles once every error case is handled, and `matchTag` does the same for discriminated unions. Add a new error variant, and every unhandled match site turns red.
78
+ - **Exhaustive matching, checked at compile time.** `matchError().when(NotFoundError, ...).run()` only compiles once every error case is handled, and `matchTag` does the same for discriminated unions. Add a new error variant, and every unhandled match site turns red. For class-based matching the check is structural: give each error class a distinguishing member, for example a literal `readonly code`, because TypeScript cannot tell two classes of the same shape apart.
79
79
  - **Four interchangeable styles, one type.** Explicit `isOk()`/`isErr()` checks, `pipe`/`pipeAsync` operator chains, generator-based do-notation (`task`), and builder-based error matching all work on the same immutable, frozen `Result`. Use whichever style fits each call site.
80
- - **Safe at runtime boundaries.** `isResult()` validates an internal brand plus payload shape instead of accepting lookalike objects, and `toSerialized()`/`fromSerialized()` round-trip Results through JSON without ambiguity.
80
+ - **Safe at runtime boundaries.** `isResult()` validates an internal brand plus payload shape instead of accepting lookalike objects, and `toSerialized()` emits the discriminated `{ _tag, value | error }` shape, which `JSON.stringify` encodes exactly as it encodes the Result itself. `Ok(undefined)` survives the wire on its `_tag` alone, because `JSON.stringify` drops the `undefined` `value` key, and a validated payload rebuilds with plain `ok`/`err`.
81
81
  - **Zero dependencies, runs anywhere.** The package ships ESM and CJS builds with tree-shakeable subpath exports, and it runs on Node 20+ and in edge runtimes.
82
82
  - **Verified, not promised.** Every TypeScript snippet in this README and the docs is compile-checked in CI, the API is covered by 400+ runtime tests plus compile-time type tests, and the package exports are verified for ESM, CJS, and TypeScript consumers.
83
83
 
@@ -236,6 +236,10 @@ The full documentation lives in `docs/` and is built with VitePress.
236
236
  - [Version 1 Migration](docs/migration/v1.md)
237
237
  - [Design Decisions](docs/decisions/lazy-async-abstraction.md) ([Defensive State Checks](docs/decisions/defensive-state-checks.md))
238
238
 
239
+ ## Agent Skill
240
+
241
+ The repository ships an agent skill for AI coding assistants in [`skills/result-ts/`](skills/result-ts/). Copy the folder into your project's skill directory (for example `.claude/skills/` for Claude Code or `.agents/skills/` for other agents). It gives your assistant the API cheatsheet, refactoring patterns, and best practices for `@shirudo/result`; every snippet in it is compile-checked in this repository's CI.
242
+
239
243
  ## Development
240
244
 
241
245
  ```sh
@@ -1,13 +1,185 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
- const require_result = require('./result-BBOGxvSH.cjs');
3
- const require_flatten = require('./flatten-B_XIkaOK.cjs');
2
+ const require_result = require('./result-DoqQufvR.cjs');
3
+ const require_errors = require('./errors-CVgC7NII.cjs');
4
4
 
5
+ //#region src/core/sequenceRecord.ts
6
+ /**
7
+ * Like `sequence`, but for Records/Objects.
8
+ * Short-circuits on the first Err.
9
+ *
10
+ * A non-enumerable own property is an input only when it holds a `Result`, so a
11
+ * hidden helper field of another type is ignored. An array throws, because its
12
+ * indices would sequence into an object; use `sequence` for a list.
13
+ */
14
+ function sequenceRecord(record) {
15
+ if (Array.isArray(record)) throw new require_errors.InvalidResultStateError("sequenceRecord");
16
+ const out = {};
17
+ for (const key of Reflect.ownKeys(record)) {
18
+ const result = record[key];
19
+ if (!require_result.isResult(result)) {
20
+ if (!Object.getOwnPropertyDescriptor(record, key)?.enumerable) continue;
21
+ throw new require_errors.InvalidResultStateError("sequenceRecord");
22
+ }
23
+ if (result.isOk()) {
24
+ out[key] = result.value;
25
+ continue;
26
+ }
27
+ if (result.isErr()) return result;
28
+ throw new require_errors.InvalidResultStateError("sequenceRecord");
29
+ }
30
+ return require_result.ok(out);
31
+ }
32
+
33
+ //#endregion
34
+ //#region src/core/collectFirstOk.ts
35
+ /**
36
+ * Parse a set of `Result`s, short-circuits when an input value is `Ok`.
37
+ * If no `Ok` is found, returns an `Err` containing the collected error values.
38
+ * Useful for "try multiple approaches until one works" patterns.
39
+ */
40
+ function collectFirstOk(results) {
41
+ const errors = [];
42
+ for (const result of results) {
43
+ if (result.isOk()) return require_result.ok(result.value);
44
+ if (result.isErr()) {
45
+ errors.push(result.error);
46
+ continue;
47
+ }
48
+ throw new require_errors.InvalidResultStateError("collectFirstOk");
49
+ }
50
+ return require_result.err(errors);
51
+ }
52
+
53
+ //#endregion
54
+ //#region src/core/collectFirstOkAsync.ts
55
+ async function collectFirstOkAsync(inputs, errorMapper) {
56
+ const errors = [];
57
+ for (const input of inputs) {
58
+ const pendingResult = typeof input === "function" ? input() : input;
59
+ let result;
60
+ try {
61
+ result = await pendingResult;
62
+ } catch (error) {
63
+ errors.push(errorMapper ? errorMapper(error) : error);
64
+ continue;
65
+ }
66
+ if (require_result.isResult(result)) {
67
+ if (result.isOk()) return require_result.ok(result.value);
68
+ if (result.isErr()) {
69
+ errors.push(result.error);
70
+ continue;
71
+ }
72
+ }
73
+ throw new require_errors.InvalidResultStateError("collectFirstOkAsync");
74
+ }
75
+ return require_result.err(errors);
76
+ }
77
+
78
+ //#endregion
79
+ //#region src/core/collectFirstOkParallelAsync.ts
80
+ async function collectFirstOkParallelAsync(inputs, errorMapper) {
81
+ if (inputs.length === 0) return require_result.err([]);
82
+ const started = [];
83
+ try {
84
+ for (const input of inputs) started.push(typeof input === "function" ? Promise.resolve(input()) : input);
85
+ } catch (bug) {
86
+ for (const promise of started) promise.catch(() => {});
87
+ throw bug;
88
+ }
89
+ const firstOk = new Promise((resolve, reject) => {
90
+ for (const promise of started) promise.then((value) => {
91
+ if (!require_result.isResult(value)) reject(new require_errors.InvalidResultStateError("collectFirstOkParallelAsync"));
92
+ else if (value.isOk()) resolve(require_result.ok(value.value));
93
+ }, () => {});
94
+ });
95
+ const allErrors = Promise.allSettled(started).then((settled) => {
96
+ const errors = [];
97
+ for (const entry of settled) {
98
+ if (entry.status === "rejected") {
99
+ errors.push(errorMapper ? errorMapper(entry.reason) : entry.reason);
100
+ continue;
101
+ }
102
+ const result = entry.value;
103
+ if (require_result.isResult(result)) {
104
+ if (result.isErr()) {
105
+ errors.push(result.error);
106
+ continue;
107
+ }
108
+ if (result.isOk()) continue;
109
+ }
110
+ throw new require_errors.InvalidResultStateError("collectFirstOkParallelAsync");
111
+ }
112
+ return require_result.err(errors);
113
+ });
114
+ return Promise.race([firstOk, allErrors]);
115
+ }
116
+
117
+ //#endregion
118
+ //#region src/core/collectAllErrors.ts
119
+ /**
120
+ * Combines a list of Results.
121
+ * Return Ok(values) only if all are Ok, otherwise Err([errors]).
122
+ */
123
+ function collectAllErrors(results) {
124
+ const values = [];
125
+ const errors = [];
126
+ for (const result of results) {
127
+ if (result.isOk()) {
128
+ values.push(result.value);
129
+ continue;
130
+ }
131
+ if (result.isErr()) {
132
+ errors.push(result.error);
133
+ continue;
134
+ }
135
+ throw new require_errors.InvalidResultStateError("collectAllErrors");
136
+ }
137
+ return errors.length === 0 ? require_result.ok(values) : require_result.err(errors);
138
+ }
139
+
140
+ //#endregion
141
+ //#region src/core/partition.ts
142
+ /**
143
+ * Partitions Results into Ok values and Err errors.
144
+ */
145
+ function partition(results) {
146
+ const oks = [];
147
+ const errs = [];
148
+ for (const result of results) {
149
+ if (result.isOk()) {
150
+ oks.push(result.value);
151
+ continue;
152
+ }
153
+ if (result.isErr()) {
154
+ errs.push(result.error);
155
+ continue;
156
+ }
157
+ throw new require_errors.InvalidResultStateError("partition");
158
+ }
159
+ return [oks, errs];
160
+ }
161
+
162
+ //#endregion
163
+ //#region src/core/flatten.ts
164
+ /**
165
+ * Flattens a nested Result.
166
+ * Result<Result<T, E>, E> → Result<T, E>
167
+ * Corresponds to Rust `flatten`.
168
+ */
169
+ function flatten(result) {
170
+ if (result.isOk()) return result.value;
171
+ if (result.isErr()) return result;
172
+ throw new require_errors.InvalidResultStateError("flatten");
173
+ }
174
+
175
+ //#endregion
5
176
  exports.all = require_result.all;
6
- exports.collectAllErrors = require_flatten.collectAllErrors;
7
- exports.collectFirstOk = require_flatten.collectFirstOk;
8
- exports.collectFirstOkAsync = require_flatten.collectFirstOkAsync;
9
- exports.collectFirstOkParallelAsync = require_flatten.collectFirstOkParallelAsync;
10
- exports.flatten = require_flatten.flatten;
11
- exports.partition = require_flatten.partition;
177
+ exports.collectAllErrors = collectAllErrors;
178
+ exports.collectFirstOk = collectFirstOk;
179
+ exports.collectFirstOkAsync = collectFirstOkAsync;
180
+ exports.collectFirstOkParallelAsync = collectFirstOkParallelAsync;
181
+ exports.flatten = flatten;
182
+ exports.partition = partition;
12
183
  exports.sequence = require_result.sequence;
13
- exports.sequenceRecord = require_flatten.sequenceRecord;
184
+ exports.sequenceRecord = sequenceRecord;
185
+ //# sourceMappingURL=collections.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"collections.cjs","names":["InvalidResultStateError","isResult","ok","ok","InvalidResultStateError","err","isResult","ok","InvalidResultStateError","err","err","isResult","InvalidResultStateError","ok","InvalidResultStateError","ok","err","InvalidResultStateError","InvalidResultStateError"],"sources":["../src/core/sequenceRecord.ts","../src/core/collectFirstOk.ts","../src/core/collectFirstOkAsync.ts","../src/core/collectFirstOkParallelAsync.ts","../src/core/collectAllErrors.ts","../src/core/partition.ts","../src/core/flatten.ts"],"sourcesContent":["import type { Result } from './result';\nimport { ok } from './result';\nimport { InvalidResultStateError } from '../errors';\nimport { isResult } from './isResult';\n\ntype OkValueOf<R> = R extends Result<infer T, any> ? T : never;\ntype ErrValueOf<R> = R extends Result<any, infer E> ? E : never;\n\n/**\n * Like `sequence`, but for Records/Objects.\n * Short-circuits on the first Err.\n *\n * A non-enumerable own property is an input only when it holds a `Result`, so a\n * hidden helper field of another type is ignored. An array throws, because its\n * indices would sequence into an object; use `sequence` for a list.\n */\nexport function sequenceRecord<const R extends { readonly [K in keyof R]: Result<any, any> }>(\n record: R\n): Result<{ [K in keyof R]: OkValueOf<R[K]> }, ErrValueOf<R[keyof R]>> {\n type Out = { [K in keyof R]: OkValueOf<R[K]> };\n type E = ErrValueOf<R[keyof R]>;\n\n // An array reaches this point only from JavaScript, and it would sequence\n // into an object keyed by its indices: `length` is a non-enumerable\n // non-Result and the rule below would skip it. A list of Results belongs to\n // `sequence()`, so the mistake fails here instead of returning a wrong shape.\n if (Array.isArray(record)) throw new InvalidResultStateError('sequenceRecord');\n\n const out: Partial<Out> = {};\n\n // `Reflect.ownKeys` keeps the symbol keys, which the signature supports, and\n // it also visits the non-enumerable properties. `keyof R` sees those too, so\n // a hidden Result stays an input. A hidden value of another type is a helper\n // field that the caller attached, and it is skipped instead of rejected.\n for (const key of Reflect.ownKeys(record) as Array<keyof R>) {\n const result = record[key];\n\n if (!isResult(result)) {\n if (!Object.getOwnPropertyDescriptor(record, key)?.enumerable) continue;\n throw new InvalidResultStateError('sequenceRecord');\n }\n\n if (result.isOk()) {\n out[key] = result.value as Out[typeof key];\n continue;\n }\n if (result.isErr()) return result as unknown as Result<Out, E>;\n throw new InvalidResultStateError('sequenceRecord');\n }\n\n return ok<Out, E>(out as Out);\n}\n","import type { Result } from './result';\nimport { ok, err } from './result';\nimport { InvalidResultStateError } from '../errors';\n\ntype OkValueOf<R> = R extends Result<infer T, any> ? T : never;\ntype ErrValueOf<R> = R extends Result<any, infer E> ? E : never;\n\n/**\n * Parse a set of `Result`s, short-circuits when an input value is `Ok`.\n * If no `Ok` is found, returns an `Err` containing the collected error values.\n * Useful for \"try multiple approaches until one works\" patterns.\n */\nexport function collectFirstOk<const Results extends readonly Result<any, any>[]>(\n results: Results\n): Result<OkValueOf<Results[number]>, ErrValueOf<Results[number]>[]> {\n const errors: Array<ErrValueOf<Results[number]>> = [];\n\n for (const result of results) {\n if (result.isOk()) {\n return ok<OkValueOf<Results[number]>, ErrValueOf<Results[number]>[]>(\n result.value as OkValueOf<Results[number]>\n );\n }\n if (result.isErr()) {\n errors.push(result.error as ErrValueOf<Results[number]>);\n continue;\n }\n throw new InvalidResultStateError('collectFirstOk');\n }\n\n return err<ErrValueOf<Results[number]>[], OkValueOf<Results[number]>>(errors);\n}\n","import type { Result } from './result';\nimport { ok, err } from './result';\nimport type { Awaitable } from './pipeable';\nimport { isResult } from './isResult';\nimport { InvalidResultStateError } from '../errors';\n\ntype CollectFirstOkAsyncInput =\n | Promise<Result<any, any>>\n | (() => Awaitable<Result<any, any>>);\n\ntype ResolvedResult<I> = I extends () => infer R ? Awaited<R> : I extends Promise<infer R> ? R : never;\ntype OkValueOfInput<I> = ResolvedResult<I> extends Result<infer T, any> ? T : never;\ntype ErrValueOfInput<I> = ResolvedResult<I> extends Result<any, infer E> ? E : never;\n\n/**\n * Async version of collectFirstOk.\n *\n * - Takes either already started Promises or \"Thunks\" (`() => Awaitable<Result<...>>`).\n * A thunk that throws synchronously is a programmer error: the call rejects\n * with that exception.\n * - Processes inputs strictly sequentially (like `for ... of` + `await`).\n * - Returns the first `Ok` and collects all errors if no `Ok` is found.\n * - A fulfilled value that is not a `Result` is a programmer error: the call\n * rejects with `InvalidResultStateError`.\n * - A rejected input counts as a failed attempt. Without `errorMapper` the\n * collected errors are `unknown[]`, because a rejection reason can be\n * anything. `errorMapper` turns each rejection reason into a typed error;\n * `Err` values pass through untouched, and bugs inside the mapper are rethrown.\n */\nexport function collectFirstOkAsync<const Inputs extends readonly CollectFirstOkAsyncInput[]>(\n inputs: Inputs\n): Promise<Result<OkValueOfInput<Inputs[number]>, unknown[]>>;\nexport function collectFirstOkAsync<const Inputs extends readonly CollectFirstOkAsyncInput[], F>(\n inputs: Inputs,\n errorMapper: (error: unknown) => F\n): Promise<Result<OkValueOfInput<Inputs[number]>, Array<ErrValueOfInput<Inputs[number]> | F>>>;\nexport async function collectFirstOkAsync<const Inputs extends readonly CollectFirstOkAsyncInput[], F>(\n inputs: Inputs,\n errorMapper?: (error: unknown) => F\n): Promise<Result<OkValueOfInput<Inputs[number]>, Array<ErrValueOfInput<Inputs[number]> | F>>> {\n type OkValue = OkValueOfInput<Inputs[number]>;\n type ErrValue = ErrValueOfInput<Inputs[number]> | F;\n\n const errors: ErrValue[] = [];\n\n for (const input of inputs) {\n const pendingResult = typeof input === 'function' ? input() : input;\n let result: unknown;\n try {\n result = await pendingResult;\n } catch (error) {\n errors.push(errorMapper ? errorMapper(error) : (error as F));\n continue;\n }\n\n if (isResult(result)) {\n if (result.isOk()) {\n return ok<OkValue, ErrValue[]>(result.value as OkValue);\n }\n if (result.isErr()) {\n errors.push(result.error as ErrValue);\n continue;\n }\n }\n throw new InvalidResultStateError('collectFirstOkAsync');\n }\n\n return err<ErrValue[], OkValue>(errors);\n}\n","import type { Awaitable } from './pipeable';\nimport type { Result } from './result';\nimport { err, ok } from './result';\nimport { isResult } from './isResult';\nimport { InvalidResultStateError } from '../errors';\n\ntype CollectFirstOkAsyncInput = Promise<Result<any, any>> | (() => Awaitable<Result<any, any>>);\n\ntype ResolvedResult<I> = I extends () => infer R ? Awaited<R> : I extends Promise<infer R> ? R : never;\ntype OkValueOfInput<I> = ResolvedResult<I> extends Result<infer T, any> ? T : never;\ntype ErrValueOfInput<I> = ResolvedResult<I> extends Result<any, infer E> ? E : never;\n\n/**\n * Parallel version of `collectFirstOkAsync`.\n *\n * - Starts all inputs immediately (Promises or Thunks). A thunk that throws\n * synchronously is a programmer error: the call rejects with that exception,\n * as `collectFirstOkAsync` does.\n * - Returns the first `Ok` as soon as it is available.\n * - If no `Ok` is found, returns an `Err` with all error values (in input order).\n * - A fulfilled value that is not a `Result` is a programmer error: the call\n * rejects with `InvalidResultStateError`, unless an `Ok` already won the race.\n * - A rejected input counts as a failed attempt. Without `errorMapper` the\n * collected errors are `unknown[]`, because a rejection reason can be\n * anything. `errorMapper` turns each rejection reason into a typed error;\n * `Err` values pass through untouched, and bugs inside the mapper are rethrown.\n * - If multiple inputs provide an `Ok`, the one that completes first wins.\n * In case of simultaneous completion, the first observed result wins.\n * - If no `Ok` arrives and at least one input never settles, the Promise remains pending.\n */\nexport function collectFirstOkParallelAsync<const Inputs extends readonly CollectFirstOkAsyncInput[]>(\n inputs: Inputs\n): Promise<Result<OkValueOfInput<Inputs[number]>, unknown[]>>;\nexport function collectFirstOkParallelAsync<const Inputs extends readonly CollectFirstOkAsyncInput[], F>(\n inputs: Inputs,\n errorMapper: (error: unknown) => F\n): Promise<Result<OkValueOfInput<Inputs[number]>, Array<ErrValueOfInput<Inputs[number]> | F>>>;\nexport async function collectFirstOkParallelAsync<const Inputs extends readonly CollectFirstOkAsyncInput[], F>(\n inputs: Inputs,\n errorMapper?: (error: unknown) => F\n): Promise<Result<OkValueOfInput<Inputs[number]>, Array<ErrValueOfInput<Inputs[number]> | F>>> {\n type OkValue = OkValueOfInput<Inputs[number]>;\n type ErrValue = ErrValueOfInput<Inputs[number]> | F;\n\n if (inputs.length === 0) {\n return err<ErrValue[], OkValue>([]);\n }\n\n // Discarding the outcomes of the attempts that already started keeps an\n // abandoned rejection from surfacing as an unhandled rejection.\n const started: Promise<unknown>[] = [];\n try {\n for (const input of inputs) {\n started.push(typeof input === 'function' ? Promise.resolve(input()) : input);\n }\n } catch (bug) {\n for (const promise of started) promise.catch(() => {});\n throw bug;\n }\n\n const firstOk = new Promise<Result<OkValue, ErrValue[]>>((resolve, reject) => {\n for (const promise of started) {\n promise.then(\n (value) => {\n if (!isResult(value)) {\n reject(new InvalidResultStateError('collectFirstOkParallelAsync'));\n } else if (value.isOk()) {\n resolve(ok<OkValue, ErrValue[]>(value.value as OkValue));\n }\n },\n () => {\n // A rejection is a failed attempt; allSettled below collects it.\n }\n );\n }\n });\n\n const allErrors = Promise.allSettled(started).then((settled) => {\n const errors: ErrValue[] = [];\n for (const entry of settled) {\n if (entry.status === 'rejected') {\n errors.push(errorMapper ? errorMapper(entry.reason) : (entry.reason as F));\n continue;\n }\n const result = entry.value;\n if (isResult(result)) {\n if (result.isErr()) {\n errors.push(result.error as ErrValue);\n continue;\n }\n if (result.isOk()) continue;\n }\n throw new InvalidResultStateError('collectFirstOkParallelAsync');\n }\n return err<ErrValue[], OkValue>(errors);\n });\n\n return Promise.race([firstOk, allErrors]);\n}\n","import type { Result } from './result';\nimport { ok, err } from './result';\nimport { InvalidResultStateError } from '../errors';\n\ntype OkValueOf<R> = R extends Result<infer T, any> ? T : never;\ntype ErrValueOf<R> = R extends Result<any, infer E> ? E : never;\ntype CollectionValues<Results extends readonly Result<any, any>[]> = {\n -readonly [K in keyof Results]: OkValueOf<Results[K]>;\n};\n\n/**\n * Combines a list of Results.\n * Return Ok(values) only if all are Ok, otherwise Err([errors]).\n */\nexport function collectAllErrors<const Results extends readonly Result<any, any>[]>(\n results: Results\n): Result<CollectionValues<Results>, Array<ErrValueOf<Results[number]>>> {\n const values: Array<OkValueOf<Results[number]>> = [];\n const errors: Array<ErrValueOf<Results[number]>> = [];\n\n for (const result of results) {\n if (result.isOk()) {\n values.push(result.value as OkValueOf<Results[number]>);\n continue;\n }\n if (result.isErr()) {\n errors.push(result.error as ErrValueOf<Results[number]>);\n continue;\n }\n throw new InvalidResultStateError('collectAllErrors');\n }\n\n return errors.length === 0\n ? ok<CollectionValues<Results>, Array<ErrValueOf<Results[number]>>>(values as CollectionValues<Results>)\n : err<Array<ErrValueOf<Results[number]>>, CollectionValues<Results>>(errors);\n}\n","import type { Result } from './result';\nimport { InvalidResultStateError } from '../errors';\n\ntype OkValueOf<R> = R extends Result<infer T, any> ? T : never;\ntype ErrValueOf<R> = R extends Result<any, infer E> ? E : never;\n\n/**\n * Partitions Results into Ok values and Err errors.\n */\nexport function partition<const Results extends readonly Result<any, any>[]>(\n results: Results\n): [oks: Array<OkValueOf<Results[number]>>, errs: Array<ErrValueOf<Results[number]>>] {\n const oks: Array<OkValueOf<Results[number]>> = [];\n const errs: Array<ErrValueOf<Results[number]>> = [];\n\n for (const result of results) {\n if (result.isOk()) {\n oks.push(result.value as OkValueOf<Results[number]>);\n continue;\n }\n if (result.isErr()) {\n errs.push(result.error as ErrValueOf<Results[number]>);\n continue;\n }\n throw new InvalidResultStateError('partition');\n }\n\n return [oks, errs];\n}\n","import type { Result } from './result';\nimport { InvalidResultStateError } from '../errors';\n\n/**\n * Flattens a nested Result.\n * Result<Result<T, E>, E> → Result<T, E>\n * Corresponds to Rust `flatten`.\n */\nexport function flatten<T, E>(result: Result<Result<T, E>, E>): Result<T, E> {\n if (result.isOk()) {\n return result.value;\n }\n if (result.isErr()) return result as unknown as Result<T, E>;\n throw new InvalidResultStateError('flatten');\n}\n"],"mappings":"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"}
@@ -1,3 +1,101 @@
1
- import { n as sequence, t as all } from "./sequence-DDwePRLd.cjs";
2
- import { a as collectFirstOkAsync, i as collectFirstOkParallelAsync, n as partition, o as collectFirstOk, r as collectAllErrors, s as sequenceRecord, t as flatten } from "./flatten-D0K8UcQH.cjs";
3
- export { all, collectAllErrors, collectFirstOk, collectFirstOkAsync, collectFirstOkParallelAsync, flatten, partition, sequence, sequenceRecord };
1
+ import { E as Awaitable, n as sequence, s as Result, t as all } from "./sequence-CmugKPbu.cjs";
2
+ //#region src/core/sequenceRecord.d.ts
3
+ type OkValueOf$3<R> = R extends Result<infer T, any> ? T : never;
4
+ type ErrValueOf$3<R> = R extends Result<any, infer E> ? E : never;
5
+ /**
6
+ * Like `sequence`, but for Records/Objects.
7
+ * Short-circuits on the first Err.
8
+ *
9
+ * A non-enumerable own property is an input only when it holds a `Result`, so a
10
+ * hidden helper field of another type is ignored. An array throws, because its
11
+ * indices would sequence into an object; use `sequence` for a list.
12
+ */
13
+ declare function sequenceRecord<const R extends { readonly [K in keyof R]: Result<any, any>; }>(record: R): Result<{ [K in keyof R]: OkValueOf$3<R[K]>; }, ErrValueOf$3<R[keyof R]>>;
14
+ //#endregion
15
+ //#region src/core/collectFirstOk.d.ts
16
+ type OkValueOf$2<R> = R extends Result<infer T, any> ? T : never;
17
+ type ErrValueOf$2<R> = R extends Result<any, infer E> ? E : never;
18
+ /**
19
+ * Parse a set of `Result`s, short-circuits when an input value is `Ok`.
20
+ * If no `Ok` is found, returns an `Err` containing the collected error values.
21
+ * Useful for "try multiple approaches until one works" patterns.
22
+ */
23
+ declare function collectFirstOk<const Results extends readonly Result<any, any>[]>(results: Results): Result<OkValueOf$2<Results[number]>, ErrValueOf$2<Results[number]>[]>;
24
+ //#endregion
25
+ //#region src/core/collectFirstOkAsync.d.ts
26
+ type CollectFirstOkAsyncInput$1 = Promise<Result<any, any>> | (() => Awaitable<Result<any, any>>);
27
+ type ResolvedResult$1<I> = I extends (() => infer R) ? Awaited<R> : I extends Promise<infer R> ? R : never;
28
+ type OkValueOfInput$1<I> = ResolvedResult$1<I> extends Result<infer T, any> ? T : never;
29
+ type ErrValueOfInput$1<I> = ResolvedResult$1<I> extends Result<any, infer E> ? E : never;
30
+ /**
31
+ * Async version of collectFirstOk.
32
+ *
33
+ * - Takes either already started Promises or "Thunks" (`() => Awaitable<Result<...>>`).
34
+ * A thunk that throws synchronously is a programmer error: the call rejects
35
+ * with that exception.
36
+ * - Processes inputs strictly sequentially (like `for ... of` + `await`).
37
+ * - Returns the first `Ok` and collects all errors if no `Ok` is found.
38
+ * - A fulfilled value that is not a `Result` is a programmer error: the call
39
+ * rejects with `InvalidResultStateError`.
40
+ * - A rejected input counts as a failed attempt. Without `errorMapper` the
41
+ * collected errors are `unknown[]`, because a rejection reason can be
42
+ * anything. `errorMapper` turns each rejection reason into a typed error;
43
+ * `Err` values pass through untouched, and bugs inside the mapper are rethrown.
44
+ */
45
+ declare function collectFirstOkAsync<const Inputs extends readonly CollectFirstOkAsyncInput$1[]>(inputs: Inputs): Promise<Result<OkValueOfInput$1<Inputs[number]>, unknown[]>>;
46
+ declare function collectFirstOkAsync<const Inputs extends readonly CollectFirstOkAsyncInput$1[], F>(inputs: Inputs, errorMapper: (error: unknown) => F): Promise<Result<OkValueOfInput$1<Inputs[number]>, Array<ErrValueOfInput$1<Inputs[number]> | F>>>;
47
+ //#endregion
48
+ //#region src/core/collectFirstOkParallelAsync.d.ts
49
+ type CollectFirstOkAsyncInput = Promise<Result<any, any>> | (() => Awaitable<Result<any, any>>);
50
+ type ResolvedResult<I> = I extends (() => infer R) ? Awaited<R> : I extends Promise<infer R> ? R : never;
51
+ type OkValueOfInput<I> = ResolvedResult<I> extends Result<infer T, any> ? T : never;
52
+ type ErrValueOfInput<I> = ResolvedResult<I> extends Result<any, infer E> ? E : never;
53
+ /**
54
+ * Parallel version of `collectFirstOkAsync`.
55
+ *
56
+ * - Starts all inputs immediately (Promises or Thunks). A thunk that throws
57
+ * synchronously is a programmer error: the call rejects with that exception,
58
+ * as `collectFirstOkAsync` does.
59
+ * - Returns the first `Ok` as soon as it is available.
60
+ * - If no `Ok` is found, returns an `Err` with all error values (in input order).
61
+ * - A fulfilled value that is not a `Result` is a programmer error: the call
62
+ * rejects with `InvalidResultStateError`, unless an `Ok` already won the race.
63
+ * - A rejected input counts as a failed attempt. Without `errorMapper` the
64
+ * collected errors are `unknown[]`, because a rejection reason can be
65
+ * anything. `errorMapper` turns each rejection reason into a typed error;
66
+ * `Err` values pass through untouched, and bugs inside the mapper are rethrown.
67
+ * - If multiple inputs provide an `Ok`, the one that completes first wins.
68
+ * In case of simultaneous completion, the first observed result wins.
69
+ * - If no `Ok` arrives and at least one input never settles, the Promise remains pending.
70
+ */
71
+ declare function collectFirstOkParallelAsync<const Inputs extends readonly CollectFirstOkAsyncInput[]>(inputs: Inputs): Promise<Result<OkValueOfInput<Inputs[number]>, unknown[]>>;
72
+ declare function collectFirstOkParallelAsync<const Inputs extends readonly CollectFirstOkAsyncInput[], F>(inputs: Inputs, errorMapper: (error: unknown) => F): Promise<Result<OkValueOfInput<Inputs[number]>, Array<ErrValueOfInput<Inputs[number]> | F>>>;
73
+ //#endregion
74
+ //#region src/core/collectAllErrors.d.ts
75
+ type OkValueOf$1<R> = R extends Result<infer T, any> ? T : never;
76
+ type ErrValueOf$1<R> = R extends Result<any, infer E> ? E : never;
77
+ type CollectionValues<Results extends readonly Result<any, any>[]> = { -readonly [K in keyof Results]: OkValueOf$1<Results[K]>; };
78
+ /**
79
+ * Combines a list of Results.
80
+ * Return Ok(values) only if all are Ok, otherwise Err([errors]).
81
+ */
82
+ declare function collectAllErrors<const Results extends readonly Result<any, any>[]>(results: Results): Result<CollectionValues<Results>, Array<ErrValueOf$1<Results[number]>>>;
83
+ //#endregion
84
+ //#region src/core/partition.d.ts
85
+ type OkValueOf<R> = R extends Result<infer T, any> ? T : never;
86
+ type ErrValueOf<R> = R extends Result<any, infer E> ? E : never;
87
+ /**
88
+ * Partitions Results into Ok values and Err errors.
89
+ */
90
+ declare function partition<const Results extends readonly Result<any, any>[]>(results: Results): [oks: Array<OkValueOf<Results[number]>>, errs: Array<ErrValueOf<Results[number]>>];
91
+ //#endregion
92
+ //#region src/core/flatten.d.ts
93
+ /**
94
+ * Flattens a nested Result.
95
+ * Result<Result<T, E>, E> → Result<T, E>
96
+ * Corresponds to Rust `flatten`.
97
+ */
98
+ declare function flatten<T, E>(result: Result<Result<T, E>, E>): Result<T, E>;
99
+ //#endregion
100
+ export { all, collectAllErrors, collectFirstOk, collectFirstOkAsync, collectFirstOkParallelAsync, flatten, partition, sequence, sequenceRecord };
101
+ //# sourceMappingURL=collections.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"collections.d.cts","names":[],"sources":["../src/core/sequenceRecord.ts","../src/core/collectFirstOk.ts","../src/core/collectFirstOkAsync.ts","../src/core/collectFirstOkParallelAsync.ts","../src/core/collectAllErrors.ts","../src/core/partition.ts","../src/core/flatten.ts"],"mappings":";;KAKK,YAAU,KAAK,UAAU,aAAa,UAAU;KAChD,aAAW,KAAK,UAAU,kBAAkB,KAAK;;;;;;;;;iBAUtC,qBAAqB,sBAAsB,WAAW,IAAI,qBACtE,QAAQ,IACT,UAAU,WAAW,IAAI,YAAU,EAAE,QAAO,aAAW,QAAQ;;;KCd7D,YAAU,KAAK,UAAU,aAAa,UAAU;KAChD,aAAW,KAAK,UAAU,kBAAkB,KAAK;;;;;;iBAOtC,qBAAqB,yBAAyB,oBAC1D,SAAS,UACV,OAAO,YAAU,kBAAkB,aAAW;;;KCR5C,6BACC,QAAQ,2BACD,UAAU;KAElB,iBAAe,KAAK,uBAAsB,KAAI,QAAQ,KAAK,UAAU,cAAc,KAAK;KACxF,iBAAe,KAAK,iBAAe,WAAW,aAAa,UAAU;KACrE,kBAAgB,KAAK,iBAAe,WAAW,kBAAkB,KAAK;;;;;;;;;;;;;;;;iBAiB3D,0BAA0B,wBAAwB,8BAC9D,QAAQ,SACT,QAAQ,OAAO,iBAAe;iBACjB,0BAA0B,wBAAwB,8BAA4B,GAC1F,QAAQ,QACR,cAAc,mBAAmB,IAClC,QAAQ,OAAO,iBAAe,iBAAiB,MAAM,kBAAgB,kBAAkB;;;KC7BrF,2BAA2B,QAAQ,2BAA2B,UAAU;KAExE,eAAe,KAAK,uBAAsB,KAAI,QAAQ,KAAK,UAAU,cAAc,KAAK;KACxF,eAAe,KAAK,eAAe,WAAW,aAAa,UAAU;KACrE,gBAAgB,KAAK,eAAe,WAAW,kBAAkB,KAAK;;;;;;;;;;;;;;;;;;;iBAoB3D,kCAAkC,wBAAwB,4BACtE,QAAQ,SACT,QAAQ,OAAO,eAAe;iBACjB,kCAAkC,wBAAwB,4BAA4B,GAClG,QAAQ,QACR,cAAc,mBAAmB,IAClC,QAAQ,OAAO,eAAe,iBAAiB,MAAM,gBAAgB,kBAAkB;;;KChCrF,YAAU,KAAK,UAAU,aAAa,UAAU;KAChD,aAAW,KAAK,UAAU,kBAAkB,KAAK;KACjD,iBAAiB,yBAAyB,mCAChC,WAAW,UAAU,YAAU,QAAQ;;;;;iBAOtC,uBAAuB,yBAAyB,oBAC5D,SAAS,UACV,OAAO,iBAAiB,UAAU,MAAM,aAAW;;;KCbjD,UAAU,KAAK,UAAU,aAAa,UAAU;KAChD,WAAW,KAAK,UAAU,kBAAkB,KAAK;;;;iBAKtC,gBAAgB,yBAAyB,oBACrD,SAAS,WACT,KAAK,MAAM,UAAU,mBAAmB,MAAM,MAAM,WAAW;;;;;;;;iBCHnD,QAAQ,GAAG,GAAG,QAAQ,OAAO,OAAO,GAAG,IAAI,KAAK,OAAO,GAAG"}
@@ -1,3 +1,101 @@
1
- import { n as sequence, t as all } from "./sequence-DDwePRLd.mjs";
2
- import { a as collectFirstOkAsync, i as collectFirstOkParallelAsync, n as partition, o as collectFirstOk, r as collectAllErrors, s as sequenceRecord, t as flatten } from "./flatten-C7D6Kttf.mjs";
3
- export { all, collectAllErrors, collectFirstOk, collectFirstOkAsync, collectFirstOkParallelAsync, flatten, partition, sequence, sequenceRecord };
1
+ import { E as Awaitable, n as sequence, s as Result, t as all } from "./sequence-CmugKPbu.mjs";
2
+ //#region src/core/sequenceRecord.d.ts
3
+ type OkValueOf$3<R> = R extends Result<infer T, any> ? T : never;
4
+ type ErrValueOf$3<R> = R extends Result<any, infer E> ? E : never;
5
+ /**
6
+ * Like `sequence`, but for Records/Objects.
7
+ * Short-circuits on the first Err.
8
+ *
9
+ * A non-enumerable own property is an input only when it holds a `Result`, so a
10
+ * hidden helper field of another type is ignored. An array throws, because its
11
+ * indices would sequence into an object; use `sequence` for a list.
12
+ */
13
+ declare function sequenceRecord<const R extends { readonly [K in keyof R]: Result<any, any>; }>(record: R): Result<{ [K in keyof R]: OkValueOf$3<R[K]>; }, ErrValueOf$3<R[keyof R]>>;
14
+ //#endregion
15
+ //#region src/core/collectFirstOk.d.ts
16
+ type OkValueOf$2<R> = R extends Result<infer T, any> ? T : never;
17
+ type ErrValueOf$2<R> = R extends Result<any, infer E> ? E : never;
18
+ /**
19
+ * Parse a set of `Result`s, short-circuits when an input value is `Ok`.
20
+ * If no `Ok` is found, returns an `Err` containing the collected error values.
21
+ * Useful for "try multiple approaches until one works" patterns.
22
+ */
23
+ declare function collectFirstOk<const Results extends readonly Result<any, any>[]>(results: Results): Result<OkValueOf$2<Results[number]>, ErrValueOf$2<Results[number]>[]>;
24
+ //#endregion
25
+ //#region src/core/collectFirstOkAsync.d.ts
26
+ type CollectFirstOkAsyncInput$1 = Promise<Result<any, any>> | (() => Awaitable<Result<any, any>>);
27
+ type ResolvedResult$1<I> = I extends (() => infer R) ? Awaited<R> : I extends Promise<infer R> ? R : never;
28
+ type OkValueOfInput$1<I> = ResolvedResult$1<I> extends Result<infer T, any> ? T : never;
29
+ type ErrValueOfInput$1<I> = ResolvedResult$1<I> extends Result<any, infer E> ? E : never;
30
+ /**
31
+ * Async version of collectFirstOk.
32
+ *
33
+ * - Takes either already started Promises or "Thunks" (`() => Awaitable<Result<...>>`).
34
+ * A thunk that throws synchronously is a programmer error: the call rejects
35
+ * with that exception.
36
+ * - Processes inputs strictly sequentially (like `for ... of` + `await`).
37
+ * - Returns the first `Ok` and collects all errors if no `Ok` is found.
38
+ * - A fulfilled value that is not a `Result` is a programmer error: the call
39
+ * rejects with `InvalidResultStateError`.
40
+ * - A rejected input counts as a failed attempt. Without `errorMapper` the
41
+ * collected errors are `unknown[]`, because a rejection reason can be
42
+ * anything. `errorMapper` turns each rejection reason into a typed error;
43
+ * `Err` values pass through untouched, and bugs inside the mapper are rethrown.
44
+ */
45
+ declare function collectFirstOkAsync<const Inputs extends readonly CollectFirstOkAsyncInput$1[]>(inputs: Inputs): Promise<Result<OkValueOfInput$1<Inputs[number]>, unknown[]>>;
46
+ declare function collectFirstOkAsync<const Inputs extends readonly CollectFirstOkAsyncInput$1[], F>(inputs: Inputs, errorMapper: (error: unknown) => F): Promise<Result<OkValueOfInput$1<Inputs[number]>, Array<ErrValueOfInput$1<Inputs[number]> | F>>>;
47
+ //#endregion
48
+ //#region src/core/collectFirstOkParallelAsync.d.ts
49
+ type CollectFirstOkAsyncInput = Promise<Result<any, any>> | (() => Awaitable<Result<any, any>>);
50
+ type ResolvedResult<I> = I extends (() => infer R) ? Awaited<R> : I extends Promise<infer R> ? R : never;
51
+ type OkValueOfInput<I> = ResolvedResult<I> extends Result<infer T, any> ? T : never;
52
+ type ErrValueOfInput<I> = ResolvedResult<I> extends Result<any, infer E> ? E : never;
53
+ /**
54
+ * Parallel version of `collectFirstOkAsync`.
55
+ *
56
+ * - Starts all inputs immediately (Promises or Thunks). A thunk that throws
57
+ * synchronously is a programmer error: the call rejects with that exception,
58
+ * as `collectFirstOkAsync` does.
59
+ * - Returns the first `Ok` as soon as it is available.
60
+ * - If no `Ok` is found, returns an `Err` with all error values (in input order).
61
+ * - A fulfilled value that is not a `Result` is a programmer error: the call
62
+ * rejects with `InvalidResultStateError`, unless an `Ok` already won the race.
63
+ * - A rejected input counts as a failed attempt. Without `errorMapper` the
64
+ * collected errors are `unknown[]`, because a rejection reason can be
65
+ * anything. `errorMapper` turns each rejection reason into a typed error;
66
+ * `Err` values pass through untouched, and bugs inside the mapper are rethrown.
67
+ * - If multiple inputs provide an `Ok`, the one that completes first wins.
68
+ * In case of simultaneous completion, the first observed result wins.
69
+ * - If no `Ok` arrives and at least one input never settles, the Promise remains pending.
70
+ */
71
+ declare function collectFirstOkParallelAsync<const Inputs extends readonly CollectFirstOkAsyncInput[]>(inputs: Inputs): Promise<Result<OkValueOfInput<Inputs[number]>, unknown[]>>;
72
+ declare function collectFirstOkParallelAsync<const Inputs extends readonly CollectFirstOkAsyncInput[], F>(inputs: Inputs, errorMapper: (error: unknown) => F): Promise<Result<OkValueOfInput<Inputs[number]>, Array<ErrValueOfInput<Inputs[number]> | F>>>;
73
+ //#endregion
74
+ //#region src/core/collectAllErrors.d.ts
75
+ type OkValueOf$1<R> = R extends Result<infer T, any> ? T : never;
76
+ type ErrValueOf$1<R> = R extends Result<any, infer E> ? E : never;
77
+ type CollectionValues<Results extends readonly Result<any, any>[]> = { -readonly [K in keyof Results]: OkValueOf$1<Results[K]>; };
78
+ /**
79
+ * Combines a list of Results.
80
+ * Return Ok(values) only if all are Ok, otherwise Err([errors]).
81
+ */
82
+ declare function collectAllErrors<const Results extends readonly Result<any, any>[]>(results: Results): Result<CollectionValues<Results>, Array<ErrValueOf$1<Results[number]>>>;
83
+ //#endregion
84
+ //#region src/core/partition.d.ts
85
+ type OkValueOf<R> = R extends Result<infer T, any> ? T : never;
86
+ type ErrValueOf<R> = R extends Result<any, infer E> ? E : never;
87
+ /**
88
+ * Partitions Results into Ok values and Err errors.
89
+ */
90
+ declare function partition<const Results extends readonly Result<any, any>[]>(results: Results): [oks: Array<OkValueOf<Results[number]>>, errs: Array<ErrValueOf<Results[number]>>];
91
+ //#endregion
92
+ //#region src/core/flatten.d.ts
93
+ /**
94
+ * Flattens a nested Result.
95
+ * Result<Result<T, E>, E> → Result<T, E>
96
+ * Corresponds to Rust `flatten`.
97
+ */
98
+ declare function flatten<T, E>(result: Result<Result<T, E>, E>): Result<T, E>;
99
+ //#endregion
100
+ export { all, collectAllErrors, collectFirstOk, collectFirstOkAsync, collectFirstOkParallelAsync, flatten, partition, sequence, sequenceRecord };
101
+ //# sourceMappingURL=collections.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"collections.d.mts","names":[],"sources":["../src/core/sequenceRecord.ts","../src/core/collectFirstOk.ts","../src/core/collectFirstOkAsync.ts","../src/core/collectFirstOkParallelAsync.ts","../src/core/collectAllErrors.ts","../src/core/partition.ts","../src/core/flatten.ts"],"mappings":";;KAKK,YAAU,KAAK,UAAU,aAAa,UAAU;KAChD,aAAW,KAAK,UAAU,kBAAkB,KAAK;;;;;;;;;iBAUtC,qBAAqB,sBAAsB,WAAW,IAAI,qBACtE,QAAQ,IACT,UAAU,WAAW,IAAI,YAAU,EAAE,QAAO,aAAW,QAAQ;;;KCd7D,YAAU,KAAK,UAAU,aAAa,UAAU;KAChD,aAAW,KAAK,UAAU,kBAAkB,KAAK;;;;;;iBAOtC,qBAAqB,yBAAyB,oBAC1D,SAAS,UACV,OAAO,YAAU,kBAAkB,aAAW;;;KCR5C,6BACC,QAAQ,2BACD,UAAU;KAElB,iBAAe,KAAK,uBAAsB,KAAI,QAAQ,KAAK,UAAU,cAAc,KAAK;KACxF,iBAAe,KAAK,iBAAe,WAAW,aAAa,UAAU;KACrE,kBAAgB,KAAK,iBAAe,WAAW,kBAAkB,KAAK;;;;;;;;;;;;;;;;iBAiB3D,0BAA0B,wBAAwB,8BAC9D,QAAQ,SACT,QAAQ,OAAO,iBAAe;iBACjB,0BAA0B,wBAAwB,8BAA4B,GAC1F,QAAQ,QACR,cAAc,mBAAmB,IAClC,QAAQ,OAAO,iBAAe,iBAAiB,MAAM,kBAAgB,kBAAkB;;;KC7BrF,2BAA2B,QAAQ,2BAA2B,UAAU;KAExE,eAAe,KAAK,uBAAsB,KAAI,QAAQ,KAAK,UAAU,cAAc,KAAK;KACxF,eAAe,KAAK,eAAe,WAAW,aAAa,UAAU;KACrE,gBAAgB,KAAK,eAAe,WAAW,kBAAkB,KAAK;;;;;;;;;;;;;;;;;;;iBAoB3D,kCAAkC,wBAAwB,4BACtE,QAAQ,SACT,QAAQ,OAAO,eAAe;iBACjB,kCAAkC,wBAAwB,4BAA4B,GAClG,QAAQ,QACR,cAAc,mBAAmB,IAClC,QAAQ,OAAO,eAAe,iBAAiB,MAAM,gBAAgB,kBAAkB;;;KChCrF,YAAU,KAAK,UAAU,aAAa,UAAU;KAChD,aAAW,KAAK,UAAU,kBAAkB,KAAK;KACjD,iBAAiB,yBAAyB,mCAChC,WAAW,UAAU,YAAU,QAAQ;;;;;iBAOtC,uBAAuB,yBAAyB,oBAC5D,SAAS,UACV,OAAO,iBAAiB,UAAU,MAAM,aAAW;;;KCbjD,UAAU,KAAK,UAAU,aAAa,UAAU;KAChD,WAAW,KAAK,UAAU,kBAAkB,KAAK;;;;iBAKtC,gBAAgB,yBAAyB,oBACrD,SAAS,WACT,KAAK,MAAM,UAAU,mBAAmB,MAAM,MAAM,WAAW;;;;;;;;iBCHnD,QAAQ,GAAG,GAAG,QAAQ,OAAO,OAAO,GAAG,IAAI,KAAK,OAAO,GAAG"}