effect 3.3.4 → 3.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (103) 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/Config.js.map +1 -1
  7. package/dist/cjs/Effect.js +249 -23
  8. package/dist/cjs/Effect.js.map +1 -1
  9. package/dist/cjs/Either.js +31 -1
  10. package/dist/cjs/Either.js.map +1 -1
  11. package/dist/cjs/ManagedRuntime.js.map +1 -1
  12. package/dist/cjs/Micro.js +2383 -0
  13. package/dist/cjs/Micro.js.map +1 -0
  14. package/dist/cjs/Option.js +1 -2
  15. package/dist/cjs/Option.js.map +1 -1
  16. package/dist/cjs/Schedule.js +2 -2
  17. package/dist/cjs/Stream.js.map +1 -1
  18. package/dist/cjs/Tuple.js +16 -9
  19. package/dist/cjs/Tuple.js.map +1 -1
  20. package/dist/cjs/index.js +4 -2
  21. package/dist/cjs/index.js.map +1 -1
  22. package/dist/cjs/internal/core-effect.js +4 -2
  23. package/dist/cjs/internal/core-effect.js.map +1 -1
  24. package/dist/cjs/internal/core.js +12 -2
  25. package/dist/cjs/internal/core.js.map +1 -1
  26. package/dist/cjs/internal/fiberRuntime.js +32 -0
  27. package/dist/cjs/internal/fiberRuntime.js.map +1 -1
  28. package/dist/cjs/internal/stream.js.map +1 -1
  29. package/dist/cjs/internal/version.js +1 -1
  30. package/dist/dts/Array.d.ts +14 -0
  31. package/dist/dts/Array.d.ts.map +1 -1
  32. package/dist/dts/Cause.d.ts +1 -1
  33. package/dist/dts/Chunk.d.ts +11 -0
  34. package/dist/dts/Chunk.d.ts.map +1 -1
  35. package/dist/dts/Config.d.ts +3 -4
  36. package/dist/dts/Config.d.ts.map +1 -1
  37. package/dist/dts/Effect.d.ts +248 -20
  38. package/dist/dts/Effect.d.ts.map +1 -1
  39. package/dist/dts/Either.d.ts +35 -0
  40. package/dist/dts/Either.d.ts.map +1 -1
  41. package/dist/dts/ManagedRuntime.d.ts +15 -0
  42. package/dist/dts/ManagedRuntime.d.ts.map +1 -1
  43. package/dist/dts/Micro.d.ts +2002 -0
  44. package/dist/dts/Micro.d.ts.map +1 -0
  45. package/dist/dts/Option.d.ts +2 -0
  46. package/dist/dts/Option.d.ts.map +1 -1
  47. package/dist/dts/Schedule.d.ts +2 -2
  48. package/dist/dts/Stream.d.ts +45 -6
  49. package/dist/dts/Stream.d.ts.map +1 -1
  50. package/dist/dts/Tuple.d.ts +18 -0
  51. package/dist/dts/Tuple.d.ts.map +1 -1
  52. package/dist/dts/index.d.ts +7 -0
  53. package/dist/dts/index.d.ts.map +1 -1
  54. package/dist/dts/internal/core-effect.d.ts.map +1 -1
  55. package/dist/dts/internal/core.d.ts.map +1 -1
  56. package/dist/dts/internal/fiberRuntime.d.ts.map +1 -1
  57. package/dist/esm/Array.js +14 -0
  58. package/dist/esm/Array.js.map +1 -1
  59. package/dist/esm/Chunk.js +11 -0
  60. package/dist/esm/Chunk.js.map +1 -1
  61. package/dist/esm/Config.js.map +1 -1
  62. package/dist/esm/Effect.js +246 -20
  63. package/dist/esm/Effect.js.map +1 -1
  64. package/dist/esm/Either.js +30 -0
  65. package/dist/esm/Either.js.map +1 -1
  66. package/dist/esm/ManagedRuntime.js.map +1 -1
  67. package/dist/esm/Micro.js +2307 -0
  68. package/dist/esm/Micro.js.map +1 -0
  69. package/dist/esm/Option.js +1 -1
  70. package/dist/esm/Option.js.map +1 -1
  71. package/dist/esm/Schedule.js +2 -2
  72. package/dist/esm/Stream.js.map +1 -1
  73. package/dist/esm/Tuple.js +15 -8
  74. package/dist/esm/Tuple.js.map +1 -1
  75. package/dist/esm/index.js +7 -0
  76. package/dist/esm/index.js.map +1 -1
  77. package/dist/esm/internal/core-effect.js +2 -0
  78. package/dist/esm/internal/core-effect.js.map +1 -1
  79. package/dist/esm/internal/core.js +10 -1
  80. package/dist/esm/internal/core.js.map +1 -1
  81. package/dist/esm/internal/fiberRuntime.js +32 -0
  82. package/dist/esm/internal/fiberRuntime.js.map +1 -1
  83. package/dist/esm/internal/stream.js.map +1 -1
  84. package/dist/esm/internal/version.js +1 -1
  85. package/package.json +9 -1
  86. package/src/Array.ts +15 -0
  87. package/src/Cause.ts +1 -1
  88. package/src/Chunk.ts +12 -0
  89. package/src/Config.ts +7 -5
  90. package/src/Effect.ts +256 -20
  91. package/src/Either.ts +51 -0
  92. package/src/ManagedRuntime.ts +16 -0
  93. package/src/Micro.ts +3826 -0
  94. package/src/Option.ts +12 -1
  95. package/src/Schedule.ts +2 -2
  96. package/src/Stream.ts +60 -8
  97. package/src/Tuple.ts +18 -8
  98. package/src/index.ts +8 -0
  99. package/src/internal/core-effect.ts +33 -0
  100. package/src/internal/core.ts +18 -1
  101. package/src/internal/fiberRuntime.ts +32 -0
  102. package/src/internal/stream.ts +8 -4
  103. package/src/internal/version.ts +1 -1
@@ -228,8 +228,38 @@ export declare namespace Effect {
228
228
  */
229
229
  export declare const isEffect: (u: unknown) => u is Effect<unknown, unknown, unknown>;
230
230
  /**
231
- * Returns an effect that, if evaluated, will return the cached result of this
232
- * effect. Cached results will expire after `timeToLive` duration.
231
+ * Returns an effect that caches its result for a specified duration, known as
232
+ * the `timeToLive`. When the cache expires after the duration, the effect will be
233
+ * recomputed upon next evaluation.
234
+ *
235
+ * @example
236
+ * import { Effect, Console } from "effect"
237
+ *
238
+ * let i = 1
239
+ * const expensiveTask = Effect.promise<string>(() => {
240
+ * console.log("expensive task...")
241
+ * return new Promise((resolve) => {
242
+ * setTimeout(() => {
243
+ * resolve(`result ${i++}`)
244
+ * }, 100)
245
+ * })
246
+ * })
247
+ *
248
+ * const program = Effect.gen(function* () {
249
+ * const cached = yield* Effect.cachedWithTTL(expensiveTask, "150 millis")
250
+ * yield* cached.pipe(Effect.andThen(Console.log))
251
+ * yield* cached.pipe(Effect.andThen(Console.log))
252
+ * yield* Effect.sleep("100 millis")
253
+ * yield* cached.pipe(Effect.andThen(Console.log))
254
+ * })
255
+ *
256
+ * Effect.runFork(program)
257
+ * // Output:
258
+ * // expensive task...
259
+ * // result 1
260
+ * // result 1
261
+ * // expensive task...
262
+ * // result 2
233
263
  *
234
264
  * @since 2.0.0
235
265
  * @category caching
@@ -239,10 +269,41 @@ export declare const cachedWithTTL: {
239
269
  <A, E, R>(self: Effect<A, E, R>, timeToLive: Duration.DurationInput): Effect<Effect<A, E>, never, R>;
240
270
  };
241
271
  /**
242
- * Returns an effect that, if evaluated, will return the cached result of this
243
- * effect. Cached results will expire after `timeToLive` duration. In
244
- * addition, returns an effect that can be used to invalidate the current
245
- * cached value before the `timeToLive` duration expires.
272
+ * Similar to {@link cachedWithTTL}, this function caches an effect's result for a
273
+ * specified duration. It also includes an additional effect for manually
274
+ * invalidating the cached value before it naturally expires.
275
+ *
276
+ * @example
277
+ * import { Effect, Console } from "effect"
278
+ *
279
+ * let i = 1
280
+ * const expensiveTask = Effect.promise<string>(() => {
281
+ * console.log("expensive task...")
282
+ * return new Promise((resolve) => {
283
+ * setTimeout(() => {
284
+ * resolve(`result ${i++}`)
285
+ * }, 100)
286
+ * })
287
+ * })
288
+ *
289
+ * const program = Effect.gen(function* () {
290
+ * const [cached, invalidate] = yield* Effect.cachedInvalidateWithTTL(
291
+ * expensiveTask,
292
+ * "1 hour"
293
+ * )
294
+ * yield* cached.pipe(Effect.andThen(Console.log))
295
+ * yield* cached.pipe(Effect.andThen(Console.log))
296
+ * yield* invalidate
297
+ * yield* cached.pipe(Effect.andThen(Console.log))
298
+ * })
299
+ *
300
+ * Effect.runFork(program)
301
+ * // Output:
302
+ * // expensive task...
303
+ * // result 1
304
+ * // result 1
305
+ * // expensive task...
306
+ * // result 2
246
307
  *
247
308
  * @since 2.0.0
248
309
  * @category caching
@@ -252,39 +313,102 @@ export declare const cachedInvalidateWithTTL: {
252
313
  <A, E, R>(self: Effect<A, E, R>, timeToLive: Duration.DurationInput): Effect<[Effect<A, E>, Effect<void>], never, R>;
253
314
  };
254
315
  /**
255
- * Returns an effect that, if evaluated, will return the lazily computed
256
- * result of this effect.
316
+ * Returns an effect that computes a result lazily and caches it. Subsequent
317
+ * evaluations of this effect will return the cached result without re-executing
318
+ * the logic.
319
+ *
320
+ * @example
321
+ * import { Effect, Console } from "effect"
322
+ *
323
+ * let i = 1
324
+ * const expensiveTask = Effect.promise<string>(() => {
325
+ * console.log("expensive task...")
326
+ * return new Promise((resolve) => {
327
+ * setTimeout(() => {
328
+ * resolve(`result ${i++}`)
329
+ * }, 100)
330
+ * })
331
+ * })
332
+ *
333
+ * const program = Effect.gen(function* () {
334
+ * console.log("non-cached version:")
335
+ * yield* expensiveTask.pipe(Effect.andThen(Console.log))
336
+ * yield* expensiveTask.pipe(Effect.andThen(Console.log))
337
+ * console.log("cached version:")
338
+ * const cached = yield* Effect.cached(expensiveTask)
339
+ * yield* cached.pipe(Effect.andThen(Console.log))
340
+ * yield* cached.pipe(Effect.andThen(Console.log))
341
+ * })
342
+ *
343
+ * Effect.runFork(program)
344
+ * // Output:
345
+ * // non-cached version:
346
+ * // expensive task...
347
+ * // result 1
348
+ * // expensive task...
349
+ * // result 2
350
+ * // cached version:
351
+ * // expensive task...
352
+ * // result 3
353
+ * // result 3
257
354
  *
258
355
  * @since 2.0.0
259
356
  * @category caching
260
357
  */
261
358
  export declare const cached: <A, E, R>(self: Effect<A, E, R>) => Effect<Effect<A, E, R>>;
262
359
  /**
263
- * Returns a memoized version of the specified effectual function.
360
+ * Returns a memoized version of a function with effects. Memoization ensures
361
+ * that results are stored and reused for the same inputs, reducing the need to
362
+ * recompute them.
363
+ *
364
+ * @example
365
+ * import { Effect, Random } from "effect"
366
+ *
367
+ * const program = Effect.gen(function* () {
368
+ * const randomNumber = (n: number) => Random.nextIntBetween(1, n)
369
+ * console.log("non-memoized version:")
370
+ * console.log(yield* randomNumber(10))
371
+ * console.log(yield* randomNumber(10))
372
+ *
373
+ * console.log("memoized version:")
374
+ * const memoized = yield* Effect.cachedFunction(randomNumber)
375
+ * console.log(yield* memoized(10))
376
+ * console.log(yield* memoized(10))
377
+ * })
378
+ *
379
+ * Effect.runFork(program)
380
+ * // Example Output:
381
+ * // non-memoized version:
382
+ * // 2
383
+ * // 8
384
+ * // memoized version:
385
+ * // 5
386
+ * // 5
264
387
  *
265
388
  * @since 2.0.0
266
389
  * @category caching
267
390
  */
268
391
  export declare const cachedFunction: <A, B, E, R>(f: (a: A) => Effect<B, E, R>, eq?: Equivalence<A>) => Effect<(a: A) => Effect<B, E, R>>;
269
392
  /**
270
- * Returns an effect that will be executed at most once, even if it is
271
- * evaluated multiple times.
393
+ * Returns an effect that executes only once, regardless of how many times it's
394
+ * called.
272
395
  *
273
396
  * @example
274
397
  * import { Effect, Console } from "effect"
275
398
  *
276
- * const program = Effect.gen(function* (_) {
277
- * const twice = Console.log("twice")
278
- * yield* _(twice, Effect.repeatN(1))
279
- * const once = yield* _(Console.log("once"), Effect.once)
280
- * yield* _(once, Effect.repeatN(1))
399
+ * const program = Effect.gen(function* () {
400
+ * const task1 = Console.log("task1")
401
+ * yield* Effect.repeatN(task1, 2)
402
+ * const task2 = yield* Effect.once(Console.log("task2"))
403
+ * yield* Effect.repeatN(task2, 2)
281
404
  * })
282
405
  *
283
406
  * Effect.runFork(program)
284
407
  * // Output:
285
- * // twice
286
- * // twice
287
- * // once
408
+ * // task1
409
+ * // task1
410
+ * // task1
411
+ * // task2
288
412
  *
289
413
  * @since 2.0.0
290
414
  * @category caching
@@ -1415,6 +1539,32 @@ export declare const uninterruptible: <A, E, R>(self: Effect<A, E, R>) => Effect
1415
1539
  * @category interruption
1416
1540
  */
1417
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
+ };
1418
1568
  /**
1419
1569
  * This function maps the success value of an `Effect` value to a specified
1420
1570
  * constant value.
@@ -1758,7 +1908,7 @@ export declare const scope: Effect<Scope.Scope, never, Scope.Scope>;
1758
1908
  */
1759
1909
  export declare const scopeWith: <A, E, R>(f: (scope: Scope.Scope) => Effect<A, E, R>) => Effect<A, E, R | Scope.Scope>;
1760
1910
  /**
1761
- * Scopes all resources uses in this workflow to the lifetime of the workflow,
1911
+ * Scopes all resources used in this workflow to the lifetime of the workflow,
1762
1912
  * ensuring that their finalizers are run as soon as this workflow completes
1763
1913
  * execution, whether by success, failure, or interruption.
1764
1914
  *
@@ -3751,6 +3901,55 @@ export declare const validateWith: {
3751
3901
  } | undefined): Effect<C, E | E1, R | R1>;
3752
3902
  };
3753
3903
  /**
3904
+ * The `Effect.zip` function allows you to combine two effects into a single
3905
+ * effect. This combined effect yields a tuple containing the results of both
3906
+ * input effects once they succeed.
3907
+ *
3908
+ * Note that `Effect.zip` processes effects sequentially: it first completes the
3909
+ * effect on the left and then the effect on the right.
3910
+ *
3911
+ * If you want to run the effects concurrently, you can use the `concurrent` option.
3912
+ *
3913
+ * @example
3914
+ * import { Effect } from "effect"
3915
+ *
3916
+ * const task1 = Effect.succeed(1).pipe(
3917
+ * Effect.delay("200 millis"),
3918
+ * Effect.tap(Effect.log("task1 done"))
3919
+ * )
3920
+ * const task2 = Effect.succeed("hello").pipe(
3921
+ * Effect.delay("100 millis"),
3922
+ * Effect.tap(Effect.log("task2 done"))
3923
+ * )
3924
+ *
3925
+ * const task3 = Effect.zip(task1, task2)
3926
+ *
3927
+ * Effect.runPromise(task3).then(console.log)
3928
+ * // Output:
3929
+ * // timestamp=... level=INFO fiber=#0 message="task1 done"
3930
+ * // timestamp=... level=INFO fiber=#0 message="task2 done"
3931
+ * // [ 1, 'hello' ]
3932
+ *
3933
+ * @example
3934
+ * import { Effect } from "effect"
3935
+ *
3936
+ * const task1 = Effect.succeed(1).pipe(
3937
+ * Effect.delay("200 millis"),
3938
+ * Effect.tap(Effect.log("task1 done"))
3939
+ * )
3940
+ * const task2 = Effect.succeed("hello").pipe(
3941
+ * Effect.delay("100 millis"),
3942
+ * Effect.tap(Effect.log("task2 done"))
3943
+ * )
3944
+ *
3945
+ * const task3 = Effect.zip(task1, task2, { concurrent: true })
3946
+ *
3947
+ * Effect.runPromise(task3).then(console.log)
3948
+ * // Output:
3949
+ * // timestamp=... level=INFO fiber=#0 message="task2 done"
3950
+ * // timestamp=... level=INFO fiber=#0 message="task1 done"
3951
+ * // [ 1, 'hello' ]
3952
+ *
3754
3953
  * @since 2.0.0
3755
3954
  * @category zipping
3756
3955
  */
@@ -3825,6 +4024,35 @@ export declare const zipRight: {
3825
4024
  }): Effect<A2, E2 | E, R2 | R>;
3826
4025
  };
3827
4026
  /**
4027
+ * The `Effect.zipWith` function operates similarly to {@link zip} by combining
4028
+ * two effects. However, instead of returning a tuple, it allows you to apply a
4029
+ * function to the results of the combined effects, transforming them into a
4030
+ * single value
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.zipWith(
4045
+ * task1,
4046
+ * task2,
4047
+ * (number, string) => number + string.length
4048
+ * )
4049
+ *
4050
+ * Effect.runPromise(task3).then(console.log)
4051
+ * // Output:
4052
+ * // timestamp=... level=INFO fiber=#3 message="task1 done"
4053
+ * // timestamp=... level=INFO fiber=#2 message="task2 done"
4054
+ * // 6
4055
+ *
3828
4056
  * @since 2.0.0
3829
4057
  * @category zipping
3830
4058
  */