effect 3.3.3 → 3.3.5

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/src/Effect.ts CHANGED
@@ -266,8 +266,38 @@ export const isEffect: (u: unknown) => u is Effect<unknown, unknown, unknown> =
266
266
  // -------------------------------------------------------------------------------------
267
267
 
268
268
  /**
269
- * Returns an effect that, if evaluated, will return the cached result of this
270
- * effect. Cached results will expire after `timeToLive` duration.
269
+ * Returns an effect that caches its result for a specified duration, known as
270
+ * the `timeToLive`. When the cache expires after the duration, the effect will be
271
+ * recomputed upon next evaluation.
272
+ *
273
+ * @example
274
+ * import { Effect, Console } from "effect"
275
+ *
276
+ * let i = 1
277
+ * const expensiveTask = Effect.promise<string>(() => {
278
+ * console.log("expensive task...")
279
+ * return new Promise((resolve) => {
280
+ * setTimeout(() => {
281
+ * resolve(`result ${i++}`)
282
+ * }, 100)
283
+ * })
284
+ * })
285
+ *
286
+ * const program = Effect.gen(function* () {
287
+ * const cached = yield* Effect.cachedWithTTL(expensiveTask, "150 millis")
288
+ * yield* cached.pipe(Effect.andThen(Console.log))
289
+ * yield* cached.pipe(Effect.andThen(Console.log))
290
+ * yield* Effect.sleep("100 millis")
291
+ * yield* cached.pipe(Effect.andThen(Console.log))
292
+ * })
293
+ *
294
+ * // Effect.runFork(program)
295
+ * // Output:
296
+ * // expensive task...
297
+ * // result 1
298
+ * // result 1
299
+ * // expensive task...
300
+ * // result 2
271
301
  *
272
302
  * @since 2.0.0
273
303
  * @category caching
@@ -278,10 +308,41 @@ export const cachedWithTTL: {
278
308
  } = circular.cached
279
309
 
280
310
  /**
281
- * Returns an effect that, if evaluated, will return the cached result of this
282
- * effect. Cached results will expire after `timeToLive` duration. In
283
- * addition, returns an effect that can be used to invalidate the current
284
- * cached value before the `timeToLive` duration expires.
311
+ * Similar to {@link cachedWithTTL}, this function caches an effect's result for a
312
+ * specified duration. It also includes an additional effect for manually
313
+ * invalidating the cached value before it naturally expires.
314
+ *
315
+ * @example
316
+ * import { Effect, Console } from "effect"
317
+ *
318
+ * let i = 1
319
+ * const expensiveTask = Effect.promise<string>(() => {
320
+ * console.log("expensive task...")
321
+ * return new Promise((resolve) => {
322
+ * setTimeout(() => {
323
+ * resolve(`result ${i++}`)
324
+ * }, 100)
325
+ * })
326
+ * })
327
+ *
328
+ * const program = Effect.gen(function* () {
329
+ * const [cached, invalidate] = yield* Effect.cachedInvalidateWithTTL(
330
+ * expensiveTask,
331
+ * "1 hour"
332
+ * )
333
+ * yield* cached.pipe(Effect.andThen(Console.log))
334
+ * yield* cached.pipe(Effect.andThen(Console.log))
335
+ * yield* invalidate
336
+ * yield* cached.pipe(Effect.andThen(Console.log))
337
+ * })
338
+ *
339
+ * // Effect.runFork(program)
340
+ * // Output:
341
+ * // expensive task...
342
+ * // result 1
343
+ * // result 1
344
+ * // expensive task...
345
+ * // result 2
285
346
  *
286
347
  * @since 2.0.0
287
348
  * @category caching
@@ -297,8 +358,44 @@ export const cachedInvalidateWithTTL: {
297
358
  } = circular.cachedInvalidateWithTTL
298
359
 
299
360
  /**
300
- * Returns an effect that, if evaluated, will return the lazily computed
301
- * result of this effect.
361
+ * Returns an effect that computes a result lazily and caches it. Subsequent
362
+ * evaluations of this effect will return the cached result without re-executing
363
+ * the logic.
364
+ *
365
+ * @example
366
+ * import { Effect, Console } from "effect"
367
+ *
368
+ * let i = 1
369
+ * const expensiveTask = Effect.promise<string>(() => {
370
+ * console.log("expensive task...")
371
+ * return new Promise((resolve) => {
372
+ * setTimeout(() => {
373
+ * resolve(`result ${i++}`)
374
+ * }, 100)
375
+ * })
376
+ * })
377
+ *
378
+ * const program = Effect.gen(function* () {
379
+ * console.log("non-cached version:")
380
+ * yield* expensiveTask.pipe(Effect.andThen(Console.log))
381
+ * yield* expensiveTask.pipe(Effect.andThen(Console.log))
382
+ * console.log("cached version:")
383
+ * const cached = yield* Effect.cached(expensiveTask)
384
+ * yield* cached.pipe(Effect.andThen(Console.log))
385
+ * yield* cached.pipe(Effect.andThen(Console.log))
386
+ * })
387
+ *
388
+ * // Effect.runFork(program)
389
+ * // Output:
390
+ * // non-cached version:
391
+ * // expensive task...
392
+ * // result 1
393
+ * // expensive task...
394
+ * // result 2
395
+ * // cached version:
396
+ * // expensive task...
397
+ * // result 3
398
+ * // result 3
302
399
  *
303
400
  * @since 2.0.0
304
401
  * @category caching
@@ -306,7 +403,33 @@ export const cachedInvalidateWithTTL: {
306
403
  export const cached: <A, E, R>(self: Effect<A, E, R>) => Effect<Effect<A, E, R>> = effect.memoize
307
404
 
308
405
  /**
309
- * Returns a memoized version of the specified effectual function.
406
+ * Returns a memoized version of a function with effects. Memoization ensures
407
+ * that results are stored and reused for the same inputs, reducing the need to
408
+ * recompute them.
409
+ *
410
+ * @example
411
+ * import { Effect, Random } from "effect"
412
+ *
413
+ * const program = Effect.gen(function* () {
414
+ * const randomNumber = (n: number) => Random.nextIntBetween(1, n)
415
+ * console.log("non-memoized version:")
416
+ * console.log(yield* randomNumber(10))
417
+ * console.log(yield* randomNumber(10))
418
+ *
419
+ * console.log("memoized version:")
420
+ * const memoized = yield* Effect.cachedFunction(randomNumber)
421
+ * console.log(yield* memoized(10))
422
+ * console.log(yield* memoized(10))
423
+ * })
424
+ *
425
+ * // Effect.runFork(program)
426
+ * // Example Output:
427
+ * // non-memoized version:
428
+ * // 2
429
+ * // 8
430
+ * // memoized version:
431
+ * // 5
432
+ * // 5
310
433
  *
311
434
  * @since 2.0.0
312
435
  * @category caching
@@ -317,24 +440,25 @@ export const cachedFunction: <A, B, E, R>(
317
440
  ) => Effect<(a: A) => Effect<B, E, R>> = circular.cachedFunction
318
441
 
319
442
  /**
320
- * Returns an effect that will be executed at most once, even if it is
321
- * evaluated multiple times.
443
+ * Returns an effect that executes only once, regardless of how many times it's
444
+ * called.
322
445
  *
323
446
  * @example
324
447
  * import { Effect, Console } from "effect"
325
448
  *
326
- * const program = Effect.gen(function* (_) {
327
- * const twice = Console.log("twice")
328
- * yield* _(twice, Effect.repeatN(1))
329
- * const once = yield* _(Console.log("once"), Effect.once)
330
- * yield* _(once, Effect.repeatN(1))
449
+ * const program = Effect.gen(function* () {
450
+ * const task1 = Console.log("task1")
451
+ * yield* Effect.repeatN(task1, 2)
452
+ * const task2 = yield* Effect.once(Console.log("task2"))
453
+ * yield* Effect.repeatN(task2, 2)
331
454
  * })
332
455
  *
333
- * Effect.runFork(program)
456
+ * // Effect.runFork(program)
334
457
  * // Output:
335
- * // twice
336
- * // twice
337
- * // once
458
+ * // task1
459
+ * // task1
460
+ * // task1
461
+ * // task2
338
462
  *
339
463
  * @since 2.0.0
340
464
  * @category caching
@@ -2457,7 +2581,7 @@ export const scopeWith: <A, E, R>(f: (scope: Scope.Scope) => Effect<A, E, R>) =>
2457
2581
  fiberRuntime.scopeWith
2458
2582
 
2459
2583
  /**
2460
- * Scopes all resources uses in this workflow to the lifetime of the workflow,
2584
+ * Scopes all resources used in this workflow to the lifetime of the workflow,
2461
2585
  * ensuring that their finalizers are run as soon as this workflow completes
2462
2586
  * execution, whether by success, failure, or interruption.
2463
2587
  *
package/src/Hash.ts CHANGED
@@ -4,18 +4,13 @@
4
4
  import { pipe } from "./Function.js"
5
5
  import { globalValue } from "./GlobalValue.js"
6
6
  import { hasProperty } from "./Predicate.js"
7
- import { PCGRandom, structuralRegionState } from "./Utils.js"
7
+ import { structuralRegionState } from "./Utils.js"
8
8
 
9
9
  /** @internal */
10
10
  const randomHashCache = globalValue(
11
11
  Symbol.for("effect/Hash/randomHashCache"),
12
12
  () => new WeakMap<object, number>()
13
13
  )
14
- /** @internal */
15
- const pcgr = globalValue(
16
- Symbol.for("effect/Hash/pcgr"),
17
- () => new PCGRandom()
18
- )
19
14
 
20
15
  /**
21
16
  * @since 2.0.0
@@ -78,7 +73,7 @@ export const hash: <A>(self: A) => number = <A>(self: A) => {
78
73
  */
79
74
  export const random: <A extends object>(self: A) => number = (self) => {
80
75
  if (!randomHashCache.has(self)) {
81
- randomHashCache.set(self, number(pcgr.integer(Number.MAX_SAFE_INTEGER)))
76
+ randomHashCache.set(self, number(Math.floor(Math.random() * Number.MAX_SAFE_INTEGER)))
82
77
  }
83
78
  return randomHashCache.get(self)!
84
79
  }
@@ -1,4 +1,4 @@
1
- let moduleVersion = "3.3.3"
1
+ let moduleVersion = "3.3.5"
2
2
 
3
3
  export const getCurrentVersion = () => moduleVersion
4
4