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.
Files changed (98) hide show
  1. package/Micro/package.json +6 -0
  2. package/dist/cjs/Array.js +18 -3
  3. package/dist/cjs/Array.js.map +1 -1
  4. package/dist/cjs/Chunk.js +13 -2
  5. package/dist/cjs/Chunk.js.map +1 -1
  6. package/dist/cjs/Effect.js +236 -15
  7. package/dist/cjs/Effect.js.map +1 -1
  8. package/dist/cjs/Either.js +31 -1
  9. package/dist/cjs/Either.js.map +1 -1
  10. package/dist/cjs/ManagedRuntime.js.map +1 -1
  11. package/dist/cjs/Micro.js +2383 -0
  12. package/dist/cjs/Micro.js.map +1 -0
  13. package/dist/cjs/Option.js +1 -2
  14. package/dist/cjs/Option.js.map +1 -1
  15. package/dist/cjs/Schedule.js +2 -2
  16. package/dist/cjs/Stream.js.map +1 -1
  17. package/dist/cjs/Tuple.js +16 -9
  18. package/dist/cjs/Tuple.js.map +1 -1
  19. package/dist/cjs/index.js +4 -2
  20. package/dist/cjs/index.js.map +1 -1
  21. package/dist/cjs/internal/core-effect.js +4 -2
  22. package/dist/cjs/internal/core-effect.js.map +1 -1
  23. package/dist/cjs/internal/core.js +12 -2
  24. package/dist/cjs/internal/core.js.map +1 -1
  25. package/dist/cjs/internal/fiberRuntime.js +32 -0
  26. package/dist/cjs/internal/fiberRuntime.js.map +1 -1
  27. package/dist/cjs/internal/stream.js.map +1 -1
  28. package/dist/cjs/internal/version.js +1 -1
  29. package/dist/dts/Array.d.ts +14 -0
  30. package/dist/dts/Array.d.ts.map +1 -1
  31. package/dist/dts/Cause.d.ts +1 -1
  32. package/dist/dts/Chunk.d.ts +11 -0
  33. package/dist/dts/Chunk.d.ts.map +1 -1
  34. package/dist/dts/Effect.d.ts +235 -12
  35. package/dist/dts/Effect.d.ts.map +1 -1
  36. package/dist/dts/Either.d.ts +35 -0
  37. package/dist/dts/Either.d.ts.map +1 -1
  38. package/dist/dts/ManagedRuntime.d.ts +15 -0
  39. package/dist/dts/ManagedRuntime.d.ts.map +1 -1
  40. package/dist/dts/Micro.d.ts +2010 -0
  41. package/dist/dts/Micro.d.ts.map +1 -0
  42. package/dist/dts/Option.d.ts +2 -0
  43. package/dist/dts/Option.d.ts.map +1 -1
  44. package/dist/dts/Schedule.d.ts +2 -2
  45. package/dist/dts/Stream.d.ts +45 -6
  46. package/dist/dts/Stream.d.ts.map +1 -1
  47. package/dist/dts/Tuple.d.ts +18 -0
  48. package/dist/dts/Tuple.d.ts.map +1 -1
  49. package/dist/dts/index.d.ts +7 -0
  50. package/dist/dts/index.d.ts.map +1 -1
  51. package/dist/dts/internal/core-effect.d.ts.map +1 -1
  52. package/dist/dts/internal/core.d.ts.map +1 -1
  53. package/dist/dts/internal/fiberRuntime.d.ts.map +1 -1
  54. package/dist/esm/Array.js +14 -0
  55. package/dist/esm/Array.js.map +1 -1
  56. package/dist/esm/Chunk.js +11 -0
  57. package/dist/esm/Chunk.js.map +1 -1
  58. package/dist/esm/Effect.js +233 -12
  59. package/dist/esm/Effect.js.map +1 -1
  60. package/dist/esm/Either.js +30 -0
  61. package/dist/esm/Either.js.map +1 -1
  62. package/dist/esm/ManagedRuntime.js.map +1 -1
  63. package/dist/esm/Micro.js +2307 -0
  64. package/dist/esm/Micro.js.map +1 -0
  65. package/dist/esm/Option.js +1 -1
  66. package/dist/esm/Option.js.map +1 -1
  67. package/dist/esm/Schedule.js +2 -2
  68. package/dist/esm/Stream.js.map +1 -1
  69. package/dist/esm/Tuple.js +15 -8
  70. package/dist/esm/Tuple.js.map +1 -1
  71. package/dist/esm/index.js +7 -0
  72. package/dist/esm/index.js.map +1 -1
  73. package/dist/esm/internal/core-effect.js +2 -0
  74. package/dist/esm/internal/core-effect.js.map +1 -1
  75. package/dist/esm/internal/core.js +10 -1
  76. package/dist/esm/internal/core.js.map +1 -1
  77. package/dist/esm/internal/fiberRuntime.js +32 -0
  78. package/dist/esm/internal/fiberRuntime.js.map +1 -1
  79. package/dist/esm/internal/stream.js.map +1 -1
  80. package/dist/esm/internal/version.js +1 -1
  81. package/package.json +9 -1
  82. package/src/Array.ts +15 -0
  83. package/src/Cause.ts +1 -1
  84. package/src/Chunk.ts +12 -0
  85. package/src/Effect.ts +243 -12
  86. package/src/Either.ts +51 -0
  87. package/src/ManagedRuntime.ts +16 -0
  88. package/src/Micro.ts +3835 -0
  89. package/src/Option.ts +12 -1
  90. package/src/Schedule.ts +2 -2
  91. package/src/Stream.ts +60 -8
  92. package/src/Tuple.ts +18 -8
  93. package/src/index.ts +8 -0
  94. package/src/internal/core-effect.ts +33 -0
  95. package/src/internal/core.ts +18 -1
  96. package/src/internal/fiberRuntime.ts +32 -0
  97. package/src/internal/stream.ts +8 -4
  98. package/src/internal/version.ts +1 -1
@@ -253,7 +253,7 @@ export declare const isEffect: (u: unknown) => u is Effect<unknown, unknown, unk
253
253
  * yield* cached.pipe(Effect.andThen(Console.log))
254
254
  * })
255
255
  *
256
- * // Effect.runFork(program)
256
+ * Effect.runFork(program)
257
257
  * // Output:
258
258
  * // expensive task...
259
259
  * // result 1
@@ -297,7 +297,7 @@ export declare const cachedWithTTL: {
297
297
  * yield* cached.pipe(Effect.andThen(Console.log))
298
298
  * })
299
299
  *
300
- * // Effect.runFork(program)
300
+ * Effect.runFork(program)
301
301
  * // Output:
302
302
  * // expensive task...
303
303
  * // result 1
@@ -340,7 +340,7 @@ export declare const cachedInvalidateWithTTL: {
340
340
  * yield* cached.pipe(Effect.andThen(Console.log))
341
341
  * })
342
342
  *
343
- * // Effect.runFork(program)
343
+ * Effect.runFork(program)
344
344
  * // Output:
345
345
  * // non-cached version:
346
346
  * // expensive task...
@@ -376,7 +376,7 @@ export declare const cached: <A, E, R>(self: Effect<A, E, R>) => Effect<Effect<A
376
376
  * console.log(yield* memoized(10))
377
377
  * })
378
378
  *
379
- * // Effect.runFork(program)
379
+ * Effect.runFork(program)
380
380
  * // Example Output:
381
381
  * // non-memoized version:
382
382
  * // 2
@@ -403,7 +403,7 @@ export declare const cachedFunction: <A, B, E, R>(f: (a: A) => Effect<B, E, R>,
403
403
  * yield* Effect.repeatN(task2, 2)
404
404
  * })
405
405
  *
406
- * // Effect.runFork(program)
406
+ * Effect.runFork(program)
407
407
  * // Output:
408
408
  * // task1
409
409
  * // task1
@@ -1539,6 +1539,32 @@ export declare const uninterruptible: <A, E, R>(self: Effect<A, E, R>) => Effect
1539
1539
  * @category interruption
1540
1540
  */
1541
1541
  export declare const uninterruptibleMask: <A, E, R>(f: (restore: <AX, EX, RX>(effect: Effect<AX, EX, RX>) => Effect<AX, EX, RX>) => Effect<A, E, R>) => Effect<A, E, R>;
1542
+ /**
1543
+ * Transforms a `Predicate` function into an `Effect` returning the input value if the predicate returns `true`
1544
+ * or failing with specified error if the predicate fails
1545
+ *
1546
+ * @param predicate - A `Predicate` function that takes in a value of type `A` and returns a boolean.
1547
+ *
1548
+ * @example
1549
+ * import { Effect } from "effect"
1550
+ *
1551
+ * const isPositive = (n: number): boolean => n > 0
1552
+ *
1553
+ * // succeeds with `1`
1554
+ * Effect.liftPredicate(1, isPositive, n => `${n} is not positive`)
1555
+ *
1556
+ * // fails with `"0 is not positive"`
1557
+ * Effect.liftPredicate(0, isPositive, n => `${n} is not positive`)
1558
+ *
1559
+ * @category lifting
1560
+ * @since 3.4.0
1561
+ */
1562
+ export declare const liftPredicate: {
1563
+ <A, B extends A, E>(refinement: Refinement<NoInfer<A>, B>, orFailWith: (a: NoInfer<A>) => E): (a: A) => Effect<B, E>;
1564
+ <A, E>(predicate: Predicate<NoInfer<A>>, orFailWith: (a: NoInfer<A>) => E): (a: A) => Effect<A, E>;
1565
+ <A, E, B extends A>(self: A, refinement: Refinement<A, B>, orFailWith: (a: A) => E): Effect<B, E>;
1566
+ <A, E>(self: A, predicate: Predicate<NoInfer<A>>, orFailWith: (a: NoInfer<A>) => E): Effect<A, E>;
1567
+ };
1542
1568
  /**
1543
1569
  * This function maps the success value of an `Effect` value to a specified
1544
1570
  * constant value.
@@ -2975,8 +3001,27 @@ export declare const tap: {
2975
3001
  <A, E, R, X>(self: Effect<A, E, R>, f: NotFunction<X>): [X] extends [Effect<infer _A1, infer E1, infer R1>] ? Effect<A, E | E1, R | R1> : [X] extends [PromiseLike<infer _A1>] ? Effect<A, E | Cause.UnknownException, R> : Effect<A, E, R>;
2976
3002
  };
2977
3003
  /**
2978
- * Returns an effect that effectfully "peeks" at the failure or success of
2979
- * this effect.
3004
+ * Inspects both success and failure outcomes of an effect, performing different actions based on the result.
3005
+ *
3006
+ * @example
3007
+ * import { Effect, Random, Console } from "effect"
3008
+ *
3009
+ * // Simulate an effect that might fail
3010
+ * const task = Effect.filterOrFail(
3011
+ * Random.nextRange(-1, 1),
3012
+ * (n) => n >= 0,
3013
+ * () => "random number is negative"
3014
+ * )
3015
+ *
3016
+ * // Define an effect that logs both success and failure outcomes of the 'task'
3017
+ * const tapping = Effect.tapBoth(task, {
3018
+ * onFailure: (error) => Console.log(`failure: ${error}`),
3019
+ * onSuccess: (randomNumber) => Console.log(`random number: ${randomNumber}`)
3020
+ * })
3021
+ *
3022
+ * Effect.runFork(tapping)
3023
+ * // Example Output:
3024
+ * // failure: random number is negative
2980
3025
  *
2981
3026
  * @since 2.0.0
2982
3027
  * @category sequencing
@@ -2992,7 +3037,36 @@ export declare const tapBoth: {
2992
3037
  }): Effect<A, E | E2 | E3, R | R2 | R3>;
2993
3038
  };
2994
3039
  /**
2995
- * Returns an effect that effectually "peeks" at the defect of this effect.
3040
+ * Specifically inspects non-recoverable failures or defects in an effect (i.e., one or more `Die` causes).
3041
+ *
3042
+ * @example
3043
+ * import { Effect, Console } from "effect"
3044
+ *
3045
+ * // Create an effect that is designed to fail, simulating an occurrence of a network error
3046
+ * const task1: Effect.Effect<number, string> = Effect.fail("NetworkError")
3047
+ *
3048
+ * // this won't log anything because is not a defect
3049
+ * const tapping1 = Effect.tapDefect(task1, (cause) =>
3050
+ * Console.log(`defect: ${cause}`)
3051
+ * )
3052
+ *
3053
+ * Effect.runFork(tapping1)
3054
+ * // No Output
3055
+ *
3056
+ * // Simulate a severe failure in the system by causing a defect with a specific message.
3057
+ * const task2: Effect.Effect<number, string> = Effect.dieMessage(
3058
+ * "Something went wrong"
3059
+ * )
3060
+ *
3061
+ * // This will only log defects, not errors
3062
+ * const tapping2 = Effect.tapDefect(task2, (cause) =>
3063
+ * Console.log(`defect: ${cause}`)
3064
+ * )
3065
+ *
3066
+ * Effect.runFork(tapping2)
3067
+ * // Output:
3068
+ * // defect: RuntimeException: Something went wrong
3069
+ * // ... stack trace ...
2996
3070
  *
2997
3071
  * @since 2.0.0
2998
3072
  * @category sequencing
@@ -3002,7 +3076,23 @@ export declare const tapDefect: {
3002
3076
  <A, E, R, X, E2, R2>(self: Effect<A, E, R>, f: (cause: Cause.Cause<never>) => Effect<X, E2, R2>): Effect<A, E | E2, R | R2>;
3003
3077
  };
3004
3078
  /**
3005
- * Returns an effect that effectfully "peeks" at the failure of this effect.
3079
+ * Executes an effectful operation to inspect the failure of an effect without altering it.
3080
+ *
3081
+ * @example
3082
+ * import { Effect, Console } from "effect"
3083
+ *
3084
+ * // Create an effect that is designed to fail, simulating an occurrence of a network error
3085
+ * const task: Effect.Effect<number, string> = Effect.fail("NetworkError")
3086
+ *
3087
+ * // Log the error message if the task fails. This function only executes if there is an error,
3088
+ * // providing a method to handle or inspect errors without altering the outcome of the original effect.
3089
+ * const tapping = Effect.tapError(task, (error) =>
3090
+ * Console.log(`expected error: ${error}`)
3091
+ * )
3092
+ *
3093
+ * Effect.runFork(tapping)
3094
+ * // Output:
3095
+ * // expected error: NetworkError
3006
3096
  *
3007
3097
  * @since 2.0.0
3008
3098
  * @category sequencing
@@ -3012,7 +3102,33 @@ export declare const tapError: {
3012
3102
  <A, E, R, X, E2, R2>(self: Effect<A, E, R>, f: (e: E) => Effect<X, E2, R2>): Effect<A, E | E2, R | R2>;
3013
3103
  };
3014
3104
  /**
3015
- * Returns an effect that effectfully "peeks" at the specific tagged failure of this effect.
3105
+ * Specifically inspects a failure with a particular tag, allowing focused error handling.
3106
+ *
3107
+ * @example
3108
+ * import { Effect, Console } from "effect"
3109
+ *
3110
+ * class NetworkError {
3111
+ * readonly _tag = "NetworkError"
3112
+ * constructor(readonly statusCode: number) {}
3113
+ * }
3114
+ * class ValidationError {
3115
+ * readonly _tag = "ValidationError"
3116
+ * constructor(readonly field: string) {}
3117
+ * }
3118
+ *
3119
+ * // Create an effect that is designed to fail, simulating an occurrence of a network error
3120
+ * const task: Effect.Effect<number, NetworkError | ValidationError> =
3121
+ * Effect.fail(new NetworkError(504))
3122
+ *
3123
+ * // Apply an error handling function only to errors tagged as "NetworkError",
3124
+ * // and log the corresponding status code of the error.
3125
+ * const tapping = Effect.tapErrorTag(task, "NetworkError", (error) =>
3126
+ * Console.log(`expected error: ${error.statusCode}`)
3127
+ * )
3128
+ *
3129
+ * Effect.runFork(tapping)
3130
+ * // Output:
3131
+ * // expected error: 504
3016
3132
  *
3017
3133
  * @since 2.0.0
3018
3134
  * @category sequencing
@@ -3030,8 +3146,37 @@ export declare const tapErrorTag: {
3030
3146
  }>) => Effect<A1, E1, R1>): Effect<A, E | E1, R | R1>;
3031
3147
  };
3032
3148
  /**
3033
- * Returns an effect that effectually "peeks" at the cause of the failure of
3034
- * this effect.
3149
+ * Inspects the underlying cause of an effect's failure.
3150
+ *
3151
+ * @example
3152
+ * import { Effect, Console } from "effect"
3153
+ *
3154
+ * // Create an effect that is designed to fail, simulating an occurrence of a network error
3155
+ * const task1: Effect.Effect<number, string> = Effect.fail("NetworkError")
3156
+ *
3157
+ * // This will log the cause of any expected error or defect
3158
+ * const tapping1 = Effect.tapErrorCause(task1, (cause) =>
3159
+ * Console.log(`error cause: ${cause}`)
3160
+ * )
3161
+ *
3162
+ * Effect.runFork(tapping1)
3163
+ * // Output:
3164
+ * // error cause: Error: NetworkError
3165
+ *
3166
+ * // Simulate a severe failure in the system by causing a defect with a specific message.
3167
+ * const task2: Effect.Effect<number, string> = Effect.dieMessage(
3168
+ * "Something went wrong"
3169
+ * )
3170
+ *
3171
+ * // This will log the cause of any expected error or defect
3172
+ * const tapping2 = Effect.tapErrorCause(task2, (cause) =>
3173
+ * Console.log(`error cause: ${cause}`)
3174
+ * )
3175
+ *
3176
+ * Effect.runFork(tapping2)
3177
+ * // Output:
3178
+ * // error cause: RuntimeException: Something went wrong
3179
+ * // ... stack trace ...
3035
3180
  *
3036
3181
  * @since 2.0.0
3037
3182
  * @category sequencing
@@ -3875,6 +4020,55 @@ export declare const validateWith: {
3875
4020
  } | undefined): Effect<C, E | E1, R | R1>;
3876
4021
  };
3877
4022
  /**
4023
+ * The `Effect.zip` function allows you to combine two effects into a single
4024
+ * effect. This combined effect yields a tuple containing the results of both
4025
+ * input effects once they succeed.
4026
+ *
4027
+ * Note that `Effect.zip` processes effects sequentially: it first completes the
4028
+ * effect on the left and then the effect on the right.
4029
+ *
4030
+ * If you want to run the effects concurrently, you can use the `concurrent` option.
4031
+ *
4032
+ * @example
4033
+ * import { Effect } from "effect"
4034
+ *
4035
+ * const task1 = Effect.succeed(1).pipe(
4036
+ * Effect.delay("200 millis"),
4037
+ * Effect.tap(Effect.log("task1 done"))
4038
+ * )
4039
+ * const task2 = Effect.succeed("hello").pipe(
4040
+ * Effect.delay("100 millis"),
4041
+ * Effect.tap(Effect.log("task2 done"))
4042
+ * )
4043
+ *
4044
+ * const task3 = Effect.zip(task1, task2)
4045
+ *
4046
+ * Effect.runPromise(task3).then(console.log)
4047
+ * // Output:
4048
+ * // timestamp=... level=INFO fiber=#0 message="task1 done"
4049
+ * // timestamp=... level=INFO fiber=#0 message="task2 done"
4050
+ * // [ 1, 'hello' ]
4051
+ *
4052
+ * @example
4053
+ * import { Effect } from "effect"
4054
+ *
4055
+ * const task1 = Effect.succeed(1).pipe(
4056
+ * Effect.delay("200 millis"),
4057
+ * Effect.tap(Effect.log("task1 done"))
4058
+ * )
4059
+ * const task2 = Effect.succeed("hello").pipe(
4060
+ * Effect.delay("100 millis"),
4061
+ * Effect.tap(Effect.log("task2 done"))
4062
+ * )
4063
+ *
4064
+ * const task3 = Effect.zip(task1, task2, { concurrent: true })
4065
+ *
4066
+ * Effect.runPromise(task3).then(console.log)
4067
+ * // Output:
4068
+ * // timestamp=... level=INFO fiber=#0 message="task2 done"
4069
+ * // timestamp=... level=INFO fiber=#0 message="task1 done"
4070
+ * // [ 1, 'hello' ]
4071
+ *
3878
4072
  * @since 2.0.0
3879
4073
  * @category zipping
3880
4074
  */
@@ -3949,6 +4143,35 @@ export declare const zipRight: {
3949
4143
  }): Effect<A2, E2 | E, R2 | R>;
3950
4144
  };
3951
4145
  /**
4146
+ * The `Effect.zipWith` function operates similarly to {@link zip} by combining
4147
+ * two effects. However, instead of returning a tuple, it allows you to apply a
4148
+ * function to the results of the combined effects, transforming them into a
4149
+ * single value
4150
+ *
4151
+ * @example
4152
+ * import { Effect } from "effect"
4153
+ *
4154
+ * const task1 = Effect.succeed(1).pipe(
4155
+ * Effect.delay("200 millis"),
4156
+ * Effect.tap(Effect.log("task1 done"))
4157
+ * )
4158
+ * const task2 = Effect.succeed("hello").pipe(
4159
+ * Effect.delay("100 millis"),
4160
+ * Effect.tap(Effect.log("task2 done"))
4161
+ * )
4162
+ *
4163
+ * const task3 = Effect.zipWith(
4164
+ * task1,
4165
+ * task2,
4166
+ * (number, string) => number + string.length
4167
+ * )
4168
+ *
4169
+ * Effect.runPromise(task3).then(console.log)
4170
+ * // Output:
4171
+ * // timestamp=... level=INFO fiber=#3 message="task1 done"
4172
+ * // timestamp=... level=INFO fiber=#2 message="task2 done"
4173
+ * // 6
4174
+ *
3952
4175
  * @since 2.0.0
3953
4176
  * @category zipping
3954
4177
  */