@onrails/result 0.1.0 → 0.1.2
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 +2 -2
- package/dist/compat/neverthrow.cjs +51 -54
- package/dist/compat/neverthrow.cjs.map +1 -1
- package/dist/compat/neverthrow.js +51 -54
- package/dist/compat/neverthrow.js.map +1 -1
- package/dist/extra.cjs.map +1 -1
- package/dist/extra.js.map +1 -1
- package/dist/fluent.cjs.map +1 -1
- package/dist/fluent.js.map +1 -1
- package/dist/index.cjs +38 -49
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +38 -50
- package/dist/index.js.map +1 -1
- package/dist/interop.cjs +22 -41
- package/dist/interop.cjs.map +1 -1
- package/dist/interop.js +22 -41
- package/dist/interop.js.map +1 -1
- package/dist/mcp.cjs +22 -41
- package/dist/mcp.cjs.map +1 -1
- package/dist/mcp.js +22 -41
- package/dist/mcp.js.map +1 -1
- package/dist/railway.cjs +31 -50
- package/dist/railway.cjs.map +1 -1
- package/dist/railway.d.cts +6 -5
- package/dist/railway.d.ts +6 -5
- package/dist/railway.js +31 -50
- package/dist/railway.js.map +1 -1
- package/dist/try-gen.cjs.map +1 -1
- package/dist/try-gen.js.map +1 -1
- package/dist/validation.cjs +8 -25
- package/dist/validation.cjs.map +1 -1
- package/dist/validation.js +8 -25
- package/dist/validation.js.map +1 -1
- package/package.json +1 -1
package/dist/railway.cjs
CHANGED
|
@@ -50,17 +50,21 @@ var liftPromiseResult = async (promise, onDefect) => {
|
|
|
50
50
|
if (isErr(result)) {
|
|
51
51
|
return result;
|
|
52
52
|
}
|
|
53
|
-
|
|
54
|
-
if (inner && typeof inner === "object" && "_tag" in inner) {
|
|
55
|
-
if (inner._tag === "Ok" || inner._tag === "Err") {
|
|
56
|
-
return inner;
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
return result;
|
|
53
|
+
return isResultLike(result.value) ? result.value : result;
|
|
60
54
|
} catch (error) {
|
|
61
55
|
return err(onDefect(error));
|
|
62
56
|
}
|
|
63
57
|
};
|
|
58
|
+
var sequenceSettled = (settled) => {
|
|
59
|
+
const values = [];
|
|
60
|
+
for (const result of settled) {
|
|
61
|
+
if (isErr(result)) {
|
|
62
|
+
return err(result.error);
|
|
63
|
+
}
|
|
64
|
+
values.push(result.value);
|
|
65
|
+
}
|
|
66
|
+
return ok(values);
|
|
67
|
+
};
|
|
64
68
|
var ResultAsync = class _ResultAsync {
|
|
65
69
|
constructor(run) {
|
|
66
70
|
this.run = run;
|
|
@@ -113,34 +117,18 @@ var ResultAsync = class _ResultAsync {
|
|
|
113
117
|
});
|
|
114
118
|
}
|
|
115
119
|
static combineTuple(results) {
|
|
116
|
-
return
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
const result = await ra.resolve();
|
|
120
|
-
if (isErr(result)) {
|
|
121
|
-
return err(result.error);
|
|
122
|
-
}
|
|
123
|
-
values.push(result.value);
|
|
124
|
-
}
|
|
125
|
-
return ok(values);
|
|
126
|
-
});
|
|
120
|
+
return _ResultAsync.combine(
|
|
121
|
+
results
|
|
122
|
+
);
|
|
127
123
|
}
|
|
128
124
|
/**
|
|
129
125
|
* Like {@link combineTuple}, but starts every branch before awaiting (wall-clock
|
|
130
126
|
* parallel for independent IO). On failure, returns the first `Err` in input order.
|
|
131
127
|
*/
|
|
132
128
|
static combineTupleParallel(results) {
|
|
133
|
-
return new _ResultAsync(
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
for (const result of settled) {
|
|
137
|
-
if (isErr(result)) {
|
|
138
|
-
return err(result.error);
|
|
139
|
-
}
|
|
140
|
-
values.push(result.value);
|
|
141
|
-
}
|
|
142
|
-
return ok(values);
|
|
143
|
-
});
|
|
129
|
+
return new _ResultAsync(
|
|
130
|
+
async () => sequenceSettled(await Promise.all(results.map((ra) => ra.resolve())))
|
|
131
|
+
);
|
|
144
132
|
}
|
|
145
133
|
map(fn) {
|
|
146
134
|
return new _ResultAsync(async () => map(await this.run(), fn));
|
|
@@ -152,7 +140,7 @@ var ResultAsync = class _ResultAsync {
|
|
|
152
140
|
return new _ResultAsync(async () => {
|
|
153
141
|
const first = await this.run();
|
|
154
142
|
if (isErr(first)) {
|
|
155
|
-
return
|
|
143
|
+
return first;
|
|
156
144
|
}
|
|
157
145
|
const next = fn(first.value);
|
|
158
146
|
if (next instanceof _ResultAsync) {
|
|
@@ -161,10 +149,7 @@ var ResultAsync = class _ResultAsync {
|
|
|
161
149
|
if (isResultLike(next)) {
|
|
162
150
|
return next;
|
|
163
151
|
}
|
|
164
|
-
|
|
165
|
-
return next.inner;
|
|
166
|
-
}
|
|
167
|
-
return next;
|
|
152
|
+
return isCompatLike(next) ? next.inner : next;
|
|
168
153
|
});
|
|
169
154
|
}
|
|
170
155
|
andThen(fn) {
|
|
@@ -180,10 +165,7 @@ var ResultAsync = class _ResultAsync {
|
|
|
180
165
|
return first;
|
|
181
166
|
}
|
|
182
167
|
const next = fn(first.error);
|
|
183
|
-
|
|
184
|
-
return next.resolve();
|
|
185
|
-
}
|
|
186
|
-
return next;
|
|
168
|
+
return next instanceof _ResultAsync ? next.resolve() : next;
|
|
187
169
|
});
|
|
188
170
|
}
|
|
189
171
|
orElse(fn) {
|
|
@@ -217,9 +199,7 @@ var ResultAsync = class _ResultAsync {
|
|
|
217
199
|
return this.run().then((result) => isErr(result));
|
|
218
200
|
}
|
|
219
201
|
match(onOk, onErr) {
|
|
220
|
-
return this.run().then(
|
|
221
|
-
(result) => isErr(result) ? onErr(result.error) : onOk(result.value)
|
|
222
|
-
);
|
|
202
|
+
return this.run().then((result) => isErr(result) ? onErr(result.error) : onOk(result.value));
|
|
223
203
|
}
|
|
224
204
|
resolve() {
|
|
225
205
|
return this.run();
|
|
@@ -231,6 +211,7 @@ var ResultAsync = class _ResultAsync {
|
|
|
231
211
|
// biome-ignore lint/suspicious/noThenProperty: makes ResultAsync awaitable
|
|
232
212
|
then(onfulfilled, onrejected) {
|
|
233
213
|
return this.run().then(
|
|
214
|
+
// Safe: without onfulfilled, R1 stays at its Result<T, E> default.
|
|
234
215
|
(r) => onfulfilled ? onfulfilled(r) : r,
|
|
235
216
|
onrejected ?? void 0
|
|
236
217
|
);
|
|
@@ -243,10 +224,9 @@ function isCompatLike(v) {
|
|
|
243
224
|
return typeof v === "object" && v !== null && "inner" in v && isResultLike(v.inner);
|
|
244
225
|
}
|
|
245
226
|
|
|
246
|
-
// src/railway.ts
|
|
227
|
+
// src/railway-core.ts
|
|
247
228
|
var addField = (ctx, key, value) => ({ ...ctx, [key]: value });
|
|
248
229
|
var liftResult = (result) => ResultAsync.fromResult(result);
|
|
249
|
-
var parseWithParser = (parser, input) => typeof parser === "function" ? parser(input) : parser.parse(input);
|
|
250
230
|
var Railway = class _Railway {
|
|
251
231
|
constructor(state) {
|
|
252
232
|
this.state = state;
|
|
@@ -402,16 +382,17 @@ var Railway = class _Railway {
|
|
|
402
382
|
* every named field; prefer {@link select} when you can project to a DTO.
|
|
403
383
|
*/
|
|
404
384
|
done() {
|
|
405
|
-
return this.state.
|
|
385
|
+
return this.state.result;
|
|
406
386
|
}
|
|
407
387
|
};
|
|
388
|
+
|
|
389
|
+
// src/railway-steps.ts
|
|
390
|
+
var parseWithParser = (parser, input) => typeof parser === "function" ? parser(input) : parser.parse(input);
|
|
408
391
|
function railway(input, ...steps) {
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
}
|
|
414
|
-
return current;
|
|
392
|
+
return steps.reduce(
|
|
393
|
+
(current, step) => step(current),
|
|
394
|
+
Railway.context({ input })
|
|
395
|
+
);
|
|
415
396
|
}
|
|
416
397
|
var parseWith = (parser, onThrow) => ({
|
|
417
398
|
as: (key) => (workflow) => workflow.fromSync(key, ({ input }) => parseWithParser(parser, input), onThrow)
|
package/dist/railway.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/result.ts","../src/types.ts","../src/async.ts","../src/railway.ts"],"names":[],"mappings":";;;AAaO,IAAM,EAAA,GAAK,CAAe,KAAA,MAA4B;AAAA,EAC3D,IAAA,EAAM,IAAA;AAAA,EACN;AACF,CAAA,CAAA;AAWO,IAAM,GAAA,GAAM,CAAyB,KAAA,MAA4B;AAAA,EACtE,IAAA,EAAM,KAAA;AAAA,EACN;AACF,CAAA,CAAA;AAYO,IAAM,IAAA,GAAO,CAAO,MAAA,KAA6C,MAAA,CAAO,IAAA,KAAS,IAAA;AAYjF,IAAM,KAAA,GAAQ,CAAO,MAAA,KAA8C,MAAA,CAAO,IAAA,KAAS,KAAA;AAY1F,IAAM,OAAA,GAAU,CAAU,MAAA,EAAsB,EAAA,KAC9C,KAAK,MAAM,CAAA,GAAI,EAAA,CAAG,EAAA,CAAG,OAAO,KAAK,CAAC,CAAA,GAAI,GAAA,CAAI,OAAO,KAAK,CAAA;AAcjD,SAAS,OACX,IAAA,EACM;AACT,EAAA,IAAI,IAAA,CAAK,MAAA,KAAW,CAAA,EAAG,OAAO,OAAA,CAAQ,KAAK,CAAC,CAAA,EAAG,IAAA,CAAK,CAAC,CAAC,CAAA;AACtD,EAAA,MAAM,EAAA,GAAK,KAAK,CAAC,CAAA;AACjB,EAAA,OAAO,CAAC,MAAA,KAAqC,OAAA,CAAQ,MAAA,EAAQ,EAAE,CAAA;AACjE;AAEA,IAAM,UAAA,GAAa,CAAU,MAAA,EAAsB,EAAA,KACjD,MAAM,MAAM,CAAA,GAAI,GAAA,CAAI,EAAA,CAAG,OAAO,KAAK,CAAC,CAAA,GAAI,EAAA,CAAG,OAAO,KAAK,CAAA;AAiBlD,SAAS,UACX,IAAA,EACM;AACT,EAAA,IAAI,IAAA,CAAK,MAAA,KAAW,CAAA,EAAG,OAAO,UAAA,CAAW,KAAK,CAAC,CAAA,EAAG,IAAA,CAAK,CAAC,CAAC,CAAA;AACzD,EAAA,MAAM,EAAA,GAAK,KAAK,CAAC,CAAA;AACjB,EAAA,OAAO,CAAC,MAAA,KAAqC,UAAA,CAAW,MAAA,EAAQ,EAAE,CAAA;AACpE;AAkPO,SAAS,OAAA,CACd,IACA,OAAA,EAC8C;AAC9C,EAAA,OAAO,IAAI,IAAA,KAAgB;AACzB,IAAA,IAAI;AACF,MAAA,OAAO,EAAA,CAAG,EAAA,CAAG,GAAG,IAAI,CAAC,CAAA;AAAA,IACvB,SAAS,KAAA,EAAO;AACd,MAAA,OAAO,GAAA,CAAI,OAAA,CAAQ,KAAK,CAAC,CAAA;AAAA,IAC3B;AAAA,EACF,CAAA;AACF;;;ACrWO,IAAM,eAAA,GAAN,cAA8B,KAAA,CAAM;AAAA,EACzC,WAAA,CACE,SACkB,KAAA,EAClB;AACA,IAAA,KAAA,CAAM,OAAO,CAAA;AAFK,IAAA,IAAA,CAAA,KAAA,GAAA,KAAA;AAGlB,IAAA,IAAA,CAAK,IAAA,GAAO,iBAAA;AAAA,EACd;AAAA,EAJoB,KAAA;AAKtB,CAAA;;;ACLA,IAAM,iBAAA,GAAoB,OACxB,OAAA,EACA,QAAA,KAC4C;AAC5C,EAAA,IAAI;AACF,IAAA,MAAM,SAAS,MAAM,OAAA;AACrB,IAAA,IAAI,KAAA,CAAM,MAAM,CAAA,EAAG;AACjB,MAAA,OAAO,MAAA;AAAA,IACT;AACA,IAAA,MAAM,QAAQ,MAAA,CAAO,KAAA;AACrB,IAAA,IAAI,KAAA,IAAS,OAAO,KAAA,KAAU,QAAA,IAAY,UAAU,KAAA,EAAO;AACzD,MAAA,IAAI,KAAA,CAAM,IAAA,KAAS,IAAA,IAAQ,KAAA,CAAM,SAAS,KAAA,EAAO;AAC/C,QAAA,OAAO,KAAA;AAAA,MACT;AAAA,IACF;AACA,IAAA,OAAO,MAAA;AAAA,EACT,SAAS,KAAA,EAAO;AACd,IAAA,OAAO,GAAA,CAAI,QAAA,CAAS,KAAK,CAAC,CAAA;AAAA,EAC5B;AACF,CAAA;AAMO,IAAM,WAAA,GAAN,MAAM,YAAA,CAAkB;AAAA,EACnB,YAA+B,GAAA,EAA2B;AAA3B,IAAA,IAAA,CAAA,GAAA,GAAA,GAAA;AAAA,EAA4B;AAAA,EAA5B,GAAA;AAAA,EAEzC,OAAO,WAAiB,MAAA,EAAyC;AAC/D,IAAA,OAAO,IAAI,YAAA,CAAY,YAAY,MAAM,CAAA;AAAA,EAC3C;AAAA,EAEA,OAAO,WAAA,CACL,OAAA,EACA,QAAA,EACmB;AACnB,IAAA,OAAO,IAAI,aAAY,YAAY;AACjC,MAAA,IAAI;AACF,QAAA,OAAO,EAAA,CAAG,MAAM,OAAO,CAAA;AAAA,MACzB,SAAS,KAAA,EAAO;AACd,QAAA,OAAO,GAAA,CAAI,QAAA,CAAS,KAAK,CAAC,CAAA;AAAA,MAC5B;AAAA,IACF,CAAC,CAAA;AAAA,EACH;AAAA,EAEA,OAAO,gBAA8B,OAAA,EAA4C;AAC/E,IAAA,OAAO,IAAI,YAAA,CAAY,YAAY,EAAA,CAAG,MAAM,OAAO,CAAC,CAAA;AAAA,EACtD;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,OAAO,MAAY,EAAA,EAAoD;AACrE,IAAA,OAAO,IAAI,aAAY,EAAE,CAAA;AAAA,EAC3B;AAAA,EAIA,OAAO,GAAiB,KAAA,EAA6B;AACnD,IAAA,OAAO,IAAI,YAAA,CAAY,YAAY,EAAA,CAAG,KAAK,CAAC,CAAA;AAAA,EAC9C;AAAA,EAEA,OAAO,IAA4B,KAAA,EAA6B;AAC9D,IAAA,OAAO,IAAI,YAAA,CAAY,YAAY,GAAA,CAAI,KAAK,CAAC,CAAA;AAAA,EAC/C;AAAA;AAAA,EAGA,OAAO,iBAAA,CACL,OAAA,EACA,QAAA,EACqC;AACrC,IAAA,MAAM,YACJ,QAAA,KAAa,CAAC,UAAmB,IAAI,eAAA,CAAgB,2BAA2B,KAAK,CAAA,CAAA;AACvF,IAAA,OAAO,IAAI,YAAA,CAAY,MAAM,iBAAA,CAAkB,OAAA,EAAS,SAAS,CAAC,CAAA;AAAA,EACpE;AAAA,EAEA,OAAO,QAAc,OAAA,EAA4D;AAC/E,IAAA,OAAO,IAAI,aAAY,YAAY;AACjC,MAAA,MAAM,SAAc,EAAC;AACrB,MAAA,KAAA,MAAW,MAAM,OAAA,EAAS;AACxB,QAAA,MAAM,MAAA,GAAS,MAAM,EAAA,CAAG,OAAA,EAAQ;AAChC,QAAA,IAAI,KAAA,CAAM,MAAM,CAAA,EAAG;AACjB,UAAA,OAAO,GAAA,CAAI,OAAO,KAAK,CAAA;AAAA,QACzB;AACA,QAAA,MAAA,CAAO,IAAA,CAAK,OAAO,KAAK,CAAA;AAAA,MAC1B;AACA,MAAA,OAAO,GAAG,MAAM,CAAA;AAAA,IAClB,CAAC,CAAA;AAAA,EACH;AAAA,EAEA,OAAO,aACL,OAAA,EACsB;AACtB,IAAA,OAAO,IAAI,aAAY,YAAY;AACjC,MAAA,MAAM,SAAoB,EAAC;AAC3B,MAAA,KAAA,MAAW,MAAM,OAAA,EAAS;AACxB,QAAA,MAAM,MAAA,GAAS,MAAM,EAAA,CAAG,OAAA,EAAQ;AAChC,QAAA,IAAI,KAAA,CAAM,MAAM,CAAA,EAAG;AACjB,UAAA,OAAO,GAAA,CAAI,OAAO,KAAK,CAAA;AAAA,QAIzB;AACA,QAAA,MAAA,CAAO,IAAA,CAAK,OAAO,KAAK,CAAA;AAAA,MAC1B;AACA,MAAA,OAAO,GAAG,MAAM,CAAA;AAAA,IAIlB,CAAC,CAAA;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,OAAO,qBACL,OAAA,EACsB;AACtB,IAAA,OAAO,IAAI,aAAY,YAAY;AACjC,MAAA,MAAM,OAAA,GAAU,MAAM,OAAA,CAAQ,GAAA,CAAI,OAAA,CAAQ,GAAA,CAAI,CAAC,EAAA,KAAO,EAAA,CAAG,OAAA,EAAS,CAAC,CAAA;AACnE,MAAA,MAAM,SAAoB,EAAC;AAC3B,MAAA,KAAA,MAAW,UAAU,OAAA,EAAS;AAC5B,QAAA,IAAI,KAAA,CAAM,MAAM,CAAA,EAAG;AACjB,UAAA,OAAO,GAAA,CAAI,OAAO,KAAK,CAAA;AAAA,QAIzB;AACA,QAAA,MAAA,CAAO,IAAA,CAAK,OAAO,KAAK,CAAA;AAAA,MAC1B;AACA,MAAA,OAAO,GAAG,MAAM,CAAA;AAAA,IAIlB,CAAC,CAAA;AAAA,EACH;AAAA,EAEA,IAAO,EAAA,EAAwC;AAC7C,IAAA,OAAO,IAAI,aAAY,YAAY,GAAA,CAAI,MAAM,IAAA,CAAK,GAAA,EAAI,EAAG,EAAE,CAAC,CAAA;AAAA,EAC9D;AAAA,EAEA,OAAU,EAAA,EAAwC;AAChD,IAAA,OAAO,IAAI,aAAY,YAAY,MAAA,CAAO,MAAM,IAAA,CAAK,GAAA,EAAI,EAAG,EAAE,CAAC,CAAA;AAAA,EACjE;AAAA,EAEA,QACE,EAAA,EACuB;AACvB,IAAA,OAAO,IAAI,aAAY,YAAY;AACjC,MAAA,MAAM,KAAA,GAAQ,MAAM,IAAA,CAAK,GAAA,EAAI;AAC7B,MAAA,IAAI,KAAA,CAAM,KAAK,CAAA,EAAG;AAChB,QAAA,OAAO,GAAA,CAAI,MAAM,KAAK,CAAA;AAAA,MACxB;AACA,MAAA,MAAM,IAAA,GAAO,EAAA,CAAG,KAAA,CAAM,KAAK,CAAA;AAC3B,MAAA,IAAI,gBAAgB,YAAA,EAAa;AAC/B,QAAA,OAAO,KAAK,OAAA,EAAQ;AAAA,MACtB;AACA,MAAA,IAAI,YAAA,CAAa,IAAI,CAAA,EAAG;AACtB,QAAA,OAAO,IAAA;AAAA,MACT;AACA,MAAA,IAAI,YAAA,CAAa,IAAI,CAAA,EAAG;AACtB,QAAA,OAAO,IAAA,CAAK,KAAA;AAAA,MACd;AACA,MAAA,OAAO,IAAA;AAAA,IACT,CAAC,CAAA;AAAA,EACH;AAAA,EAEA,QACE,EAAA,EACuB;AACvB,IAAA,OAAO,IAAA,CAAK,QAAQ,EAAE,CAAA;AAAA,EACxB;AAAA,EAEA,MACE,EAAA,EACuB;AACvB,IAAA,OAAO,IAAA,CAAK,QAAQ,EAAE,CAAA;AAAA,EACxB;AAAA,EAEA,QAAW,EAAA,EAAuE;AAChF,IAAA,OAAO,IAAI,aAAY,YAAY;AACjC,MAAA,MAAM,KAAA,GAAQ,MAAM,IAAA,CAAK,GAAA,EAAI;AAC7B,MAAA,IAAI,CAAC,KAAA,CAAM,KAAK,CAAA,EAAG;AACjB,QAAA,OAAO,KAAA;AAAA,MACT;AACA,MAAA,MAAM,IAAA,GAAO,EAAA,CAAG,KAAA,CAAM,KAAK,CAAA;AAC3B,MAAA,IAAI,gBAAgB,YAAA,EAAa;AAC/B,QAAA,OAAO,KAAK,OAAA,EAAQ;AAAA,MACtB;AACA,MAAA,OAAO,IAAA;AAAA,IACT,CAAC,CAAA;AAAA,EACH;AAAA,EAEA,OAAU,EAAA,EAAuE;AAC/E,IAAA,OAAO,IAAA,CAAK,QAAQ,EAAE,CAAA;AAAA,EACxB;AAAA,EAEA,IAAI,EAAA,EAA2C;AAC7C,IAAA,OAAO,IAAI,aAAY,YAAY;AACjC,MAAA,MAAM,MAAA,GAAS,MAAM,IAAA,CAAK,GAAA,EAAI;AAC9B,MAAA,IAAI,CAAC,KAAA,CAAM,MAAM,CAAA,EAAG;AAClB,QAAA,EAAA,CAAG,OAAO,KAAK,CAAA;AAAA,MACjB;AACA,MAAA,OAAO,MAAA;AAAA,IACT,CAAC,CAAA;AAAA,EACH;AAAA,EAEA,OAAO,EAAA,EAA2C;AAChD,IAAA,OAAO,IAAI,aAAY,YAAY;AACjC,MAAA,MAAM,MAAA,GAAS,MAAM,IAAA,CAAK,GAAA,EAAI;AAC9B,MAAA,IAAI,KAAA,CAAM,MAAM,CAAA,EAAG;AACjB,QAAA,EAAA,CAAG,OAAO,KAAK,CAAA;AAAA,MACjB;AACA,MAAA,OAAO,MAAA;AAAA,IACT,CAAC,CAAA;AAAA,EACH;AAAA,EAEA,SAAY,YAAA,EAAiC;AAC3C,IAAA,OAAO,IAAA,CAAK,GAAA,EAAI,CAAE,IAAA,CAAK,CAAC,MAAA,KAAY,KAAA,CAAM,MAAM,CAAA,GAAI,YAAA,GAAe,MAAA,CAAO,KAAM,CAAA;AAAA,EAClF;AAAA,EAEA,IAAA,GAAyB;AACvB,IAAA,OAAO,IAAA,CAAK,KAAI,CAAE,IAAA,CAAK,CAAC,MAAA,KAAW,CAAC,KAAA,CAAM,MAAM,CAAC,CAAA;AAAA,EACnD;AAAA,EAEA,KAAA,GAA0B;AACxB,IAAA,OAAO,IAAA,CAAK,KAAI,CAAE,IAAA,CAAK,CAAC,MAAA,KAAW,KAAA,CAAM,MAAM,CAAC,CAAA;AAAA,EAClD;AAAA,EAEA,KAAA,CAAmB,MAAwB,KAAA,EAA2C;AACpF,IAAA,OAAO,IAAA,CAAK,KAAI,CAAE,IAAA;AAAA,MAAK,CAAC,MAAA,KACtB,KAAA,CAAM,MAAM,CAAA,GAAI,KAAA,CAAM,MAAA,CAAO,KAAK,CAAA,GAAI,IAAA,CAAK,MAAA,CAAO,KAAK;AAAA,KACzD;AAAA,EACF;AAAA,EAEA,OAAA,GAAiC;AAC/B,IAAA,OAAO,KAAK,GAAA,EAAI;AAAA,EAClB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,IAAA,CACE,aACA,UAAA,EACkB;AAClB,IAAA,OAAO,IAAA,CAAK,KAAI,CAAE,IAAA;AAAA,MAChB,CAAC,CAAA,KAAO,WAAA,GAAc,WAAA,CAAY,CAAC,CAAA,GAAK,CAAA;AAAA,MACxC,UAAA,IAAc;AAAA,KAChB;AAAA,EACF;AACF,CAAA;AAEA,SAAS,aAAmB,CAAA,EAA+B;AACzD,EAAA,OACE,OAAO,CAAA,KAAM,QAAA,IACb,CAAA,KAAM,IAAA,IACN,MAAA,IAAU,CAAA,KACR,CAAA,CAAwB,IAAA,KAAS,IAAA,IAAS,CAAA,CAAwB,IAAA,KAAS,KAAA,CAAA;AAEjF;AAEA,SAAS,aAAmB,CAAA,EAA0C;AACpE,EAAA,OACE,OAAO,MAAM,QAAA,IACb,CAAA,KAAM,QACN,OAAA,IAAW,CAAA,IACX,YAAA,CAAc,CAAA,CAAyB,KAAK,CAAA;AAEhD;;;ACnPA,IAAM,QAAA,GAAW,CACf,GAAA,EACA,GAAA,EACA,KAAA,MACsB,EAAE,GAAG,GAAA,EAAK,CAAC,GAAG,GAAG,KAAA,EAAM,CAAA;AAE/C,IAAM,UAAA,GAAa,CAAsB,MAAA,KACvC,WAAA,CAAY,WAAW,MAAM,CAAA;AAE/B,IAAM,eAAA,GAAkB,CAAO,MAAA,EAA0B,KAAA,KACvD,OAAO,MAAA,KAAW,UAAA,GAAa,MAAA,CAAO,KAAK,CAAA,GAAI,MAAA,CAAO,KAAA,CAAM,KAAK,CAAA;AA4B5D,IAAM,OAAA,GAAN,MAAM,QAAA,CAAoD;AAAA,EACvD,YAA6B,KAAA,EAA2B;AAA3B,IAAA,IAAA,CAAA,KAAA,GAAA,KAAA;AAAA,EAA4B;AAAA,EAA5B,KAAA;AAAA;AAAA,EAGrC,OAAO,KAAA,GAAsD;AAC3D,IAAA,OAAO,IAAI,QAAA,CAAQ,EAAE,IAAA,EAAM,MAAA,EAAQ,QAAQ,EAAA,CAAG,EAAE,CAAA,EAAG,CAAA;AAAA,EACrD;AAAA;AAAA,EAGA,OAAO,QAA0B,OAAA,EAAuC;AACtE,IAAA,OAAO,IAAI,SAAQ,EAAE,IAAA,EAAM,QAAQ,MAAA,EAAQ,EAAA,CAAG,OAAO,CAAA,EAAG,CAAA;AAAA,EAC1D;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,OAAO,QAAA,CACL,GAAA,EACA,EAAA,EACA,OAAA,EACkC;AAClC,IAAA,OAAO,SAAQ,KAAA,EAAM,CAAE,QAAA,CAAS,GAAA,EAAK,IAAI,OAAO,CAAA;AAAA,EAClD;AAAA;AAAA,EAGA,OAAO,UAAA,CACL,GAAA,EACA,EAAA,EACkC;AAClC,IAAA,OAAO,QAAA,CAAQ,KAAA,EAAM,CAAE,UAAA,CAAW,KAAK,EAAE,CAAA;AAAA,EAC3C;AAAA;AAAA,EAGA,OAAO,WAAA,CACL,GAAA,EACA,EAAA,EACA,QAAA,EACmC;AACnC,IAAA,OAAO,SAAQ,KAAA,EAAM,CAAE,WAAA,CAAY,GAAA,EAAK,IAAI,QAAQ,CAAA;AAAA,EACtD;AAAA;AAAA,EAGA,OAAO,SAAA,CACL,GAAA,EACA,EAAA,EACmC;AACnC,IAAA,OAAO,QAAA,CAAQ,KAAA,EAAM,CAAE,SAAA,CAAU,KAAK,EAAE,CAAA;AAAA,EAC1C;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAA,CAA4B,KAAQ,EAAA,EAAoD;AACtF,IAAA,OAAO,IAAA,CAAK,WAAW,GAAA,EAAK,CAAC,QAAQ,EAAA,CAAG,EAAA,CAAG,GAAG,CAAC,CAAC,CAAA;AAAA,EAClD;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,QAAA,CACE,GAAA,EACA,EAAA,EACA,OAAA,EACqC;AACrC,IAAA,OAAO,IAAA,CAAK,UAAA,CAAW,GAAA,EAAK,CAAC,GAAA,KAAQ,QAAQ,EAAA,EAAI,OAAO,CAAA,CAAE,GAAG,CAAC,CAAA;AAAA,EAChE;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,UAAA,CACE,KACA,EAAA,EACqC;AACrC,IAAA,IAAI,IAAA,CAAK,KAAA,CAAM,IAAA,KAAS,MAAA,EAAQ;AAC9B,MAAA,MAAM,OAAA,GAAU,KAAK,KAAA,CAAM,MAAA;AAC3B,MAAA,IAAI,KAAA,CAAM,OAAO,CAAA,EAAG;AAClB,QAAA,OAAO,IAAI,QAAA,CAAQ,EAAE,IAAA,EAAM,MAAA,EAAQ,QAAQ,GAAA,CAAI,OAAA,CAAQ,KAAK,CAAA,EAAG,CAAA;AAAA,MACjE;AACA,MAAA,MAAM,IAAA,GAAO,EAAA,CAAG,OAAA,CAAQ,KAAK,CAAA;AAC7B,MAAA,IAAI,KAAA,CAAM,IAAI,CAAA,EAAG;AACf,QAAA,OAAO,IAAI,QAAA,CAAQ,EAAE,IAAA,EAAM,MAAA,EAAQ,QAAQ,GAAA,CAAI,IAAA,CAAK,KAAK,CAAA,EAAG,CAAA;AAAA,MAC9D;AACA,MAAA,OAAO,IAAI,QAAA,CAAQ;AAAA,QACjB,IAAA,EAAM,MAAA;AAAA,QACN,MAAA,EAAQ,GAAG,QAAA,CAAS,OAAA,CAAQ,OAAO,GAAA,EAAK,IAAA,CAAK,KAAK,CAAC;AAAA,OACpD,CAAA;AAAA,IACH;AAEA,IAAA,OAAO,IAAI,QAAA,CAAQ;AAAA,MACjB,IAAA,EAAM,OAAA;AAAA,MACN,MAAA,EAAQ,IAAA,CAAK,KAAA,CAAM,MAAA,CAAO,OAAA;AAAA,QAAQ,CAAC,GAAA,KACjC,WAAA,CAAY,UAAA,CAAW,GAAG,GAAG,CAAC,CAAA,CAAE,GAAA,CAAI,CAAC,KAAA,KAAU,QAAA,CAAS,GAAA,EAAK,GAAA,EAAK,KAAK,CAAC;AAAA;AAC1E,KACD,CAAA;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,WAAA,CACE,GAAA,EACA,EAAA,EACA,QAAA,EAC2C;AAC3C,IAAA,OAAO,IAAA,CAAK,SAAA,CAAU,GAAA,EAAK,CAAC,GAAA,KAAQ,WAAA,CAAY,WAAA,CAAY,EAAA,CAAG,GAAG,CAAA,EAAG,QAAQ,CAAC,CAAA;AAAA,EAChF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,SAAA,CACE,KACA,EAAA,EAC2C;AAC3C,IAAA,MAAM,OAAA,GAAU,IAAA,CAAK,KAAA,CAAM,IAAA,KAAS,MAAA,GAAS,UAAA,CAAW,IAAA,CAAK,KAAA,CAAM,MAAM,CAAA,GAAI,IAAA,CAAK,KAAA,CAAM,MAAA;AAExF,IAAA,OAAO,IAAI,QAAA,CAAQ;AAAA,MACjB,IAAA,EAAM,OAAA;AAAA,MACN,QAAQ,OAAA,CAAQ,OAAA,CAAQ,CAAC,GAAA,KAAQ,GAAG,GAAG,CAAA,CAAE,GAAA,CAAI,CAAC,UAAU,QAAA,CAAS,GAAA,EAAK,GAAA,EAAK,KAAK,CAAC,CAAC;AAAA,KACnF,CAAA;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcA,OAAA,CACE,GAAA,EACA,MAAA,EACA,SAAA,EACqD;AACrD,IAAA,OAAO,IAAA,CAAK,UAAA,CAAW,GAAA,EAAK,CAAC,GAAA,KAAQ;AACnC,MAAA,MAAM,KAAA,GAAQ,IAAI,MAAM,CAAA;AACxB,MAAA,OAAO,KAAA,IAAS,OAAO,GAAA,CAAI,SAAA,CAAU,GAAG,CAAC,CAAA,GAAI,GAAG,KAA0B,CAAA;AAAA,IAC5E,CAAC,CAAA;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAgBA,SACE,QAAA,EAC+D;AAC/D,IAAA,MAAM,OAAA,GAAU,IAAA,CAAK,KAAA,CAAM,IAAA,KAAS,MAAA,GAAS,UAAA,CAAW,IAAA,CAAK,KAAA,CAAM,MAAM,CAAA,GAAI,IAAA,CAAK,KAAA,CAAM,MAAA;AAExF,IAAA,OAAO,IAAI,QAAA,CAAQ;AAAA,MACjB,IAAA,EAAM,OAAA;AAAA,MACN,QAAQ,OAAA,CAAQ,OAAA;AAAA,QAAQ,CAAC,QACvB,WAAA,CAAY,oBAAA;AAAA,UACV,MAAA,CAAO,OAAA,CAAQ,QAAQ,CAAA,CAAE,GAAA,CAAI,CAAC,GAAG,MAAM,CAAA,KAAM,MAAA,CAAO,GAAG,CAAC;AAAA,SAC1D,CAAE,GAAA,CAAI,CAAC,MAAA,KAAW;AAChB,UAAA,MAAM,IAAA,GAAO,EAAE,GAAG,GAAA,EAAI;AACtB,UAAA,MAAA,CAAO,KAAK,QAAQ,CAAA,CAAE,OAAA,CAAQ,CAAC,KAAK,KAAA,KAAU;AAC5C,YAAC,IAAA,CAAiC,GAAG,CAAA,GAAI,MAAA,CAAO,KAAK,CAAA;AAAA,UACvD,CAAC,CAAA;AACD,UAAA,OAAO,IAAA;AAAA,QACT,CAAC;AAAA;AACH,KACD,CAAA;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,OAAU,EAAA,EAA2C;AACnD,IAAA,IAAI,IAAA,CAAK,KAAA,CAAM,IAAA,KAAS,MAAA,EAAQ;AAC9B,MAAA,MAAM,OAAA,GAAU,KAAK,KAAA,CAAM,MAAA;AAC3B,MAAA,OAAQ,KAAA,CAAM,OAAO,CAAA,GAAI,GAAA,CAAI,OAAA,CAAQ,KAAK,CAAA,GAAI,EAAA,CAAG,EAAA,CAAG,OAAA,CAAQ,KAAK,CAAC,CAAA;AAAA,IAKpE;AAEA,IAAA,OAAO,IAAA,CAAK,KAAA,CAAM,MAAA,CAAO,GAAA,CAAI,EAAE,CAAA;AAAA,EACjC;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,IAAA,GAA+B;AAC7B,IAAA,OAAQ,IAAA,CAAK,MAAM,IAAA,KAAS,MAAA,GAAS,KAAK,KAAA,CAAM,MAAA,GAAS,KAAK,KAAA,CAAM,MAAA;AAAA,EAKtE;AACF;AAkFO,SAAS,OAAA,CAAW,UAAa,KAAA,EAAwD;AAC9F,EAAA,IAAI,OAAA,GAAmB,OAAA,CAAQ,OAAA,CAAQ,EAAE,OAAO,CAAA;AAChD,EAAA,KAAA,MAAW,QAAQ,KAAA,EAAO;AACxB,IAAA,MAAM,SAAA,GAAY,IAAA;AAClB,IAAA,OAAA,GAAU,UAAU,OAAO,CAAA;AAAA,EAC7B;AACA,EAAA,OAAO,OAAA;AACT;AAYO,IAAM,SAAA,GAAY,CAAU,MAAA,EAA0B,OAAA,MAAoC;AAAA,EAC/F,IACE,CAAmB,GAAA,KACnB,CACE,QAAA,KAEA,SAAS,QAAA,CAAS,GAAA,EAAK,CAAC,EAAE,OAAM,KAAM,eAAA,CAAgB,MAAA,EAAQ,KAAK,GAAG,OAAO;AACnF,CAAA;AAMO,IAAM,aAAA,GACX,CACE,GAAA,EACA,EAAA,EACA,OAAA,KAEF,CACE,QAAA,KAEA,QAAA,CAAS,QAAA,CAAS,GAAA,EAAK,EAAA,EAAI,OAAO;AAG/B,IAAM,eAAA,GACX,CAA2C,GAAA,EAAQ,EAAA,KACnD,CACE,QAAA,KAEA,QAAA,CAAS,UAAA,CAAW,GAAA,EAAK,EAAE;AAMxB,IAAM,gBAAA,GACX,CACE,GAAA,EACA,EAAA,EACA,QAAA,KAEF,CACE,QAAA,KAEA,QAAA,CAAS,WAAA,CAAY,GAAA,EAAK,EAAA,EAAI,QAAQ;AAGnC,IAAM,cAAA,GACX,CAA2C,GAAA,EAAQ,EAAA,KACnD,CACE,QAAA,KAEA,QAAA,CAAS,SAAA,CAAU,GAAA,EAAK,EAAE;AAGvB,IAAM,WAAA,GACX,CAAwC,GAAA,EAAQ,EAAA,KAChD,CACE,QAAA,KAEA,QAAA,CAAS,MAAA,CAAO,GAAA,EAAK,EAAE;AAGpB,IAAM,YAAA,GACX,CACE,GAAA,EACA,MAAA,EACA,SAAA,KAEF,CACE,QAAA,KAEA,QAAA,CAAS,OAAA,CAAQ,GAAA,EAAK,MAAA,EAAQ,SAAS;AAMpC,IAAM,aAAA,GACX,CAAyB,QAAA,KACzB,CACE,QAAA,KACkE;AAElE,EAAA,MAAM,aAAA,GAAgB,QAAA;AACtB,EAAA,OAAO,QAAA,CAAS,SAAS,aAAa,CAAA;AAKxC;AAMK,IAAM,SACX,CAAsB,EAAA,KACtB,CAA2B,QAAA,KACzB,QAAA,CAAS,OAAO,EAAE","file":"railway.cjs","sourcesContent":["import type { Err, Ok, Result } from \"./types.js\";\n\nexport type { Err, Ok, Result } from \"./types.js\";\n\n/**\n * Lifts a value into the success track.\n *\n * @example\n * ```ts\n * const r = ok(42); // Result<number, never>\n * const typed: Result<number, \"parse\"> = ok(1);\n * ```\n */\nexport const ok = <T, E = never>(value: T): Result<T, E> => ({\n _tag: \"Ok\",\n value,\n});\n\n/**\n * Lifts a value into the error track.\n *\n * @example\n * ```ts\n * const r = err({ kind: \"parse\", message: \"bad json\" });\n * // Result<never, { kind: \"parse\"; message: string }>\n * ```\n */\nexport const err = <T = never, E = unknown>(error: E): Result<T, E> => ({\n _tag: \"Err\",\n error,\n});\n\n/**\n * Type-narrowing predicate: returns `true` when the result is `Ok`.\n *\n * @example\n * ```ts\n * if (isOk(r)) {\n * console.log(r.value); // narrowed to Ok branch\n * }\n * ```\n */\nexport const isOk = <T, E>(result: Result<T, E>): result is Ok<T, E> => result._tag === \"Ok\";\n\n/**\n * Type-narrowing predicate: returns `true` when the result is `Err`.\n *\n * @example\n * ```ts\n * if (isErr(r)) {\n * metrics.inc(\"error\", { kind: r.error.kind });\n * }\n * ```\n */\nexport const isErr = <T, E>(result: Result<T, E>): result is Err<T, E> => result._tag === \"Err\";\n\n/** Fantasy Land `of` — alias of {@link ok}. */\nexport const of = ok;\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Dual-form helpers — each export accepts either shape:\n// data-first: `map(result, fn)`\n// curried: `map(fn)(result)`\n// Arity at the call site selects the overload.\n// ─────────────────────────────────────────────────────────────────────────────\n\nconst mapImpl = <T, U, E>(result: Result<T, E>, fn: (value: T) => U): Result<U, E> =>\n isOk(result) ? ok(fn(result.value)) : err(result.error);\n\n/**\n * Transform the `Ok` value, passing `Err` through unchanged. Dual-form:\n * call data-first or curried (for use with {@link pipe}).\n *\n * @example\n * ```ts\n * map(ok(2), (n) => n * 3); // Ok 6 — data-first\n * pipe(ok(\"x\"), map((s) => s.length));// Ok 1 — curried\n * ```\n */\nexport function map<T, U, E>(result: Result<T, E>, fn: (value: T) => U): Result<U, E>;\nexport function map<T, U>(fn: (value: T) => U): <E>(result: Result<T, E>) => Result<U, E>;\nexport function map(\n ...args: [Result<unknown, unknown>, (value: unknown) => unknown] | [(value: unknown) => unknown]\n): unknown {\n if (args.length === 2) return mapImpl(args[0], args[1]);\n const fn = args[0];\n return (result: Result<unknown, unknown>) => mapImpl(result, fn);\n}\n\nconst mapErrImpl = <T, E, F>(result: Result<T, E>, fn: (error: E) => F): Result<T, F> =>\n isErr(result) ? err(fn(result.error)) : ok(result.value);\n\n/**\n * Transform the `Err` value, passing `Ok` through unchanged. Useful for\n * unifying heterogeneous failure types into one app-level union.\n *\n * @example\n * ```ts\n * type AppError = { kind: \"http\"; status: number } | { kind: \"parse\" };\n * pipe(\n * fetchSync(url), // Result<Body, { status: number }>\n * mapErr((e): AppError => ({ kind: \"http\", status: e.status })),\n * );\n * ```\n */\nexport function mapErr<T, E, F>(result: Result<T, E>, fn: (error: E) => F): Result<T, F>;\nexport function mapErr<E, F>(fn: (error: E) => F): <T>(result: Result<T, E>) => Result<T, F>;\nexport function mapErr(\n ...args: [Result<unknown, unknown>, (error: unknown) => unknown] | [(error: unknown) => unknown]\n): unknown {\n if (args.length === 2) return mapErrImpl(args[0], args[1]);\n const fn = args[0];\n return (result: Result<unknown, unknown>) => mapErrImpl(result, fn);\n}\n\nconst bimapImpl = <T, U, E, F>(\n result: Result<T, E>,\n onOk: (value: T) => U,\n onErr: (error: E) => F,\n): Result<U, F> => (isOk(result) ? ok(onOk(result.value)) : err(onErr(result.error)));\n\n/**\n * Transform both tracks at once — `Ok` via `onOk`, `Err` via `onErr`.\n * Equivalent to `mapErr(onErr)(map(onOk)(result))` but in one pass.\n *\n * @example\n * ```ts\n * bimap(parsed, (cfg) => cfg.name, (e) => ({ kind: \"input\", cause: e }));\n * ```\n */\nexport function bimap<T, U, E, F>(\n result: Result<T, E>,\n onOk: (value: T) => U,\n onErr: (error: E) => F,\n): Result<U, F>;\nexport function bimap<T, U, E, F>(\n onOk: (value: T) => U,\n onErr: (error: E) => F,\n): (result: Result<T, E>) => Result<U, F>;\nexport function bimap(\n ...args:\n | [Result<unknown, unknown>, (value: unknown) => unknown, (error: unknown) => unknown]\n | [(value: unknown) => unknown, (error: unknown) => unknown]\n): unknown {\n if (args.length === 3) return bimapImpl(args[0], args[1], args[2]);\n const [onOk, onErr] = args;\n return (result: Result<unknown, unknown>) => bimapImpl(result, onOk, onErr);\n}\n\nconst flatMapImpl = <T, U, E, F>(\n result: Result<T, E>,\n fn: (value: T) => Result<U, F>,\n): Result<U, E | F> => (isOk(result) ? fn(result.value) : err(result.error));\n\n/**\n * Canonical bind (Fantasy Land `chain`). Chains a Result-returning step,\n * widening the error union to `E | F`. Short-circuits on `Err`.\n *\n * @example\n * ```ts\n * flatMap(parseInput(raw), (data) =>\n * data.id != null ? ok(data) : err({ kind: \"missing_id\" as const }),\n * );\n * // Result<Data, ParseError | { kind: \"missing_id\" }>\n * ```\n */\nexport function flatMap<T, U, E, F>(\n result: Result<T, E>,\n fn: (value: T) => Result<U, F>,\n): Result<U, E | F>;\nexport function flatMap<T, U, F>(\n fn: (value: T) => Result<U, F>,\n): <E>(result: Result<T, E>) => Result<U, E | F>;\nexport function flatMap(\n ...args:\n | [Result<unknown, unknown>, (value: unknown) => Result<unknown, unknown>]\n | [(value: unknown) => Result<unknown, unknown>]\n): unknown {\n if (args.length === 2) return flatMapImpl(args[0], args[1]);\n const fn = args[0];\n return (result: Result<unknown, unknown>) => flatMapImpl(result, fn);\n}\n\nconst recoverImpl = <T, E, F>(\n result: Result<T, E>,\n fn: (error: E) => Result<T, F>,\n): Result<T, F> => (isErr(result) ? fn(result.error) : ok(result.value));\n\n/**\n * Error-track bind — runs `fn` only when the result is `Err`, allowing\n * a failed workflow to recover to `Ok` or remap the failure. Mirror of\n * {@link flatMap} on the error channel.\n *\n * @example\n * ```ts\n * recover(networkResult, (e) =>\n * e.kind === \"rate_limit\" ? ok(cachedBody) : err(e),\n * );\n * ```\n */\nexport function recover<T, E, F>(\n result: Result<T, E>,\n fn: (error: E) => Result<T, F>,\n): Result<T, F>;\nexport function recover<T, E, F>(\n fn: (error: E) => Result<T, F>,\n): (result: Result<T, E>) => Result<T, F>;\nexport function recover(\n ...args:\n | [Result<unknown, unknown>, (error: unknown) => Result<unknown, unknown>]\n | [(error: unknown) => Result<unknown, unknown>]\n): unknown {\n if (args.length === 2) return recoverImpl(args[0], args[1]);\n const fn = args[0];\n return (result: Result<unknown, unknown>) => recoverImpl(result, fn);\n}\n\nconst tapImpl = <T, E>(result: Result<T, E>, fn: (value: T) => void): Result<T, E> => {\n if (isOk(result)) fn(result.value);\n return result;\n};\n\n/**\n * Observe the `Ok` value for side effects (logging, metrics) without\n * changing the carried value. Passes `Err` through untouched.\n *\n * @example\n * ```ts\n * pipe(\n * parseConfig(raw),\n * tap((cfg) => log.info({ msg: \"parsed\", name: cfg.name })),\n * flatMap(validate),\n * );\n * ```\n */\nexport function tap<T, E>(result: Result<T, E>, fn: (value: T) => void): Result<T, E>;\nexport function tap<T>(fn: (value: T) => void): <E>(result: Result<T, E>) => Result<T, E>;\nexport function tap(\n ...args: [Result<unknown, unknown>, (value: unknown) => void] | [(value: unknown) => void]\n): unknown {\n if (args.length === 2) return tapImpl(args[0], args[1]);\n const fn = args[0];\n return (result: Result<unknown, unknown>) => tapImpl(result, fn);\n}\n\nconst tapErrImpl = <T, E>(result: Result<T, E>, fn: (error: E) => void): Result<T, E> => {\n if (isErr(result)) fn(result.error);\n return result;\n};\n\n/**\n * Observe the `Err` value for side effects (logging, metrics) without\n * changing the carried error. Passes `Ok` through untouched.\n *\n * @example\n * ```ts\n * pipe(\n * loadUser(id),\n * tapErr((e) => metrics.inc(\"user.load.fail\", { kind: e.kind })),\n * );\n * ```\n */\nexport function tapErr<T, E>(result: Result<T, E>, fn: (error: E) => void): Result<T, E>;\nexport function tapErr<E>(fn: (error: E) => void): <T>(result: Result<T, E>) => Result<T, E>;\nexport function tapErr(\n ...args: [Result<unknown, unknown>, (error: unknown) => void] | [(error: unknown) => void]\n): unknown {\n if (args.length === 2) return tapErrImpl(args[0], args[1]);\n const fn = args[0];\n return (result: Result<unknown, unknown>) => tapErrImpl(result, fn);\n}\n\nconst matchImpl = <T, E, U>(\n result: Result<T, E>,\n onOk: (value: T) => U,\n onErr: (error: E) => U,\n): U => (isOk(result) ? onOk(result.value) : onErr(result.error));\n\n/**\n * Terminal collapse — fold both tracks into a single value. Dual-form:\n * 3-args data-first, 2-args curried for {@link pipe}. Returns whatever\n * the handlers return.\n *\n * For files that also import `match` from `ts-pattern`, the\n * collision-free alias {@link matchResult} is identical.\n *\n * @example\n * ```ts\n * const html = match(parsed, (cfg) => render(cfg), (e) => renderError(e));\n * ```\n */\nexport function match<T, E, U>(\n result: Result<T, E>,\n onOk: (value: T) => U,\n onErr: (error: E) => U,\n): U;\nexport function match<T, E, U>(\n onOk: (value: T) => U,\n onErr: (error: E) => U,\n): (result: Result<T, E>) => U;\nexport function match(\n ...args:\n | [Result<unknown, unknown>, (value: unknown) => unknown, (error: unknown) => unknown]\n | [(value: unknown) => unknown, (error: unknown) => unknown]\n): unknown {\n if (args.length === 3) return matchImpl(args[0], args[1], args[2]);\n const [onOk, onErr] = args;\n return (result: Result<unknown, unknown>) => matchImpl(result, onOk, onErr);\n}\n\n/** Collision-free alias for files that also import `match` from ts-pattern. */\nexport const matchResult = match;\n\n/**\n * Curried collapse with named slots — escape valve when positional `match`\n * order is unclear at the call site (e.g. when both handlers return the same\n * type and a transposed `match(r, onErr, onOk)` would silently compile).\n */\nexport const fold =\n <T, E, U>(handlers: { readonly ok: (value: T) => U; readonly err: (error: E) => U }) =>\n (result: Result<T, E>): U =>\n matchImpl(result, handlers.ok, handlers.err);\n\n/**\n * Returns the `Ok` value, or `defaultValue` when the result is `Err`.\n *\n * @example\n * ```ts\n * unwrapOr(parsedSetting, \"default-value\");\n * ```\n */\nexport const unwrapOr = <T, E>(result: Result<T, E>, defaultValue: T): T =>\n isOk(result) ? result.value : defaultValue;\n\n/** Test/assert helper — throws the original Err value when called on Err. */\nexport function unwrapOk<T, E>(result: Result<T, E>): T {\n if (isErr(result)) throw result.error;\n return result.value;\n}\n\n/** Test/assert helper — throws TypeError when called on Ok. */\nexport function unwrapErr<T, E>(result: Result<T, E>): E {\n if (isOk(result)) throw new TypeError(\"unwrapErr called on Ok\");\n return result.error;\n}\n\n/** Wrap a throwing sync function — neverthrow `Result.fromThrowable` */\nexport function trySync<A extends readonly unknown[], T, E>(\n fn: (...args: A) => T,\n onThrow: (error: unknown) => E,\n): (...args: A) => Result<T, E>;\nexport function trySync<F extends (...args: never) => unknown, E>(\n fn: F,\n onThrow: (error: unknown) => E,\n): (...args: Parameters<F>) => Result<ReturnType<F>, E>;\nexport function trySync(\n fn: (...args: never) => unknown,\n onThrow: (error: unknown) => unknown,\n): (...args: never) => Result<unknown, unknown> {\n return (...args: never) => {\n try {\n return ok(fn(...args));\n } catch (error) {\n return err(onThrow(error));\n }\n };\n}\n\n/** First failure wins; otherwise collects values in order */\nexport const combine = <T, E>(results: readonly Result<T, E>[]): Result<T[], E> => {\n const values: T[] = [];\n for (const result of results) {\n if (isErr(result)) return err(result.error);\n values.push(result.value);\n }\n return ok(values);\n};\n\n/** Tuple-preserving combine (neverthrow-style) */\nexport const combineTuple = <const R extends readonly Result<unknown, unknown>[]>(\n results: R,\n): CombineTuple<R> => {\n const values: unknown[] = [];\n for (const result of results) {\n if (isErr(result)) return err(result.error) as CombineTuple<R>;\n values.push(result.value);\n }\n return ok(values) as CombineTuple<R>;\n};\n\ntype _OkValue<R> = R extends { _tag: \"Ok\"; readonly value: infer T } ? T : never;\ntype _ErrValue<R> = R extends { _tag: \"Err\"; readonly error: infer E } ? E : never;\n\ntype CombineTuple<R extends readonly Result<unknown, unknown>[]> = Result<\n { [K in keyof R]: _OkValue<R[K]> },\n { [K in keyof R]: _ErrValue<R[K]> }[number]\n>;\n\n/**\n * Variadic value-first pipe — threads `value` through up to nine unary fns.\n *\n * ```ts\n * pipe(\n * parseConfig(raw),\n * map((cfg) => cfg.name),\n * flatMap((name) => name ? ok(name) : err({ kind: \"empty\" })),\n * tap(log),\n * );\n * ```\n */\nexport function pipe<A>(value: A): A;\nexport function pipe<A, B>(value: A, ab: (a: A) => B): B;\nexport function pipe<A, B, C>(value: A, ab: (a: A) => B, bc: (b: B) => C): C;\nexport function pipe<A, B, C, D>(value: A, ab: (a: A) => B, bc: (b: B) => C, cd: (c: C) => D): D;\nexport function pipe<A, B, C, D, E>(\n value: A,\n ab: (a: A) => B,\n bc: (b: B) => C,\n cd: (c: C) => D,\n de: (d: D) => E,\n): E;\nexport function pipe<A, B, C, D, E, F>(\n value: A,\n ab: (a: A) => B,\n bc: (b: B) => C,\n cd: (c: C) => D,\n de: (d: D) => E,\n ef: (e: E) => F,\n): F;\nexport function pipe<A, B, C, D, E, F, G>(\n value: A,\n ab: (a: A) => B,\n bc: (b: B) => C,\n cd: (c: C) => D,\n de: (d: D) => E,\n ef: (e: E) => F,\n fg: (f: F) => G,\n): G;\nexport function pipe<A, B, C, D, E, F, G, H>(\n value: A,\n ab: (a: A) => B,\n bc: (b: B) => C,\n cd: (c: C) => D,\n de: (d: D) => E,\n ef: (e: E) => F,\n fg: (f: F) => G,\n gh: (g: G) => H,\n): H;\nexport function pipe<A, B, C, D, E, F, G, H, I>(\n value: A,\n ab: (a: A) => B,\n bc: (b: B) => C,\n cd: (c: C) => D,\n de: (d: D) => E,\n ef: (e: E) => F,\n fg: (f: F) => G,\n gh: (g: G) => H,\n hi: (h: H) => I,\n): I;\nexport function pipe(value: unknown, ...fns: ReadonlyArray<(x: unknown) => unknown>): unknown {\n let acc = value;\n for (const fn of fns) {\n acc = fn(acc);\n }\n return acc;\n}\n","/** Tagged success/failure — no classes, tree-shake friendly. */\nexport type Result<T, E> =\n | { readonly _tag: \"Ok\"; readonly value: T }\n | { readonly _tag: \"Err\"; readonly error: E };\n\nexport type Ok<T, E = never> = Extract<Result<T, E>, { _tag: \"Ok\" }>;\nexport type Err<T, E> = Extract<Result<T, E>, { _tag: \"Err\" }>;\n\n/** Thrown defect mapped when {@link fromAsync} has no `onDefect` */\nexport class UnexpectedError extends Error {\n constructor(\n message: string,\n override readonly cause?: unknown,\n ) {\n super(message);\n this.name = \"UnexpectedError\";\n }\n}\n","import { err, isErr, map, mapErr, ok } from \"./result.js\";\nimport type { Result } from \"./types.js\";\nimport { UnexpectedError } from \"./types.js\";\n\ntype PromiseFactory<T, E> = () => Promise<Result<T, E>>;\ntype AsyncOk<R> = R extends ResultAsync<infer T, unknown> ? T : never;\ntype AsyncErr<R> = R extends ResultAsync<unknown, infer E> ? E : never;\ntype CombineTupleAsync<R extends readonly ResultAsync<unknown, unknown>[]> = ResultAsync<\n { [K in keyof R]: AsyncOk<R[K]> },\n { [K in keyof R]: AsyncErr<R[K]> }[number]\n>;\n\nconst liftPromiseResult = async <T, E>(\n promise: Promise<Result<T, E>>,\n onDefect: (error: unknown) => E | UnexpectedError,\n): Promise<Result<T, E | UnexpectedError>> => {\n try {\n const result = await promise;\n if (isErr(result)) {\n return result;\n }\n const inner = result.value;\n if (inner && typeof inner === \"object\" && \"_tag\" in inner) {\n if (inner._tag === \"Ok\" || inner._tag === \"Err\") {\n return inner as unknown as Result<T, E | UnexpectedError>;\n }\n }\n return result;\n } catch (error) {\n return err(onDefect(error));\n }\n};\n\n/**\n * Async result — public API never exposes `Promise<Result<…>>` directly;\n * await via `.resolve()` or `.match()`.\n */\nexport class ResultAsync<T, E> {\n protected constructor(protected readonly run: PromiseFactory<T, E>) {}\n\n static fromResult<T, E>(result: Result<T, E>): ResultAsync<T, E> {\n return new ResultAsync(async () => result);\n }\n\n static fromPromise<T, E>(\n promise: PromiseLike<T>,\n onReject: (error: unknown) => E,\n ): ResultAsync<T, E> {\n return new ResultAsync(async () => {\n try {\n return ok(await promise);\n } catch (error) {\n return err(onReject(error));\n }\n });\n }\n\n static fromSafePromise<T, E = never>(promise: PromiseLike<T>): ResultAsync<T, E> {\n return new ResultAsync(async () => ok(await promise));\n }\n\n /**\n * Defers work until {@link resolve}. Unlike {@link fromPromise}, nothing runs\n * until the `ResultAsync` is resolved (e.g. by `combineTuple` / `combineTupleParallel`).\n */\n static defer<T, E>(fn: () => Promise<Result<T, E>>): ResultAsync<T, E> {\n return new ResultAsync(fn);\n }\n\n static ok<T>(value: T): ResultAsync<T, never>;\n static ok<T, E>(value: T): ResultAsync<T, E>;\n static ok<T, E = never>(value: T): ResultAsync<T, E> {\n return new ResultAsync(async () => ok(value));\n }\n\n static err<T = never, E = unknown>(error: E): ResultAsync<T, E> {\n return new ResultAsync(async () => err(error));\n }\n\n /** @see {@link fromAsync} from `@onrails/result/interop` */\n static fromResultPromise<T, E>(\n promise: Promise<Result<T, E>>,\n onDefect?: (error: unknown) => E | UnexpectedError,\n ): ResultAsync<T, E | UnexpectedError> {\n const mapDefect =\n onDefect ?? ((error: unknown) => new UnexpectedError(\"Unexpected async defect\", error));\n return new ResultAsync(() => liftPromiseResult(promise, mapDefect));\n }\n\n static combine<T, E>(results: readonly ResultAsync<T, E>[]): ResultAsync<T[], E> {\n return new ResultAsync(async () => {\n const values: T[] = [];\n for (const ra of results) {\n const result = await ra.resolve();\n if (isErr(result)) {\n return err(result.error);\n }\n values.push(result.value);\n }\n return ok(values);\n });\n }\n\n static combineTuple<const R extends readonly ResultAsync<unknown, unknown>[]>(\n results: R,\n ): CombineTupleAsync<R> {\n return new ResultAsync(async () => {\n const values: unknown[] = [];\n for (const ra of results) {\n const result = await ra.resolve();\n if (isErr(result)) {\n return err(result.error) as Result<\n { [K in keyof R]: AsyncOk<R[K]> },\n { [K in keyof R]: AsyncErr<R[K]> }[number]\n >;\n }\n values.push(result.value);\n }\n return ok(values) as Result<\n { [K in keyof R]: AsyncOk<R[K]> },\n { [K in keyof R]: AsyncErr<R[K]> }[number]\n >;\n }) as CombineTupleAsync<R>;\n }\n\n /**\n * Like {@link combineTuple}, but starts every branch before awaiting (wall-clock\n * parallel for independent IO). On failure, returns the first `Err` in input order.\n */\n static combineTupleParallel<const R extends readonly ResultAsync<unknown, unknown>[]>(\n results: R,\n ): CombineTupleAsync<R> {\n return new ResultAsync(async () => {\n const settled = await Promise.all(results.map((ra) => ra.resolve()));\n const values: unknown[] = [];\n for (const result of settled) {\n if (isErr(result)) {\n return err(result.error) as Result<\n { [K in keyof R]: AsyncOk<R[K]> },\n { [K in keyof R]: AsyncErr<R[K]> }[number]\n >;\n }\n values.push(result.value);\n }\n return ok(values) as Result<\n { [K in keyof R]: AsyncOk<R[K]> },\n { [K in keyof R]: AsyncErr<R[K]> }[number]\n >;\n }) as CombineTupleAsync<R>;\n }\n\n map<U>(fn: (value: T) => U): ResultAsync<U, E> {\n return new ResultAsync(async () => map(await this.run(), fn));\n }\n\n mapErr<F>(fn: (error: E) => F): ResultAsync<T, F> {\n return new ResultAsync(async () => mapErr(await this.run(), fn));\n }\n\n flatMap<U, F = E>(\n fn: (value: T) => ResultAsync<U, F> | Result<U, F> | { inner: Result<U, F> },\n ): ResultAsync<U, E | F> {\n return new ResultAsync(async () => {\n const first = await this.run();\n if (isErr(first)) {\n return err(first.error) as Result<U, E | F>;\n }\n const next = fn(first.value);\n if (next instanceof ResultAsync) {\n return next.resolve() as Promise<Result<U, E | F>>;\n }\n if (isResultLike(next)) {\n return next as Result<U, E | F>;\n }\n if (isCompatLike(next)) {\n return next.inner as Result<U, E | F>;\n }\n return next as Result<U, E | F>;\n });\n }\n\n andThen<U, F = E>(\n fn: (value: T) => ResultAsync<U, F> | Result<U, F> | { inner: Result<U, F> },\n ): ResultAsync<U, E | F> {\n return this.flatMap(fn);\n }\n\n chain<U, F = E>(\n fn: (value: T) => ResultAsync<U, F> | Result<U, F> | { inner: Result<U, F> },\n ): ResultAsync<U, E | F> {\n return this.flatMap(fn);\n }\n\n recover<F>(fn: (error: E) => ResultAsync<T, F> | Result<T, F>): ResultAsync<T, F> {\n return new ResultAsync(async () => {\n const first = await this.run();\n if (!isErr(first)) {\n return first as Result<T, F>;\n }\n const next = fn(first.error);\n if (next instanceof ResultAsync) {\n return next.resolve();\n }\n return next;\n });\n }\n\n orElse<F>(fn: (error: E) => ResultAsync<T, F> | Result<T, F>): ResultAsync<T, F> {\n return this.recover(fn);\n }\n\n tap(fn: (value: T) => void): ResultAsync<T, E> {\n return new ResultAsync(async () => {\n const result = await this.run();\n if (!isErr(result)) {\n fn(result.value);\n }\n return result;\n });\n }\n\n tapErr(fn: (error: E) => void): ResultAsync<T, E> {\n return new ResultAsync(async () => {\n const result = await this.run();\n if (isErr(result)) {\n fn(result.error);\n }\n return result;\n });\n }\n\n unwrapOr<U>(defaultValue: U): Promise<T | U> {\n return this.run().then((result) => (isErr(result) ? defaultValue : result.value));\n }\n\n isOk(): Promise<boolean> {\n return this.run().then((result) => !isErr(result));\n }\n\n isErr(): Promise<boolean> {\n return this.run().then((result) => isErr(result));\n }\n\n match<U1, U2 = U1>(onOk: (value: T) => U1, onErr: (error: E) => U2): Promise<U1 | U2> {\n return this.run().then((result) =>\n isErr(result) ? onErr(result.error) : onOk(result.value),\n ) as Promise<U1 | U2>;\n }\n\n resolve(): Promise<Result<T, E>> {\n return this.run();\n }\n\n /**\n * Thenable shim — `await ra` resolves to a bare tagged-union `Result<T, E>`.\n * Narrow with `isOk(r)` / `isErr(r)` to read `.value` / `.error`.\n */\n // biome-ignore lint/suspicious/noThenProperty: makes ResultAsync awaitable\n then<R1 = Result<T, E>, R2 = never>(\n onfulfilled?: ((value: Result<T, E>) => R1 | PromiseLike<R1>) | undefined | null,\n onrejected?: ((reason: unknown) => R2 | PromiseLike<R2>) | undefined | null,\n ): Promise<R1 | R2> {\n return this.run().then(\n (r) => (onfulfilled ? onfulfilled(r) : (r as unknown as R1)),\n onrejected ?? undefined,\n );\n }\n}\n\nfunction isResultLike<U, F>(v: unknown): v is Result<U, F> {\n return (\n typeof v === \"object\" &&\n v !== null &&\n \"_tag\" in v &&\n ((v as { _tag: unknown })._tag === \"Ok\" || (v as { _tag: unknown })._tag === \"Err\")\n );\n}\n\nfunction isCompatLike<U, F>(v: unknown): v is { inner: Result<U, F> } {\n return (\n typeof v === \"object\" &&\n v !== null &&\n \"inner\" in v &&\n isResultLike((v as { inner: unknown }).inner)\n );\n}\n\n/**\n * Lifts a value into an `Ok` async result.\n *\n * @example\n * ```ts\n * const r = okAsync(42); // ResultAsync<number, never>\n * ```\n */\nexport const okAsync = ResultAsync.ok;\n\n/**\n * Lifts a value into an `Err` async result.\n *\n * @example\n * ```ts\n * const r = errAsync({ kind: \"not_found\" as const });\n * ```\n */\nexport const errAsync = ResultAsync.err;\n\n/**\n * Wraps a `PromiseLike<T>` into a {@link ResultAsync}. Reject reasons go\n * through `onReject` to become typed `Err`s; success becomes `Ok<T>`.\n *\n * @example\n * ```ts\n * const body = fromPromise(\n * fetch(url).then((r) => r.text()),\n * (e): NetworkError => ({ kind: \"network\", cause: String(e) }),\n * );\n * ```\n */\nexport const fromPromise = ResultAsync.fromPromise;\n\n/**\n * Wraps a `PromiseLike<T>` that **never rejects** into {@link ResultAsync}.\n * Skips the `onReject` mapper. Use only when the promise is provably safe.\n */\nexport const fromSafePromise = ResultAsync.fromSafePromise;\n\n/**\n * Heterogeneous async tuple combine — left-to-right, short-circuit on\n * first `Err` in input order. Preserves tuple positions so destructuring\n * stays type-safe.\n *\n * @example\n * ```ts\n * const combined = sequenceTupleAsync([loadCfg(), loadCatalog()] as const);\n * // ResultAsync<readonly [Cfg, Catalog], CfgError | CatalogError>\n * ```\n */\nexport const sequenceTupleAsync = ResultAsync.combineTuple;\n\n/**\n * Heterogeneous async tuple combine — branches overlap in wall-clock time.\n * Returns the first `Err` in **input** order (not completion order).\n *\n * @example\n * ```ts\n * const combined = parallelTupleAsync([\n * loadProfile(id),\n * loadMetrics(id),\n * loadFlags(id),\n * ] as const);\n * // ResultAsync<readonly [Profile, Metrics, Flags], …>\n * ```\n */\nexport const parallelTupleAsync = ResultAsync.combineTupleParallel;\n\nconst toError = (error: unknown): Error =>\n error instanceof Error ? error : new Error(String(error));\n\n/**\n * Convenience wrapper over {@link fromPromise} with default `Error`\n * normalization. Call without `onReject` to get `ResultAsync<T, Error>`,\n * or pass a custom mapper for a typed error.\n *\n * @example\n * ```ts\n * // Default: rejection → Err(Error)\n * const a = tryAsync(db.users.insert(row));\n *\n * // Custom: typed error\n * const b = tryAsync(db.users.insert(row), (e): DbError => ({\n * kind: \"db\",\n * cause: e,\n * }));\n * ```\n */\nexport function tryAsync<T>(promise: PromiseLike<T>): ResultAsync<T, Error>;\nexport function tryAsync<T, E>(\n promise: PromiseLike<T>,\n onReject: (error: unknown) => E,\n): ResultAsync<T, E>;\nexport function tryAsync<T, E>(\n promise: PromiseLike<T>,\n onReject?: (error: unknown) => E,\n): ResultAsync<T, E | Error> {\n if (onReject) {\n return ResultAsync.fromPromise(promise, onReject);\n }\n return ResultAsync.fromPromise(promise, toError);\n}\n","import { ResultAsync } from \"./async.js\";\nimport { err, isErr, ok, trySync } from \"./result.js\";\nimport type { Result } from \"./types.js\";\n\n/**\n * Tracks whether a {@link Railway} workflow has crossed an async boundary.\n * Sync workflows return {@link Result}; async workflows return {@link ResultAsync}.\n */\nexport type RailwayMode = \"sync\" | \"async\";\n\n/**\n * Mode-aware output type for a {@link Railway} workflow: sync mode →\n * `Result<T, E>`, async mode → `ResultAsync<T, E>`.\n */\nexport type RailwayOutput<T, E, M extends RailwayMode> = M extends \"async\"\n ? ResultAsync<T, E>\n : Result<T, E>;\n\n/**\n * Initial context shape for a {@link railway} functional pipeline.\n * Wraps the raw input under the `input` key so subsequent named steps\n * can reference it via `ctx.input`.\n */\nexport type RailwayInput<I> = { readonly input: I };\n\ntype RailwayState<C extends object, E> =\n | { readonly mode: \"sync\"; readonly result: Result<C, E> }\n | { readonly mode: \"async\"; readonly result: ResultAsync<C, E> };\n\ntype BranchFn<C extends object> = (ctx: C) => ResultAsync<unknown, unknown>;\ntype BranchRecord = Record<string, (ctx: never) => ResultAsync<unknown, unknown>>;\ntype BranchOk<R> = R extends (ctx: never) => ResultAsync<infer T, infer _E> ? T : never;\ntype BranchErr<R> = R extends (ctx: never) => ResultAsync<infer _T, infer E> ? E : never;\ntype BranchInput<R> = R extends (ctx: infer C) => ResultAsync<unknown, unknown> ? C : never;\ntype ParallelInput<R extends BranchRecord> = BranchInput<R[keyof R]> & object;\ntype ParallelOutput<R extends BranchRecord> = {\n [K in keyof R]: BranchOk<R[K]>;\n};\ntype ParallelError<R extends BranchRecord> = BranchErr<R[keyof R]>;\ntype ParserLike<I, T> = { readonly parse: (input: I) => T } | ((input: I) => T);\ntype UnaryStep<I, O> = (input: I) => O;\n\nconst addField = <C extends object, K extends string, T>(\n ctx: C,\n key: K,\n value: T,\n): C & Record<K, T> => ({ ...ctx, [key]: value }) as C & Record<K, T>;\n\nconst liftResult = <C extends object, E>(result: Result<C, E>): ResultAsync<C, E> =>\n ResultAsync.fromResult(result);\n\nconst parseWithParser = <I, T>(parser: ParserLike<I, T>, input: I): T =>\n typeof parser === \"function\" ? parser(input) : parser.parse(input);\n\n/**\n * Named-context workflow builder. Each step appends a typed field to the\n * accumulating context object; the workflow tracks sync/async mode so the\n * final output type ({@link RailwayOutput}) is correct.\n *\n * Use `Railway` when a service workflow has 4+ named steps, mixed sync and\n * async boundaries, or independent async branches that should run in\n * parallel. For 1–2 step flows, prefer `flatMap` / `asyncAfter` directly.\n *\n * @example\n * ```ts\n * const summary = Railway\n * .fromSync(\"id\", () => IdSchema.parse(raw), toError)\n * .fromPromise(\"row\", ({ id }) => db.profiles.findFirst({ where: eq(profiles.id, id) }), toError)\n * .require(\"profile\", \"row\", ({ id }) => ({ kind: \"not_found\" as const, id }))\n * .derive(\"normalized\", ({ profile }) => normalizeProfile(profile))\n * .parallel({\n * artifacts: ({ normalized }) => loadArtifacts(normalized.id),\n * metrics: ({ normalized }) => loadMetrics(normalized.id),\n * })\n * .select(({ normalized, artifacts, metrics }) =>\n * toProfileSummary({ profile: normalized, artifacts, metrics }),\n * );\n * // ResultAsync<ProfileSummary, ParseError | DbError | NotFound>\n * ```\n */\nexport class Railway<C extends object, E, M extends RailwayMode> {\n private constructor(private readonly state: RailwayState<C, E>) {}\n\n /** Start an empty sync workflow with no fields in context. */\n static empty(): Railway<Record<never, never>, never, \"sync\"> {\n return new Railway({ mode: \"sync\", result: ok({}) });\n }\n\n /** Start a sync workflow with the given context as the initial state. */\n static context<C extends object>(context: C): Railway<C, never, \"sync\"> {\n return new Railway({ mode: \"sync\", result: ok(context) });\n }\n\n /**\n * Start a sync workflow with a throwing function — `onThrow` maps any\n * exception to a typed error.\n */\n static fromSync<K extends string, T, E>(\n key: K,\n fn: () => T,\n onThrow: (error: unknown) => E,\n ): Railway<Record<K, T>, E, \"sync\"> {\n return Railway.empty().fromSync(key, fn, onThrow);\n }\n\n /** Start a sync workflow with a `Result`-returning function. */\n static fromResult<K extends string, T, E>(\n key: K,\n fn: () => Result<T, E>,\n ): Railway<Record<K, T>, E, \"sync\"> {\n return Railway.empty().fromResult(key, fn);\n }\n\n /** Start an async workflow with a `PromiseLike`-returning function. */\n static fromPromise<K extends string, T, E>(\n key: K,\n fn: () => PromiseLike<T>,\n onReject: (error: unknown) => E,\n ): Railway<Record<K, T>, E, \"async\"> {\n return Railway.empty().fromPromise(key, fn, onReject);\n }\n\n /** Start an async workflow with a `ResultAsync`-returning function. */\n static fromAsync<K extends string, T, E>(\n key: K,\n fn: () => ResultAsync<T, E>,\n ): Railway<Record<K, T>, E, \"async\"> {\n return Railway.empty().fromAsync(key, fn);\n }\n\n /**\n * Pure sync derivation — `fn` must not throw. Use {@link fromSync} for\n * throwing transforms.\n */\n derive<K extends string, T>(key: K, fn: (ctx: C) => T): Railway<C & Record<K, T>, E, M> {\n return this.fromResult(key, (ctx) => ok(fn(ctx)));\n }\n\n /**\n * Throwing sync transform. Adds `{ [key]: T }` to context; converts any\n * exception to `Err<F>` via `onThrow`.\n */\n fromSync<K extends string, T, F>(\n key: K,\n fn: (ctx: C) => T,\n onThrow: (error: unknown) => F,\n ): Railway<C & Record<K, T>, E | F, M> {\n return this.fromResult(key, (ctx) => trySync(fn, onThrow)(ctx));\n }\n\n /**\n * Sync `Result`-returning step. Adds `{ [key]: T }` to context on `Ok`;\n * short-circuits the workflow on `Err`. Error union widens to `E | F`.\n */\n fromResult<K extends string, T, F>(\n key: K,\n fn: (ctx: C) => Result<T, F>,\n ): Railway<C & Record<K, T>, E | F, M> {\n if (this.state.mode === \"sync\") {\n const current = this.state.result;\n if (isErr(current)) {\n return new Railway({ mode: \"sync\", result: err(current.error) });\n }\n const next = fn(current.value);\n if (isErr(next)) {\n return new Railway({ mode: \"sync\", result: err(next.error) });\n }\n return new Railway({\n mode: \"sync\",\n result: ok(addField(current.value, key, next.value)),\n });\n }\n\n return new Railway({\n mode: \"async\",\n result: this.state.result.flatMap((ctx) =>\n ResultAsync.fromResult(fn(ctx)).map((value) => addField(ctx, key, value)),\n ),\n }) as Railway<C & Record<K, T>, E | F, M>;\n }\n\n /**\n * Promise-returning step — upgrades the workflow to async mode. Reject\n * reasons go through `onReject` to become typed `Err<F>`.\n */\n fromPromise<K extends string, T, F>(\n key: K,\n fn: (ctx: C) => PromiseLike<T>,\n onReject: (error: unknown) => F,\n ): Railway<C & Record<K, T>, E | F, \"async\"> {\n return this.fromAsync(key, (ctx) => ResultAsync.fromPromise(fn(ctx), onReject));\n }\n\n /**\n * `ResultAsync`-returning step — upgrades the workflow to async mode.\n * Already-typed error: no mapper needed.\n */\n fromAsync<K extends string, T, F>(\n key: K,\n fn: (ctx: C) => ResultAsync<T, F>,\n ): Railway<C & Record<K, T>, E | F, \"async\"> {\n const current = this.state.mode === \"sync\" ? liftResult(this.state.result) : this.state.result;\n\n return new Railway({\n mode: \"async\",\n result: current.flatMap((ctx) => fn(ctx).map((value) => addField(ctx, key, value))),\n });\n }\n\n /**\n * Narrow a nullable context field into a required non-null field. If the\n * source field is `null` / `undefined`, the workflow short-circuits with\n * `onMissing(ctx)`.\n *\n * @example\n * ```ts\n * .fromPromise(\"row\", ({ id }) => db.users.findFirst({ where: eq(users.id, id) }))\n * .require(\"user\", \"row\", ({ id }) => ({ kind: \"not_found\" as const, id }))\n * // user is now User (non-null), not User | null\n * ```\n */\n require<K extends string, S extends keyof C, F>(\n key: K,\n source: S,\n onMissing: (ctx: C) => F,\n ): Railway<C & Record<K, NonNullable<C[S]>>, E | F, M> {\n return this.fromResult(key, (ctx) => {\n const value = ctx[source];\n return value == null ? err(onMissing(ctx)) : ok(value as NonNullable<C[S]>);\n });\n }\n\n /**\n * Run independent `ResultAsync` branches concurrently and merge their\n * named outputs back into context. Upgrades the workflow to async mode.\n * On multiple failures, the first `Err` in record-iteration order wins.\n *\n * @example\n * ```ts\n * .parallel({\n * recent: ({ userId }) => loadRecent(userId),\n * metrics: ({ userId }) => loadMetrics(userId),\n * })\n * // ctx now has { ..., recent, metrics }\n * ```\n */\n parallel<R extends Record<string, BranchFn<C>>>(\n branches: R,\n ): Railway<C & ParallelOutput<R>, E | ParallelError<R>, \"async\"> {\n const current = this.state.mode === \"sync\" ? liftResult(this.state.result) : this.state.result;\n\n return new Railway({\n mode: \"async\",\n result: current.flatMap((ctx) =>\n ResultAsync.combineTupleParallel(\n Object.entries(branches).map(([, branch]) => branch(ctx)),\n ).map((values) => {\n const next = { ...ctx } as C & ParallelOutput<R>;\n Object.keys(branches).forEach((key, index) => {\n (next as Record<string, unknown>)[key] = values[index];\n });\n return next;\n }),\n ),\n }) as Railway<C & ParallelOutput<R>, E | ParallelError<R>, \"async\">;\n }\n\n /**\n * Project the final context into the workflow's output type. Hides the\n * internal context shape from callers.\n */\n select<T>(fn: (ctx: C) => T): RailwayOutput<T, E, M> {\n if (this.state.mode === \"sync\") {\n const current = this.state.result;\n return (isErr(current) ? err(current.error) : ok(fn(current.value))) as RailwayOutput<\n T,\n E,\n M\n >;\n }\n\n return this.state.result.map(fn) as RailwayOutput<T, E, M>;\n }\n\n /**\n * Return the accumulated context as-is. Use when downstream code needs\n * every named field; prefer {@link select} when you can project to a DTO.\n */\n done(): RailwayOutput<C, E, M> {\n return (this.state.mode === \"sync\" ? this.state.result : this.state.result) as RailwayOutput<\n C,\n E,\n M\n >;\n }\n}\n\n/**\n * Functional companion to {@link Railway} — point-free composition of\n * reusable workflow steps. Starts from `Railway.context({ input })` and\n * applies each step in order. Step factories live below: {@link parseWith},\n * {@link fromSyncNamed}, {@link fromResultNamed}, {@link fromPromiseNamed},\n * {@link fromAsyncNamed}, {@link deriveNamed}, {@link requireNamed},\n * {@link parallelNamed}, {@link select}.\n *\n * @example\n * ```ts\n * const summary = railway(\n * rawId,\n * parseWith(IdSchema, toError).as(\"id\"),\n * fromPromiseNamed(\"row\", ({ id }) => db.profiles.findFirst({ where: eq(profiles.id, id) }), toError),\n * requireNamed(\"profile\", \"row\", ({ id }) => ({ kind: \"not_found\" as const, id })),\n * deriveNamed(\"normalized\", ({ profile }) => normalizeProfile(profile)),\n * select(({ normalized }) => toProfileSummary(normalized)),\n * );\n * ```\n */\nexport function railway<I, A>(\n input: I,\n step1: UnaryStep<Railway<RailwayInput<I>, never, \"sync\">, A>,\n): A;\nexport function railway<I, A, B>(\n input: I,\n step1: UnaryStep<Railway<RailwayInput<I>, never, \"sync\">, A>,\n step2: UnaryStep<A, B>,\n): B;\nexport function railway<I, A, B, C>(\n input: I,\n step1: UnaryStep<Railway<RailwayInput<I>, never, \"sync\">, A>,\n step2: UnaryStep<A, B>,\n step3: UnaryStep<B, C>,\n): C;\nexport function railway<I, A, B, C, D>(\n input: I,\n step1: UnaryStep<Railway<RailwayInput<I>, never, \"sync\">, A>,\n step2: UnaryStep<A, B>,\n step3: UnaryStep<B, C>,\n step4: UnaryStep<C, D>,\n): D;\nexport function railway<I, A, B, C, D, E>(\n input: I,\n step1: UnaryStep<Railway<RailwayInput<I>, never, \"sync\">, A>,\n step2: UnaryStep<A, B>,\n step3: UnaryStep<B, C>,\n step4: UnaryStep<C, D>,\n step5: UnaryStep<D, E>,\n): E;\nexport function railway<I, A, B, C, D, E, F>(\n input: I,\n step1: UnaryStep<Railway<RailwayInput<I>, never, \"sync\">, A>,\n step2: UnaryStep<A, B>,\n step3: UnaryStep<B, C>,\n step4: UnaryStep<C, D>,\n step5: UnaryStep<D, E>,\n step6: UnaryStep<E, F>,\n): F;\nexport function railway<I, A, B, C, D, E, F, G>(\n input: I,\n step1: UnaryStep<Railway<RailwayInput<I>, never, \"sync\">, A>,\n step2: UnaryStep<A, B>,\n step3: UnaryStep<B, C>,\n step4: UnaryStep<C, D>,\n step5: UnaryStep<D, E>,\n step6: UnaryStep<E, F>,\n step7: UnaryStep<F, G>,\n): G;\nexport function railway<I, A, B, C, D, E, F, G, H>(\n input: I,\n step1: UnaryStep<Railway<RailwayInput<I>, never, \"sync\">, A>,\n step2: UnaryStep<A, B>,\n step3: UnaryStep<B, C>,\n step4: UnaryStep<C, D>,\n step5: UnaryStep<D, E>,\n step6: UnaryStep<E, F>,\n step7: UnaryStep<F, G>,\n step8: UnaryStep<G, H>,\n): H;\nexport function railway<I>(input: I, ...steps: readonly ((input: never) => unknown)[]): unknown {\n let current: unknown = Railway.context({ input });\n for (const step of steps) {\n const applyStep = step as (input: unknown) => unknown;\n current = applyStep(current);\n }\n return current;\n}\n\n/**\n * Step factory: parse the workflow input with a Zod-like schema (or a\n * unary parse function). Call `.as(key)` to name the output field.\n *\n * @example\n * ```ts\n * parseWith(IdSchema, toError).as(\"id\");\n * // Used as the first step in `railway(rawId, parseId, ...)`\n * ```\n */\nexport const parseWith = <I, T, E>(parser: ParserLike<I, T>, onThrow: (error: unknown) => E) => ({\n as:\n <K extends string>(key: K) =>\n <F, M extends RailwayMode>(\n workflow: Railway<RailwayInput<I>, F, M>,\n ): Railway<RailwayInput<I> & Record<K, T>, F | E, M> =>\n workflow.fromSync(key, ({ input }) => parseWithParser(parser, input), onThrow),\n});\n\n/**\n * Reusable wrapper around {@link Railway.fromSync}. Captures key + fn +\n * onThrow once; applies to any compatible workflow.\n */\nexport const fromSyncNamed =\n <K extends string, C extends object, T, E>(\n key: K,\n fn: (ctx: C) => T,\n onThrow: (error: unknown) => E,\n ) =>\n <I extends C, F, M extends RailwayMode>(\n workflow: Railway<I, F, M>,\n ): Railway<I & Record<K, T>, F | E, M> =>\n workflow.fromSync(key, fn, onThrow);\n\n/** Reusable wrapper around {@link Railway.fromResult}. */\nexport const fromResultNamed =\n <K extends string, C extends object, T, E>(key: K, fn: (ctx: C) => Result<T, E>) =>\n <I extends C, F, M extends RailwayMode>(\n workflow: Railway<I, F, M>,\n ): Railway<I & Record<K, T>, F | E, M> =>\n workflow.fromResult(key, fn);\n\n/**\n * Reusable wrapper around {@link Railway.fromPromise}. Upgrades the\n * workflow to async mode when applied.\n */\nexport const fromPromiseNamed =\n <K extends string, C extends object, T, E>(\n key: K,\n fn: (ctx: C) => PromiseLike<T>,\n onReject: (error: unknown) => E,\n ) =>\n <I extends C, F, M extends RailwayMode>(\n workflow: Railway<I, F, M>,\n ): Railway<I & Record<K, T>, F | E, \"async\"> =>\n workflow.fromPromise(key, fn, onReject);\n\n/** Reusable wrapper around {@link Railway.fromAsync}. */\nexport const fromAsyncNamed =\n <K extends string, C extends object, T, E>(key: K, fn: (ctx: C) => ResultAsync<T, E>) =>\n <I extends C, F, M extends RailwayMode>(\n workflow: Railway<I, F, M>,\n ): Railway<I & Record<K, T>, F | E, \"async\"> =>\n workflow.fromAsync(key, fn);\n\n/** Reusable wrapper around {@link Railway.derive} — pure sync derivation. */\nexport const deriveNamed =\n <K extends string, C extends object, T>(key: K, fn: (ctx: C) => T) =>\n <I extends C, E, M extends RailwayMode>(\n workflow: Railway<I, E, M>,\n ): Railway<I & Record<K, T>, E, M> =>\n workflow.derive(key, fn);\n\n/** Reusable wrapper around {@link Railway.require} — narrows a nullable field. */\nexport const requireNamed =\n <K extends string, S extends string, C extends object, E>(\n key: K,\n source: S,\n onMissing: (ctx: C & Record<S, unknown>) => E,\n ) =>\n <I extends C & Record<S, unknown>, F, M extends RailwayMode>(\n workflow: Railway<I, F, M>,\n ): Railway<I & Record<K, NonNullable<I[S]>>, F | E, M> =>\n workflow.require(key, source, onMissing);\n\n/**\n * Reusable wrapper around {@link Railway.parallel}. Branches run\n * concurrently and merge their named outputs back into context.\n */\nexport const parallelNamed =\n <R extends BranchRecord>(branches: R) =>\n <I extends ParallelInput<R>, E, M extends RailwayMode>(\n workflow: Railway<I, E, M>,\n ): Railway<I & ParallelOutput<R>, E | ParallelError<R>, \"async\"> => {\n // TS cannot prove contravariant branch params after storing reusable steps.\n const typedBranches = branches as unknown as Record<string, BranchFn<I>>;\n return workflow.parallel(typedBranches) as unknown as Railway<\n I & ParallelOutput<R>,\n E | ParallelError<R>,\n \"async\"\n >;\n };\n\n/**\n * Reusable wrapper around {@link Railway.select} — projects the final\n * context into the workflow's output type.\n */\nexport const select =\n <C extends object, T>(fn: (ctx: C) => T) =>\n <E, M extends RailwayMode>(workflow: Railway<C, E, M>): RailwayOutput<T, E, M> =>\n workflow.select(fn);\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/result.ts","../src/types.ts","../src/async.ts","../src/railway-core.ts","../src/railway-steps.ts"],"names":[],"mappings":"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","file":"railway.cjs","sourcesContent":["import type { Err, Ok, Result } from \"./types.js\";\n\nexport type { Err, Ok, Result } from \"./types.js\";\n\n/**\n * Lifts a value into the success track.\n *\n * @example\n * ```ts\n * const r = ok(42); // Result<number, never>\n * const typed: Result<number, \"parse\"> = ok(1);\n * ```\n */\nexport const ok = <T, E = never>(value: T): Result<T, E> => ({\n _tag: \"Ok\",\n value,\n});\n\n/**\n * Lifts a value into the error track.\n *\n * @example\n * ```ts\n * const r = err({ kind: \"parse\", message: \"bad json\" });\n * // Result<never, { kind: \"parse\"; message: string }>\n * ```\n */\nexport const err = <T = never, E = unknown>(error: E): Result<T, E> => ({\n _tag: \"Err\",\n error,\n});\n\n/**\n * Type-narrowing predicate: returns `true` when the result is `Ok`.\n *\n * @example\n * ```ts\n * if (isOk(r)) {\n * console.log(r.value); // narrowed to Ok branch\n * }\n * ```\n */\nexport const isOk = <T, E>(result: Result<T, E>): result is Ok<T, E> => result._tag === \"Ok\";\n\n/**\n * Type-narrowing predicate: returns `true` when the result is `Err`.\n *\n * @example\n * ```ts\n * if (isErr(r)) {\n * metrics.inc(\"error\", { kind: r.error.kind });\n * }\n * ```\n */\nexport const isErr = <T, E>(result: Result<T, E>): result is Err<T, E> => result._tag === \"Err\";\n\n/** Fantasy Land `of` — alias of {@link ok}. */\nexport const of = ok;\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Dual-form helpers — each export accepts either shape:\n// data-first: `map(result, fn)`\n// curried: `map(fn)(result)`\n// Arity at the call site selects the overload.\n// ─────────────────────────────────────────────────────────────────────────────\n\nconst mapImpl = <T, U, E>(result: Result<T, E>, fn: (value: T) => U): Result<U, E> =>\n isOk(result) ? ok(fn(result.value)) : err(result.error);\n\n/**\n * Transform the `Ok` value, passing `Err` through unchanged. Dual-form:\n * call data-first or curried (for use with {@link pipe}).\n *\n * @example\n * ```ts\n * map(ok(2), (n) => n * 3); // Ok 6 — data-first\n * pipe(ok(\"x\"), map((s) => s.length));// Ok 1 — curried\n * ```\n */\nexport function map<T, U, E>(result: Result<T, E>, fn: (value: T) => U): Result<U, E>;\nexport function map<T, U>(fn: (value: T) => U): <E>(result: Result<T, E>) => Result<U, E>;\nexport function map(\n ...args: [Result<unknown, unknown>, (value: unknown) => unknown] | [(value: unknown) => unknown]\n): unknown {\n if (args.length === 2) return mapImpl(args[0], args[1]);\n const fn = args[0];\n return (result: Result<unknown, unknown>) => mapImpl(result, fn);\n}\n\nconst mapErrImpl = <T, E, F>(result: Result<T, E>, fn: (error: E) => F): Result<T, F> =>\n isErr(result) ? err(fn(result.error)) : ok(result.value);\n\n/**\n * Transform the `Err` value, passing `Ok` through unchanged. Useful for\n * unifying heterogeneous failure types into one app-level union.\n *\n * @example\n * ```ts\n * type AppError = { kind: \"http\"; status: number } | { kind: \"parse\" };\n * pipe(\n * fetchSync(url), // Result<Body, { status: number }>\n * mapErr((e): AppError => ({ kind: \"http\", status: e.status })),\n * );\n * ```\n */\nexport function mapErr<T, E, F>(result: Result<T, E>, fn: (error: E) => F): Result<T, F>;\nexport function mapErr<E, F>(fn: (error: E) => F): <T>(result: Result<T, E>) => Result<T, F>;\nexport function mapErr(\n ...args: [Result<unknown, unknown>, (error: unknown) => unknown] | [(error: unknown) => unknown]\n): unknown {\n if (args.length === 2) return mapErrImpl(args[0], args[1]);\n const fn = args[0];\n return (result: Result<unknown, unknown>) => mapErrImpl(result, fn);\n}\n\nconst bimapImpl = <T, U, E, F>(\n result: Result<T, E>,\n onOk: (value: T) => U,\n onErr: (error: E) => F,\n): Result<U, F> => (isOk(result) ? ok(onOk(result.value)) : err(onErr(result.error)));\n\n/**\n * Transform both tracks at once — `Ok` via `onOk`, `Err` via `onErr`.\n * Equivalent to `mapErr(onErr)(map(onOk)(result))` but in one pass.\n *\n * @example\n * ```ts\n * bimap(parsed, (cfg) => cfg.name, (e) => ({ kind: \"input\", cause: e }));\n * ```\n */\nexport function bimap<T, U, E, F>(\n result: Result<T, E>,\n onOk: (value: T) => U,\n onErr: (error: E) => F,\n): Result<U, F>;\nexport function bimap<T, U, E, F>(\n onOk: (value: T) => U,\n onErr: (error: E) => F,\n): (result: Result<T, E>) => Result<U, F>;\nexport function bimap(\n ...args:\n | [Result<unknown, unknown>, (value: unknown) => unknown, (error: unknown) => unknown]\n | [(value: unknown) => unknown, (error: unknown) => unknown]\n): unknown {\n if (args.length === 3) return bimapImpl(args[0], args[1], args[2]);\n const [onOk, onErr] = args;\n return (result: Result<unknown, unknown>) => bimapImpl(result, onOk, onErr);\n}\n\nconst flatMapImpl = <T, U, E, F>(\n result: Result<T, E>,\n fn: (value: T) => Result<U, F>,\n): Result<U, E | F> => (isOk(result) ? fn(result.value) : err(result.error));\n\n/**\n * Canonical bind (Fantasy Land `chain`). Chains a Result-returning step,\n * widening the error union to `E | F`. Short-circuits on `Err`.\n *\n * @example\n * ```ts\n * flatMap(parseInput(raw), (data) =>\n * data.id != null ? ok(data) : err({ kind: \"missing_id\" as const }),\n * );\n * // Result<Data, ParseError | { kind: \"missing_id\" }>\n * ```\n */\nexport function flatMap<T, U, E, F>(\n result: Result<T, E>,\n fn: (value: T) => Result<U, F>,\n): Result<U, E | F>;\nexport function flatMap<T, U, F>(\n fn: (value: T) => Result<U, F>,\n): <E>(result: Result<T, E>) => Result<U, E | F>;\nexport function flatMap(\n ...args:\n | [Result<unknown, unknown>, (value: unknown) => Result<unknown, unknown>]\n | [(value: unknown) => Result<unknown, unknown>]\n): unknown {\n if (args.length === 2) return flatMapImpl(args[0], args[1]);\n const fn = args[0];\n return (result: Result<unknown, unknown>) => flatMapImpl(result, fn);\n}\n\nconst recoverImpl = <T, E, F>(\n result: Result<T, E>,\n fn: (error: E) => Result<T, F>,\n): Result<T, F> => (isErr(result) ? fn(result.error) : ok(result.value));\n\n/**\n * Error-track bind — runs `fn` only when the result is `Err`, allowing\n * a failed workflow to recover to `Ok` or remap the failure. Mirror of\n * {@link flatMap} on the error channel.\n *\n * @example\n * ```ts\n * recover(networkResult, (e) =>\n * e.kind === \"rate_limit\" ? ok(cachedBody) : err(e),\n * );\n * ```\n */\nexport function recover<T, E, F>(\n result: Result<T, E>,\n fn: (error: E) => Result<T, F>,\n): Result<T, F>;\nexport function recover<T, E, F>(\n fn: (error: E) => Result<T, F>,\n): (result: Result<T, E>) => Result<T, F>;\nexport function recover(\n ...args:\n | [Result<unknown, unknown>, (error: unknown) => Result<unknown, unknown>]\n | [(error: unknown) => Result<unknown, unknown>]\n): unknown {\n if (args.length === 2) return recoverImpl(args[0], args[1]);\n const fn = args[0];\n return (result: Result<unknown, unknown>) => recoverImpl(result, fn);\n}\n\nconst tapImpl = <T, E>(result: Result<T, E>, fn: (value: T) => void): Result<T, E> => {\n if (isOk(result)) fn(result.value);\n return result;\n};\n\n/**\n * Observe the `Ok` value for side effects (logging, metrics) without\n * changing the carried value. Passes `Err` through untouched.\n *\n * @example\n * ```ts\n * pipe(\n * parseConfig(raw),\n * tap((cfg) => log.info({ msg: \"parsed\", name: cfg.name })),\n * flatMap(validate),\n * );\n * ```\n */\nexport function tap<T, E>(result: Result<T, E>, fn: (value: T) => void): Result<T, E>;\nexport function tap<T>(fn: (value: T) => void): <E>(result: Result<T, E>) => Result<T, E>;\nexport function tap(\n ...args: [Result<unknown, unknown>, (value: unknown) => void] | [(value: unknown) => void]\n): unknown {\n if (args.length === 2) return tapImpl(args[0], args[1]);\n const fn = args[0];\n return (result: Result<unknown, unknown>) => tapImpl(result, fn);\n}\n\nconst tapErrImpl = <T, E>(result: Result<T, E>, fn: (error: E) => void): Result<T, E> => {\n if (isErr(result)) fn(result.error);\n return result;\n};\n\n/**\n * Observe the `Err` value for side effects (logging, metrics) without\n * changing the carried error. Passes `Ok` through untouched.\n *\n * @example\n * ```ts\n * pipe(\n * loadUser(id),\n * tapErr((e) => metrics.inc(\"user.load.fail\", { kind: e.kind })),\n * );\n * ```\n */\nexport function tapErr<T, E>(result: Result<T, E>, fn: (error: E) => void): Result<T, E>;\nexport function tapErr<E>(fn: (error: E) => void): <T>(result: Result<T, E>) => Result<T, E>;\nexport function tapErr(\n ...args: [Result<unknown, unknown>, (error: unknown) => void] | [(error: unknown) => void]\n): unknown {\n if (args.length === 2) return tapErrImpl(args[0], args[1]);\n const fn = args[0];\n return (result: Result<unknown, unknown>) => tapErrImpl(result, fn);\n}\n\nconst matchImpl = <T, E, U>(\n result: Result<T, E>,\n onOk: (value: T) => U,\n onErr: (error: E) => U,\n): U => (isOk(result) ? onOk(result.value) : onErr(result.error));\n\n/**\n * Terminal collapse — fold both tracks into a single value. Dual-form:\n * 3-args data-first, 2-args curried for {@link pipe}. Returns whatever\n * the handlers return.\n *\n * For files that also import `match` from `ts-pattern`, the\n * collision-free alias {@link matchResult} is identical.\n *\n * @example\n * ```ts\n * const html = match(parsed, (cfg) => render(cfg), (e) => renderError(e));\n * ```\n */\nexport function match<T, E, U>(\n result: Result<T, E>,\n onOk: (value: T) => U,\n onErr: (error: E) => U,\n): U;\nexport function match<T, E, U>(\n onOk: (value: T) => U,\n onErr: (error: E) => U,\n): (result: Result<T, E>) => U;\nexport function match(\n ...args:\n | [Result<unknown, unknown>, (value: unknown) => unknown, (error: unknown) => unknown]\n | [(value: unknown) => unknown, (error: unknown) => unknown]\n): unknown {\n if (args.length === 3) return matchImpl(args[0], args[1], args[2]);\n const [onOk, onErr] = args;\n return (result: Result<unknown, unknown>) => matchImpl(result, onOk, onErr);\n}\n\n/** Collision-free alias for files that also import `match` from ts-pattern. */\nexport const matchResult = match;\n\n/**\n * Curried collapse with named slots — escape valve when positional `match`\n * order is unclear at the call site (e.g. when both handlers return the same\n * type and a transposed `match(r, onErr, onOk)` would silently compile).\n */\nexport const fold =\n <T, E, U>(handlers: { readonly ok: (value: T) => U; readonly err: (error: E) => U }) =>\n (result: Result<T, E>): U =>\n matchImpl(result, handlers.ok, handlers.err);\n\n/**\n * Returns the `Ok` value, or `defaultValue` when the result is `Err`.\n *\n * @example\n * ```ts\n * unwrapOr(parsedSetting, \"default-value\");\n * ```\n */\nexport const unwrapOr = <T, E>(result: Result<T, E>, defaultValue: T): T =>\n isOk(result) ? result.value : defaultValue;\n\n/** Test/assert helper — throws the original Err value when called on Err. */\nexport function unwrapOk<T, E>(result: Result<T, E>): T {\n if (isErr(result)) throw result.error;\n return result.value;\n}\n\n/** Test/assert helper — throws TypeError when called on Ok. */\nexport function unwrapErr<T, E>(result: Result<T, E>): E {\n if (isOk(result)) throw new TypeError(\"unwrapErr called on Ok\");\n return result.error;\n}\n\n/** Wrap a throwing sync function — neverthrow `Result.fromThrowable` */\nexport function trySync<A extends readonly unknown[], T, E>(\n fn: (...args: A) => T,\n onThrow: (error: unknown) => E,\n): (...args: A) => Result<T, E>;\nexport function trySync<F extends (...args: never) => unknown, E>(\n fn: F,\n onThrow: (error: unknown) => E,\n): (...args: Parameters<F>) => Result<ReturnType<F>, E>;\nexport function trySync(\n fn: (...args: never) => unknown,\n onThrow: (error: unknown) => unknown,\n): (...args: never) => Result<unknown, unknown> {\n return (...args: never) => {\n try {\n return ok(fn(...args));\n } catch (error) {\n return err(onThrow(error));\n }\n };\n}\n\n/** First failure wins; otherwise collects values in order */\nexport const combine = <T, E>(results: readonly Result<T, E>[]): Result<T[], E> => {\n const values: T[] = [];\n for (const result of results) {\n if (isErr(result)) return err(result.error);\n values.push(result.value);\n }\n return ok(values);\n};\n\n/** Tuple-preserving combine (neverthrow-style) */\nexport const combineTuple = <const R extends readonly Result<unknown, unknown>[]>(\n results: R,\n): CombineTuple<R> =>\n // Runtime identical to combine; the cast restores per-index tuple types.\n combine(results as readonly Result<unknown, unknown>[]) as CombineTuple<R>;\n\ntype _OkValue<R> = R extends { _tag: \"Ok\"; readonly value: infer T } ? T : never;\ntype _ErrValue<R> = R extends { _tag: \"Err\"; readonly error: infer E } ? E : never;\n\ntype CombineTuple<R extends readonly Result<unknown, unknown>[]> = Result<\n { [K in keyof R]: _OkValue<R[K]> },\n { [K in keyof R]: _ErrValue<R[K]> }[number]\n>;\n\n/**\n * Variadic value-first pipe — threads `value` through up to nine unary fns.\n *\n * ```ts\n * pipe(\n * parseConfig(raw),\n * map((cfg) => cfg.name),\n * flatMap((name) => name ? ok(name) : err({ kind: \"empty\" })),\n * tap(log),\n * );\n * ```\n */\nexport function pipe<A>(value: A): A;\nexport function pipe<A, B>(value: A, ab: (a: A) => B): B;\nexport function pipe<A, B, C>(value: A, ab: (a: A) => B, bc: (b: B) => C): C;\nexport function pipe<A, B, C, D>(value: A, ab: (a: A) => B, bc: (b: B) => C, cd: (c: C) => D): D;\nexport function pipe<A, B, C, D, E>(\n value: A,\n ab: (a: A) => B,\n bc: (b: B) => C,\n cd: (c: C) => D,\n de: (d: D) => E,\n): E;\nexport function pipe<A, B, C, D, E, F>(\n value: A,\n ab: (a: A) => B,\n bc: (b: B) => C,\n cd: (c: C) => D,\n de: (d: D) => E,\n ef: (e: E) => F,\n): F;\nexport function pipe<A, B, C, D, E, F, G>(\n value: A,\n ab: (a: A) => B,\n bc: (b: B) => C,\n cd: (c: C) => D,\n de: (d: D) => E,\n ef: (e: E) => F,\n fg: (f: F) => G,\n): G;\nexport function pipe<A, B, C, D, E, F, G, H>(\n value: A,\n ab: (a: A) => B,\n bc: (b: B) => C,\n cd: (c: C) => D,\n de: (d: D) => E,\n ef: (e: E) => F,\n fg: (f: F) => G,\n gh: (g: G) => H,\n): H;\nexport function pipe<A, B, C, D, E, F, G, H, I>(\n value: A,\n ab: (a: A) => B,\n bc: (b: B) => C,\n cd: (c: C) => D,\n de: (d: D) => E,\n ef: (e: E) => F,\n fg: (f: F) => G,\n gh: (g: G) => H,\n hi: (h: H) => I,\n): I;\nexport function pipe(value: unknown, ...fns: ReadonlyArray<(x: unknown) => unknown>): unknown {\n let acc = value;\n for (const fn of fns) {\n acc = fn(acc);\n }\n return acc;\n}\n","/** Tagged success/failure — no classes, tree-shake friendly. */\nexport type Result<T, E> =\n | { readonly _tag: \"Ok\"; readonly value: T }\n | { readonly _tag: \"Err\"; readonly error: E };\n\nexport type Ok<T, E = never> = Extract<Result<T, E>, { _tag: \"Ok\" }>;\nexport type Err<T, E> = Extract<Result<T, E>, { _tag: \"Err\" }>;\n\n/** Thrown defect mapped when {@link fromAsync} has no `onDefect` */\nexport class UnexpectedError extends Error {\n constructor(\n message: string,\n override readonly cause?: unknown,\n ) {\n super(message);\n this.name = \"UnexpectedError\";\n }\n}\n","import { err, isErr, map, mapErr, ok } from \"./result.js\";\nimport type { Result } from \"./types.js\";\nimport { UnexpectedError } from \"./types.js\";\n\ntype PromiseFactory<T, E> = () => Promise<Result<T, E>>;\ntype AsyncOk<R> = R extends ResultAsync<infer T, unknown> ? T : never;\ntype AsyncErr<R> = R extends ResultAsync<unknown, infer E> ? E : never;\ntype CombineTupleAsync<R extends readonly ResultAsync<unknown, unknown>[]> = ResultAsync<\n { [K in keyof R]: AsyncOk<R[K]> },\n { [K in keyof R]: AsyncErr<R[K]> }[number]\n>;\n\nconst liftPromiseResult = async <T, E>(\n promise: Promise<Result<T, E>>,\n onDefect: (error: unknown) => E | UnexpectedError,\n): Promise<Result<T, E | UnexpectedError>> => {\n try {\n const result = await promise;\n if (isErr(result)) {\n return result;\n }\n // Auto-flatten one level: Ok<Result<…>> from double-wrapped interop.\n return isResultLike<T, E | UnexpectedError>(result.value) ? result.value : result;\n } catch (error) {\n return err(onDefect(error));\n }\n};\n\n/** Collapses settled results left-to-right, short-circuiting on the first `Err`. */\nconst sequenceSettled = (\n settled: readonly Result<unknown, unknown>[],\n): Result<unknown[], unknown> => {\n const values: unknown[] = [];\n for (const result of settled) {\n if (isErr(result)) {\n return err(result.error);\n }\n values.push(result.value);\n }\n return ok(values);\n};\n\n/**\n * Async result — public API never exposes `Promise<Result<…>>` directly;\n * await via `.resolve()` or `.match()`.\n */\nexport class ResultAsync<T, E> {\n protected constructor(protected readonly run: PromiseFactory<T, E>) {}\n\n static fromResult<T, E>(result: Result<T, E>): ResultAsync<T, E> {\n return new ResultAsync(async () => result);\n }\n\n static fromPromise<T, E>(\n promise: PromiseLike<T>,\n onReject: (error: unknown) => E,\n ): ResultAsync<T, E> {\n return new ResultAsync(async () => {\n try {\n return ok(await promise);\n } catch (error) {\n return err(onReject(error));\n }\n });\n }\n\n static fromSafePromise<T, E = never>(promise: PromiseLike<T>): ResultAsync<T, E> {\n return new ResultAsync(async () => ok(await promise));\n }\n\n /**\n * Defers work until {@link resolve}. Unlike {@link fromPromise}, nothing runs\n * until the `ResultAsync` is resolved (e.g. by `combineTuple` / `combineTupleParallel`).\n */\n static defer<T, E>(fn: () => Promise<Result<T, E>>): ResultAsync<T, E> {\n return new ResultAsync(fn);\n }\n\n static ok<T>(value: T): ResultAsync<T, never>;\n static ok<T, E>(value: T): ResultAsync<T, E>;\n static ok<T, E = never>(value: T): ResultAsync<T, E> {\n return new ResultAsync(async () => ok(value));\n }\n\n static err<T = never, E = unknown>(error: E): ResultAsync<T, E> {\n return new ResultAsync(async () => err(error));\n }\n\n /** @see {@link fromAsync} from `@onrails/result/interop` */\n static fromResultPromise<T, E>(\n promise: Promise<Result<T, E>>,\n onDefect?: (error: unknown) => E | UnexpectedError,\n ): ResultAsync<T, E | UnexpectedError> {\n const mapDefect =\n onDefect ?? ((error: unknown) => new UnexpectedError(\"Unexpected async defect\", error));\n return new ResultAsync(() => liftPromiseResult(promise, mapDefect));\n }\n\n static combine<T, E>(results: readonly ResultAsync<T, E>[]): ResultAsync<T[], E> {\n return new ResultAsync(async () => {\n const values: T[] = [];\n for (const ra of results) {\n const result = await ra.resolve();\n if (isErr(result)) {\n return err(result.error);\n }\n values.push(result.value);\n }\n return ok(values);\n });\n }\n\n static combineTuple<const R extends readonly ResultAsync<unknown, unknown>[]>(\n results: R,\n ): CombineTupleAsync<R> {\n // Runtime identical to combine; the cast restores per-index tuple types.\n return ResultAsync.combine(\n results as readonly ResultAsync<unknown, unknown>[],\n ) as CombineTupleAsync<R>;\n }\n\n /**\n * Like {@link combineTuple}, but starts every branch before awaiting (wall-clock\n * parallel for independent IO). On failure, returns the first `Err` in input order.\n */\n static combineTupleParallel<const R extends readonly ResultAsync<unknown, unknown>[]>(\n results: R,\n ): CombineTupleAsync<R> {\n // Cast restores per-index tuple types over the untyped sequence core.\n return new ResultAsync(async () =>\n sequenceSettled(await Promise.all(results.map((ra) => ra.resolve()))),\n ) as CombineTupleAsync<R>;\n }\n\n map<U>(fn: (value: T) => U): ResultAsync<U, E> {\n return new ResultAsync(async () => map(await this.run(), fn));\n }\n\n mapErr<F>(fn: (error: E) => F): ResultAsync<T, F> {\n return new ResultAsync(async () => mapErr(await this.run(), fn));\n }\n\n flatMap<U, F = E>(\n fn: (value: T) => ResultAsync<U, F> | Result<U, F> | { inner: Result<U, F> },\n ): ResultAsync<U, E | F> {\n return new ResultAsync<U, E | F>(async () => {\n const first = await this.run();\n if (isErr(first)) {\n return first;\n }\n const next = fn(first.value);\n if (next instanceof ResultAsync) {\n return next.resolve();\n }\n if (isResultLike<U, F>(next)) {\n return next;\n }\n return isCompatLike<U, F>(next) ? next.inner : next;\n });\n }\n\n andThen<U, F = E>(\n fn: (value: T) => ResultAsync<U, F> | Result<U, F> | { inner: Result<U, F> },\n ): ResultAsync<U, E | F> {\n return this.flatMap(fn);\n }\n\n chain<U, F = E>(\n fn: (value: T) => ResultAsync<U, F> | Result<U, F> | { inner: Result<U, F> },\n ): ResultAsync<U, E | F> {\n return this.flatMap(fn);\n }\n\n recover<F>(fn: (error: E) => ResultAsync<T, F> | Result<T, F>): ResultAsync<T, F> {\n return new ResultAsync<T, F>(async () => {\n const first = await this.run();\n if (!isErr(first)) {\n return first;\n }\n const next = fn(first.error);\n return next instanceof ResultAsync ? next.resolve() : next;\n });\n }\n\n orElse<F>(fn: (error: E) => ResultAsync<T, F> | Result<T, F>): ResultAsync<T, F> {\n return this.recover(fn);\n }\n\n tap(fn: (value: T) => void): ResultAsync<T, E> {\n return new ResultAsync(async () => {\n const result = await this.run();\n if (!isErr(result)) {\n fn(result.value);\n }\n return result;\n });\n }\n\n tapErr(fn: (error: E) => void): ResultAsync<T, E> {\n return new ResultAsync(async () => {\n const result = await this.run();\n if (isErr(result)) {\n fn(result.error);\n }\n return result;\n });\n }\n\n unwrapOr<U>(defaultValue: U): Promise<T | U> {\n return this.run().then((result) => (isErr(result) ? defaultValue : result.value));\n }\n\n isOk(): Promise<boolean> {\n return this.run().then((result) => !isErr(result));\n }\n\n isErr(): Promise<boolean> {\n return this.run().then((result) => isErr(result));\n }\n\n match<U1, U2 = U1>(onOk: (value: T) => U1, onErr: (error: E) => U2): Promise<U1 | U2> {\n return this.run().then((result) => (isErr(result) ? onErr(result.error) : onOk(result.value)));\n }\n\n resolve(): Promise<Result<T, E>> {\n return this.run();\n }\n\n /**\n * Thenable shim — `await ra` resolves to a bare tagged-union `Result<T, E>`.\n * Narrow with `isOk(r)` / `isErr(r)` to read `.value` / `.error`.\n */\n // biome-ignore lint/suspicious/noThenProperty: makes ResultAsync awaitable\n then<R1 = Result<T, E>, R2 = never>(\n onfulfilled?: ((value: Result<T, E>) => R1 | PromiseLike<R1>) | undefined | null,\n onrejected?: ((reason: unknown) => R2 | PromiseLike<R2>) | undefined | null,\n ): Promise<R1 | R2> {\n return this.run().then(\n // Safe: without onfulfilled, R1 stays at its Result<T, E> default.\n (r) => (onfulfilled ? onfulfilled(r) : (r as unknown as R1)),\n onrejected ?? undefined,\n );\n }\n}\n\nfunction isResultLike<U, F>(v: unknown): v is Result<U, F> {\n return (\n typeof v === \"object\" &&\n v !== null &&\n \"_tag\" in v &&\n ((v as { _tag: unknown })._tag === \"Ok\" || (v as { _tag: unknown })._tag === \"Err\")\n );\n}\n\nfunction isCompatLike<U, F>(v: unknown): v is { inner: Result<U, F> } {\n return (\n typeof v === \"object\" &&\n v !== null &&\n \"inner\" in v &&\n isResultLike((v as { inner: unknown }).inner)\n );\n}\n\n/**\n * Lifts a value into an `Ok` async result.\n *\n * @example\n * ```ts\n * const r = okAsync(42); // ResultAsync<number, never>\n * ```\n */\nexport const okAsync = ResultAsync.ok;\n\n/**\n * Lifts a value into an `Err` async result.\n *\n * @example\n * ```ts\n * const r = errAsync({ kind: \"not_found\" as const });\n * ```\n */\nexport const errAsync = ResultAsync.err;\n\n/**\n * Wraps a `PromiseLike<T>` into a {@link ResultAsync}. Reject reasons go\n * through `onReject` to become typed `Err`s; success becomes `Ok<T>`.\n *\n * @example\n * ```ts\n * const body = fromPromise(\n * fetch(url).then((r) => r.text()),\n * (e): NetworkError => ({ kind: \"network\", cause: String(e) }),\n * );\n * ```\n */\nexport const fromPromise = ResultAsync.fromPromise;\n\n/**\n * Wraps a `PromiseLike<T>` that **never rejects** into {@link ResultAsync}.\n * Skips the `onReject` mapper. Use only when the promise is provably safe.\n */\nexport const fromSafePromise = ResultAsync.fromSafePromise;\n\n/**\n * Heterogeneous async tuple combine — left-to-right, short-circuit on\n * first `Err` in input order. Preserves tuple positions so destructuring\n * stays type-safe.\n *\n * @example\n * ```ts\n * const combined = sequenceTupleAsync([loadCfg(), loadCatalog()] as const);\n * // ResultAsync<readonly [Cfg, Catalog], CfgError | CatalogError>\n * ```\n */\nexport const sequenceTupleAsync = ResultAsync.combineTuple;\n\n/**\n * Heterogeneous async tuple combine — branches overlap in wall-clock time.\n * Returns the first `Err` in **input** order (not completion order).\n *\n * @example\n * ```ts\n * const combined = parallelTupleAsync([\n * loadProfile(id),\n * loadMetrics(id),\n * loadFlags(id),\n * ] as const);\n * // ResultAsync<readonly [Profile, Metrics, Flags], …>\n * ```\n */\nexport const parallelTupleAsync = ResultAsync.combineTupleParallel;\n\nconst toError = (error: unknown): Error =>\n error instanceof Error ? error : new Error(String(error));\n\n/**\n * Convenience wrapper over {@link fromPromise} with default `Error`\n * normalization. Call without `onReject` to get `ResultAsync<T, Error>`,\n * or pass a custom mapper for a typed error.\n *\n * @example\n * ```ts\n * // Default: rejection → Err(Error)\n * const a = tryAsync(db.users.insert(row));\n *\n * // Custom: typed error\n * const b = tryAsync(db.users.insert(row), (e): DbError => ({\n * kind: \"db\",\n * cause: e,\n * }));\n * ```\n */\nexport function tryAsync<T>(promise: PromiseLike<T>): ResultAsync<T, Error>;\nexport function tryAsync<T, E>(\n promise: PromiseLike<T>,\n onReject: (error: unknown) => E,\n): ResultAsync<T, E>;\nexport function tryAsync<T, E>(\n promise: PromiseLike<T>,\n onReject?: (error: unknown) => E,\n): ResultAsync<T, E | Error> {\n if (onReject) {\n return ResultAsync.fromPromise(promise, onReject);\n }\n return ResultAsync.fromPromise(promise, toError);\n}\n","import { ResultAsync } from \"./async.js\";\nimport { err, isErr, ok, trySync } from \"./result.js\";\nimport type { Result } from \"./types.js\";\n\n/**\n * Tracks whether a {@link Railway} workflow has crossed an async boundary.\n * Sync workflows return {@link Result}; async workflows return {@link ResultAsync}.\n */\nexport type RailwayMode = \"sync\" | \"async\";\n\n/**\n * Mode-aware output type for a {@link Railway} workflow: sync mode →\n * `Result<T, E>`, async mode → `ResultAsync<T, E>`.\n */\nexport type RailwayOutput<T, E, M extends RailwayMode> = M extends \"async\"\n ? ResultAsync<T, E>\n : Result<T, E>;\n\n/**\n * Initial context shape for a `railway` functional pipeline.\n * Wraps the raw input under the `input` key so subsequent named steps\n * can reference it via `ctx.input`.\n */\nexport type RailwayInput<I> = { readonly input: I };\n\ntype RailwayState<C extends object, E> =\n | { readonly mode: \"sync\"; readonly result: Result<C, E> }\n | { readonly mode: \"async\"; readonly result: ResultAsync<C, E> };\n\nexport type BranchFn<C extends object> = (ctx: C) => ResultAsync<unknown, unknown>;\nexport type BranchRecord = Record<string, (ctx: never) => ResultAsync<unknown, unknown>>;\ntype BranchOk<R> = R extends (ctx: never) => ResultAsync<infer T, infer _E> ? T : never;\ntype BranchErr<R> = R extends (ctx: never) => ResultAsync<infer _T, infer E> ? E : never;\ntype BranchInput<R> = R extends (ctx: infer C) => ResultAsync<unknown, unknown> ? C : never;\nexport type ParallelInput<R extends BranchRecord> = BranchInput<R[keyof R]> & object;\nexport type ParallelOutput<R extends BranchRecord> = {\n [K in keyof R]: BranchOk<R[K]>;\n};\nexport type ParallelError<R extends BranchRecord> = BranchErr<R[keyof R]>;\n\nconst addField = <C extends object, K extends string, T>(\n ctx: C,\n key: K,\n value: T,\n): C & Record<K, T> => ({ ...ctx, [key]: value }) as C & Record<K, T>;\n\nconst liftResult = <C extends object, E>(result: Result<C, E>): ResultAsync<C, E> =>\n ResultAsync.fromResult(result);\n\n/**\n * Named-context workflow builder. Each step appends a typed field to the\n * accumulating context object; the workflow tracks sync/async mode so the\n * final output type ({@link RailwayOutput}) is correct.\n *\n * Use `Railway` when a service workflow has 4+ named steps, mixed sync and\n * async boundaries, or independent async branches that should run in\n * parallel. For 1–2 step flows, prefer `flatMap` / `asyncAfter` directly.\n *\n * @example\n * ```ts\n * const summary = Railway\n * .fromSync(\"id\", () => IdSchema.parse(raw), toError)\n * .fromPromise(\"row\", ({ id }) => db.profiles.findFirst({ where: eq(profiles.id, id) }), toError)\n * .require(\"profile\", \"row\", ({ id }) => ({ kind: \"not_found\" as const, id }))\n * .derive(\"normalized\", ({ profile }) => normalizeProfile(profile))\n * .parallel({\n * artifacts: ({ normalized }) => loadArtifacts(normalized.id),\n * metrics: ({ normalized }) => loadMetrics(normalized.id),\n * })\n * .select(({ normalized, artifacts, metrics }) =>\n * toProfileSummary({ profile: normalized, artifacts, metrics }),\n * );\n * // ResultAsync<ProfileSummary, ParseError | DbError | NotFound>\n * ```\n */\nexport class Railway<C extends object, E, M extends RailwayMode> {\n private constructor(private readonly state: RailwayState<C, E>) {}\n\n /** Start an empty sync workflow with no fields in context. */\n static empty(): Railway<Record<never, never>, never, \"sync\"> {\n return new Railway({ mode: \"sync\", result: ok({}) });\n }\n\n /** Start a sync workflow with the given context as the initial state. */\n static context<C extends object>(context: C): Railway<C, never, \"sync\"> {\n return new Railway({ mode: \"sync\", result: ok(context) });\n }\n\n /**\n * Start a sync workflow with a throwing function — `onThrow` maps any\n * exception to a typed error.\n */\n static fromSync<K extends string, T, E>(\n key: K,\n fn: () => T,\n onThrow: (error: unknown) => E,\n ): Railway<Record<K, T>, E, \"sync\"> {\n return Railway.empty().fromSync(key, fn, onThrow);\n }\n\n /** Start a sync workflow with a `Result`-returning function. */\n static fromResult<K extends string, T, E>(\n key: K,\n fn: () => Result<T, E>,\n ): Railway<Record<K, T>, E, \"sync\"> {\n return Railway.empty().fromResult(key, fn);\n }\n\n /** Start an async workflow with a `PromiseLike`-returning function. */\n static fromPromise<K extends string, T, E>(\n key: K,\n fn: () => PromiseLike<T>,\n onReject: (error: unknown) => E,\n ): Railway<Record<K, T>, E, \"async\"> {\n return Railway.empty().fromPromise(key, fn, onReject);\n }\n\n /** Start an async workflow with a `ResultAsync`-returning function. */\n static fromAsync<K extends string, T, E>(\n key: K,\n fn: () => ResultAsync<T, E>,\n ): Railway<Record<K, T>, E, \"async\"> {\n return Railway.empty().fromAsync(key, fn);\n }\n\n /**\n * Pure sync derivation — `fn` must not throw. Use {@link fromSync} for\n * throwing transforms.\n */\n derive<K extends string, T>(key: K, fn: (ctx: C) => T): Railway<C & Record<K, T>, E, M> {\n return this.fromResult(key, (ctx) => ok(fn(ctx)));\n }\n\n /**\n * Throwing sync transform. Adds `{ [key]: T }` to context; converts any\n * exception to `Err<F>` via `onThrow`.\n */\n fromSync<K extends string, T, F>(\n key: K,\n fn: (ctx: C) => T,\n onThrow: (error: unknown) => F,\n ): Railway<C & Record<K, T>, E | F, M> {\n return this.fromResult(key, (ctx) => trySync(fn, onThrow)(ctx));\n }\n\n /**\n * Sync `Result`-returning step. Adds `{ [key]: T }` to context on `Ok`;\n * short-circuits the workflow on `Err`. Error union widens to `E | F`.\n */\n fromResult<K extends string, T, F>(\n key: K,\n fn: (ctx: C) => Result<T, F>,\n ): Railway<C & Record<K, T>, E | F, M> {\n if (this.state.mode === \"sync\") {\n const current = this.state.result;\n if (isErr(current)) {\n return new Railway({ mode: \"sync\", result: err(current.error) });\n }\n const next = fn(current.value);\n if (isErr(next)) {\n return new Railway({ mode: \"sync\", result: err(next.error) });\n }\n return new Railway({\n mode: \"sync\",\n result: ok(addField(current.value, key, next.value)),\n });\n }\n\n return new Railway({\n mode: \"async\",\n result: this.state.result.flatMap((ctx) =>\n ResultAsync.fromResult(fn(ctx)).map((value) => addField(ctx, key, value)),\n ),\n }) as Railway<C & Record<K, T>, E | F, M>;\n }\n\n /**\n * Promise-returning step — upgrades the workflow to async mode. Reject\n * reasons go through `onReject` to become typed `Err<F>`.\n */\n fromPromise<K extends string, T, F>(\n key: K,\n fn: (ctx: C) => PromiseLike<T>,\n onReject: (error: unknown) => F,\n ): Railway<C & Record<K, T>, E | F, \"async\"> {\n return this.fromAsync(key, (ctx) => ResultAsync.fromPromise(fn(ctx), onReject));\n }\n\n /**\n * `ResultAsync`-returning step — upgrades the workflow to async mode.\n * Already-typed error: no mapper needed.\n */\n fromAsync<K extends string, T, F>(\n key: K,\n fn: (ctx: C) => ResultAsync<T, F>,\n ): Railway<C & Record<K, T>, E | F, \"async\"> {\n const current = this.state.mode === \"sync\" ? liftResult(this.state.result) : this.state.result;\n\n return new Railway({\n mode: \"async\",\n result: current.flatMap((ctx) => fn(ctx).map((value) => addField(ctx, key, value))),\n });\n }\n\n /**\n * Narrow a nullable context field into a required non-null field. If the\n * source field is `null` / `undefined`, the workflow short-circuits with\n * `onMissing(ctx)`.\n *\n * @example\n * ```ts\n * .fromPromise(\"row\", ({ id }) => db.users.findFirst({ where: eq(users.id, id) }))\n * .require(\"user\", \"row\", ({ id }) => ({ kind: \"not_found\" as const, id }))\n * // user is now User (non-null), not User | null\n * ```\n */\n require<K extends string, S extends keyof C, F>(\n key: K,\n source: S,\n onMissing: (ctx: C) => F,\n ): Railway<C & Record<K, NonNullable<C[S]>>, E | F, M> {\n return this.fromResult(key, (ctx) => {\n const value = ctx[source];\n return value == null ? err(onMissing(ctx)) : ok(value as NonNullable<C[S]>);\n });\n }\n\n /**\n * Run independent `ResultAsync` branches concurrently and merge their\n * named outputs back into context. Upgrades the workflow to async mode.\n * On multiple failures, the first `Err` in record-iteration order wins.\n *\n * @example\n * ```ts\n * .parallel({\n * recent: ({ userId }) => loadRecent(userId),\n * metrics: ({ userId }) => loadMetrics(userId),\n * })\n * // ctx now has { ..., recent, metrics }\n * ```\n */\n parallel<R extends Record<string, BranchFn<C>>>(\n branches: R,\n ): Railway<C & ParallelOutput<R>, E | ParallelError<R>, \"async\"> {\n const current = this.state.mode === \"sync\" ? liftResult(this.state.result) : this.state.result;\n\n return new Railway({\n mode: \"async\",\n result: current.flatMap((ctx) =>\n ResultAsync.combineTupleParallel(\n Object.entries(branches).map(([, branch]) => branch(ctx)),\n ).map((values) => {\n const next = { ...ctx } as C & ParallelOutput<R>;\n Object.keys(branches).forEach((key, index) => {\n (next as Record<string, unknown>)[key] = values[index];\n });\n return next;\n }),\n ),\n }) as Railway<C & ParallelOutput<R>, E | ParallelError<R>, \"async\">;\n }\n\n /**\n * Project the final context into the workflow's output type. Hides the\n * internal context shape from callers.\n */\n select<T>(fn: (ctx: C) => T): RailwayOutput<T, E, M> {\n if (this.state.mode === \"sync\") {\n const current = this.state.result;\n return (isErr(current) ? err(current.error) : ok(fn(current.value))) as RailwayOutput<\n T,\n E,\n M\n >;\n }\n\n return this.state.result.map(fn) as RailwayOutput<T, E, M>;\n }\n\n /**\n * Return the accumulated context as-is. Use when downstream code needs\n * every named field; prefer {@link select} when you can project to a DTO.\n */\n done(): RailwayOutput<C, E, M> {\n return this.state.result as RailwayOutput<C, E, M>;\n }\n}\n","import type { ResultAsync } from \"./async.js\";\nimport type {\n BranchFn,\n BranchRecord,\n ParallelError,\n ParallelInput,\n ParallelOutput,\n RailwayInput,\n RailwayMode,\n RailwayOutput,\n} from \"./railway-core.js\";\nimport { Railway } from \"./railway-core.js\";\nimport type { Result } from \"./types.js\";\n\ntype ParserLike<I, T> = { readonly parse: (input: I) => T } | ((input: I) => T);\ntype UnaryStep<I, O> = (input: I) => O;\n\nconst parseWithParser = <I, T>(parser: ParserLike<I, T>, input: I): T =>\n typeof parser === \"function\" ? parser(input) : parser.parse(input);\n\n/**\n * Functional companion to {@link Railway} — point-free composition of\n * reusable workflow steps. Starts from `Railway.context({ input })` and\n * applies each step in order. Step factories live below: {@link parseWith},\n * {@link fromSyncNamed}, {@link fromResultNamed}, {@link fromPromiseNamed},\n * {@link fromAsyncNamed}, {@link deriveNamed}, {@link requireNamed},\n * {@link parallelNamed}, {@link select}.\n *\n * @example\n * ```ts\n * const summary = railway(\n * rawId,\n * parseWith(IdSchema, toError).as(\"id\"),\n * fromPromiseNamed(\"row\", ({ id }) => db.profiles.findFirst({ where: eq(profiles.id, id) }), toError),\n * requireNamed(\"profile\", \"row\", ({ id }) => ({ kind: \"not_found\" as const, id })),\n * deriveNamed(\"normalized\", ({ profile }) => normalizeProfile(profile)),\n * select(({ normalized }) => toProfileSummary(normalized)),\n * );\n * ```\n */\nexport function railway<I, A>(\n input: I,\n step1: UnaryStep<Railway<RailwayInput<I>, never, \"sync\">, A>,\n): A;\nexport function railway<I, A, B>(\n input: I,\n step1: UnaryStep<Railway<RailwayInput<I>, never, \"sync\">, A>,\n step2: UnaryStep<A, B>,\n): B;\nexport function railway<I, A, B, C>(\n input: I,\n step1: UnaryStep<Railway<RailwayInput<I>, never, \"sync\">, A>,\n step2: UnaryStep<A, B>,\n step3: UnaryStep<B, C>,\n): C;\nexport function railway<I, A, B, C, D>(\n input: I,\n step1: UnaryStep<Railway<RailwayInput<I>, never, \"sync\">, A>,\n step2: UnaryStep<A, B>,\n step3: UnaryStep<B, C>,\n step4: UnaryStep<C, D>,\n): D;\nexport function railway<I, A, B, C, D, E>(\n input: I,\n step1: UnaryStep<Railway<RailwayInput<I>, never, \"sync\">, A>,\n step2: UnaryStep<A, B>,\n step3: UnaryStep<B, C>,\n step4: UnaryStep<C, D>,\n step5: UnaryStep<D, E>,\n): E;\nexport function railway<I, A, B, C, D, E, F>(\n input: I,\n step1: UnaryStep<Railway<RailwayInput<I>, never, \"sync\">, A>,\n step2: UnaryStep<A, B>,\n step3: UnaryStep<B, C>,\n step4: UnaryStep<C, D>,\n step5: UnaryStep<D, E>,\n step6: UnaryStep<E, F>,\n): F;\nexport function railway<I, A, B, C, D, E, F, G>(\n input: I,\n step1: UnaryStep<Railway<RailwayInput<I>, never, \"sync\">, A>,\n step2: UnaryStep<A, B>,\n step3: UnaryStep<B, C>,\n step4: UnaryStep<C, D>,\n step5: UnaryStep<D, E>,\n step6: UnaryStep<E, F>,\n step7: UnaryStep<F, G>,\n): G;\nexport function railway<I, A, B, C, D, E, F, G, H>(\n input: I,\n step1: UnaryStep<Railway<RailwayInput<I>, never, \"sync\">, A>,\n step2: UnaryStep<A, B>,\n step3: UnaryStep<B, C>,\n step4: UnaryStep<C, D>,\n step5: UnaryStep<D, E>,\n step6: UnaryStep<E, F>,\n step7: UnaryStep<F, G>,\n step8: UnaryStep<G, H>,\n): H;\nexport function railway<I>(input: I, ...steps: readonly ((input: never) => unknown)[]): unknown {\n return steps.reduce<unknown>(\n (current, step) => (step as (input: unknown) => unknown)(current),\n Railway.context({ input }),\n );\n}\n\n/**\n * Step factory: parse the workflow input with a Zod-like schema (or a\n * unary parse function). Call `.as(key)` to name the output field.\n *\n * @example\n * ```ts\n * parseWith(IdSchema, toError).as(\"id\");\n * // Used as the first step in `railway(rawId, parseId, ...)`\n * ```\n */\nexport const parseWith = <I, T, E>(parser: ParserLike<I, T>, onThrow: (error: unknown) => E) => ({\n as:\n <K extends string>(key: K) =>\n <F, M extends RailwayMode>(\n workflow: Railway<RailwayInput<I>, F, M>,\n ): Railway<RailwayInput<I> & Record<K, T>, F | E, M> =>\n workflow.fromSync(key, ({ input }) => parseWithParser(parser, input), onThrow),\n});\n\n/**\n * Reusable wrapper around {@link Railway.fromSync}. Captures key + fn +\n * onThrow once; applies to any compatible workflow.\n */\nexport const fromSyncNamed =\n <K extends string, C extends object, T, E>(\n key: K,\n fn: (ctx: C) => T,\n onThrow: (error: unknown) => E,\n ) =>\n <I extends C, F, M extends RailwayMode>(\n workflow: Railway<I, F, M>,\n ): Railway<I & Record<K, T>, F | E, M> =>\n workflow.fromSync(key, fn, onThrow);\n\n/** Reusable wrapper around {@link Railway.fromResult}. */\nexport const fromResultNamed =\n <K extends string, C extends object, T, E>(key: K, fn: (ctx: C) => Result<T, E>) =>\n <I extends C, F, M extends RailwayMode>(\n workflow: Railway<I, F, M>,\n ): Railway<I & Record<K, T>, F | E, M> =>\n workflow.fromResult(key, fn);\n\n/**\n * Reusable wrapper around {@link Railway.fromPromise}. Upgrades the\n * workflow to async mode when applied.\n */\nexport const fromPromiseNamed =\n <K extends string, C extends object, T, E>(\n key: K,\n fn: (ctx: C) => PromiseLike<T>,\n onReject: (error: unknown) => E,\n ) =>\n <I extends C, F, M extends RailwayMode>(\n workflow: Railway<I, F, M>,\n ): Railway<I & Record<K, T>, F | E, \"async\"> =>\n workflow.fromPromise(key, fn, onReject);\n\n/** Reusable wrapper around {@link Railway.fromAsync}. */\nexport const fromAsyncNamed =\n <K extends string, C extends object, T, E>(key: K, fn: (ctx: C) => ResultAsync<T, E>) =>\n <I extends C, F, M extends RailwayMode>(\n workflow: Railway<I, F, M>,\n ): Railway<I & Record<K, T>, F | E, \"async\"> =>\n workflow.fromAsync(key, fn);\n\n/** Reusable wrapper around {@link Railway.derive} — pure sync derivation. */\nexport const deriveNamed =\n <K extends string, C extends object, T>(key: K, fn: (ctx: C) => T) =>\n <I extends C, E, M extends RailwayMode>(\n workflow: Railway<I, E, M>,\n ): Railway<I & Record<K, T>, E, M> =>\n workflow.derive(key, fn);\n\n/** Reusable wrapper around {@link Railway.require} — narrows a nullable field. */\nexport const requireNamed =\n <K extends string, S extends string, C extends object, E>(\n key: K,\n source: S,\n onMissing: (ctx: C & Record<S, unknown>) => E,\n ) =>\n <I extends C & Record<S, unknown>, F, M extends RailwayMode>(\n workflow: Railway<I, F, M>,\n ): Railway<I & Record<K, NonNullable<I[S]>>, F | E, M> =>\n workflow.require(key, source, onMissing);\n\n/**\n * Reusable wrapper around {@link Railway.parallel}. Branches run\n * concurrently and merge their named outputs back into context.\n */\nexport const parallelNamed =\n <R extends BranchRecord>(branches: R) =>\n <I extends ParallelInput<R>, E, M extends RailwayMode>(\n workflow: Railway<I, E, M>,\n ): Railway<I & ParallelOutput<R>, E | ParallelError<R>, \"async\"> => {\n // TS cannot prove contravariant branch params after storing reusable steps.\n const typedBranches = branches as unknown as Record<string, BranchFn<I>>;\n return workflow.parallel(typedBranches) as unknown as Railway<\n I & ParallelOutput<R>,\n E | ParallelError<R>,\n \"async\"\n >;\n };\n\n/**\n * Reusable wrapper around {@link Railway.select} — projects the final\n * context into the workflow's output type.\n */\nexport const select =\n <C extends object, T>(fn: (ctx: C) => T) =>\n <E, M extends RailwayMode>(workflow: Railway<C, E, M>): RailwayOutput<T, E, M> =>\n workflow.select(fn);\n"]}
|
package/dist/railway.d.cts
CHANGED
|
@@ -12,7 +12,7 @@ type RailwayMode = "sync" | "async";
|
|
|
12
12
|
*/
|
|
13
13
|
type RailwayOutput<T, E, M extends RailwayMode> = M extends "async" ? ResultAsync<T, E> : Result<T, E>;
|
|
14
14
|
/**
|
|
15
|
-
* Initial context shape for a
|
|
15
|
+
* Initial context shape for a `railway` functional pipeline.
|
|
16
16
|
* Wraps the raw input under the `input` key so subsequent named steps
|
|
17
17
|
* can reference it via `ctx.input`.
|
|
18
18
|
*/
|
|
@@ -29,10 +29,6 @@ type ParallelOutput<R extends BranchRecord> = {
|
|
|
29
29
|
[K in keyof R]: BranchOk<R[K]>;
|
|
30
30
|
};
|
|
31
31
|
type ParallelError<R extends BranchRecord> = BranchErr<R[keyof R]>;
|
|
32
|
-
type ParserLike<I, T> = {
|
|
33
|
-
readonly parse: (input: I) => T;
|
|
34
|
-
} | ((input: I) => T);
|
|
35
|
-
type UnaryStep<I, O> = (input: I) => O;
|
|
36
32
|
/**
|
|
37
33
|
* Named-context workflow builder. Each step appends a typed field to the
|
|
38
34
|
* accumulating context object; the workflow tracks sync/async mode so the
|
|
@@ -141,6 +137,11 @@ declare class Railway<C extends object, E, M extends RailwayMode> {
|
|
|
141
137
|
*/
|
|
142
138
|
done(): RailwayOutput<C, E, M>;
|
|
143
139
|
}
|
|
140
|
+
|
|
141
|
+
type ParserLike<I, T> = {
|
|
142
|
+
readonly parse: (input: I) => T;
|
|
143
|
+
} | ((input: I) => T);
|
|
144
|
+
type UnaryStep<I, O> = (input: I) => O;
|
|
144
145
|
/**
|
|
145
146
|
* Functional companion to {@link Railway} — point-free composition of
|
|
146
147
|
* reusable workflow steps. Starts from `Railway.context({ input })` and
|
package/dist/railway.d.ts
CHANGED
|
@@ -12,7 +12,7 @@ type RailwayMode = "sync" | "async";
|
|
|
12
12
|
*/
|
|
13
13
|
type RailwayOutput<T, E, M extends RailwayMode> = M extends "async" ? ResultAsync<T, E> : Result<T, E>;
|
|
14
14
|
/**
|
|
15
|
-
* Initial context shape for a
|
|
15
|
+
* Initial context shape for a `railway` functional pipeline.
|
|
16
16
|
* Wraps the raw input under the `input` key so subsequent named steps
|
|
17
17
|
* can reference it via `ctx.input`.
|
|
18
18
|
*/
|
|
@@ -29,10 +29,6 @@ type ParallelOutput<R extends BranchRecord> = {
|
|
|
29
29
|
[K in keyof R]: BranchOk<R[K]>;
|
|
30
30
|
};
|
|
31
31
|
type ParallelError<R extends BranchRecord> = BranchErr<R[keyof R]>;
|
|
32
|
-
type ParserLike<I, T> = {
|
|
33
|
-
readonly parse: (input: I) => T;
|
|
34
|
-
} | ((input: I) => T);
|
|
35
|
-
type UnaryStep<I, O> = (input: I) => O;
|
|
36
32
|
/**
|
|
37
33
|
* Named-context workflow builder. Each step appends a typed field to the
|
|
38
34
|
* accumulating context object; the workflow tracks sync/async mode so the
|
|
@@ -141,6 +137,11 @@ declare class Railway<C extends object, E, M extends RailwayMode> {
|
|
|
141
137
|
*/
|
|
142
138
|
done(): RailwayOutput<C, E, M>;
|
|
143
139
|
}
|
|
140
|
+
|
|
141
|
+
type ParserLike<I, T> = {
|
|
142
|
+
readonly parse: (input: I) => T;
|
|
143
|
+
} | ((input: I) => T);
|
|
144
|
+
type UnaryStep<I, O> = (input: I) => O;
|
|
144
145
|
/**
|
|
145
146
|
* Functional companion to {@link Railway} — point-free composition of
|
|
146
147
|
* reusable workflow steps. Starts from `Railway.context({ input })` and
|