@systemfsoftware/effect-atom 0.5.3
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/LICENSE +231 -0
- package/README.md +30 -0
- package/dist/Atom-BgqgP-Qc.d.ts +1287 -0
- package/dist/Atom-BhgqoTsf.mjs +1348 -0
- package/dist/Atom-CxKJ3i4d.d.ts +1257 -0
- package/dist/Atom-DGWqaX9a.d.ts +1257 -0
- package/dist/Atom-DVWTGeoV.mjs +1449 -0
- package/dist/Atom-NsW01Gu1.mjs +1348 -0
- package/dist/Atom.d.ts +2 -0
- package/dist/Atom.mjs +2 -0
- package/dist/AtomHttpApi.d.ts +74 -0
- package/dist/AtomHttpApi.mjs +129 -0
- package/dist/AtomRef.d.ts +91 -0
- package/dist/AtomRef.mjs +248 -0
- package/dist/AtomRpc.d.ts +73 -0
- package/dist/AtomRpc.mjs +111 -0
- package/dist/Hydration.d.ts +75 -0
- package/dist/Hydration.mjs +113 -0
- package/dist/Registry-B1ULaW2_.mjs +769 -0
- package/dist/Registry-BE4aKSZk.mjs +823 -0
- package/dist/Registry-DhP1TSer.mjs +769 -0
- package/dist/Registry.d.ts +2 -0
- package/dist/Registry.mjs +2 -0
- package/dist/Result-B2vSp_sE.d.ts +480 -0
- package/dist/Result-BHH-qTvm.d.ts +491 -0
- package/dist/Result-CAjFdzam.d.ts +490 -0
- package/dist/Result-D8FNEzuX.mjs +633 -0
- package/dist/Result-DwtHFH70.mjs +663 -0
- package/dist/Result-rlUvoHzK.mjs +624 -0
- package/dist/Result.d.ts +2 -0
- package/dist/Result.mjs +2 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.mjs +8 -0
- package/dist/rolldown-runtime-D7D4PA-g.mjs +13 -0
- package/package.json +94 -0
|
@@ -0,0 +1,633 @@
|
|
|
1
|
+
import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.mjs";
|
|
2
|
+
import * as Cause from "effect/Cause";
|
|
3
|
+
import * as Effect from "effect/Effect";
|
|
4
|
+
import * as Exit from "effect/Exit";
|
|
5
|
+
import { constTrue, dual, identity } from "effect/Function";
|
|
6
|
+
import * as Option from "effect/Option";
|
|
7
|
+
import * as Schema_ from "effect/Schema";
|
|
8
|
+
import { pipeArguments } from "effect/Pipeable";
|
|
9
|
+
import { hasProperty, isIterable } from "effect/Predicate";
|
|
10
|
+
import * as Equal$1 from "effect/Equal";
|
|
11
|
+
import * as Hash from "effect/Hash";
|
|
12
|
+
import * as Either from "effect/Result";
|
|
13
|
+
import * as SchemaIssue from "effect/SchemaIssue";
|
|
14
|
+
import * as SchemaParser from "effect/SchemaParser";
|
|
15
|
+
import * as SchemaTransformation from "effect/SchemaTransformation";
|
|
16
|
+
//#region src/internal/result-schema.ts
|
|
17
|
+
/**
|
|
18
|
+
* Creates a schema for `Result` values using optional schemas for success values and failure errors.
|
|
19
|
+
*
|
|
20
|
+
* @category schemas
|
|
21
|
+
* @since 4.0.0
|
|
22
|
+
*/
|
|
23
|
+
const Schema = (options) => {
|
|
24
|
+
const success_ = options.success ?? Schema_.Never;
|
|
25
|
+
const error = options.error ?? Schema_.Never;
|
|
26
|
+
const schema = Schema_.declareConstructor()([success_, Schema_.Cause(error, Schema_.Defect())], ([value, cause]) => (input, ast, options) => {
|
|
27
|
+
if (!isResult(input)) return Effect.fail(new SchemaIssue.InvalidType(ast, input, options));
|
|
28
|
+
switch (input._tag) {
|
|
29
|
+
case "Initial": return Effect.succeed(input);
|
|
30
|
+
case "Success": return Effect.mapBothEager(SchemaParser.decodeUnknownEffect(value)(input.value, options), {
|
|
31
|
+
onSuccess: (value) => success(value, input),
|
|
32
|
+
onFailure: (issue) => new SchemaIssue.Composite(ast, [new SchemaIssue.Pointer(["value"], issue)], input, options)
|
|
33
|
+
});
|
|
34
|
+
case "Failure": {
|
|
35
|
+
const prevSuccessEffect = input.previousSuccess.pipe(Option.map((ps) => Effect.mapBothEager(SchemaParser.decodeUnknownEffect(value)(ps.value, options), {
|
|
36
|
+
onSuccess: (value) => Option.some(success(value, ps)),
|
|
37
|
+
onFailure: (issue) => new SchemaIssue.Composite(ast, [new SchemaIssue.Pointer(["previousSuccess", "value"], issue)], input, options)
|
|
38
|
+
})), Option.getOrElse(() => Effect.succeedNone));
|
|
39
|
+
const causeEffect = Effect.mapErrorEager(SchemaParser.decodeUnknownEffect(cause)(input.cause, options), (issue) => new SchemaIssue.Composite(ast, [new SchemaIssue.Pointer(["cause"], issue)], input, options));
|
|
40
|
+
return Effect.flatMapEager(prevSuccessEffect, (previousSuccess) => Effect.mapEager(causeEffect, (cause) => failure(cause, {
|
|
41
|
+
previousSuccess,
|
|
42
|
+
waiting: input.waiting
|
|
43
|
+
})));
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}, {
|
|
47
|
+
expected: "Result",
|
|
48
|
+
toCodec([value, cause]) {
|
|
49
|
+
const Success = Schema_.TaggedStruct("Success", {
|
|
50
|
+
value,
|
|
51
|
+
waiting: Schema_.Boolean,
|
|
52
|
+
timestamp: Schema_.Number
|
|
53
|
+
});
|
|
54
|
+
return Schema_.link()(Schema_.Union([
|
|
55
|
+
Schema_.TaggedStruct("Initial", { waiting: Schema_.Boolean }),
|
|
56
|
+
Success,
|
|
57
|
+
Schema_.TaggedStruct("Failure", {
|
|
58
|
+
cause,
|
|
59
|
+
previousSuccess: Schema_.Option(Success),
|
|
60
|
+
waiting: Schema_.Boolean
|
|
61
|
+
})
|
|
62
|
+
]), SchemaTransformation.transform({
|
|
63
|
+
decode: (encoded) => {
|
|
64
|
+
switch (encoded._tag) {
|
|
65
|
+
case "Initial": return initial(encoded.waiting);
|
|
66
|
+
case "Success": return success(encoded.value, {
|
|
67
|
+
waiting: encoded.waiting,
|
|
68
|
+
timestamp: encoded.timestamp
|
|
69
|
+
});
|
|
70
|
+
case "Failure": return failure(encoded.cause, {
|
|
71
|
+
previousSuccess: Option.map(encoded.previousSuccess, (ps) => success(ps.value, ps)),
|
|
72
|
+
waiting: encoded.waiting
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
},
|
|
76
|
+
encode(result) {
|
|
77
|
+
switch (result._tag) {
|
|
78
|
+
case "Initial": return {
|
|
79
|
+
_tag: "Initial",
|
|
80
|
+
waiting: result.waiting
|
|
81
|
+
};
|
|
82
|
+
case "Success": return {
|
|
83
|
+
_tag: "Success",
|
|
84
|
+
value: result.value,
|
|
85
|
+
waiting: result.waiting,
|
|
86
|
+
timestamp: result.timestamp
|
|
87
|
+
};
|
|
88
|
+
case "Failure": return {
|
|
89
|
+
_tag: "Failure",
|
|
90
|
+
cause: result.cause,
|
|
91
|
+
previousSuccess: result.previousSuccess,
|
|
92
|
+
waiting: result.waiting
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}));
|
|
97
|
+
},
|
|
98
|
+
toEquivalence: Equal$1.asEquivalence,
|
|
99
|
+
toArbitrary: ([value]) => (fc) => fc.oneof(fc.record({
|
|
100
|
+
value: value.arbitrary,
|
|
101
|
+
waiting: fc.boolean(),
|
|
102
|
+
timestamp: fc.nat()
|
|
103
|
+
}).map((r) => success(r.value, {
|
|
104
|
+
waiting: r.waiting,
|
|
105
|
+
timestamp: r.timestamp
|
|
106
|
+
})), fc.record({
|
|
107
|
+
cause: fc.oneof(Schema_.toArbitrary(error)(fc).map((e) => Cause.fail(e)), fc.jsonValue().map((d) => Cause.die(d))),
|
|
108
|
+
waiting: fc.boolean(),
|
|
109
|
+
previous: fc.option(value.arbitrary, { nil: void 0 })
|
|
110
|
+
}).map((r) => failure(r.cause, {
|
|
111
|
+
previousSuccess: r.previous === void 0 ? Option.none() : Option.some(success(r.previous)),
|
|
112
|
+
waiting: r.waiting
|
|
113
|
+
})), fc.boolean().map((waiting) => initial(waiting))),
|
|
114
|
+
toFormatter: ([value, cause]) => (t) => {
|
|
115
|
+
switch (t._tag) {
|
|
116
|
+
case "Success": return `Result.Success(${value(t.value)}, ${t.waiting}, ${t.timestamp})`;
|
|
117
|
+
case "Failure": return `Result.Failure(${cause(t.cause)}, ${t.waiting})`;
|
|
118
|
+
case "Initial": return `Result.Initial(${t.waiting})`;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
});
|
|
122
|
+
return Object.assign(schema, {
|
|
123
|
+
success: success_,
|
|
124
|
+
error
|
|
125
|
+
});
|
|
126
|
+
};
|
|
127
|
+
/**
|
|
128
|
+
* A `Schema.ConstraintCodec` for `Result<unknown, unknown>` built from the
|
|
129
|
+
* given success and error schemas.
|
|
130
|
+
*
|
|
131
|
+
* @internal
|
|
132
|
+
*/
|
|
133
|
+
const schemaCodec = (success, error) => Schema({
|
|
134
|
+
success,
|
|
135
|
+
error
|
|
136
|
+
});
|
|
137
|
+
//#endregion
|
|
138
|
+
//#region src/Result.ts
|
|
139
|
+
/**
|
|
140
|
+
* Represents observable state for asynchronous values.
|
|
141
|
+
*
|
|
142
|
+
* `Result<A, E>` records whether asynchronous work has no value yet,
|
|
143
|
+
* succeeded with an `A`, or failed with an `E`. Every state also carries a
|
|
144
|
+
* `waiting` flag, so callers can keep showing the current value while newer
|
|
145
|
+
* work is loading, refreshing, retrying, or recovering. This module includes
|
|
146
|
+
* constructors, checks, accessors, mapping and matching helpers, ways to combine
|
|
147
|
+
* several results, and schemas for encoding or decoding results.
|
|
148
|
+
*
|
|
149
|
+
* @since 4.0.0
|
|
150
|
+
*/
|
|
151
|
+
var Result_exports = /* @__PURE__ */ __exportAll({
|
|
152
|
+
Schema: () => Schema,
|
|
153
|
+
TypeId: () => TypeId,
|
|
154
|
+
all: () => all,
|
|
155
|
+
builder: () => builder,
|
|
156
|
+
cause: () => cause,
|
|
157
|
+
error: () => error,
|
|
158
|
+
fail: () => fail,
|
|
159
|
+
failWithPrevious: () => failWithPrevious,
|
|
160
|
+
failure: () => failure,
|
|
161
|
+
failureWithPrevious: () => failureWithPrevious,
|
|
162
|
+
flatMap: () => flatMap,
|
|
163
|
+
fromExit: () => fromExit,
|
|
164
|
+
fromExitWithPrevious: () => fromExitWithPrevious,
|
|
165
|
+
getOrElse: () => getOrElse,
|
|
166
|
+
getOrThrow: () => getOrThrow,
|
|
167
|
+
initial: () => initial,
|
|
168
|
+
isAsyncResult: () => isResult,
|
|
169
|
+
isFailure: () => isFailure,
|
|
170
|
+
isInitial: () => isInitial,
|
|
171
|
+
isInterrupted: () => isInterrupted,
|
|
172
|
+
isNotInitial: () => isNotInitial,
|
|
173
|
+
isResult: () => isResult,
|
|
174
|
+
isSuccess: () => isSuccess,
|
|
175
|
+
isWaiting: () => isWaiting,
|
|
176
|
+
map: () => map,
|
|
177
|
+
match: () => match,
|
|
178
|
+
matchWithError: () => matchWithError,
|
|
179
|
+
matchWithWaiting: () => matchWithWaiting,
|
|
180
|
+
replacePrevious: () => replacePrevious,
|
|
181
|
+
success: () => success,
|
|
182
|
+
toExit: () => toExit,
|
|
183
|
+
touch: () => touch,
|
|
184
|
+
value: () => value,
|
|
185
|
+
waiting: () => waiting,
|
|
186
|
+
waitingFrom: () => waitingFrom
|
|
187
|
+
});
|
|
188
|
+
/**
|
|
189
|
+
* Runtime identifier attached to `Result` values and used by `isResult`.
|
|
190
|
+
*
|
|
191
|
+
* @category type IDs
|
|
192
|
+
* @since 4.0.0
|
|
193
|
+
*/
|
|
194
|
+
const TypeId = "~effect-atom/atom/Result";
|
|
195
|
+
/**
|
|
196
|
+
* Returns `true` when a value is an `Result`.
|
|
197
|
+
*
|
|
198
|
+
* @category guards
|
|
199
|
+
* @since 4.0.0
|
|
200
|
+
*/
|
|
201
|
+
const isResult = (u) => hasProperty(u, TypeId);
|
|
202
|
+
const ResultProto = {
|
|
203
|
+
[TypeId]: {
|
|
204
|
+
E: identity,
|
|
205
|
+
A: identity
|
|
206
|
+
},
|
|
207
|
+
pipe() {
|
|
208
|
+
return pipeArguments(this, arguments);
|
|
209
|
+
},
|
|
210
|
+
[Equal$1.symbol](that) {
|
|
211
|
+
if (this._tag !== that._tag || this.waiting !== that.waiting) return false;
|
|
212
|
+
switch (this._tag) {
|
|
213
|
+
case "Initial": return true;
|
|
214
|
+
case "Success": return Equal$1.equals(this.value, that.value);
|
|
215
|
+
case "Failure": return Equal$1.equals(this.cause, that.cause);
|
|
216
|
+
}
|
|
217
|
+
},
|
|
218
|
+
[Hash.symbol]() {
|
|
219
|
+
const tagHash = Hash.string(`${this._tag}:${this.waiting}`);
|
|
220
|
+
if (this._tag === "Initial") return tagHash;
|
|
221
|
+
return Hash.combine(tagHash)(this._tag === "Success" ? Hash.hash(this.value) : Hash.hash(this.cause));
|
|
222
|
+
}
|
|
223
|
+
};
|
|
224
|
+
/**
|
|
225
|
+
* Returns whether an `Result` is currently waiting for an asynchronous computation or refresh to finish.
|
|
226
|
+
*
|
|
227
|
+
* @category predicates
|
|
228
|
+
* @since 4.0.0
|
|
229
|
+
*/
|
|
230
|
+
const isWaiting = (result) => result.waiting;
|
|
231
|
+
/**
|
|
232
|
+
* Converts an `Exit` into a `Success` when it succeeds or a `Failure` carrying the exit cause when it fails.
|
|
233
|
+
*
|
|
234
|
+
* @category constructors
|
|
235
|
+
* @since 4.0.0
|
|
236
|
+
*/
|
|
237
|
+
const fromExit = (exit) => exit._tag === "Success" ? success(exit.value) : failure(exit.cause);
|
|
238
|
+
/**
|
|
239
|
+
* Converts an `Exit` to a result, preserving the latest previous success when the exit is a failure.
|
|
240
|
+
*
|
|
241
|
+
* @category constructors
|
|
242
|
+
* @since 4.0.0
|
|
243
|
+
*/
|
|
244
|
+
const fromExitWithPrevious = (exit, previous) => exit._tag === "Success" ? success(exit.value) : failureWithPrevious(exit.cause, { previous });
|
|
245
|
+
/**
|
|
246
|
+
* Creates a waiting result from an optional previous result, using `Initial(true)` when no previous result exists.
|
|
247
|
+
*
|
|
248
|
+
* @category constructors
|
|
249
|
+
* @since 4.0.0
|
|
250
|
+
*/
|
|
251
|
+
const waitingFrom = (previous) => {
|
|
252
|
+
if (previous._tag === "None") return initial(true);
|
|
253
|
+
return waiting(previous.value);
|
|
254
|
+
};
|
|
255
|
+
/**
|
|
256
|
+
* Returns `true` when an `Result` is in the `Initial` state.
|
|
257
|
+
*
|
|
258
|
+
* @category guards
|
|
259
|
+
* @since 4.0.0
|
|
260
|
+
*/
|
|
261
|
+
const isInitial = (result) => result._tag === "Initial";
|
|
262
|
+
/**
|
|
263
|
+
* Returns `true` when an `Result` is either `Success` or `Failure`.
|
|
264
|
+
*
|
|
265
|
+
* @category guards
|
|
266
|
+
* @since 4.0.0
|
|
267
|
+
*/
|
|
268
|
+
const isNotInitial = (result) => result._tag !== "Initial";
|
|
269
|
+
/**
|
|
270
|
+
* Creates an `Initial` result, optionally marking it as waiting.
|
|
271
|
+
*
|
|
272
|
+
* @category constructors
|
|
273
|
+
* @since 4.0.0
|
|
274
|
+
*/
|
|
275
|
+
const initial = (waiting = false) => {
|
|
276
|
+
const result = Object.create(ResultProto);
|
|
277
|
+
result._tag = "Initial";
|
|
278
|
+
result.waiting = waiting;
|
|
279
|
+
return result;
|
|
280
|
+
};
|
|
281
|
+
/**
|
|
282
|
+
* Returns `true` when an `Result` is a `Success`.
|
|
283
|
+
*
|
|
284
|
+
* @category guards
|
|
285
|
+
* @since 4.0.0
|
|
286
|
+
*/
|
|
287
|
+
const isSuccess = (result) => result._tag === "Success";
|
|
288
|
+
/**
|
|
289
|
+
* Creates a `Success` result with a value and optional `waiting` flag or timestamp override.
|
|
290
|
+
*
|
|
291
|
+
* @category constructors
|
|
292
|
+
* @since 4.0.0
|
|
293
|
+
*/
|
|
294
|
+
const success = (value, options) => {
|
|
295
|
+
const result = Object.create(ResultProto);
|
|
296
|
+
result._tag = "Success";
|
|
297
|
+
result.value = value;
|
|
298
|
+
result.waiting = options?.waiting ?? false;
|
|
299
|
+
result.timestamp = options?.timestamp ?? Date.now();
|
|
300
|
+
return result;
|
|
301
|
+
};
|
|
302
|
+
/**
|
|
303
|
+
* Returns `true` when an `Result` is a `Failure`.
|
|
304
|
+
*
|
|
305
|
+
* @category guards
|
|
306
|
+
* @since 4.0.0
|
|
307
|
+
*/
|
|
308
|
+
const isFailure = (result) => result._tag === "Failure";
|
|
309
|
+
/**
|
|
310
|
+
* Returns `true` when an `Result` is a `Failure` whose cause contains only interruptions.
|
|
311
|
+
*
|
|
312
|
+
* @category guards
|
|
313
|
+
* @since 4.0.0
|
|
314
|
+
*/
|
|
315
|
+
const isInterrupted = (result) => result._tag === "Failure" && Cause.hasInterruptsOnly(result.cause);
|
|
316
|
+
/**
|
|
317
|
+
* Creates a `Failure` result from a `Cause`, optionally preserving a previous success and marking the result as waiting.
|
|
318
|
+
*
|
|
319
|
+
* @category constructors
|
|
320
|
+
* @since 4.0.0
|
|
321
|
+
*/
|
|
322
|
+
const failure = (cause, options) => {
|
|
323
|
+
const result = Object.create(ResultProto);
|
|
324
|
+
result._tag = "Failure";
|
|
325
|
+
result.cause = cause;
|
|
326
|
+
result.previousSuccess = options?.previousSuccess ?? Option.none();
|
|
327
|
+
result.waiting = options?.waiting ?? false;
|
|
328
|
+
return result;
|
|
329
|
+
};
|
|
330
|
+
/**
|
|
331
|
+
* Creates a `Failure` result from a `Cause`, carrying forward the latest success stored in a previous result.
|
|
332
|
+
*
|
|
333
|
+
* @category constructors
|
|
334
|
+
* @since 4.0.0
|
|
335
|
+
*/
|
|
336
|
+
const failureWithPrevious = (cause, options) => failure(cause, {
|
|
337
|
+
previousSuccess: Option.flatMap(options.previous, (result) => isSuccess(result) ? Option.some(result) : isFailure(result) ? result.previousSuccess : Option.none()),
|
|
338
|
+
waiting: options.waiting
|
|
339
|
+
});
|
|
340
|
+
/**
|
|
341
|
+
* Creates a `Failure` result from a typed error, wrapping it in `Cause.fail`.
|
|
342
|
+
*
|
|
343
|
+
* @category constructors
|
|
344
|
+
* @since 4.0.0
|
|
345
|
+
*/
|
|
346
|
+
const fail = (error, options) => failure(Cause.fail(error), options);
|
|
347
|
+
/**
|
|
348
|
+
* Creates a `Failure` result from a typed error while carrying forward the latest success stored in a previous result.
|
|
349
|
+
*
|
|
350
|
+
* @category constructors
|
|
351
|
+
* @since 4.0.0
|
|
352
|
+
*/
|
|
353
|
+
const failWithPrevious = (error, options) => failureWithPrevious(Cause.fail(error), options);
|
|
354
|
+
/**
|
|
355
|
+
* Marks an `Result` as waiting, optionally touching the timestamp when the result is a `Success`.
|
|
356
|
+
*
|
|
357
|
+
* @category constructors
|
|
358
|
+
* @since 4.0.0
|
|
359
|
+
*/
|
|
360
|
+
const waiting = (self, options) => {
|
|
361
|
+
if (self.waiting) return options?.touch ? touch(self) : self;
|
|
362
|
+
const result = Object.assign(Object.create(ResultProto), self, { waiting: true });
|
|
363
|
+
return options?.touch ? touch(result) : result;
|
|
364
|
+
};
|
|
365
|
+
/**
|
|
366
|
+
* Refreshes the timestamp of a `Success` result while preserving its value and waiting flag; non-success results are returned unchanged.
|
|
367
|
+
*
|
|
368
|
+
* @category combinators
|
|
369
|
+
* @since 4.0.0
|
|
370
|
+
*/
|
|
371
|
+
const touch = (result) => {
|
|
372
|
+
if (isSuccess(result)) return success(result.value, { waiting: result.waiting });
|
|
373
|
+
return result;
|
|
374
|
+
};
|
|
375
|
+
/**
|
|
376
|
+
* Replaces a `Failure` value's stored previous success with the latest success
|
|
377
|
+
* found in another result.
|
|
378
|
+
*
|
|
379
|
+
* @category combinators
|
|
380
|
+
* @since 4.0.0
|
|
381
|
+
*/
|
|
382
|
+
const replacePrevious = (self, previous) => replacePreviousImpl(self, previous);
|
|
383
|
+
const replacePreviousImpl = (self, previous) => self._tag === "Failure" ? failureWithPrevious(self.cause, {
|
|
384
|
+
previous,
|
|
385
|
+
waiting: self.waiting
|
|
386
|
+
}) : self;
|
|
387
|
+
/**
|
|
388
|
+
* Returns the current success value, or the previous success value stored in a failure, as an `Option`.
|
|
389
|
+
*
|
|
390
|
+
* @category accessors
|
|
391
|
+
* @since 4.0.0
|
|
392
|
+
*/
|
|
393
|
+
const value = (self) => {
|
|
394
|
+
if (self._tag === "Success") return Option.some(self.value);
|
|
395
|
+
else if (self._tag === "Failure") return Option.map(self.previousSuccess, (s) => s.value);
|
|
396
|
+
return Option.none();
|
|
397
|
+
};
|
|
398
|
+
/**
|
|
399
|
+
* Returns the available value from `value`, or evaluates the fallback when no current or previous success exists.
|
|
400
|
+
*
|
|
401
|
+
* @category accessors
|
|
402
|
+
* @since 4.0.0
|
|
403
|
+
*/
|
|
404
|
+
const getOrElse = dual(2, (self, orElse) => Option.getOrElse(value(self), orElse));
|
|
405
|
+
/**
|
|
406
|
+
* Returns the available value from `value`, or throws `NoSuchElementError` when no current or previous success exists.
|
|
407
|
+
*
|
|
408
|
+
* @category accessors
|
|
409
|
+
* @since 4.0.0
|
|
410
|
+
*/
|
|
411
|
+
const getOrThrow = (self) => Option.getOrThrowWith(value(self), () => new Cause.NoSuchElementError("Result.getOrThrow: no value found"));
|
|
412
|
+
/**
|
|
413
|
+
* Returns the failure cause when the result is a `Failure`, otherwise `None`.
|
|
414
|
+
*
|
|
415
|
+
* @category accessors
|
|
416
|
+
* @since 4.0.0
|
|
417
|
+
*/
|
|
418
|
+
const cause = (self) => self._tag === "Failure" ? Option.some(self.cause) : Option.none();
|
|
419
|
+
/**
|
|
420
|
+
* Returns the first typed error from a failure cause, or `None` for successes, initial results, defects, and interrupt-only causes.
|
|
421
|
+
*
|
|
422
|
+
* @category accessors
|
|
423
|
+
* @since 4.0.0
|
|
424
|
+
*/
|
|
425
|
+
const error = (self) => self._tag === "Failure" ? Cause.findErrorOption(self.cause) : Option.none();
|
|
426
|
+
/**
|
|
427
|
+
* Converts a result to an `Exit`, succeeding with a success value, failing with a failure cause, or failing with `NoSuchElementError` for `Initial`.
|
|
428
|
+
*
|
|
429
|
+
* @category combinators
|
|
430
|
+
* @since 4.0.0
|
|
431
|
+
*/
|
|
432
|
+
const toExit = (self) => {
|
|
433
|
+
switch (self._tag) {
|
|
434
|
+
case "Success": return Exit.succeed(self.value);
|
|
435
|
+
case "Failure": return Exit.failCause(self.cause);
|
|
436
|
+
default: return Exit.fail(new Cause.NoSuchElementError());
|
|
437
|
+
}
|
|
438
|
+
};
|
|
439
|
+
/**
|
|
440
|
+
* Maps the success value of an `Result`, also mapping any previous success stored in a failure while leaving initial results unchanged.
|
|
441
|
+
*
|
|
442
|
+
* @category combinators
|
|
443
|
+
* @since 4.0.0
|
|
444
|
+
*/
|
|
445
|
+
const map = dual(2, (self, f) => {
|
|
446
|
+
switch (self._tag) {
|
|
447
|
+
case "Initial": return initial(self.waiting);
|
|
448
|
+
case "Failure": return failure(self.cause, {
|
|
449
|
+
previousSuccess: Option.map(self.previousSuccess, (s) => success(f(s.value), s)),
|
|
450
|
+
waiting: self.waiting
|
|
451
|
+
});
|
|
452
|
+
case "Success": return success(f(self.value), self);
|
|
453
|
+
}
|
|
454
|
+
});
|
|
455
|
+
/**
|
|
456
|
+
* Maps the success value of an `Result` and flattens the result.
|
|
457
|
+
*
|
|
458
|
+
* **When to use**
|
|
459
|
+
*
|
|
460
|
+
* Use to sequence computations that may return another `Result` while
|
|
461
|
+
* preserving initial and failure states.
|
|
462
|
+
*
|
|
463
|
+
* **Details**
|
|
464
|
+
*
|
|
465
|
+
* Initial results are left unchanged. Failures preserve their cause and remap
|
|
466
|
+
* the stored previous success when the mapping function returns a success.
|
|
467
|
+
*
|
|
468
|
+
* @category combinators
|
|
469
|
+
* @since 4.0.0
|
|
470
|
+
*/
|
|
471
|
+
const flatMap = dual(2, (self, f) => {
|
|
472
|
+
switch (self._tag) {
|
|
473
|
+
case "Initial": return initial(self.waiting);
|
|
474
|
+
case "Failure": return failure(self.cause, {
|
|
475
|
+
previousSuccess: Option.flatMap(self.previousSuccess, (s) => {
|
|
476
|
+
const next = f(s.value, s);
|
|
477
|
+
return isSuccess(next) ? Option.some(next) : Option.none();
|
|
478
|
+
}),
|
|
479
|
+
waiting: self.waiting
|
|
480
|
+
});
|
|
481
|
+
case "Success": return f(self.value, self);
|
|
482
|
+
}
|
|
483
|
+
});
|
|
484
|
+
/**
|
|
485
|
+
* Pattern matches an `Result` by calling the handler for `Initial`, `Failure`, or `Success`.
|
|
486
|
+
*
|
|
487
|
+
* @category combinators
|
|
488
|
+
* @since 4.0.0
|
|
489
|
+
*/
|
|
490
|
+
const match = dual(2, (self, options) => {
|
|
491
|
+
switch (self._tag) {
|
|
492
|
+
case "Initial": return options.onInitial(self);
|
|
493
|
+
case "Failure": return options.onFailure(self);
|
|
494
|
+
case "Success": return options.onSuccess(self);
|
|
495
|
+
}
|
|
496
|
+
});
|
|
497
|
+
/**
|
|
498
|
+
* Pattern matches a result, handling successes and initials directly while splitting failures into typed errors or squashed non-error causes passed to `onDefect`.
|
|
499
|
+
*
|
|
500
|
+
* @category combinators
|
|
501
|
+
* @since 4.0.0
|
|
502
|
+
*/
|
|
503
|
+
const matchWithError = dual(2, (self, options) => {
|
|
504
|
+
switch (self._tag) {
|
|
505
|
+
case "Initial": return options.onInitial(self);
|
|
506
|
+
case "Failure": {
|
|
507
|
+
const result = Cause.findError(self.cause);
|
|
508
|
+
if (Either.isFailure(result)) return options.onDefect(Cause.squash(result.failure), self);
|
|
509
|
+
return options.onError(result.success, self);
|
|
510
|
+
}
|
|
511
|
+
case "Success": return options.onSuccess(self);
|
|
512
|
+
}
|
|
513
|
+
});
|
|
514
|
+
/**
|
|
515
|
+
* Pattern matches a result by calling `onWaiting` for waiting or initial states, otherwise handling successes and splitting failures into typed errors or squashed non-error causes.
|
|
516
|
+
*
|
|
517
|
+
* @category combinators
|
|
518
|
+
* @since 4.0.0
|
|
519
|
+
*/
|
|
520
|
+
const matchWithWaiting = dual(2, (self, options) => {
|
|
521
|
+
if (self.waiting) return options.onWaiting(self);
|
|
522
|
+
switch (self._tag) {
|
|
523
|
+
case "Initial": return options.onWaiting(self);
|
|
524
|
+
case "Failure": {
|
|
525
|
+
const e = Cause.findError(self.cause);
|
|
526
|
+
if (Either.isFailure(e)) return options.onDefect(Cause.squash(e.failure), self);
|
|
527
|
+
return options.onError(e.success, self);
|
|
528
|
+
}
|
|
529
|
+
case "Success": return options.onSuccess(self);
|
|
530
|
+
}
|
|
531
|
+
});
|
|
532
|
+
const all = (results) => allImpl(results);
|
|
533
|
+
const allImpl = (results) => {
|
|
534
|
+
let waiting = false;
|
|
535
|
+
if (isIterable(results)) {
|
|
536
|
+
const list = Array.from(results);
|
|
537
|
+
const successes = [];
|
|
538
|
+
for (let i = 0; i < list.length; i++) {
|
|
539
|
+
const result = list[i];
|
|
540
|
+
if (!isResult(result)) {
|
|
541
|
+
successes[i] = result;
|
|
542
|
+
continue;
|
|
543
|
+
}
|
|
544
|
+
if (!isSuccess(result)) return result;
|
|
545
|
+
successes[i] = result.value;
|
|
546
|
+
if (result.waiting) waiting = true;
|
|
547
|
+
}
|
|
548
|
+
return success(successes, { waiting });
|
|
549
|
+
}
|
|
550
|
+
const successes = {};
|
|
551
|
+
for (const [key, result] of Object.entries(results)) {
|
|
552
|
+
if (!isResult(result)) {
|
|
553
|
+
successes[key] = result;
|
|
554
|
+
continue;
|
|
555
|
+
}
|
|
556
|
+
if (!isSuccess(result)) return result;
|
|
557
|
+
successes[key] = result.value;
|
|
558
|
+
if (result.waiting) waiting = true;
|
|
559
|
+
}
|
|
560
|
+
return success(successes, { waiting });
|
|
561
|
+
};
|
|
562
|
+
const builder = (self) => {
|
|
563
|
+
return new BuilderImpl(self);
|
|
564
|
+
};
|
|
565
|
+
var BuilderImpl = class {
|
|
566
|
+
constructor(result) {
|
|
567
|
+
this.result = result;
|
|
568
|
+
}
|
|
569
|
+
result;
|
|
570
|
+
output = Option.none();
|
|
571
|
+
when(refinement, f) {
|
|
572
|
+
if (Option.isNone(this.output) && refinement(this.result)) {
|
|
573
|
+
const b = f(this.result);
|
|
574
|
+
if (Option.isSome(b)) this.output = b;
|
|
575
|
+
}
|
|
576
|
+
return this;
|
|
577
|
+
}
|
|
578
|
+
pipe() {
|
|
579
|
+
return pipeArguments(this, arguments);
|
|
580
|
+
}
|
|
581
|
+
onWaiting(f) {
|
|
582
|
+
return this.when((r) => r.waiting, (r) => Option.some(f(r)));
|
|
583
|
+
}
|
|
584
|
+
onInitialOrWaiting(f) {
|
|
585
|
+
return this.when((r) => isInitial(r) || r.waiting, (r) => Option.some(f(r)));
|
|
586
|
+
}
|
|
587
|
+
onInitial(f) {
|
|
588
|
+
return this.when(isInitial, (r) => Option.some(f(r)));
|
|
589
|
+
}
|
|
590
|
+
onSuccess(f) {
|
|
591
|
+
return this.when(isSuccess, (r) => Option.some(f(r.value, r)));
|
|
592
|
+
}
|
|
593
|
+
onFailure(f) {
|
|
594
|
+
return this.when(isFailure, (r) => Option.some(f(r.cause, r)));
|
|
595
|
+
}
|
|
596
|
+
onError(f) {
|
|
597
|
+
return this.onErrorIf(constTrue, f);
|
|
598
|
+
}
|
|
599
|
+
onErrorIf(refinement, f) {
|
|
600
|
+
return this.when(isFailure, (result) => Cause.findErrorOption(result.cause).pipe(Option.filter(refinement), Option.map((error) => f(error, result))));
|
|
601
|
+
}
|
|
602
|
+
onErrorTag(tag, f) {
|
|
603
|
+
return this.onErrorIf((e) => hasProperty(e, "_tag") && (Array.isArray(tag) ? tag.includes(e._tag) : e._tag === tag), f);
|
|
604
|
+
}
|
|
605
|
+
onDefect(f) {
|
|
606
|
+
return this.when(isFailure, (result) => {
|
|
607
|
+
const defect = Cause.findDefect(result.cause);
|
|
608
|
+
return Either.isFailure(defect) ? Option.none() : Option.some(f(defect.success, result));
|
|
609
|
+
});
|
|
610
|
+
}
|
|
611
|
+
onInterrupt(f) {
|
|
612
|
+
return this.when(isFailure, (result) => {
|
|
613
|
+
const interruptors = Cause.filterInterruptors(result.cause);
|
|
614
|
+
return Either.isFailure(interruptors) ? Option.none() : Option.some(f(interruptors.success, result));
|
|
615
|
+
});
|
|
616
|
+
}
|
|
617
|
+
orElse(orElse) {
|
|
618
|
+
return Option.getOrElse(this.output, orElse);
|
|
619
|
+
}
|
|
620
|
+
orNull() {
|
|
621
|
+
return Option.getOrNull(this.output);
|
|
622
|
+
}
|
|
623
|
+
render() {
|
|
624
|
+
if (Option.isSome(this.output)) return this.output.value;
|
|
625
|
+
else if (isFailure(this.result)) throw Cause.squash(this.result.cause);
|
|
626
|
+
return null;
|
|
627
|
+
}
|
|
628
|
+
exhaustive() {
|
|
629
|
+
return this.render();
|
|
630
|
+
}
|
|
631
|
+
};
|
|
632
|
+
//#endregion
|
|
633
|
+
export { toExit as A, isWaiting as C, matchWithWaiting as D, matchWithError as E, Schema as F, schemaCodec as I, value as M, waiting as N, replacePrevious as O, waitingFrom as P, isSuccess as S, match as T, isFailure as _, cause as a, isNotInitial as b, failWithPrevious as c, flatMap as d, fromExit as f, initial as g, getOrThrow as h, builder as i, touch as j, success as k, failure as l, getOrElse as m, TypeId as n, error as o, fromExitWithPrevious as p, all as r, fail as s, Result_exports as t, failureWithPrevious as u, isInitial as v, map as w, isResult as x, isInterrupted as y };
|