effect 3.3.5 → 3.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Micro/package.json +6 -0
- package/dist/cjs/Array.js +18 -3
- package/dist/cjs/Array.js.map +1 -1
- package/dist/cjs/Chunk.js +13 -2
- package/dist/cjs/Chunk.js.map +1 -1
- package/dist/cjs/Effect.js +236 -15
- package/dist/cjs/Effect.js.map +1 -1
- package/dist/cjs/Either.js +31 -1
- package/dist/cjs/Either.js.map +1 -1
- package/dist/cjs/ManagedRuntime.js.map +1 -1
- package/dist/cjs/Micro.js +2383 -0
- package/dist/cjs/Micro.js.map +1 -0
- package/dist/cjs/Option.js +1 -2
- package/dist/cjs/Option.js.map +1 -1
- package/dist/cjs/Schedule.js +2 -2
- package/dist/cjs/Stream.js.map +1 -1
- package/dist/cjs/Tuple.js +16 -9
- package/dist/cjs/Tuple.js.map +1 -1
- package/dist/cjs/index.js +4 -2
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/internal/core-effect.js +4 -2
- package/dist/cjs/internal/core-effect.js.map +1 -1
- package/dist/cjs/internal/core.js +12 -2
- package/dist/cjs/internal/core.js.map +1 -1
- package/dist/cjs/internal/fiberRuntime.js +32 -0
- package/dist/cjs/internal/fiberRuntime.js.map +1 -1
- package/dist/cjs/internal/stream.js.map +1 -1
- package/dist/cjs/internal/version.js +1 -1
- package/dist/dts/Array.d.ts +14 -0
- package/dist/dts/Array.d.ts.map +1 -1
- package/dist/dts/Cause.d.ts +1 -1
- package/dist/dts/Chunk.d.ts +11 -0
- package/dist/dts/Chunk.d.ts.map +1 -1
- package/dist/dts/Effect.d.ts +235 -12
- package/dist/dts/Effect.d.ts.map +1 -1
- package/dist/dts/Either.d.ts +35 -0
- package/dist/dts/Either.d.ts.map +1 -1
- package/dist/dts/ManagedRuntime.d.ts +15 -0
- package/dist/dts/ManagedRuntime.d.ts.map +1 -1
- package/dist/dts/Micro.d.ts +2010 -0
- package/dist/dts/Micro.d.ts.map +1 -0
- package/dist/dts/Option.d.ts +2 -0
- package/dist/dts/Option.d.ts.map +1 -1
- package/dist/dts/Schedule.d.ts +2 -2
- package/dist/dts/Stream.d.ts +45 -6
- package/dist/dts/Stream.d.ts.map +1 -1
- package/dist/dts/Tuple.d.ts +18 -0
- package/dist/dts/Tuple.d.ts.map +1 -1
- package/dist/dts/index.d.ts +7 -0
- package/dist/dts/index.d.ts.map +1 -1
- package/dist/dts/internal/core-effect.d.ts.map +1 -1
- package/dist/dts/internal/core.d.ts.map +1 -1
- package/dist/dts/internal/fiberRuntime.d.ts.map +1 -1
- package/dist/esm/Array.js +14 -0
- package/dist/esm/Array.js.map +1 -1
- package/dist/esm/Chunk.js +11 -0
- package/dist/esm/Chunk.js.map +1 -1
- package/dist/esm/Effect.js +233 -12
- package/dist/esm/Effect.js.map +1 -1
- package/dist/esm/Either.js +30 -0
- package/dist/esm/Either.js.map +1 -1
- package/dist/esm/ManagedRuntime.js.map +1 -1
- package/dist/esm/Micro.js +2307 -0
- package/dist/esm/Micro.js.map +1 -0
- package/dist/esm/Option.js +1 -1
- package/dist/esm/Option.js.map +1 -1
- package/dist/esm/Schedule.js +2 -2
- package/dist/esm/Stream.js.map +1 -1
- package/dist/esm/Tuple.js +15 -8
- package/dist/esm/Tuple.js.map +1 -1
- package/dist/esm/index.js +7 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/internal/core-effect.js +2 -0
- package/dist/esm/internal/core-effect.js.map +1 -1
- package/dist/esm/internal/core.js +10 -1
- package/dist/esm/internal/core.js.map +1 -1
- package/dist/esm/internal/fiberRuntime.js +32 -0
- package/dist/esm/internal/fiberRuntime.js.map +1 -1
- package/dist/esm/internal/stream.js.map +1 -1
- package/dist/esm/internal/version.js +1 -1
- package/package.json +9 -1
- package/src/Array.ts +15 -0
- package/src/Cause.ts +1 -1
- package/src/Chunk.ts +12 -0
- package/src/Effect.ts +243 -12
- package/src/Either.ts +51 -0
- package/src/ManagedRuntime.ts +16 -0
- package/src/Micro.ts +3835 -0
- package/src/Option.ts +12 -1
- package/src/Schedule.ts +2 -2
- package/src/Stream.ts +60 -8
- package/src/Tuple.ts +18 -8
- package/src/index.ts +8 -0
- package/src/internal/core-effect.ts +33 -0
- package/src/internal/core.ts +18 -1
- package/src/internal/fiberRuntime.ts +32 -0
- package/src/internal/stream.ts +8 -4
- package/src/internal/version.ts +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "effect",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.4.1",
|
|
4
4
|
"description": "The missing standard library for TypeScript, for writing production-grade software.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -372,6 +372,11 @@
|
|
|
372
372
|
"import": "./dist/esm/MetricState.js",
|
|
373
373
|
"default": "./dist/cjs/MetricState.js"
|
|
374
374
|
},
|
|
375
|
+
"./Micro": {
|
|
376
|
+
"types": "./dist/dts/Micro.d.ts",
|
|
377
|
+
"import": "./dist/esm/Micro.js",
|
|
378
|
+
"default": "./dist/cjs/Micro.js"
|
|
379
|
+
},
|
|
375
380
|
"./ModuleVersion": {
|
|
376
381
|
"types": "./dist/dts/ModuleVersion.d.ts",
|
|
377
382
|
"import": "./dist/esm/ModuleVersion.js",
|
|
@@ -1020,6 +1025,9 @@
|
|
|
1020
1025
|
"MetricState": [
|
|
1021
1026
|
"./dist/dts/MetricState.d.ts"
|
|
1022
1027
|
],
|
|
1028
|
+
"Micro": [
|
|
1029
|
+
"./dist/dts/Micro.d.ts"
|
|
1030
|
+
],
|
|
1023
1031
|
"ModuleVersion": [
|
|
1024
1032
|
"./dist/dts/ModuleVersion.d.ts"
|
|
1025
1033
|
],
|
package/src/Array.ts
CHANGED
|
@@ -145,6 +145,21 @@ export const replicate: {
|
|
|
145
145
|
export const fromIterable = <A>(collection: Iterable<A>): Array<A> =>
|
|
146
146
|
Array.isArray(collection) ? collection : Array.from(collection)
|
|
147
147
|
|
|
148
|
+
/**
|
|
149
|
+
* Creates a new `Array` from a value that might not be an iterable.
|
|
150
|
+
*
|
|
151
|
+
* @example
|
|
152
|
+
* import { Array } from "effect"
|
|
153
|
+
*
|
|
154
|
+
* assert.deepStrictEqual(Array.ensure("a"), ["a"])
|
|
155
|
+
* assert.deepStrictEqual(Array.ensure(["a"]), ["a"])
|
|
156
|
+
* assert.deepStrictEqual(Array.ensure(["a", "b", "c"]), ["a", "b", "c"])
|
|
157
|
+
*
|
|
158
|
+
* @category constructors
|
|
159
|
+
* @since 3.3.0
|
|
160
|
+
*/
|
|
161
|
+
export const ensure = <A>(self: ReadonlyArray<A> | A): Array<A> => Array.isArray(self) ? self : [self as A]
|
|
162
|
+
|
|
148
163
|
/**
|
|
149
164
|
* Takes a record and returns an array of tuples containing its keys and values.
|
|
150
165
|
*
|
package/src/Cause.ts
CHANGED
|
@@ -192,7 +192,7 @@ export interface CauseReducer<in C, in E, in out Z> {
|
|
|
192
192
|
*/
|
|
193
193
|
export interface YieldableError extends Pipeable, Inspectable, Readonly<Error> {
|
|
194
194
|
readonly [Effect.EffectTypeId]: Effect.Effect.VarianceStruct<never, this, never>
|
|
195
|
-
readonly [Stream.StreamTypeId]:
|
|
195
|
+
readonly [Stream.StreamTypeId]: Stream.Stream.VarianceStruct<never, this, never>
|
|
196
196
|
readonly [Sink.SinkTypeId]: Sink.Sink.VarianceStruct<never, unknown, never, this, never>
|
|
197
197
|
readonly [Channel.ChannelTypeId]: Channel.Channel.VarianceStruct<never, unknown, this, unknown, never, unknown, never>
|
|
198
198
|
[Symbol.iterator](): Effect.EffectGenerator<Effect.Effect<never, this, never>>
|
package/src/Chunk.ts
CHANGED
|
@@ -819,6 +819,8 @@ export const head: <A>(self: Chunk<A>) => Option<A> = get(0)
|
|
|
819
819
|
/**
|
|
820
820
|
* Returns the first element of this chunk.
|
|
821
821
|
*
|
|
822
|
+
* It will throw an error if the chunk is empty.
|
|
823
|
+
*
|
|
822
824
|
* @since 2.0.0
|
|
823
825
|
* @category unsafe
|
|
824
826
|
*/
|
|
@@ -843,11 +845,21 @@ export const last = <A>(self: Chunk<A>): Option<A> => get(self, self.length - 1)
|
|
|
843
845
|
/**
|
|
844
846
|
* Returns the last element of this chunk.
|
|
845
847
|
*
|
|
848
|
+
* It will throw an error if the chunk is empty.
|
|
849
|
+
*
|
|
846
850
|
* @since 2.0.0
|
|
847
851
|
* @category unsafe
|
|
848
852
|
*/
|
|
849
853
|
export const unsafeLast = <A>(self: Chunk<A>): A => unsafeGet(self, self.length - 1)
|
|
850
854
|
|
|
855
|
+
/**
|
|
856
|
+
* Returns the last element of this non empty chunk.
|
|
857
|
+
*
|
|
858
|
+
* @since 3.4.0
|
|
859
|
+
* @category elements
|
|
860
|
+
*/
|
|
861
|
+
export const lastNonEmpty: <A>(self: NonEmptyChunk<A>) => A = unsafeLast
|
|
862
|
+
|
|
851
863
|
/**
|
|
852
864
|
* @since 2.0.0
|
|
853
865
|
*/
|
package/src/Effect.ts
CHANGED
|
@@ -291,7 +291,7 @@ export const isEffect: (u: unknown) => u is Effect<unknown, unknown, unknown> =
|
|
|
291
291
|
* yield* cached.pipe(Effect.andThen(Console.log))
|
|
292
292
|
* })
|
|
293
293
|
*
|
|
294
|
-
*
|
|
294
|
+
* Effect.runFork(program)
|
|
295
295
|
* // Output:
|
|
296
296
|
* // expensive task...
|
|
297
297
|
* // result 1
|
|
@@ -336,7 +336,7 @@ export const cachedWithTTL: {
|
|
|
336
336
|
* yield* cached.pipe(Effect.andThen(Console.log))
|
|
337
337
|
* })
|
|
338
338
|
*
|
|
339
|
-
*
|
|
339
|
+
* Effect.runFork(program)
|
|
340
340
|
* // Output:
|
|
341
341
|
* // expensive task...
|
|
342
342
|
* // result 1
|
|
@@ -385,7 +385,7 @@ export const cachedInvalidateWithTTL: {
|
|
|
385
385
|
* yield* cached.pipe(Effect.andThen(Console.log))
|
|
386
386
|
* })
|
|
387
387
|
*
|
|
388
|
-
*
|
|
388
|
+
* Effect.runFork(program)
|
|
389
389
|
* // Output:
|
|
390
390
|
* // non-cached version:
|
|
391
391
|
* // expensive task...
|
|
@@ -422,7 +422,7 @@ export const cached: <A, E, R>(self: Effect<A, E, R>) => Effect<Effect<A, E, R>>
|
|
|
422
422
|
* console.log(yield* memoized(10))
|
|
423
423
|
* })
|
|
424
424
|
*
|
|
425
|
-
*
|
|
425
|
+
* Effect.runFork(program)
|
|
426
426
|
* // Example Output:
|
|
427
427
|
* // non-memoized version:
|
|
428
428
|
* // 2
|
|
@@ -453,7 +453,7 @@ export const cachedFunction: <A, B, E, R>(
|
|
|
453
453
|
* yield* Effect.repeatN(task2, 2)
|
|
454
454
|
* })
|
|
455
455
|
*
|
|
456
|
-
*
|
|
456
|
+
* Effect.runFork(program)
|
|
457
457
|
* // Output:
|
|
458
458
|
* // task1
|
|
459
459
|
* // task1
|
|
@@ -2159,6 +2159,40 @@ export const uninterruptibleMask: <A, E, R>(
|
|
|
2159
2159
|
f: (restore: <AX, EX, RX>(effect: Effect<AX, EX, RX>) => Effect<AX, EX, RX>) => Effect<A, E, R>
|
|
2160
2160
|
) => Effect<A, E, R> = core.uninterruptibleMask
|
|
2161
2161
|
|
|
2162
|
+
// -------------------------------------------------------------------------------------
|
|
2163
|
+
// lifting
|
|
2164
|
+
// -------------------------------------------------------------------------------------
|
|
2165
|
+
|
|
2166
|
+
/**
|
|
2167
|
+
* Transforms a `Predicate` function into an `Effect` returning the input value if the predicate returns `true`
|
|
2168
|
+
* or failing with specified error if the predicate fails
|
|
2169
|
+
*
|
|
2170
|
+
* @param predicate - A `Predicate` function that takes in a value of type `A` and returns a boolean.
|
|
2171
|
+
*
|
|
2172
|
+
* @example
|
|
2173
|
+
* import { Effect } from "effect"
|
|
2174
|
+
*
|
|
2175
|
+
* const isPositive = (n: number): boolean => n > 0
|
|
2176
|
+
*
|
|
2177
|
+
* // succeeds with `1`
|
|
2178
|
+
* Effect.liftPredicate(1, isPositive, n => `${n} is not positive`)
|
|
2179
|
+
*
|
|
2180
|
+
* // fails with `"0 is not positive"`
|
|
2181
|
+
* Effect.liftPredicate(0, isPositive, n => `${n} is not positive`)
|
|
2182
|
+
*
|
|
2183
|
+
* @category lifting
|
|
2184
|
+
* @since 3.4.0
|
|
2185
|
+
*/
|
|
2186
|
+
export const liftPredicate: {
|
|
2187
|
+
<A, B extends A, E>(
|
|
2188
|
+
refinement: Refinement<NoInfer<A>, B>,
|
|
2189
|
+
orFailWith: (a: NoInfer<A>) => E
|
|
2190
|
+
): (a: A) => Effect<B, E>
|
|
2191
|
+
<A, E>(predicate: Predicate<NoInfer<A>>, orFailWith: (a: NoInfer<A>) => E): (a: A) => Effect<A, E>
|
|
2192
|
+
<A, E, B extends A>(self: A, refinement: Refinement<A, B>, orFailWith: (a: A) => E): Effect<B, E>
|
|
2193
|
+
<A, E>(self: A, predicate: Predicate<NoInfer<A>>, orFailWith: (a: NoInfer<A>) => E): Effect<A, E>
|
|
2194
|
+
} = effect.liftPredicate
|
|
2195
|
+
|
|
2162
2196
|
// -------------------------------------------------------------------------------------
|
|
2163
2197
|
// mapping
|
|
2164
2198
|
// -------------------------------------------------------------------------------------
|
|
@@ -4017,8 +4051,27 @@ export const tap: {
|
|
|
4017
4051
|
} = core.tap
|
|
4018
4052
|
|
|
4019
4053
|
/**
|
|
4020
|
-
*
|
|
4021
|
-
*
|
|
4054
|
+
* Inspects both success and failure outcomes of an effect, performing different actions based on the result.
|
|
4055
|
+
*
|
|
4056
|
+
* @example
|
|
4057
|
+
* import { Effect, Random, Console } from "effect"
|
|
4058
|
+
*
|
|
4059
|
+
* // Simulate an effect that might fail
|
|
4060
|
+
* const task = Effect.filterOrFail(
|
|
4061
|
+
* Random.nextRange(-1, 1),
|
|
4062
|
+
* (n) => n >= 0,
|
|
4063
|
+
* () => "random number is negative"
|
|
4064
|
+
* )
|
|
4065
|
+
*
|
|
4066
|
+
* // Define an effect that logs both success and failure outcomes of the 'task'
|
|
4067
|
+
* const tapping = Effect.tapBoth(task, {
|
|
4068
|
+
* onFailure: (error) => Console.log(`failure: ${error}`),
|
|
4069
|
+
* onSuccess: (randomNumber) => Console.log(`random number: ${randomNumber}`)
|
|
4070
|
+
* })
|
|
4071
|
+
*
|
|
4072
|
+
* Effect.runFork(tapping)
|
|
4073
|
+
* // Example Output:
|
|
4074
|
+
* // failure: random number is negative
|
|
4022
4075
|
*
|
|
4023
4076
|
* @since 2.0.0
|
|
4024
4077
|
* @category sequencing
|
|
@@ -4040,7 +4093,36 @@ export const tapBoth: {
|
|
|
4040
4093
|
} = effect.tapBoth
|
|
4041
4094
|
|
|
4042
4095
|
/**
|
|
4043
|
-
*
|
|
4096
|
+
* Specifically inspects non-recoverable failures or defects in an effect (i.e., one or more `Die` causes).
|
|
4097
|
+
*
|
|
4098
|
+
* @example
|
|
4099
|
+
* import { Effect, Console } from "effect"
|
|
4100
|
+
*
|
|
4101
|
+
* // Create an effect that is designed to fail, simulating an occurrence of a network error
|
|
4102
|
+
* const task1: Effect.Effect<number, string> = Effect.fail("NetworkError")
|
|
4103
|
+
*
|
|
4104
|
+
* // this won't log anything because is not a defect
|
|
4105
|
+
* const tapping1 = Effect.tapDefect(task1, (cause) =>
|
|
4106
|
+
* Console.log(`defect: ${cause}`)
|
|
4107
|
+
* )
|
|
4108
|
+
*
|
|
4109
|
+
* Effect.runFork(tapping1)
|
|
4110
|
+
* // No Output
|
|
4111
|
+
*
|
|
4112
|
+
* // Simulate a severe failure in the system by causing a defect with a specific message.
|
|
4113
|
+
* const task2: Effect.Effect<number, string> = Effect.dieMessage(
|
|
4114
|
+
* "Something went wrong"
|
|
4115
|
+
* )
|
|
4116
|
+
*
|
|
4117
|
+
* // This will only log defects, not errors
|
|
4118
|
+
* const tapping2 = Effect.tapDefect(task2, (cause) =>
|
|
4119
|
+
* Console.log(`defect: ${cause}`)
|
|
4120
|
+
* )
|
|
4121
|
+
*
|
|
4122
|
+
* Effect.runFork(tapping2)
|
|
4123
|
+
* // Output:
|
|
4124
|
+
* // defect: RuntimeException: Something went wrong
|
|
4125
|
+
* // ... stack trace ...
|
|
4044
4126
|
*
|
|
4045
4127
|
* @since 2.0.0
|
|
4046
4128
|
* @category sequencing
|
|
@@ -4056,7 +4138,23 @@ export const tapDefect: {
|
|
|
4056
4138
|
} = effect.tapDefect
|
|
4057
4139
|
|
|
4058
4140
|
/**
|
|
4059
|
-
*
|
|
4141
|
+
* Executes an effectful operation to inspect the failure of an effect without altering it.
|
|
4142
|
+
*
|
|
4143
|
+
* @example
|
|
4144
|
+
* import { Effect, Console } from "effect"
|
|
4145
|
+
*
|
|
4146
|
+
* // Create an effect that is designed to fail, simulating an occurrence of a network error
|
|
4147
|
+
* const task: Effect.Effect<number, string> = Effect.fail("NetworkError")
|
|
4148
|
+
*
|
|
4149
|
+
* // Log the error message if the task fails. This function only executes if there is an error,
|
|
4150
|
+
* // providing a method to handle or inspect errors without altering the outcome of the original effect.
|
|
4151
|
+
* const tapping = Effect.tapError(task, (error) =>
|
|
4152
|
+
* Console.log(`expected error: ${error}`)
|
|
4153
|
+
* )
|
|
4154
|
+
*
|
|
4155
|
+
* Effect.runFork(tapping)
|
|
4156
|
+
* // Output:
|
|
4157
|
+
* // expected error: NetworkError
|
|
4060
4158
|
*
|
|
4061
4159
|
* @since 2.0.0
|
|
4062
4160
|
* @category sequencing
|
|
@@ -4069,7 +4167,33 @@ export const tapError: {
|
|
|
4069
4167
|
} = effect.tapError
|
|
4070
4168
|
|
|
4071
4169
|
/**
|
|
4072
|
-
*
|
|
4170
|
+
* Specifically inspects a failure with a particular tag, allowing focused error handling.
|
|
4171
|
+
*
|
|
4172
|
+
* @example
|
|
4173
|
+
* import { Effect, Console } from "effect"
|
|
4174
|
+
*
|
|
4175
|
+
* class NetworkError {
|
|
4176
|
+
* readonly _tag = "NetworkError"
|
|
4177
|
+
* constructor(readonly statusCode: number) {}
|
|
4178
|
+
* }
|
|
4179
|
+
* class ValidationError {
|
|
4180
|
+
* readonly _tag = "ValidationError"
|
|
4181
|
+
* constructor(readonly field: string) {}
|
|
4182
|
+
* }
|
|
4183
|
+
*
|
|
4184
|
+
* // Create an effect that is designed to fail, simulating an occurrence of a network error
|
|
4185
|
+
* const task: Effect.Effect<number, NetworkError | ValidationError> =
|
|
4186
|
+
* Effect.fail(new NetworkError(504))
|
|
4187
|
+
*
|
|
4188
|
+
* // Apply an error handling function only to errors tagged as "NetworkError",
|
|
4189
|
+
* // and log the corresponding status code of the error.
|
|
4190
|
+
* const tapping = Effect.tapErrorTag(task, "NetworkError", (error) =>
|
|
4191
|
+
* Console.log(`expected error: ${error.statusCode}`)
|
|
4192
|
+
* )
|
|
4193
|
+
*
|
|
4194
|
+
* Effect.runFork(tapping)
|
|
4195
|
+
* // Output:
|
|
4196
|
+
* // expected error: 504
|
|
4073
4197
|
*
|
|
4074
4198
|
* @since 2.0.0
|
|
4075
4199
|
* @category sequencing
|
|
@@ -4087,8 +4211,37 @@ export const tapErrorTag: {
|
|
|
4087
4211
|
} = effect.tapErrorTag
|
|
4088
4212
|
|
|
4089
4213
|
/**
|
|
4090
|
-
*
|
|
4091
|
-
*
|
|
4214
|
+
* Inspects the underlying cause of an effect's failure.
|
|
4215
|
+
*
|
|
4216
|
+
* @example
|
|
4217
|
+
* import { Effect, Console } from "effect"
|
|
4218
|
+
*
|
|
4219
|
+
* // Create an effect that is designed to fail, simulating an occurrence of a network error
|
|
4220
|
+
* const task1: Effect.Effect<number, string> = Effect.fail("NetworkError")
|
|
4221
|
+
*
|
|
4222
|
+
* // This will log the cause of any expected error or defect
|
|
4223
|
+
* const tapping1 = Effect.tapErrorCause(task1, (cause) =>
|
|
4224
|
+
* Console.log(`error cause: ${cause}`)
|
|
4225
|
+
* )
|
|
4226
|
+
*
|
|
4227
|
+
* Effect.runFork(tapping1)
|
|
4228
|
+
* // Output:
|
|
4229
|
+
* // error cause: Error: NetworkError
|
|
4230
|
+
*
|
|
4231
|
+
* // Simulate a severe failure in the system by causing a defect with a specific message.
|
|
4232
|
+
* const task2: Effect.Effect<number, string> = Effect.dieMessage(
|
|
4233
|
+
* "Something went wrong"
|
|
4234
|
+
* )
|
|
4235
|
+
*
|
|
4236
|
+
* // This will log the cause of any expected error or defect
|
|
4237
|
+
* const tapping2 = Effect.tapErrorCause(task2, (cause) =>
|
|
4238
|
+
* Console.log(`error cause: ${cause}`)
|
|
4239
|
+
* )
|
|
4240
|
+
*
|
|
4241
|
+
* Effect.runFork(tapping2)
|
|
4242
|
+
* // Output:
|
|
4243
|
+
* // error cause: RuntimeException: Something went wrong
|
|
4244
|
+
* // ... stack trace ...
|
|
4092
4245
|
*
|
|
4093
4246
|
* @since 2.0.0
|
|
4094
4247
|
* @category sequencing
|
|
@@ -5152,6 +5305,55 @@ export const validateWith: {
|
|
|
5152
5305
|
} = fiberRuntime.validateWith
|
|
5153
5306
|
|
|
5154
5307
|
/**
|
|
5308
|
+
* The `Effect.zip` function allows you to combine two effects into a single
|
|
5309
|
+
* effect. This combined effect yields a tuple containing the results of both
|
|
5310
|
+
* input effects once they succeed.
|
|
5311
|
+
*
|
|
5312
|
+
* Note that `Effect.zip` processes effects sequentially: it first completes the
|
|
5313
|
+
* effect on the left and then the effect on the right.
|
|
5314
|
+
*
|
|
5315
|
+
* If you want to run the effects concurrently, you can use the `concurrent` option.
|
|
5316
|
+
*
|
|
5317
|
+
* @example
|
|
5318
|
+
* import { Effect } from "effect"
|
|
5319
|
+
*
|
|
5320
|
+
* const task1 = Effect.succeed(1).pipe(
|
|
5321
|
+
* Effect.delay("200 millis"),
|
|
5322
|
+
* Effect.tap(Effect.log("task1 done"))
|
|
5323
|
+
* )
|
|
5324
|
+
* const task2 = Effect.succeed("hello").pipe(
|
|
5325
|
+
* Effect.delay("100 millis"),
|
|
5326
|
+
* Effect.tap(Effect.log("task2 done"))
|
|
5327
|
+
* )
|
|
5328
|
+
*
|
|
5329
|
+
* const task3 = Effect.zip(task1, task2)
|
|
5330
|
+
*
|
|
5331
|
+
* Effect.runPromise(task3).then(console.log)
|
|
5332
|
+
* // Output:
|
|
5333
|
+
* // timestamp=... level=INFO fiber=#0 message="task1 done"
|
|
5334
|
+
* // timestamp=... level=INFO fiber=#0 message="task2 done"
|
|
5335
|
+
* // [ 1, 'hello' ]
|
|
5336
|
+
*
|
|
5337
|
+
* @example
|
|
5338
|
+
* import { Effect } from "effect"
|
|
5339
|
+
*
|
|
5340
|
+
* const task1 = Effect.succeed(1).pipe(
|
|
5341
|
+
* Effect.delay("200 millis"),
|
|
5342
|
+
* Effect.tap(Effect.log("task1 done"))
|
|
5343
|
+
* )
|
|
5344
|
+
* const task2 = Effect.succeed("hello").pipe(
|
|
5345
|
+
* Effect.delay("100 millis"),
|
|
5346
|
+
* Effect.tap(Effect.log("task2 done"))
|
|
5347
|
+
* )
|
|
5348
|
+
*
|
|
5349
|
+
* const task3 = Effect.zip(task1, task2, { concurrent: true })
|
|
5350
|
+
*
|
|
5351
|
+
* Effect.runPromise(task3).then(console.log)
|
|
5352
|
+
* // Output:
|
|
5353
|
+
* // timestamp=... level=INFO fiber=#0 message="task2 done"
|
|
5354
|
+
* // timestamp=... level=INFO fiber=#0 message="task1 done"
|
|
5355
|
+
* // [ 1, 'hello' ]
|
|
5356
|
+
*
|
|
5155
5357
|
* @since 2.0.0
|
|
5156
5358
|
* @category zipping
|
|
5157
5359
|
*/
|
|
@@ -5246,6 +5448,35 @@ export const zipRight: {
|
|
|
5246
5448
|
} = fiberRuntime.zipRightOptions
|
|
5247
5449
|
|
|
5248
5450
|
/**
|
|
5451
|
+
* The `Effect.zipWith` function operates similarly to {@link zip} by combining
|
|
5452
|
+
* two effects. However, instead of returning a tuple, it allows you to apply a
|
|
5453
|
+
* function to the results of the combined effects, transforming them into a
|
|
5454
|
+
* single value
|
|
5455
|
+
*
|
|
5456
|
+
* @example
|
|
5457
|
+
* import { Effect } from "effect"
|
|
5458
|
+
*
|
|
5459
|
+
* const task1 = Effect.succeed(1).pipe(
|
|
5460
|
+
* Effect.delay("200 millis"),
|
|
5461
|
+
* Effect.tap(Effect.log("task1 done"))
|
|
5462
|
+
* )
|
|
5463
|
+
* const task2 = Effect.succeed("hello").pipe(
|
|
5464
|
+
* Effect.delay("100 millis"),
|
|
5465
|
+
* Effect.tap(Effect.log("task2 done"))
|
|
5466
|
+
* )
|
|
5467
|
+
*
|
|
5468
|
+
* const task3 = Effect.zipWith(
|
|
5469
|
+
* task1,
|
|
5470
|
+
* task2,
|
|
5471
|
+
* (number, string) => number + string.length
|
|
5472
|
+
* )
|
|
5473
|
+
*
|
|
5474
|
+
* Effect.runPromise(task3).then(console.log)
|
|
5475
|
+
* // Output:
|
|
5476
|
+
* // timestamp=... level=INFO fiber=#3 message="task1 done"
|
|
5477
|
+
* // timestamp=... level=INFO fiber=#2 message="task2 done"
|
|
5478
|
+
* // 6
|
|
5479
|
+
*
|
|
5249
5480
|
* @since 2.0.0
|
|
5250
5481
|
* @category zipping
|
|
5251
5482
|
*/
|
package/src/Either.ts
CHANGED
|
@@ -389,6 +389,57 @@ export const match: {
|
|
|
389
389
|
}): B | C => isLeft(self) ? onLeft(self.left) : onRight(self.right)
|
|
390
390
|
)
|
|
391
391
|
|
|
392
|
+
/**
|
|
393
|
+
* Transforms a `Predicate` function into a `Right` of the input value if the predicate returns `true`
|
|
394
|
+
* or `Left` of the result of the provided function if the predicate returns false
|
|
395
|
+
*
|
|
396
|
+
* @param predicate - A `Predicate` function that takes in a value of type `A` and returns a boolean.
|
|
397
|
+
*
|
|
398
|
+
* @example
|
|
399
|
+
* import { pipe, Either } from "effect"
|
|
400
|
+
*
|
|
401
|
+
* const isPositive = (n: number): boolean => n > 0
|
|
402
|
+
*
|
|
403
|
+
* assert.deepStrictEqual(
|
|
404
|
+
* pipe(
|
|
405
|
+
* 1,
|
|
406
|
+
* Either.liftPredicate(isPositive, n => `${n} is not positive`)
|
|
407
|
+
* ),
|
|
408
|
+
* Either.right(1)
|
|
409
|
+
* )
|
|
410
|
+
* assert.deepStrictEqual(
|
|
411
|
+
* pipe(
|
|
412
|
+
* 0,
|
|
413
|
+
* Either.liftPredicate(isPositive, n => `${n} is not positive`)
|
|
414
|
+
* ),
|
|
415
|
+
* Either.left("0 is not positive")
|
|
416
|
+
* )
|
|
417
|
+
*
|
|
418
|
+
* @category lifting
|
|
419
|
+
* @since 3.4.0
|
|
420
|
+
*/
|
|
421
|
+
export const liftPredicate: {
|
|
422
|
+
<A, B extends A, E>(refinement: Refinement<NoInfer<A>, B>, orLeftWith: (a: NoInfer<A>) => E): (a: A) => Either<B, E>
|
|
423
|
+
<A, E>(
|
|
424
|
+
predicate: Predicate<NoInfer<A>>,
|
|
425
|
+
orLeftWith: (a: NoInfer<A>) => E
|
|
426
|
+
): (a: A) => Either<A, E>
|
|
427
|
+
<A, E, B extends A>(
|
|
428
|
+
self: A,
|
|
429
|
+
refinement: Refinement<A, B>,
|
|
430
|
+
orLeftWith: (a: A) => E
|
|
431
|
+
): Either<B, E>
|
|
432
|
+
<A, E>(
|
|
433
|
+
self: A,
|
|
434
|
+
predicate: Predicate<NoInfer<A>>,
|
|
435
|
+
orLeftWith: (a: NoInfer<A>) => E
|
|
436
|
+
): Either<A, E>
|
|
437
|
+
} = dual(
|
|
438
|
+
3,
|
|
439
|
+
<A, E>(a: A, predicate: Predicate<A>, orLeftWith: (a: A) => E): Either<A, E> =>
|
|
440
|
+
predicate(a) ? right(a) : left(orLeftWith(a))
|
|
441
|
+
)
|
|
442
|
+
|
|
392
443
|
/**
|
|
393
444
|
* Filter the right value with the provided function.
|
|
394
445
|
* If the predicate fails, set the left value with the result of the provided function.
|
package/src/ManagedRuntime.ts
CHANGED
|
@@ -9,6 +9,22 @@ import type * as Layer from "./Layer.js"
|
|
|
9
9
|
import type { Pipeable } from "./Pipeable.js"
|
|
10
10
|
import type * as Runtime from "./Runtime.js"
|
|
11
11
|
|
|
12
|
+
/**
|
|
13
|
+
* @since 3.4.0
|
|
14
|
+
*/
|
|
15
|
+
export declare namespace ManagedRuntime {
|
|
16
|
+
/**
|
|
17
|
+
* @category type-level
|
|
18
|
+
* @since 3.4.0
|
|
19
|
+
*/
|
|
20
|
+
export type Context<T extends ManagedRuntime<any, any>> = [T] extends [ManagedRuntime<infer R, infer _E>] ? R : never
|
|
21
|
+
/**
|
|
22
|
+
* @category type-level
|
|
23
|
+
* @since 3.4.0
|
|
24
|
+
*/
|
|
25
|
+
export type Error<T extends ManagedRuntime<any, any>> = [T] extends [ManagedRuntime<infer _R, infer E>] ? E : never
|
|
26
|
+
}
|
|
27
|
+
|
|
12
28
|
/**
|
|
13
29
|
* @since 2.0.0
|
|
14
30
|
* @category models
|